summaryrefslogtreecommitdiff
path: root/graphics/pgf/base/tex/generic
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/base/tex/generic')
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcore.code.tex41
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorearrows.code.tex1253
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcoreexternal.code.tex542
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcoregraphicstate.code.tex280
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcoreimage.code.tex242
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorelayers.code.tex210
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcoreobjects.code.tex101
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorepathconstruct.code.tex1477
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorepathprocessing.code.tex563
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorepathusage.code.tex661
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorepatterns.code.tex301
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorepoints.code.tex1212
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorequick.code.tex134
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorerdf.code.tex228
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcorescopes.code.tex771
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcoreshade.code.tex974
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcoretransformations.code.tex819
-rw-r--r--graphics/pgf/base/tex/generic/basiclayer/pgfcoretransparency.code.tex312
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex264
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.IEC.code.tex442
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex148
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.CDH.code.tex28
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.IEC.code.tex75
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.US.code.tex64
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.code.tex45
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.3d.code.tex79
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.barcharts.code.tex43
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex2733
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.formats.functions.code.tex16
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex565
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.sparklines.code.tex37
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex2674
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex109
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzexternalshared.code.tex1714
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex108
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex100
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryanimations.code.tex904
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryarrows.code.tex14
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryautomata.code.tex105
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex17
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex148
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex15
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex618
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex444
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex214
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex194
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.footprints.code.tex13
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.fractals.code.tex13
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.markings.code.tex31
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathmorphing.code.tex13
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathreplacing.code.tex36
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.shapes.code.tex13
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex704
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryer.code.tex40
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfadings.code.tex48
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex132
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfixedpointarithmetic.code.tex10
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex2444
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfpu.code.tex10
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex148
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarylindenmayersystems.code.tex81
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex731
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex144
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex417
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.code.tex31
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.meta.code.tex98
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryperspective.code.tex111
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex146
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplothandlers.code.tex14
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplotmarks.code.tex14
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypositioning.code.tex118
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex90
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryrdf.code.tex291
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryscopes.code.tex42
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadings.code.tex21
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadows.code.tex146
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.arrows.code.tex16
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.callouts.code.tex35
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.code.tex19
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.IEC.code.tex38
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.US.code.tex40
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.geometric.code.tex14
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.misc.code.tex14
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.multipart.code.tex36
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.symbols.code.tex17
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex77
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex134
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex33
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarythrough.code.tex36
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex381
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytrees.code.tex109
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryturtle.code.tex84
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryviews.code.tex45
-rw-r--r--graphics/pgf/base/tex/generic/frontendlayer/tikz/tikz.code.tex5599
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/LUA_CODING_STYLE27
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf.lua72
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd.lua72
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings.lua26
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/Binding.lua265
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua374
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular.lua22
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua153
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/doc.lua145
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/library.lua30
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control.lua26
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Anchoring.lua104
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua540
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua58
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua108
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua105
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Components.lua127
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Distances.lua454
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/FineTune.lua164
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua1347
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua175
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Orientation.lua303
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Sublayouts.lua536
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/doc.lua245
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/library.lua196
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua65
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Edge.lua358
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Graph.lua396
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua91
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Node.lua280
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Vector.lua256
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc.lua124
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua19
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua129
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua51
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua103
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua53
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua57
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua62
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua45
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua27
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua39
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua27
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua19
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua23
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua35
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua27
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua99
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua99
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua27
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua23
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua57
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua24
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua35
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua34
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua24
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua113
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua19
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua48
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua95
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua18
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua17
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua17
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua17
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua17
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua17
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua19
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua66
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples.lua26
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua32
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua87
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua82
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua144
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua287
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt20
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/library.lua30
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GraphAnimationCoordination.lua638
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GreedyTemporalCycleRemoval.lua177
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Skambath2016.lua875
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Supergraph.lua571
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/SupergraphVertexSplitOptimization.lua196
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/TimeSpec.lua62
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/doc.lua120
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/layered.lua107
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/library.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force.lua26
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua435
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua148
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlDeclare.lua41
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlElectric.lua105
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlIteration.lua136
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlSprings.lua59
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlStart.lua41
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/QuadTree.lua280
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua633
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua54
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua520
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua386
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua36
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/FruchtermanReingold.lua124
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/HuSpringElectricalFW.lua95
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SimpleSpring.lua74
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityCloseness.lua129
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityDegree.lua183
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/CoarseGraphFW.lua264
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceController.lua489
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceTemplate.lua44
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/InitialTemplate.lua64
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/PathLengthsFW.lua174
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/Preprocessing.lua122
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/doc.lua377
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceAbsoluteValue.lua94
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua201
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua117
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceGraphDistance.lua205
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToGrid.lua123
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToPoint.lua119
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/CircularInitialPositioning.lua60
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/GridInitialPositioning.lua60
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/RandomInitialPositioning.lua49
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/library.lua115
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/library.lua126
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface.lua26
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua191
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua968
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua78
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua1002
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/Scope.lua92
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered.lua159
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua342
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua74
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua76
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua124
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua52
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua22
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua898
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua154
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua159
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua47
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Ranking.lua291
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua476
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua81
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua136
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/edge_routing.lua49
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/library.lua94
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_positioning.lua55
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_ranking.lua72
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib.lua435
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Bezier.lua160
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua125
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Direct.lua95
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Event.lua98
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/LookupTable.lua111
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PathLengths.lua209
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua342
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua279
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Stack.lua61
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Storage.lua110
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Transform.lua120
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model.lua26
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Arc.lua653
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Collection.lua208
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Coordinate.lua306
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Digraph.lua849
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Edge.lua209
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Hyperedge.lua56
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path.lua1278
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path_arced.lua316
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Vertex.lua296
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/library.lua15
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf.lua26
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf/library.lua33
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees.lua21
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/Koerner2015.lua163
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/library.lua21
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics.lua21
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua77
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua593
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua372
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua451
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua778
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua91
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua261
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/library.lua35
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar.lua6
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/BoyerMyrvold2004.lua678
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/Embedding.lua788
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/LinkedList.lua88
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/List.lua49
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PDP.lua576
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PlanarLayout.lua159
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/ShiftMethod.lua128
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/library.lua2
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/parameters.lua144
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing.lua22
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/Hints.lua100
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/NecklaceRouting.lua90
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/library.lua29
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua183
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees.lua21
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua226
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua211
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua646
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/doc.lua340
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/library.lua35
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/experimental/tikzlibrarygraphdrawing.evolving.code.tex21
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex16
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.code.tex1165
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex17
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex136
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex17
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex19
-rw-r--r--graphics/pgf/base/tex/generic/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex262
-rw-r--r--graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.barcharts.code.tex135
-rw-r--r--graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex209
-rw-r--r--graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex198
-rw-r--r--graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.footprints.code.tex230
-rw-r--r--graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.fractals.code.tex65
-rw-r--r--graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.markings.code.tex179
-rw-r--r--graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathmorphing.code.tex294
-rw-r--r--graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathreplacing.code.tex240
-rw-r--r--graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.shapes.code.tex468
-rw-r--r--graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.text.code.tex357
-rw-r--r--graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/functions.lua626
-rw-r--r--graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/parser.lua481
-rw-r--r--graphics/pgf/base/tex/generic/libraries/luamath/pgflibraryluamath.code.tex558
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.code.tex936
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.meta.code.tex1607
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.spaced.code.tex92
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibrarycurvilinear.code.tex379
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryfadings.code.tex57
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryfixedpointarithmetic.code.tex656
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryfpu.code.tex2392
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryintersections.code.tex1172
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibrarylindenmayersystems.code.tex229
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.code.tex264
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.meta.code.tex458
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryplothandlers.code.tex1114
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryplotmarks.code.tex453
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryprofiler.code.tex530
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibraryshadings.code.tex444
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibrarysnakes.code.tex16
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibrarysvg.path.code.tex829
-rw-r--r--graphics/pgf/base/tex/generic/libraries/pgflibrarytimelines.code.tex197
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.IEC.code.tex679
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex170
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex739
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex2525
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex103
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.arrows.code.tex2361
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.callouts.code.tex951
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.code.tex21
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.geometric.code.tex4417
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.misc.code.tex1127
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.multipart.code.tex1356
-rw-r--r--graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.symbols.code.tex2775
-rw-r--r--graphics/pgf/base/tex/generic/lua/pgf/manual.lua18
-rw-r--r--graphics/pgf/base/tex/generic/lua/pgf/manual/DocumentParser.lua613
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfint.code.tex126
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmath.code.tex37
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex537
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfloat.code.tex2669
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.base.code.tex330
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.basic.code.tex803
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.code.tex267
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.comparison.code.tex179
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.integerarithmetics.code.tex124
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.misc.code.tex353
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.random.code.tex246
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.round.code.tex123
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathfunctions.trigonometric.code.tex1571
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathode.code.tex178
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathparser.code.tex1017
-rw-r--r--graphics/pgf/base/tex/generic/math/pgfmathutil.code.tex298
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmoduleanimations.code.tex1314
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmodulebending.code.tex356
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmoduledatavisualization.code.tex3216
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmoduledecorations.code.tex2191
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmodulematrix.code.tex660
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmodulenonlineartransformations.code.tex342
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmoduleoo.code.tex844
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmoduleparser.code.tex697
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmoduleplot.code.tex561
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmoduleshapes.code.tex1334
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmodulesnakes.code.tex369
-rw-r--r--graphics/pgf/base/tex/generic/modules/pgfmodulesorting.code.tex69
-rw-r--r--graphics/pgf/base/tex/generic/pgf.revision.tex4
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgf.cfg33
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf-via-dvi.def172
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf.def119
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-postscript.def600
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-svg.def1613
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvi.def394
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfm.def110
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfmx.def504
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvips.def644
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm.def217
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm4ht.def86
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-luatex.def401
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-pdftex.def398
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-tex4ht.def487
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-textures.def95
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-vtex.def110
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys-xetex.def79
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsys.code.tex1775
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsysanimations.code.tex2010
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsysprotocol.code.tex70
-rw-r--r--graphics/pgf/base/tex/generic/systemlayer/pgfsyssoftpath.code.tex204
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfcalendar.code.tex801
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfexternal.tex32
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfexternalwithdepth.tex43
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgffor.code.tex767
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfkeys.code.tex1232
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfkeyslibraryfiltered.code.tex1015
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfrcs.code.tex153
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfutil-common-lists.tex163
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfutil-common.tex913
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfutil-context.def373
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfutil-latex.def217
-rw-r--r--graphics/pgf/base/tex/generic/utilities/pgfutil-plain.def343
423 files changed, 145752 insertions, 0 deletions
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcore.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcore.code.tex
new file mode 100644
index 0000000000..b7e47f4ee3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcore.code.tex
@@ -0,0 +1,41 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesPackageRCS{pgfcore.code.tex}
+
+\newif\ifpgf@draftmode
+\def\pgf@typeout{\immediate\write0}
+
+\ifdefined\pgfmathloaded\else
+ \input pgfmath.code.tex
+\fi
+
+\ifdefined\pgfintloaded\else
+ \input pgfint.code.tex
+\fi
+
+\input pgfcorepoints.code.tex
+\input pgfcorepathconstruct.code.tex
+\input pgfcorepathusage.code.tex
+\input pgfcorescopes.code.tex
+\input pgfcoregraphicstate.code.tex
+\input pgfcoretransformations.code.tex
+\input pgfcorequick.code.tex
+\input pgfcoreobjects.code.tex
+\input pgfcorepathprocessing.code.tex
+\input pgfcorearrows.code.tex
+\input pgfcoreshade.code.tex
+\input pgfcoreimage.code.tex
+\input pgfcoreexternal.code.tex
+\input pgfcorelayers.code.tex
+\input pgfcoretransparency.code.tex
+\input pgfcorepatterns.code.tex
+\input pgfcorerdf.code.tex
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorearrows.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorearrows.code.tex
new file mode 100644
index 0000000000..7f079fa841
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorearrows.code.tex
@@ -0,0 +1,1253 @@
+% Copyright 2006, 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorearrows.code.tex}
+
+
+
+% Define a new (meta) arrow or a shorthand
+%
+% #1 = key--value pairs
+%
+% Description:
+%
+% This command is used to define a new arrow tip kind. For more
+% details on the description of the keys, please see the pgfmanual.
+%
+% name = Name of the arrow. If the name contains a dash
+% (hyphen), the text before the hyphen is the start name
+% and the text behind it the end name.
+%
+% means = If set, none of the below options may be
+% given. The effect is that whenever the arrow is
+% used, it gets replaced by this "text", which is
+% parsed by the parser.
+%
+% setup code = Code that does "precomputations". These will be
+% executed only once for each combination of the
+% dependencies. At the end of this code, you can use
+% \savethe and \save to "save" computed values, which
+% will then be available inside the "code". Values needed
+% only for the "... end" keys and the convex hull do not
+% need to be saved since these are also executed only
+% once.
+% drawing code = Code for drawing the arrow. When the cache key is set to
+% true, which is the default, the code will be protocolled
+% and the resulting code is inserted using \pgflowlevelobj.
+% cache = Boolean that decides whether the arrow can be cached. The
+% default is true, so you have to say cache=false to switch
+% caching off. In this case, each time the arrow is drawn,
+% its code is simply executed. This allows you to put things
+% like text or shadings in arrow tips.
+% bending mode = Can be set to "orthogonal", "polar", or
+% "none". Defaults to "orthogonal".
+% defaults = A list of "default" options for the arrow tip. These
+% are executed as if they were given to the arrow tip in
+% brackets. This is useful for setting up default values.
+% parameters = A list of comma-separated macro names on whose values
+% the appearance of the arrow tip depends. When an arrow
+% tip is used, these macros are expanded. If an
+% arrow tip was already installed with the same macro
+% names (and caching is true), the cached code is
+% used. Note that when you use dimensions here, add \the.
+%
+% Inside the setup code, the following macros are available:
+%
+% \pgfarrowssettipend
+% The code should draw an arrow pointing "right along the x
+% axis". The "tip" key specifies how far the arrow goes
+% along the x axis, that is, it should be the x coordinate
+% of the very tip of the arrow. In previous versions this
+% was called the "right extend". The value passed to this
+% key should be some code that sets the dimension
+% "\pgfarrowresult", which is \let to be equal to
+% \pgf@x. A \relax will be added after the code provided
+% here, so you can write things like "\pgfarrowresult=1pt".
+% \pgfarrowssetbackend
+% The leftmost x-coordinate that is still part of the
+% arrow tip (the "back end" of the arrow"). This coordinate
+% will be used when multiple arrow tips are
+% composed. Defaults to 0pt.
+% \pgfarrowssetlineend
+% The x-coordinate where a line should stop inside the arrow
+% tip so that it gets "obscured" by the arrow. Defaults to 0pt.
+% \pgfarrowssetvisualtipend
+% When the arrow tip is drawn in flex mode, it is rotated
+% such that the x-coordinates of "visual tip end" and "visual
+% back end" lie on the path. Defaults to \pgfarrowssettipend.
+% \pgfarrowssetvisualbackend
+% See above. Defaults to \pgfarrowssetbackend
+
+\def\pgfdeclarearrow#1{%
+ \let\pgf@decl@arrow@defaults\pgfutil@empty%
+ \let\pgf@decl@arrow@means\relax%
+ \let\pgf@decl@arrow@code\relax%
+ \pgfkeys{/pgf/@arrows decl/.cd,
+ name=,
+ setup code=,
+ cache=true,
+ bending mode=orthogonal,
+ parameters=,%
+ #1%
+ }%
+ \ifx\pgf@decl@arrow@name@end\pgfutil@empty%
+ \pgferror{Declaring unnamed arrow}%
+ \else%
+ \pgf@arrow@letter{name@end}%
+ \pgf@arrow@letter{name@start}%
+ \expandafter\let\csname pgf@ar@start@\pgf@decl@arrow@name@start\endcsname\pgf@decl@arrow@name@end%
+ \expandafter\let\expandafter\pgf@old@code\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname%
+ \expandafter\let\expandafter\pgf@old@means\csname pgf@ar@means@\pgf@decl@arrow@name@end\endcsname%
+ \ifx\pgf@decl@arrow@code\relax%
+ \ifx\pgf@decl@arrow@means\relax%
+ \pgferror{You must set either the 'means' or the drawing code' keys for arrow tip '\pgf@decl@arrow@name@end'}%
+ \else%
+ \ifx\pgf@old@code\relax%
+ \let\pgf@arrow@tip@sequence\pgfutil@empty%
+ \let\pgf@arrow@translate\relax%
+ \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@\pgf@decl@arrow@means\endcsname%
+ \ifx\pgf@arrows@direct\relax%
+ \let\pgf@arrows@options\pgfutil@empty%
+ \expandafter\pgfarrows@initial@parser\pgf@decl@arrow@means[]\pgf@stop%
+ \else%
+ \let\pgf@arrow@tip@sequence\pgf@arrows@direct%
+ \fi%
+ \pgf@arrow@letter@\pgf@arrow@tip@sequence{means}%
+ \expandafter\let\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname\relax%
+ \else%
+ \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already
+ defined with key 'drawing code' previously and you cannot change this}%
+ \fi%
+ \fi%
+ \else%
+ \ifx\pgf@decl@arrow@means\relax%
+ \ifx\pgf@old@means\relax%
+ \pgf@arrow@letter{code}%
+ \pgf@arrow@letter{defaults}%
+ \pgf@arrow@letter{setup}%
+ \pgf@arrow@letter{bending@mode}%
+ \pgf@arrow@letter{par}%
+ \expandafter\let\csname pgf@ar@do@cache@\pgf@decl@arrow@name@end\endcsname\pgf@decl@arrow@cache%
+ \else%
+ \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already
+ defined with key 'means' previously and you cannot change this}%
+ \fi%
+ \else%
+ \pgferror{You cannot set both the 'means' and also the 'drawing code'
+ keys for arrow tip '\pgf@decl@arrow@name@end'}%
+ \fi%
+ \fi%
+ \fi%
+}
+
+\def\pgf@arrow@letter#1{%
+ \expandafter\pgf@arrow@letter@\expandafter{\csname pgf@decl@arrow@#1\endcsname}{#1}%
+}
+\def\pgf@arrow@letter@#1#2{%
+ \expandafter\let\csname pgf@ar@#2@\pgf@decl@arrow@name@end\endcsname#1%
+}
+
+\pgfkeys{
+ /pgf/@arrows decl/.cd,
+ name/.code={%
+ \pgfutil@in@-{#1}%
+ \ifpgfutil@in@%
+ \pgf@arrows@name@decomp#1\pgf@stop%
+ \else%
+ \def\pgf@decl@arrow@name@end{#1}\let\pgf@decl@arrow@name@start\pgf@decl@arrow@name@end%
+ \fi},
+ means/.store in=\pgf@decl@arrow@means,
+ setup code/.store in=\pgf@decl@arrow@setup,
+ drawing code/.store in=\pgf@decl@arrow@code,
+ cache/.store in=\pgf@decl@arrow@cache,
+ bending mode/.is choice,
+ bending mode/none/.code=\let\pgf@decl@arrow@bending@mode\pgfutil@empty,
+ bending mode/orthogonal/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierorthogonal},
+ bending mode/polar/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierpolar},
+ parameters/.store in=\pgf@decl@arrow@par,
+ defaults/.code={%
+ \let\pgf@arrows@options\pgfutil@empty%
+ \pgfkeys{/pgf/arrow keys/.cd,#1}%
+ \let\pgf@decl@arrow@defaults\pgf@arrows@options%
+ }
+}
+
+\def\pgf@arrows@name@decomp#1-#2\pgf@stop{%
+ \def\pgf@decl@arrow@name@start{#1}%
+ \def\pgf@decl@arrow@name@end{#2}%
+}
+
+
+% Handler for defining arrow tips:
+%
+% Description:
+%
+% When you write "my name/.tip = arrow spec", this has the same
+% effect as writing \pgfdeclarearrow{name = my name, means = arrow spec}.
+
+\pgfkeys{/handlers/.tip/.code=%
+ \expandafter\expandafter\expandafter\pgf@arrows@unravel\pgfkeyscurrentpath/\pgf@stop%
+ \expandafter\pgf@arrows@key@call\expandafter{\pgf@arrows@unravelled}{#1}}
+\def\pgf@arrows@unravel#1/{\pgfutil@ifnextchar\pgf@stop{\def\pgf@arrows@unravelled{#1}\pgfutil@gobble}{\pgf@arrows@unravel}}
+\def\pgf@arrows@key@call#1#2{\pgfdeclarearrow{name={#1},means={#2}}}
+
+
+
+
+% Draw an arrow
+%
+% #1 = arrow specification
+%
+% Description:
+%
+% Draws the arrow in the given specification (and "end"
+% specification). The arrow will be drawn such that it touches the
+% origin "from the left", that is, the arrow will lie completely in
+% the half plane with negative $x$ values and the tip will end exactly
+% at the origin.
+
+\def\pgfarrowdraw#1{%
+ {%
+ \pgfsetarrowsend{#1}%
+ \pgf@arrow@compute@shortening\pgf@end@tip@sequence%
+ \pgf@arrow@draw@arrow\pgf@end@tip@sequence\pgf@xb%
+ }%
+}
+
+
+
+% Compute the length of an arrow
+%
+% #1 = arrow specification
+%
+% Description:
+%
+% In \pgf@x, this will return the total length of the arrow given as
+% #1, in \pgf@xa it will return the distance from the tip to the line
+% end.
+
+\def\pgfarrowtotallength#1{%
+ {%
+ \pgfsetarrowsend{#1}%
+ \pgf@arrow@compute@shortening\pgf@end@tip@sequence%
+ \expandafter\expandafter\expandafter%
+ }%
+ \expandafter\expandafter\expandafter\pgf@x\expandafter\the\expandafter\pgf@xb\expandafter\pgf@xa\the\pgf@xa%
+}
+
+
+
+
+
+% Sets the end arrow tip
+%
+% #1 = An arrow specification
+%
+% Description:
+%
+% An "arrow specification" is a sequence of names of meta arrow tips
+% together with options in brackets. In detail:
+%
+% In #1, consider the text from the start up to the first bracket. If
+% this text is the name of a (meta) arrow tip, we use this arrow tip
+% with the provided options. If it is the name of a arrow tip
+% shorthand, this shorthand is expanded and the options are applied to
+% each arrow tip inside the shorthand. If the text is neither or the
+% above, the first letter of text is treated as a shorthand without
+% options.
+%
+% The special arrow tip "." is used to indicate the end of the line.
+%
+% \pgfsetarrowsend{stealth[reversed]}
+% \pgfsetarrowsend{stealth[length=1pt] . stealth[length=2pt]}
+% \pgfsetarrowsend{>>>}
+% \pgfsetarrowsend{>.>}
+
+\def\pgfsetarrowsend#1{%
+ \let\pgf@arrow@tip@sequence\pgfutil@empty%
+ \pgf@arrows@translatefalse%
+ \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@#1\endcsname%
+ \ifx\pgf@arrows@direct\relax%
+ \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}%
+ \pgf@marshal%
+ \else%
+ \let\pgf@arrow@tip@sequence\pgf@arrows@direct%
+ \fi%
+ \let\pgf@end@tip@sequence\pgf@arrow@tip@sequence%
+}
+
+\newif\ifpgf@arrows@translate
+
+\def\pgfarrows@initial@parser{%
+ \pgfutil@ifnextchar[\pgfarrows@initial@parser@{\pgfarrows@initial@parser@[]}}%}
+
+\def\pgfarrows@initial@parser@[#1]{%
+ \let\pgf@arrows@options\pgfutil@empty%
+ \pgfkeys{/pgf/arrow keys/.cd,#1}%
+ \let\pgf@arrows@options@initial\pgf@arrows@options%
+ \pgfarrows@parser%
+}
+
+\def\pgfarrows@parser#1[{%
+ \pgfkeys@spdef\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \let\pgf@next\pgf@arrows@empty%
+ \else%
+ \ifx\pgf@temp\pgf@dot@text%
+ \let\pgf@next\pgf@arrows@dot@parsed%
+ \else%
+ \let\pgf@untranslated\pgf@temp%
+ \ifpgf@arrows@translate%
+ \pgf@arrow@swapper%
+ \fi%
+ % Now, let's see what we do with this...
+ \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax
+ \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax
+ % #1 should start with a single-char shorthands
+ \let\pgf@next\pgf@arrows@single@char@parser%
+ \let\pgf@temp\pgf@untranslated%
+ \else%
+ % #1 is a shorthand!
+ \let\pgf@next\pgf@arrows@shorthand@parsed%
+ \fi%
+ \else%
+ % #1 is a meta arrow!
+ \let\pgf@next\pgf@arrows@meta@parsed%
+ \fi%
+ \fi%
+ \fi%
+ \expandafter\pgf@next\pgf@temp[%
+}
+
+\def\pgf@arrows@empty[#1]{%
+ \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser%
+}
+
+\def\pgf@arrows@single@char@parser#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@dot@text%
+ \let\pgf@next\pgf@arrows@dot@parsed%
+ \else%
+ \let\pgf@untranslated\pgf@temp%
+ \ifpgf@arrows@translate%
+ \pgf@arrow@swapper%
+ \fi%
+ \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax
+ \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax
+ \let\pgf@temp\pgf@untranslated%
+ \let\pgf@next\pgf@arrows@unknown%
+ \else%
+ \let\pgf@next\pgf@arrows@shorthand@parsed%
+ \fi%
+ \else%
+ \let\pgf@next\pgf@arrows@meta@parsed%
+ \fi
+ \fi
+ \expandafter\pgf@next\pgf@temp[]%
+}
+\def\pgf@arrows@unknown#1[]#2[#3]{%
+ \pgferror{Unknown arrow tip kind '#1#2'}%
+}
+
+\def\pgf@arrows@meta@parsed#1[#2]{%
+ % Ok, run the keys #2. This will add commands to \pgf@arrows@options:
+ %
+ \let\pgf@arrows@options\pgf@arrows@options@initial%
+ \pgfkeys{/pgf/arrow keys/.cd,#2}%
+ % Append the arrow and its options to the arrow tip sequence:
+ \expandafter\pgf@arrows@meta@set\expandafter{\pgf@arrows@options}{#1}{\pgf@arrow@handle}%
+ \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser%
+}
+
+\def\pgf@arrows@parser@done#1{%
+}
+
+\def\pgf@arrows@dot@parsed#1[#2]{%
+ \pgf@arrows@append@to@tips{\pgf@arrow@handle@dot}%
+ \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser%
+}
+
+\def\pgf@arrows@meta@set#1#2#3{%
+ \pgf@arrows@append@to@tips{#3{#2}{#1}}%
+}
+\def\pgf@arrows@append@to@tips#1{%
+ \let\pgf@tempa\pgf@arrow@tip@sequence%
+ \def\pgf@tempb{#1}%
+ \ifpgf@arrows@translate%
+ \let\pgf@tempa\pgf@tempb%
+ \let\pgf@tempb\pgf@arrow@tip@sequence%
+ \fi%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@arrow@tip@sequence%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@tempa\pgf@tempb}%
+}
+
+\def\pgf@arrows@shorthand@parsed#1[#2]{%
+ \let\pgf@arrows@options\pgf@arrows@options@initial%
+ \pgfkeys{/pgf/arrow keys/.cd,#2}%
+ \ifx\pgf@arrows@options\pgfutil@empty%
+ \expandafter\pgf@arrows@append@to@tips\expandafter{%
+ \expandafter\pgf@arrow@handle@shorthand@empty\expandafter{\csname pgf@ar@means@#1\endcsname}}%
+ \else%
+ \expandafter\expandafter\expandafter\pgf@arrows@meta@set\expandafter\expandafter\expandafter{%
+ \expandafter\pgf@arrows@options\expandafter}\expandafter{\csname pgf@ar@means@#1\endcsname}{\pgf@arrow@handle@shorthand}%
+ \fi%
+ \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser%
+}
+
+
+% General handler:
+
+\def\pgf@arrow@handle@shorthand@empty#1{#1}
+
+\def\pgf@arrow@handle@shorthand#1#2{%
+ \def\pgf@temp@opt{#2}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@arrows@nested@options@temp%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@temp@opt\pgf@arrows@nested@options}%
+ \expandafter\let\expandafter\pgf@arrows@nested@options\expandafter\pgf@arrows@nested@options@temp%
+ \expandafter#1% all these expandafters to avoid creating groups, but having the options nest
+ \expandafter\def\expandafter\pgf@arrows@nested@options\expandafter{\pgf@arrows@nested@options}%
+}
+
+\let\pgf@arrows@nested@options\pgfutil@empty
+
+
+
+
+% Sets the start arrow tip
+%
+% #1 = An arrow specification
+%
+% Description:
+%
+% This works like \pgfsetarrowsend, only the order of the tips in the
+% arrow specification is reversed and the "reversed names" are used.
+%
+% \pgfsetarrowsend{<<}
+% \pgfsetarrowsend{>.>}
+
+\def\pgfsetarrowsstart#1{%
+ \let\pgf@arrow@tip@sequence\pgfutil@empty%
+ \pgf@arrows@translatetrue%
+ \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@start@#1\endcsname%
+ \ifx\pgf@arrows@direct\relax%
+ \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}%
+ \pgf@marshal%
+ \else%
+ \let\pgf@arrow@tip@sequence\pgf@arrows@direct%
+ \fi%
+ \let\pgf@start@tip@sequence\pgf@arrow@tip@sequence%
+}
+
+\def\pgf@arrow@swapper{%
+ \expandafter\let\expandafter\pgf@temp\csname pgf@ar@start@\pgf@temp\endcsname%
+ \ifx\pgf@temp\relax%
+ \def\pgf@temp{undefined}%
+ \fi%
+}
+
+\let\pgf@start@tip@sequence\pgfutil@empty
+\let\pgf@end@tip@sequence\pgfutil@empty
+
+
+\expandafter\def\csname pgf@arrows@direct@name@start@\endcsname{}
+\expandafter\def\csname pgf@arrows@direct@name@end@\endcsname{}
+
+
+% Predefined lengths and ifs
+
+\newdimen\pgfarrowsep
+
+\newif\ifpgfarrowswap
+\newif\ifpgfarrowreversed
+\newif\ifpgfarrowharpoon
+\newif\ifpgfarrowopen
+
+\let\pgf@arrows@stroke@color\pgfutil@empty
+\let\pgf@arrows@fill@color\pgfutil@empty
+
+\def\pgfarrows@length@scale{1}
+\def\pgfarrows@width@scale{1}
+\def\pgfarrows@slant{0}
+
+\let\pgfarrows@scale@list\pgfutil@empty
+\def\pgfarrowsaddtolengthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@length@scale#1}}
+\def\pgfarrowsaddtowidthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@width@scale#1}}
+
+\pgfkeys{
+ /pgf/arrow keys/.cd,
+ scale/.code={%
+ \pgfmathparse{#1}%
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}%
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}%
+ },
+ scale length/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}},
+ scale width/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}},
+ slant/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@slant\expandafter{\pgfmathresult}}},
+ sep/.code={
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowsep\pgf@x}%
+ },
+ sep/.default=0.88pt .3 1,
+ %
+ swap/.code=\pgfarrowsaddtooptions{\ifpgfarrowswap\pgfarrowswapfalse\else\pgfarrowswaptrue\fi},
+ reversed/.code=\pgfarrowsaddtooptions{\ifpgfarrowreversed\pgfarrowreversedfalse\else\pgfarrowreversedtrue\fi},
+ harpoon/.is choice,
+ harpoon/.default=true,
+ harpoon/true/.code=\pgfarrowsaddtooptions{\pgfarrowharpoontrue},
+ harpoon/false/.code=\pgfarrowsaddtooptions{\pgfarrowharpoonfalse},
+ left/.style={harpoon},
+ right/.style={harpoon,swap},
+ %
+ color/.code=\pgfarrowsaddtooptions{\def\pgf@arrows@stroke@color{#1}},
+ fill/.code={%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@nonetext%
+ \pgfarrowsaddtooptions{\pgfarrowopentrue}
+ \else
+ \pgfarrowsaddtooptions{\pgfarrowopenfalse\def\pgf@arrows@fill@color{#1}}
+ \fi
+ },
+ fill/.value required,
+ open/.style={fill=none},
+ .unknown/.code={
+ \expandafter\pgfutil@in@\expandafter!\expandafter{\pgfkeyscurrentname}%
+ \ifpgfutil@in@%
+ % this is a color!
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}%
+ \else%
+ \pgfutil@doifcolorelse{\pgfkeyscurrentname}
+ {%
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}%
+ }
+ {%
+ \edef\pgf@temp{\pgfkeyscurrentname}%
+ \pgfkeys{/errors/unknown key/.expand once=\expandafter{\pgf@temp}{#1}}%
+ }
+ \fi
+ }
+}
+\def\pgf@nonetext{none}
+
+\def\pgfarrowsaddtooptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options#1}}
+\def\pgfarrowsaddtolateoptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options\pgf@arrows@add@to@late@options{#1}}}
+\def\pgf@arrows@add@to@late@options#1{\expandafter\def\expandafter\pgf@arrows@late@options\expandafter{\pgf@arrows@late@options#1}}
+
+
+
+\def\pgfarrowsthreeparameters#1{%
+ \pgfarrowsthreeparameters@#1 +0 +0 +0 \pgf@stop%
+}
+\def\pgfarrowsthreeparameters@#1 #2 #3 #4\pgf@stop{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgfmathsetmacro\pgf@temp@a{#2}%
+ \pgfmathsetmacro\pgf@temp@b{#3}%
+ \edef\pgfarrowstheparameters{{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}%
+}
+
+\def\pgfarrowsfourparameters#1{%
+ \pgfarrowsfourparameters@#1 +0 +0 +0 \pgf@stop%
+}
+\def\pgfarrowsfourparameters@#1:#2 #3 #4 #5\pgf@stop{%
+ \pgfmathsetmacro\pgf@temp@z{#1}%
+ \pgfmathsetlength\pgf@x{#2}%
+ \pgfmathsetmacro\pgf@temp@a{#3}%
+ \pgfmathsetmacro\pgf@temp@b{#4}%
+ \edef\pgfarrowstheparameters{{\pgf@temp@z}{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}%
+}
+
+\def\pgfarrows@angle@setup#1#2#3#4{%
+ \pgfarrowslinewidthdependent{#2}{#3}{#4}
+ \pgf@xc\pgf@x
+ \pgf@yc#1 pt%
+ \pgf@yc.5\pgf@yc%
+ \pgfpointpolar{\pgf@yc}{\pgf@xc}
+ \pgfarrowlength\pgf@x%
+ \pgf@y2\pgf@y%
+ \expandafter\pgf@arrows@add@to@late@options\expandafter{\expandafter\pgfarrowwidth\the\pgf@y}%
+}
+
+\def\pgfarrows@angle@setup@prime#1{%
+ \pgf@yc#1 pt %
+ \pgf@yc=0.5\pgf@yc
+ \pgfmathtan@{\pgf@sys@tonumber\pgf@yc}%
+ \pgfarrowwidth\pgfmathresult\pgfarrowlength%
+ \pgfarrowwidth2\pgfarrowwidth%
+}
+
+\def\pgfarrowslinewidthdependent#1#2#3{%
+ \pgf@x#1%
+ \ifdim\pgfinnerlinewidth>0pt%
+ \pgf@arrows@inner@line@width@dep{#2}{#3}%
+ \else%
+ \advance\pgf@x by#2\pgflinewidth%
+ \fi%
+}
+\def\pgf@arrows@inner@line@width@dep#1#2{%
+ % #1*((1-#2/2)*full line width - (#2/2) * inner line width)
+ % Compute "real" line width
+ \pgf@xa\pgflinewidth%
+ \pgf@xb-.5\pgflinewidth%
+ \pgf@xb#2\pgf@xb%
+ \advance\pgf@xa by\pgf@xb%
+ \pgf@xb\pgfinnerlinewidth%
+ \pgf@xb-.5\pgf@xb
+ \advance\pgf@xa by#2\pgf@xb%
+ \advance\pgf@x by#1\pgf@xa%
+}
+
+
+\def\pgfarrowslengthdependent#1#2#3#4{%
+ #4#1%
+ \advance#4by#2\pgfarrowlength%
+ \advance#4by#3\pgflinewidth%
+}
+
+
+
+% Build the full name:
+
+\def\pgf@arrow@fullname#1{pgf@@ar@#1@\the\pgflinewidth @\pgfinnerlinewidth @\ifpgfarrowreversed r\fi @\pgf@arrows@stroke@color @\pgf@arrows@fill@color @\csname pgf@ar@par@#1\endcsname}
+\def\pgf@arrow@id@count{0}%
+
+% Compute the arrow id of an arrow
+%
+% #1 = arrow name
+% #2 = options
+%
+% Description:
+%
+% Returns the an id in \pgf@arrow@id that identifies the instantiation
+% of the given arrow. If the arrow was not instantiated, this happens now.
+
+\def\pgfarrows@getid#1#2{%
+ % Execute options:
+ \let\pgf@arrows@late@options\pgfutil@empty%
+ % 1. Defaults:
+ \csname pgf@ar@defaults@#1\endcsname%
+ % 2. Scope:
+ \pgf@arrows@options@scope
+ % 3. Local:
+ #2\relax%
+ % 4. Nested:
+ \pgf@arrows@nested@options%
+ % 5. Last options:
+ \pgf@arrows@late@options%
+ % 6. Scaling:
+ \pgfarrows@scale@list%
+ % Now, test:
+ \expandafter\global\expandafter\let\expandafter\pgf@arrow@id\csname\pgf@arrow@fullname{#1}\endcsname\relax%
+ \ifx\pgf@arrow@id\relax%
+ \pgf@arrows@instantiate{#1}
+ \fi%
+}
+
+\def\pgf@arrows@instantiate#1{%
+ % Not defined. Rats!
+ % Allocate new id:
+ \pgfutil@tempcnta\pgf@arrow@id@count\relax%
+ \advance\pgfutil@tempcnta by1\relax%
+ \xdef\pgf@arrow@id@count{\the\pgfutil@tempcnta}%
+ \expandafter\global\expandafter\let\csname\pgf@arrow@fullname{#1}\endcsname\pgf@arrow@id@count%
+ \global\let\pgf@arrow@id\pgf@arrow@id@count%
+ {%
+ \pgfclearid%
+ \csname pgf@ar@setup@#1\endcsname%
+ % Handle reversal
+ \ifpgfarrowreversed%
+ % Compute transformation:
+ \pgf@arrows@handle@reverse%
+ \fi%
+ % Save computed values
+ \expandafter\global\expandafter\let\csname pgf@ar@saves@\pgf@arrow@id\endcsname\pgf@arrows@saves%
+ \expandafter\global\expandafter\let\csname pgf@ar@hull@\pgf@arrow@id\endcsname\pgf@arrows@convexhull%
+ \expandafter\xdef\csname pgf@ar@ends@\pgf@arrow@id\endcsname{{\pgf@arrows@the@tipend}{\pgf@arrows@the@backend}{\pgf@arrows@the@lineend}}%
+ \expandafter\xdef\csname pgf@ar@visual@\pgf@arrow@id\endcsname{{\pgf@arrows@the@visualtipend}{\pgf@arrows@the@visualbackend}{}}%
+ % Save code (needed for bending)
+ \edef\pgf@arrow@code{%
+ \ifpgfarrowreversed\noexpand\pgftransformxscale{-1}\fi%
+ \expandafter\noexpand\csname pgf@ar@code@#1\endcsname%
+ }%
+ \expandafter\global\expandafter\let\csname pgf@ar@inst@code@\pgf@arrow@id\endcsname\pgf@arrow@code%
+ % Should we cache?
+ \expandafter\ifx\csname pgf@ar@do@cache@#1\endcsname\pgf@truetext%
+ \pgfsysprotocol@getcurrentprotocol\pgf@arrow@temp%
+ {%
+ \pgfinterruptpath%
+ \let\pgfusepath=\pgf@nousepath@here%
+ \pgf@relevantforpicturesizefalse%
+ \pgftransformreset%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfscope%
+ \pgf@arrow@code%
+ \endpgfscope%
+ \pgfsysprotocol@getcurrentprotocol\pgf@@arrow@temp%
+ \expandafter\gdef\expandafter\pgf@arrow@code\expandafter{\expandafter\pgfsysprotocol@literal\expandafter{\pgf@@arrow@temp}}%
+ \endpgfinterruptpath%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgf@arrow@temp%
+ \fi%
+ \expandafter\global\expandafter\let\csname pgf@ar@cache@\pgf@arrow@id\endcsname\pgf@arrow@code%
+ }%
+}
+\def\pgf@truetext{true}
+
+% Ok, now run setup:
+\def\pgf@arrows@copy@tipend{\pgf@arrows@the@tipend}
+\def\pgf@arrows@copy@backend{\pgf@arrows@the@backend}
+\def\pgf@arrows@copy@lineend{\pgf@arrows@the@lineend}
+\def\pgf@arrows@zeropt{0pt}%
+
+\let\pgf@arrows@saves\pgfutil@empty%
+\let\pgf@arrows@convexhull\pgfutil@empty%
+\let\pgf@arrows@the@tipend\pgf@arrows@zeropt%
+\let\pgf@arrows@the@backend\pgf@arrows@zeropt%
+\let\pgf@arrows@the@lineend\pgf@arrows@zeropt%
+\let\pgf@arrows@the@visualtipend\pgf@arrows@copy@tipend%
+\let\pgf@arrows@the@visualbackend\pgf@arrows@copy@backend%
+
+
+\def\pgf@arrows@handle@reverse{%
+ \pgf@x\pgf@arrows@the@visualtipend\pgf@x-\pgf@x%
+ \pgf@y\pgf@arrows@the@visualbackend\pgf@y-\pgf@y
+ \edef\pgf@arrows@the@visualtipend{\the\pgf@y}%
+ \edef\pgf@arrows@the@visualbackend{\the\pgf@x}%
+ \pgf@x\pgf@arrows@the@tipend\pgf@x-\pgf@x%
+ \pgf@y\pgf@arrows@the@backend\pgf@y-\pgf@y
+ \edef\pgf@arrows@the@tipend{\the\pgf@y}%
+ \edef\pgf@arrows@the@backend{\the\pgf@x}%
+ \pgf@x\pgf@arrows@the@lineend\pgf@x-\pgf@x\edef\pgf@arrows@the@lineend{\the\pgf@x}%
+ \let\pgf@temp\pgf@arrows@convexhull%
+ \let\pgf@arrows@convexhull\pgfutil@empty%
+ \let\pgf@arrow@hull@point\pgf@arrow@hull@point@reverse%
+ \pgf@temp%
+}
+\def\pgf@arrow@hull@point@reverse#1#2{%
+ \pgf@x#1%
+ \pgfarrowshullpoint{-\pgf@x}{#2}%
+}
+
+\def\pgf@nousepath@here#1{\pgferror{The definition of an arrow may not use \string\pgfusepath}}
+
+\def\pgfarrowssavethe#1{%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@arrows@saves%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter#1\the#1\relax}
+}
+
+\def\pgfarrowssave#1{%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@arrows@saves%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter\def\expandafter#1\expandafter{#1}}
+}
+
+\def\pgfarrowshullpoint#1#2{%
+ \pgf@x#1\relax%
+ \pgf@y#2\relax%
+ \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}%
+}
+
+\def\pgfarrowsupperhullpoint#1#2{%
+ \pgf@x#1\relax%
+ \pgf@y#2\relax%
+ \ifdim\pgf@y>0pt
+ \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}\ifpgfarrowharpoon\else\noexpand\pgf@arrow@hull@point{\the\pgf@x}{-\the\pgf@y}\fi}%
+ \else
+ \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}%
+ \fi
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}%
+}
+
+\def\pgfarrowssettipend#1{\pgf@x#1\edef\pgf@arrows@the@tipend{\the\pgf@x}}
+\def\pgfarrowssetbackend#1{\pgf@x#1\edef\pgf@arrows@the@backend{\the\pgf@x}}
+\def\pgfarrowssetlineend#1{\pgf@x#1\edef\pgf@arrows@the@lineend{\the\pgf@x}}
+\def\pgfarrowssetvisualtipend#1{\pgf@x#1\edef\pgf@arrows@the@visualtipend{\the\pgf@x}}
+\def\pgfarrowssetvisualbackend#1{\pgf@x#1\edef\pgf@arrows@the@visualbackend{\the\pgf@x}}
+
+
+% Internal computation of the line end (shortening) for an arrow
+%
+% #1 = arrow tip list
+%
+% Description:
+%
+% \pgf@xa will contain the necessary path shortening for the given
+% arrow tip list, \pgf@xb will contain the total length of the arrow
+% tip list (sum of the differences between tip end and back end plus
+% the seps).
+
+\def\pgf@arrow@compute@shortening#1{%
+ \let\pgf@arrow@handle\pgf@arrow@compute@shortening@
+ \let\pgf@arrow@handle@dot\pgf@arrow@after@line@endtrue%
+ \pgf@arrow@after@line@endfalse%
+ \pgf@xa0pt%
+ \pgf@xb0pt%
+ #1%
+}
+\newif\ifpgf@arrow@after@line@end
+
+\def\pgf@arrow@compute@shortening@#1#2{%
+ {\pgfarrows@getid{#1}{#2}\ifnum\pgf@arrow@flex@mode>0\relax\global\pgf@precise@shorteningtrue\fi\expandafter}\expandafter\pgf@x\the\pgfarrowsep%
+ \expandafter\expandafter\expandafter\pgf@arrow@cont@short\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
+}
+\def\pgf@dot@text{.}
+
+\def\pgf@arrow@cont@short#1#2#3{% tip end, back end, line end, sep
+ \advance\pgf@xb by#1%
+ \pgf@xc#2%
+ \advance\pgf@xb by-\pgf@xc%
+ \advance\pgf@xb by\pgf@x%
+ \ifpgf@arrow@after@line@end%
+ \advance\pgf@xa by#1%
+ \advance\pgf@xa by\pgf@x%
+ \pgf@xc#2%
+ \advance\pgf@xa by-\pgf@xc%
+ \else%
+ \pgf@xa#1%
+ \advance\pgf@xa by\pgf@x%
+ \pgf@xc#3%
+ \advance\pgf@xa by-\pgf@xc%
+ \fi%
+}
+
+
+
+\def\pgf@arrow@rigid@arrow#1#2{%
+ {%
+ \pgf@xb=#2%
+ \pgftransformxshift{-\pgf@xb}%
+ \let\pgf@arrow@handle\pgf@arrow@rigid
+ \let\pgf@arrow@handle@dot\relax%
+ #1%
+ }%
+}
+
+
+\def\pgf@arrow@rigid#1#2{%
+ % Prepare:
+ {%
+ \pgfarrows@getid{#1}{#2}%
+ % Do shift:
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
+ % Do slant:
+ \ifdim\pgfarrows@slant pt=0pt%
+ \else%
+ \pgftransformxslant{\pgfarrows@slant}%
+ \fi%
+ % do swap:
+ \ifpgfarrowswap%
+ \pgftransformyscale{-1}%
+ \fi%
+ {%
+ \csname pgf@ar@saves@\pgf@arrow@id\endcsname%
+ \pgf@arrows@rigid@hull%
+ }%
+ \expandafter}%
+ % Transform to next tip:
+ \expandafter\pgftransformxshift\expandafter{\the\pgf@xc}%
+}
+
+
+
+
+% Draw an arrow
+%
+% #1 = arrow tip list
+% #2 = total length of the arrow (the value of \pgf@xb computed by
+% \pgf@arrow@compute@shortening)
+%
+% Description:
+%
+% Draws an arrow tip list. The coordinate system must have been
+% transformed so that the to-be-drawn arrow points right and should
+% "end" at the origin.
+
+\def\pgf@arrow@draw@arrow#1#2{%
+ {%
+ \pgf@xb=#2%
+ \pgftransformxshift{-\pgf@xb}%
+ \let\pgf@arrow@handle\pgf@arrow@drawer
+ \let\pgf@arrow@handle@dot\relax%
+ #1%
+ }%
+}
+
+
+\def\pgf@arrow@drawer#1#2{%
+ % Prepare:
+ {%
+ \pgfarrows@getid{#1}{#2}%
+ % Do shift:
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
+ % Do slant:
+ \ifdim\pgfarrows@slant pt=0pt%
+ \else%
+ \pgftransformxslant{\pgfarrows@slant}%
+ \fi%
+ % do swap:
+ \ifpgfarrowswap%
+ \pgftransformyscale{-1}%
+ \fi%
+ {%
+ \csname pgf@ar@saves@\pgf@arrow@id\endcsname%
+ \pgfscope%
+ \pgf@arrows@color@setup%
+ \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname%
+ \endpgfscope%
+ \pgf@arrows@rigid@hull%
+ }%
+ \expandafter}%
+ % Transform to next tip:
+ \expandafter\pgftransformxshift\expandafter{\the\pgf@xc}%
+}
+
+\def\pgf@arrows@color@setup@restore@std@colors{%
+ % we want to allow 'arrows={fill=pgffillcolor}'. To this end, we have to ensure that \string\color@pgffillcolor is known.
+ % we can safely keep the macro in the current TeX group since it has global character anyway.
+ %
+ % Note that declaring \string\color@pgfstrokecolor as \global macro causes save stack issues and should be avoided.
+ \pgfutil@namelet{\string\color@pgfstrokecolor}{pgf@strokecolor@global}%
+ \pgfutil@namelet{\string\color@pgffillcolor}{pgf@fillcolor@global}%
+ %
+}%
+
+\def\pgf@arrows@color@setup{%
+ \ifx\pgf@arrows@stroke@color\pgfutil@empty\else\pgfsetstrokecolor{\pgf@arrows@stroke@color}\fi%
+ \ifx\pgf@arrows@fill@color\pgfutil@empty%
+ \ifx\pgf@strokecolor@global\pgf@fillcolor@global
+ \else
+ \pgf@arrows@color@setup@restore@std@colors
+ \pgfsetfillcolor{pgfstrokecolor}%
+ \fi%
+ \else%
+ \pgf@arrows@color@setup@restore@std@colors
+ \pgfsetfillcolor{\pgf@arrows@fill@color}%
+ \fi%
+}
+
+\def\pgf@arrow@drawer@shift#1#2#3{% tip end, back end, line end, sep
+ \pgf@xb#2\pgftransformxshift{-\pgf@xb}%
+ \pgf@xc#1%
+ \advance\pgf@xc by\pgfarrowsep%
+ \advance\pgf@xc by-\pgf@xb%
+}
+
+\def\pgf@arrows@rigid@hull{%
+ \ifpgf@relevantforpicturesize%
+ % Do bb update:
+ \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname%
+ \ifx\pgf@temp\pgfutil@empty\else%
+ \let\pgf@arrow@hull@point\pgf@arrow@hull@point@first%
+ \pgf@temp%
+ \pgf@arrow@update@bb%
+ \fi%
+ \fi
+}
+
+
+% Convex hull stuff:
+
+\def\pgf@arrow@hull@point@first#1#2{%
+% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}%
+ \pgf@x#1\pgf@y#2%
+ \pgf@xa\pgf@pt@aa\pgf@x%
+ \advance\pgf@xa by\pgf@pt@ba\pgf@y%
+ \pgf@ya\pgf@pt@ab\pgf@x%
+ \advance\pgf@ya by\pgf@pt@bb\pgf@y%
+ \pgf@xb\pgf@xa\pgf@yb\pgf@ya%
+ \let\pgf@arrow@hull@point\pgf@arrow@hull@point@other%
+}
+\def\pgf@arrow@hull@point@other#1#2{%
+% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}%
+ \pgfutil@tempdima#1\pgfutil@tempdimb#2%
+ \pgf@x\pgf@pt@aa\pgfutil@tempdima%
+ \advance\pgf@x by\pgf@pt@ba\pgfutil@tempdimb%
+ \pgf@y\pgf@pt@ab\pgfutil@tempdima%
+ \advance\pgf@y by\pgf@pt@bb\pgfutil@tempdimb%
+ \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi%
+ \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi%
+}
+
+\def\pgf@arrow@update@bb{%
+ \advance\pgf@xa by\pgf@pt@x%
+ \advance\pgf@ya by\pgf@pt@y%
+ \advance\pgf@xb by\pgf@pt@x%
+ \advance\pgf@yb by\pgf@pt@y%
+ \ifdim\pgf@picmaxx=-16000pt\relax%
+ \global\pgf@picminx\pgf@xa%
+ \global\pgf@picmaxx\pgf@xb%
+ \global\pgf@picminy\pgf@ya%
+ \global\pgf@picmaxy\pgf@yb%
+ \else%
+ \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi%
+ \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi%
+ \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi%
+ \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi%
+ \fi%
+}
+
+
+
+% Sets arrows
+%
+% #1 = An arrow specification of the form
+% <start spec>-<end spec>. This will call \pgfsetstartarrow{start
+% spec} and \pgfsetendarrow{end spec}.
+%
+% Alternatively, it may be of the form [options]. In this case,
+% the arrow options are set for the local scope and all arrows in
+% the current scope will have these options set.
+%
+% Example:
+%
+% \pgfsetarrows{-to}
+
+\def\pgfsetarrows#1{\pgf@arrows#1\pgf@stop}
+\def\pgf@arrows{\pgfutil@ifnextchar[\pgf@arrows@test@opt\pgf@arrows@}%}
+\def\pgf@arrows@#1-#2\pgf@stop{%
+ \pgfsetarrowsstart{#1}%
+ \pgfsetarrowsend{#2}%
+}
+\def\pgf@arrows@test@opt[{%
+ \pgfutil@ifnextchar-{\pgf@arrows@[}%} go back to normal reading for compat. reasons.
+ \pgf@arrows@test@opt@%
+}
+\def\pgf@arrows@test@opt@#1]{%
+ \pgfutil@ifnextchar\pgf@stop{%
+ \let\pgf@arrows@options\pgf@arrows@options@scope%
+ \pgfkeys{/pgf/arrow keys/.cd,#1}%
+ \let\pgf@arrows@options@scope\pgf@arrows@options%
+ % Ok, setup the options
+ \pgfutil@gobble%
+ }{%
+ \pgf@arrows@[#1]% Oops: go back to normal mode
+ }%
+}
+
+\let\pgf@arrows@options@scope\pgfutil@empty
+
+
+
+
+%
+% Predefined arrows:
+%
+
+
+% A dot is used to indicate the end of the line:
+
+\pgfdeclarearrow{
+ name = .,
+ drawing code =
+}
+
+
+% An underscore adds a space as in >_> or >_ >. However, it will be
+% faster to say ">[sep] >" or ">[sep=2pt] >".
+
+\pgfdeclarearrow{
+ name = _,
+ defaults = {sep},
+ drawing code =
+}
+
+
+
+% Default shorthands:
+
+\pgfdeclarearrow{ name = To, means = } % forward declaration
+\pgfdeclarearrow{ name = Bar, means = } % forward declaration
+\pgfkeys{
+ <-> /.tip = {To},
+ >-< /.tip = {>[reversed]},
+ | /.tip = {Bar}
+}
+
+
+
+% Compatibility with old arrow system:
+
+\pgfkeys {}
+
+\def\pgf@arrows@direct@def#1#2{\expandafter\pgf@arrows@direct@def@\expandafter{\csname pgf@ar@means@#2\endcsname}{#1}}
+\def\pgf@arrows@direct@def@#1#2{\expandafter\def\csname pgf@arrows@direct@name@#2\endcsname{\pgf@arrow@handle@shorthand@empty{#1}}}
+\pgf@arrows@direct@def{start@[}{]}
+\pgf@arrows@direct@def{start@]}{[}
+\pgf@arrows@direct@def{start@spaced [}{spaced ]}
+\pgf@arrows@direct@def{start@spaced ]}{spaced [}
+\pgf@arrows@direct@def{end@[}{[}
+\pgf@arrows@direct@def{end@]}{]}
+\pgf@arrows@direct@def{end@spaced [}{spaced [}
+\pgf@arrows@direct@def{end@spaced ]}{spaced ]}
+
+\def\pgfsetarrowoptions#1#2{\expandafter\def\csname pgf@arrow@compat@opt@#1\endcsname{#2}}
+\def\pgfgetarrowoptions#1{\csname pgf@arrow@compat@opt@#1\endcsname}
+\def\pgfarrowsdeclare#1#2#3#4{%
+ \pgfdeclarearrow{ name ={#1}-{#2}, setup code ={#3}, drawing code={#4}, parameters/.expand once={\csname pgf@arrow@compat@opt@#2\endcsname}}%
+ \expandafter\def\csname pgf@arrow@compat@opt@#2\endcsname{0}}
+\def\pgfarrowsleftextend#1{\pgfmathsetlength\pgf@xa{#1}\pgfarrowssetbackend{\pgf@xa}}
+\def\pgfarrowsrightextend#1{\pgfmathsetlength\pgf@xb{#1}\pgfarrowssettipend{\pgf@xb}}
+\def\pgfarrowsdeclarealias#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means ={#4} } }
+\def\pgfarrowsdeclarereversed#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means={{#4}[reversed]}}}
+\def\pgfarrowsdeclarecombine{\pgfutil@ifnextchar*{\pgfarrowsdeclarecombine@star}{\pgf@@arrowsdeclarecombine}}
+\def\pgf@@arrowsdeclarecombine{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine}{\pgf@arrowsdeclarecombine[0pt]}}
+\def\pgf@arrowsdeclarecombine[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi%
+ \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp]#6}}}
+\def\pgf@linewidth@text{\pgflinewidth}
+\def\pgfarrowsdeclarecombine@star*{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine@star}{\pgf@arrowsdeclarecombine@star[0pt]}}
+\def\pgf@arrowsdeclarecombine@star[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi%
+ \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp].#6}}}
+\def\pgfarrowsdeclaredouble{\pgfutil@ifnextchar[{\pgf@arrowsdeclaredouble}{\pgf@arrowsdeclaredouble[0pt]}}
+\def\pgf@arrowsdeclaredouble[#1]#2#3#4#5{\pgfarrowsdeclarecombine[#1]{#2}{#3}{#4}{#5}{#4}{#5}}
+\def\pgfarrowsdeclaretriple{\pgfutil@ifnextchar[{\pgf@arrowsdeclaretriple}{\pgf@arrowsdeclaretriple[0pt]}}
+\def\pgf@arrowsdeclaretriple[#1]#2#3#4#5{ \pgfarrowsdeclarecombine[#1]{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}{#4}{#5}%
+ \pgfarrowsdeclarecombine[#1]{#2}{#3}{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}}
+\def\pgf@linewidthtext{\pgflinewidth}
+
+\pgfarrowsdeclare{stealth}{stealth}
+{
+ \pgfutil@tempdima=0.28pt%
+ \pgfutil@tempdimb=\pgflinewidth%
+ \ifdim\pgfinnerlinewidth>0pt%
+ \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}%
+ \fi%
+ \advance\pgfutil@tempdima by.3\pgfutil@tempdimb%
+ \pgfarrowsleftextend{+-3\pgfutil@tempdima}
+ \pgfarrowsrightextend{+5\pgfutil@tempdima}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \pgfutil@tempdimb=\pgflinewidth%
+ \ifdim\pgfinnerlinewidth>0pt%
+ \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}%
+ \fi%
+ \advance\pgfutil@tempdima by.3\pgfutil@tempdimb%
+ \pgfpathmoveto{\pgfqpoint{5\pgfutil@tempdima}{0pt}}
+ \pgfpathlineto{\pgfqpoint{-3\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfpointorigin}
+ \pgfpathlineto{\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfusepathqfill
+}
+\pgfarrowsdeclarereversed{stealth reversed}{stealth reversed}{stealth}{stealth}
+\pgfarrowsdeclare{to}{to}
+{
+ \pgfutil@tempdima=-0.84pt%
+ \advance\pgfutil@tempdima by-1.3\pgflinewidth%
+ \pgfutil@tempdimb=0.21pt%
+ \advance\pgfutil@tempdimb by.625\pgflinewidth%
+ \pgfarrowsleftextend{+\pgfutil@tempdima}
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfsetlinewidth{0.8\pgflinewidth}
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{-3\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-2.75\pgfutil@tempdima}{2.5\pgfutil@tempdima}}
+ {\pgfqpoint{0pt}{0.25\pgfutil@tempdima}}
+ {\pgfqpoint{0.75\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfqpoint{0pt}{-0.25\pgfutil@tempdima}}
+ {\pgfqpoint{-2.75\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}
+ {\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfusepathqstroke
+}
+\pgfkeys{To /.tip = to}
+\pgfarrowsdeclare{to reversed}{to reversed}
+{
+ \pgfutil@tempdima=-0.21pt%
+ \advance\pgfutil@tempdima by-0.475\pgflinewidth%
+ \pgfutil@tempdimb=0.98pt%
+ \advance\pgfutil@tempdimb by1.45\pgflinewidth%
+ \pgfarrowsleftextend{+\pgfutil@tempdima}
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfsetlinewidth{+0.8\pgflinewidth}
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{3.5\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{3.25\pgfutil@tempdima}{2.5\pgfutil@tempdima}}
+ {\pgfqpoint{0.5\pgfutil@tempdima}{0.25\pgfutil@tempdima}}
+ {\pgfqpoint{-0.25\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{0.5\pgfutil@tempdima}{-0.25\pgfutil@tempdima}}
+ {\pgfqpoint{3.25\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}
+ {\pgfqpoint{3.5\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfusepathqstroke
+}
+\pgfarrowsdeclare{latex}{latex}
+{
+ \pgfutil@tempdima=0.28pt%
+ \pgfutil@tempdimb=\pgflinewidth%
+ \ifdim\pgfinnerlinewidth>0pt%
+ \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}%
+ \fi%
+ \advance\pgfutil@tempdima by.3\pgfutil@tempdimb%
+ \pgfarrowsleftextend{+-1\pgfutil@tempdima}
+ \pgfarrowsrightextend{+9\pgfutil@tempdima}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \pgfutil@tempdimb=\pgflinewidth%
+ \ifdim\pgfinnerlinewidth>0pt%
+ \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth-.4*\pgfinnerlinewidth}%
+ \fi%
+ \advance\pgfutil@tempdima by.3\pgfutil@tempdimb%
+ \pgfpathmoveto{\pgfqpoint{9\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfqpoint{6.3333\pgfutil@tempdima}{.5\pgfutil@tempdima}}
+ {\pgfqpoint{2\pgfutil@tempdima}{2\pgfutil@tempdima}}
+ {\pgfqpoint{-1\pgfutil@tempdima}{3.75\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-1\pgfutil@tempdima}{-3.75\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{2\pgfutil@tempdima}{-2\pgfutil@tempdima}}
+ {\pgfqpoint{6.3333\pgfutil@tempdima}{-.5\pgfutil@tempdima}}
+ {\pgfqpoint{9\pgfutil@tempdima}{0pt}}
+ \pgfusepathqfill
+}
+\pgfarrowsdeclarereversed{latex reversed}{latex reversed}{latex}{latex}
+\pgfarrowsdeclare{@bar}{@bar}
+{
+ \pgfarrowsleftextend{+-0.25\pgflinewidth}
+ \pgfarrowsrightextend{+.75\pgflinewidth}
+}
+{
+ \pgfutil@tempdima=2pt%
+ \advance\pgfutil@tempdima by1.5\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetrectcap
+ \pgfpathmoveto{\pgfqpoint{0.25\pgflinewidth}{-\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0.25\pgflinewidth}{\pgfutil@tempdima}}
+ \pgfusepathqstroke
+}
+\pgfkeys{Bar /.tip = @bar}
+\pgfarrowsdeclare{space}{space}
+{
+ \pgfutil@tempdima=0.88pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfarrowsleftextend{0pt}
+ \pgfarrowsrightextend{\pgfutil@tempdima}
+}
+{}
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcoreexternal.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreexternal.code.tex
new file mode 100644
index 0000000000..f6fef57755
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreexternal.code.tex
@@ -0,0 +1,542 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcoreexternal.code.tex}
+
+
+
+\newif\ifpgfexternal@aux@in@dpth
+\newif\ifpgfexternal@info
+
+\pgfkeys{
+ /pgf/images/include external/.code={\pgfimage{#1}},
+ /pgf/images/aux in dpth/.is if=pgfexternal@aux@in@dpth,
+ /pgf/images/aux in dpth/.default=true,
+ /pgf/images/trim external/.code n args={4}{%
+ \def\pgf@external@kern@left{#1}%
+ \def\pgf@external@kern@bottom{#2}%
+ \def\pgf@external@kern@right{#3}%
+ \def\pgf@external@kern@top{#4}%
+ \ifx\pgf@external@kern@left\pgfutil@empty\def\pgf@external@kern@left{0sp}\fi%
+ \ifx\pgf@external@kern@bottom\pgfutil@empty\def\pgf@external@kern@bottom{0sp}\fi%
+ \ifx\pgf@external@kern@right\pgfutil@empty\def\pgf@external@kern@right{0sp}\fi%
+ \ifx\pgf@external@kern@top\pgfutil@empty\def\pgf@external@kern@top{0sp}\fi%
+ },
+ /pgf/images/trim external={1truein}{1truein}{1truein}{1truein},
+ /pgf/images/external info/.is if=pgfexternal@info,
+ /pgf/images/external info/.default=true,
+}
+
+% The external read/write mechanism is used as follows:
+%
+% In your document, you put a number or all of your pgfpicture (or
+% tikzpicture) environments inside a pair of \beginpgfexternal and
+% \endpgfexternal. The \beginpgfexternal gets one parameter called the
+% graphics name.
+%
+% Once this is done, the next step is to declare the names of your
+% graphics in the document at the beginning using the
+% \pgfdeclaregraphicname command.
+%
+% Now, when you typeset your document, each time a \beginpgfexternal
+% command is encountered, it will be checked whether the corresponding
+% graphics file exists. If this is the case, it will be included and
+% the code between \beginpgfexternal and \endpgfexternal is
+% ignored. Otherwise, the code is executed normally.
+%
+% Things change when you run tex on your file with the \jobname set to
+% the name of a declared graphics name. In this case, only your
+% graphic will be typeset, the rest of the document will be "thrown away".
+% To be more precise, everything is gobbled up to the beginning
+% of the first \beginpgfexternal with the given graphics name. Then,
+% the content of the "environment" is put in a box (this "environment"
+% need not contain a graphics, it may contain anything that can be put
+% in a box). Then a single page is output whose size is exactly the
+% size of the picture.
+%
+% So, once you have run tex repeatedly, each time with the jobname set
+% to each of the graphics, you can then run tex on the whole document
+% and this will cause all graphics to be included rather than begin
+% typeset.
+%
+% Finally, once all the graphics have been created, you can also say
+% \input pgfexternal.tex instead of including pgf/TikZ.
+
+
+\newif\ifpgfexternalreadmainaux
+\pgfexternalreadmainauxtrue
+
+% Tells pgf which jobname is the name of the real file
+%
+% #1 = name
+%
+% Description:
+%
+% This command is used to tell pgf that the file named #1 should be
+% typeset normally. If \jobname is not equal to #1, only
+% the graphic called \jobname will be typeset.
+%
+% Example:
+%
+% \pgfrealjobname{survey}
+%
+% Note that afterwards, \jobname will be set to the argument. In our
+% example, \jobname will be 'survey'. This is to accomplish
+% compatibility with aux-file generation.
+
+\def\pgfrealjobname#1{%
+ \global\let\pgfactualjobname=\jobname
+ \edef\pgf@tempa{\expandafter\string\csname #1\endcsname}%
+ \edef\pgf@tempb{\expandafter\string\csname\jobname\endcsname}%
+ \ifx\pgf@tempa\pgf@tempb%
+ \else%
+ \pgf@external@grabshipouttrue%
+ \pgfexternal@nofiles% see also \pgf@external@init@aux@in@dpth
+ \ifpgfexternalreadmainaux
+ % and reset the jobname. This should allow to handle any
+ % \label/\ref constructions which are stored in \jobname.aux (and
+ % which won't be found otherwise)
+ \gdef\jobname{#1}%
+ \fi
+ \ifpgfexternal@aux@in@dpth
+ \csname newwrite\endcsname\w@pgfexternal@auxout
+ \fi
+ \pgfexternal@geometry@compatibility
+ \fi%
+ \gdef\pgfrealjobname##1{}% avoid multiple calls.
+}
+
+\def\pgfexternal@geometry@compatibility{%
+ % check if \usepackage{geometry} is loaded:
+ \pgfutil@ifundefined{geometry}{%
+ }{%
+ % The geometry package hooks into \begin{document}, evaluates
+ % its driver -- and generates \special instructions to set the
+ % paper size.
+ %
+ % Unfortunately, this confuses dvips utterly - and perhaps
+ % other drivers as well.
+ %
+ % Thus, if we currently about to generate some external
+ % graphics, we WANT to disable geometry (it has no purpose in
+ % this context anyway).
+ %
+ % This here works well:
+ \pgf@typeout{Package TikZ externalization: calling \string\geometry{driver=none} during externalization.^^J}%
+ \geometry{driver=none}%
+ }%
+}%
+
+\def\pgfexternal@nofiles{%
+ % replace \relax. The \nofiles macros does
+ % \let\makeglossary=\relax
+ % but the glossary.sty calls \renewcommand\makeglossary (which
+ % will fail if \makeglossary=\relax). Stupid, but it works.
+ \let\pgfexternal@nofiles@=\relax
+ \def\relax{\relax}%
+ %
+ % suppress generation of LaTeX .aux, .toc etc files.
+ % generation of these files is not thread-safe.
+ % the \csname \endcsname yields \relax if \nofiles doesn't exist.
+ \csname nofiles\endcsname
+ %
+ \let\relax=\pgfexternal@nofiles@
+}%
+
+\newif\ifpgf@external@grabshipout
+\newbox\pgfexternal@startupbox
+
+\pgfutil@ifundefined{AtBeginDocument}{}{%
+ \AtBeginDocument{%
+ \ifpgf@external@grabshipout%
+ \global\let\pgfexternal@originalshipout=\shipout%
+ \global\def\shipout{\setbox\pgfpic=}%
+ \maxdeadcycles=10000%
+ % Ok, gather everything we have seen up to now in a box. This box
+ % will contain any specials that have been used.
+ {%
+ \output{\global\setbox\pgfexternal@startupbox=\vbox{\csname @begindvi\endcsname\unvbox255}}%
+ \hbox{}\eject%
+ }%
+ \fi%
+ }
+}%
+
+\pgfutil@ifundefined{AtEndDocument}{}{%
+ \AtEndDocument{%
+ \ifpgf@external@grabshipout
+ \pgfutil@ifundefined{pgfexternal@did@a@shipout}{%
+ \pgfexternal@error@no@shipout
+ }{}%
+ \fi
+ }%
+}
+
+% This will be overwritten by the tikz external lib if it is loaded.
+\def\pgfexternal@error@no@shipout{%
+ \pgferror{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname'. Perhaps there was a typo somewhere? Please check that your document contains '\string\beginpgfgraphicnamed{\pgfactualjobname} ... \string\endpgfgraphicnamed'}%
+}%
+
+
+% "Environment" for an external graphic.
+%
+% #1 = graphic name
+%
+% Example:
+%
+% \beginpgfgraphicnamed{main-graphic2}
+% \begin{tikzpicture}
+% ...
+% \end{tikzpicture}
+% \endpgfgraphicnamed
+
+\def\pgf@externalbegin#1{%
+ % First, check whether we wish to grab this graphic:
+ \let\pgf@next=\pgf@external@normal%
+ \ifpgf@external@grabshipout%
+ \edef\pgf@tempa{\expandafter\string\csname #1\endcsname}%
+ \edef\pgf@tempb{\expandafter\string\csname\pgfactualjobname\endcsname}%
+ \ifx\pgf@tempa\pgf@tempb%
+ \let\pgf@next=\pgf@external@grab%
+ \fi%
+ \fi%
+ \pgf@next{#1}%
+}
+
+
+\AtBeginDocument{
+ \let\beginpgfgraphicnamed=\pgf@externalbegin% overwrite definition of pgfexternal.tex if necessary
+ \let\endpgfgraphicnamed=\unskip
+}
+
+
+% Normal operation: Include an external graphic instead of the
+% picture, if such an external picture exists.
+\def\pgf@external@normal#1{%
+ \let\pgf@filename=\pgfutil@empty%
+ \expandafter\pgf@findfile\pgfsys@imagesuffixlist:+{#1}%
+ \ifx\pgf@filename\pgfutil@empty%
+ % Ok, no such image... Just typeset the picture normally.
+ \let\pgf@next=\relax%
+ \else%
+ \let\pgf@next=\pgf@replacepicturebygraphic%
+ \fi%
+ \pgf@next%
+}
+
+\long\def\pgf@replacepicturebygraphic#1\endpgfgraphicnamed{%
+ \expandafter\pgfincludeexternalgraphics\expandafter{\pgf@filename}\unskip
+}
+
+% This is almost the same as \includegraphics{#1}, but it checks
+% whether '#1.dpth' exists. In such case, it restores the boxes depth
+% stored in #1.dpth.
+%
+% Furthermore, the .dpth file may contain .aux related information
+% collected for the external graphics (references). They start after
+% the first line (if any).
+\def\pgfincludeexternalgraphics#1{%
+ \begingroup
+ \pgfexternalreaddpth{#1}%
+ \pgfkeysifdefined{/pgf/images/include external/#1/.@cmd}{%
+ \pgfkeysgetvalue{/pgf/images/include external/#1/.@cmd}\pgf@tempa
+ \pgfkeyslet{/pgf/images/include external/.@cmd}\pgf@tempa
+ }{}%
+ \setbox1=\hbox{\pgfkeysvalueof{/pgf/images/include external/.@cmd}{#1}\pgfeov}%
+ \ifdim\pgfexternaltrimleft=0sp \else \kern\pgfexternaltrimleft\relax \fi
+ \ifdim\pgfexternaldepth=0pt
+ \box1
+ \else
+ \dimen0=\pgfexternaldepth\relax
+ \hbox{\lower\dimen0 \box1 }%
+ \fi
+ \ifdim\pgfexternaltrimright=0sp \else \kern\pgfexternaltrimright\relax \fi
+ \endgroup
+}
+
+% Reads the .dpth file which contains meta data of the external
+% picture.
+%
+% This command handles the following stuff:
+% - it defines \pgfexternaldepth . The macro contains the contents of
+% a line which does not start with a control sequence (for example a
+% line containing '50pt')
+% - it defines \pgfexternaltrimleft and \pgfexternaltrimright
+% - it checks if the .dpth file contains content stored by means of
+% \pgfexternalstorecommand. If so, the argument of
+% \pgfexternalstorecommand will be restored.
+% - anything else will be appended to the main .aux file, assuming that
+% it contains \label or \ref information (only if the LaTeX switch
+% \if@filesw is \iftrue).
+%
+%
+% #1: the image file name (such that #1.dpth exists)
+\def\pgfexternalreaddpth#1{%
+ % no \begingroup. Handle that manually:
+ \edef\pgfexternalreaddpth@restore{%
+ \noexpand\endlinechar=\the\endlinechar\space
+ \noexpand\catcode`\noexpand\@=\the\catcode`\@\space
+ }%
+ %
+ \def\pgfexternaldepth{0sp}%
+ \def\pgfexternaltrimleft{0sp}%
+ \def\pgfexternaltrimright{0sp}%
+ \endlinechar=-1 % suppress white space at end
+ \catcode`\@=11
+ \openin\r@pgf@reada=#1.dpth
+ \pgfincludeexternalgraphics@read@dpth
+ %
+ \pgfexternalreaddpth@restore
+}%
+%
+% The .dpth consists of 0-N lines, where each is either a single
+% dimension (the box' depth) or something which belongs to the .aux
+% file (such lines will always start with a macro).
+\def\pgfincludeexternalgraphics@read@dpth{%
+ \ifeof\r@pgf@reada
+ \closein\r@pgf@reada
+ \else
+ \read\r@pgf@reada to\pgfincludeexternalgraphics@auxline
+ \ifx\pgfincludeexternalgraphics@auxline\pgfutil@empty
+ \else
+ \expandafter\pgfincludeexternalgraphics@read@dpth@line\pgfincludeexternalgraphics@auxline\pgfincludeexternalgraphics@read@dpth@line@EOI
+ \fi
+ \expandafter\pgfincludeexternalgraphics@read@dpth
+ \fi
+}%
+
+\def\pgfexternal@restore#1{#1}%
+
+\long\def\pgfincludeexternalgraphics@read@dpth@line@getfirst#1#2\pgfincludeexternalgraphics@read@dpth@line@EOI{%
+ \def\pgf@first{#1}%
+}%
+\long\def\pgfincludeexternalgraphics@read@dpth@line#1\pgfincludeexternalgraphics@read@dpth@line@EOI{%
+ \pgfincludeexternalgraphics@read@dpth@line@getfirst#1\pgfincludeexternalgraphics@read@dpth@line@EOI
+ \expandafter\ifcat\expandafter\noexpand\pgf@first\relax
+ % Ah -- the first token is a control sequence. It belongs to
+ % the .aux file.
+ %
+ \expandafter\ifx\pgf@first\pgfexternal@restore
+ % if the first line in the .dpth file starts with the
+ % magic string \pgfexternal@restore, the complete line
+ % will be executed as-is. Example:
+ % \pgfexternal@restore{\def\somevalue{1}}
+ #1%
+ \else
+ % do NOT execute #1! many LaTeX commands don't support it (\label for example)
+ \pgfutil@ifundefined{if@filesw}{%
+ % sorry, .aux file support only for latex
+ }{%
+ % append to main .aux file (for forward references)
+ \if@filesw
+ {%
+ \toks0={#1}%
+ % believe it or not, but the
+ % \def\dpthimport{...}\dpthimport *makes* a
+ % difference! In ensures any occurring `##' characters are properly expanded to `#'.
+ \immediate\write\@auxout{%
+ \noexpand\def\noexpand\dpthimport{\the\toks0}\noexpand\dpthimport}%
+ }%
+ \fi
+ }%
+ \fi
+ \else% it is the depth (which is simply a number for backwards compatibility)
+ \def\pgfexternaldepth{#1}%
+ \fi
+}%
+
+% Stores '#1' (expanded!) into the .dpth file of the currently
+% exported image.
+%
+% This command has only an effect if an image is being exported.
+%
+% The stored contents will be read in the context where
+% /pgf/images/include external is active (i.e. by
+% \pgfexternalreaddpth).
+%
+\def\pgfexternalstorecommand#1{%
+}%
+\def\pgfexternalstorecommand@isexporting#1{%
+ \immediate\write\w@pgfexternal@auxout{\noexpand\pgfexternal@restore{#1}}%
+}%
+
+
+
+% Grab operation: If jobname matches the graphic name, typeset this
+% picture normal.
+% REMARK:
+% this method is also invoked from within the tikz external library.
+\def\pgf@external@grab#1{%
+ \def\pgf@filename{#1}%
+ \ifpgfexternal@aux@in@dpth
+ \begingroup
+ \pgf@external@init@aux@in@dpth
+ \let\G@refundefinedtrue=\pgf@external@grab@refundefinedtrue
+ \fi
+ \gdef\pgf@trimleft@final{0sp}%
+ \gdef\pgf@trimright@final{0sp}%
+ \setbox\pgfpic=\hbox\bgroup\bgroup%
+ \let\endpgfgraphicnamed=\pgf@externalend%
+}
+
+{\catcode`\^=12 \gdef\pgfexternal@hat{^}}
+
+\expandafter\let\expandafter\pgf@external@grab@refundefinedtrue@orig\csname G@refundefinedtrue\endcsname
+
+\def\pgf@external@grab@refundefinedtrue{%
+ \pgf@external@grab@refundefinedtrue@orig
+ \begingroup
+ \def\n{\pgfexternal@hat\pgfexternal@hat J}%
+ \pgfexternalstorecommand{%
+ \pgf@external@grab@refundefinedtrue@code
+ \noexpand\immediate\noexpand\write16{\pgf@external@grab@refundefinedtrue@warning}%
+ \noexpand\G@refundefinedtrue
+ }%
+ \endgroup
+}%
+
+% A hook. will be overwritten by \usetikzlibrary{external}
+\def\pgf@external@grab@refundefinedtrue@code{}
+
+\def\pgf@external@grab@refundefinedtrue@warning{%
+ LaTeX Warning: External picture `\pgfactualjobname' contains undefined references\noexpand\on@line.\n
+}%
+
+\let\pgf@external@@protected@write@orig=\protected@write
+\long\def\pgf@external@@protected@write@immediate#1#2#3{%
+ \begingroup
+ \let\pgf@write@=\write
+ \def\write{\noexpand\immediate\pgf@write@}%
+ \pgf@external@@protected@write@orig{#1}{#2}{#3}%
+ \endgroup
+}%
+
+\def\pgf@external@init@aux@in@dpth{%
+ \let\pgfexternalstorecommand=\pgfexternalstorecommand@isexporting
+ %
+ % tell LaTeX to write aux files...
+ \csname @fileswtrue\endcsname
+ % ... but redirect output to the .dpth file!
+ \immediate\openout\w@pgfexternal@auxout=\pgf@filename.dpth
+ \let\@auxout=\w@pgfexternal@auxout
+ % ... and disable the correct page numbers. I can't get that
+ % (because the correct page number is only available in the
+ % shipout routine). Use immediate output:
+ \let\protected@write=\pgf@external@@protected@write@immediate
+}%
+
+\def\pgf@externalend@storeshifts#1{%
+ \immediate\write#1{\the\dp\pgfpic}% store the depth simply as number for backw. compat.
+ \ifx\pgf@trimleft@final\pgfutil@empty\else
+ \immediate\write#1{\noexpand\pgfexternal@restore{\noexpand\def\noexpand\pgfexternaltrimleft{\pgf@trimleft@final}}}%
+ \fi
+ \ifx\pgf@trimright@final\pgfutil@empty\else
+ \immediate\write#1{\noexpand\pgfexternal@restore{\noexpand\def\noexpand\pgfexternaltrimright{\pgf@trimright@final}}}%
+ \fi
+ \ifpgfexternal@info
+ \immediate\write#1{\noexpand\pgfexternal@restore{\noexpand\def\noexpand\pgfexternalwidth{\the\wd\pgfpic}}}%
+ \immediate\write#1{\noexpand\pgfexternal@restore{\noexpand\def\noexpand\pgfexternalheight{\the\dimen0}}}%
+ \fi
+}
+% REMARK:
+% this method is also invoked from within the tikz external library.
+\def\pgf@externalend{%
+ \unskip\egroup\egroup%
+ {%
+ \def\pgf@external@trim{0}%
+ \def\pgf@external@store@dpth{0}%
+ %
+ \ifpgf@trim@lowlevel
+ \gdef\pgf@trimleft@final{}%
+ \gdef\pgf@trimright@final{}%
+ \else
+ \ifdim\pgf@trimleft@final=0sp \gdef\pgf@trimleft@final{} \else\def\pgf@external@trim{1}\fi
+ \ifdim\pgf@trimright@final=0sp \gdef\pgf@trimright@final{} \else\def\pgf@external@trim{1}\fi
+ \if1\pgf@external@trim
+ % UNDO the trimming! export to pdf doesn't supported trimmed
+ % bounding boxes (has to do with the mediabox/trimbox etc).
+ % I'll keep the bounding box intact and store the trim information
+ % into the .dpth file.
+ \setbox\pgfpic=\hbox{%
+ \ifx\pgf@trimleft@final\pgfutil@empty\else\kern-\pgf@trimleft@final\fi
+ \box\pgfpic
+ \ifx\pgf@trimright@final\pgfutil@empty\else\kern-\pgf@trimright@final\fi
+ }%
+ \def\pgf@external@store@dpth{1}%
+ \fi
+ \fi
+ %
+ \parindent0pt % leave the space
+% \leftmargin0pt%
+% \rightmargin0pt%
+ \hoffset=0pt % reset to default
+ \voffset=0pt
+ \dimen0\ht\pgfpic%
+ \advance\dimen0\dp\pgfpic%
+ \ifdim\dp\pgfpic=0pt\relax
+ \else% store the picture's depth. Otherwise, it would be lost.
+ \def\pgf@external@store@dpth{1}%
+ \fi
+ \ifpgfexternal@info
+ \def\pgf@external@store@dpth{1}%
+ \fi
+ %
+ \if1\pgf@external@store@dpth
+ \ifpgfexternal@aux@in@dpth
+ \pgf@externalend@storeshifts\@auxout
+ \immediate\closeout\@auxout
+ \else
+ \immediate\openout\pgf@plotwrite=\pgf@filename.dpth
+ \pgf@externalend@storeshifts\pgf@plotwrite
+ \immediate\closeout\pgf@plotwrite
+ \fi
+ \fi
+ \pgfsys@prepare@papersize{\the\wd\pgfpic}{\the\dimen0}%
+ %
+ \setbox0=\vbox{%
+ % I admit that I don't know why there is this kerning:
+ \kern -\pgf@external@kern@top\relax%
+ \hbox{%
+ \kern -\pgf@external@kern@left\relax%
+ \hbox to0pt{%
+ \wd\pgfexternal@startupbox=0pt %
+ \ht\pgfexternal@startupbox=0pt %
+ \dp\pgfexternal@startupbox=0pt %
+ \box\pgfexternal@startupbox%
+ \pgfsys@atbegindocument\hss}%
+ \box\pgfpic%
+ \kern\pgf@external@kern@right\relax%
+ }%
+ \kern\pgf@external@kern@bottom\relax%
+ }%
+ %
+ % compatibility with eso-pic package: \nointerlineskip is not
+ % allowed here, but the eso-pic package uses \nointerlineskip in
+ % its shipout routine.
+ \let\pgfexternal@nointerlineskip@orig=\nointerlineskip
+ \let\nointerlineskip=\pgfexternal@nointerlineskip
+ %
+ \pgfexternal@originalshipout\box0 %
+ \gdef\pgfexternal@did@a@shipout{1}%
+ }%
+ \ifpgfexternal@aux@in@dpth
+ \endgroup
+ \fi
+}
+
+\def\pgfexternal@nointerlineskip{%
+ \ifvmode
+ \pgfexternal@nointerlineskip@orig
+ \else
+ \relax% \nointerlineskip in horizontal mode not allowed. Silently ignore the error message.
+ \fi
+}%
+
+\endinput
+% vi: tabstop=4 shiftwidth=2 expandtab
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcoregraphicstate.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcoregraphicstate.code.tex
new file mode 100644
index 0000000000..f7783dcd98
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcoregraphicstate.code.tex
@@ -0,0 +1,280 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcoregraphicstate.code.tex}
+
+% Globals
+
+\newdimen\pgflinewidth
+
+
+% Set the line width to #1.
+%
+% #1 = new line width.
+%
+% Example:
+%
+% \pgfsetlinewidth{3pt}
+
+\def\pgfsetlinewidth#1{%
+ \pgfmathsetlength\pgflinewidth{#1}%
+ \global\pgflinewidth=\pgflinewidth%
+ \pgfsys@setlinewidth{\the\pgflinewidth}%
+ \ignorespaces}
+
+
+% Set the inner line width to #1.
+%
+% #1 = new inner line width.
+%
+% Description:
+%
+% The inner line width is the width of a second line that is drawn on
+% top of the main stroked line. If the inner line width is 0pt, no
+% inner line is drawn. The main use of inner lines is for creating
+% "double" lines.
+%
+% Inner lines are not drawn when a path is used for clipping.
+%
+% The inner line width is local to the current TeX group, it is not
+% part of the graphic state.
+%
+% Example:
+%
+% \pgfsetinnerlinewidth{1pt}
+
+\def\pgfsetinnerlinewidth#1{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgfinnerlinewidth{\the\pgf@x}%
+}
+\def\pgfinnerlinewidth{0pt}
+
+
+% Set the inner line color to #1.
+%
+% #1 = color for the inner line
+%
+% Example:
+%
+% \pgfsetinnerlinecolor{green} % yikes!
+
+\def\pgfsetinnerstrokecolor#1{\def\pgfinnerstrokecolor{#1}}
+\def\pgfinnerstrokecolor{white}
+
+
+% Set the miter limit to #1.
+%
+% #1 = new miter limit factor.
+%
+% Example:
+%
+% \pgfsetmiterlimit{3}
+
+\def\pgfsetmiterlimit#1{%
+ \ifdim#1pt<1pt\pgferror{miter limit cannot be less than 1}\fi%
+ \pgfsys@setmiterlimit{#1}%
+ \ignorespaces}
+
+
+% Set the dash pattern to #1 with phase #2/
+%
+% #1 = a row of numbers of length of ``on'' and ``off'' points.
+% #2 = a phase
+%
+% Example:
+%
+% \pgfsetdash{} {0pt} % solid line
+% \pgfsetdash{{.1cm}} {0pt} % long dashes
+% \pgfsetdash{{1pt}{1ex}}{0pt} % dotted
+
+\def\pgfsetdash#1#2{%
+ \def\pgf@temp{}%
+ \def\pgf@next{\pgf@strip}%
+ \pgf@strip#1{pgf@stop}%
+ \pgfmathsetlength\pgf@x{#2}%
+ \pgfsys@setdash{\pgf@temp}{\the\pgf@x}%
+ \ignorespaces}
+
+\def\pgf@strip#1{%
+ \def\pgf@@temp{#1}%
+ \ifx\pgf@@temp\pgf@stop%
+ \let\pgf@next=\relax%
+ \else%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \edef\pgf@temp{\the\pgf@x}%
+ \else%
+ \edef\pgf@temp{\pgf@temp,\the\pgf@x}%
+ \fi%
+ \fi\pgf@next}
+
+\def\pgf@stop{pgf@stop}
+
+
+% Set color of strokes. This will overrule the normal color.
+%
+% Example:
+%
+% \pgfsetstrokecolor{red}
+
+\def\pgfsetstrokecolor#1{%
+ \pgfutil@colorlet{pgfstrokecolor}{#1}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfstrokecolor}}%
+ \expandafter\let\expandafter\pgf@temp\csname\string\color@pgfstrokecolor\endcsname
+ % for arrow tips:
+ \global\let\pgf@strokecolor@global=\pgf@temp
+ \expandafter\pgf@setstrokecolor\pgf@temp%
+}
+\def\pgf@setstrokecolor#1#2#3#4#5{%
+ \expandafter\ifx\csname pgfsys@color@#4@stroke\endcsname\relax%
+ \pgferror{Unsupported color model `#4'. Sorry}%
+ \else%
+ \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4@stroke\endcsname}%
+ \pgf@uncomma#5,,%
+ \pgf@colmarshal%
+ \fi}
+
+\def\pgf@uncomma#1,{%
+ \def\pgf@coltest{#1}%
+ \ifx\pgf@coltest\pgfutil@empty%
+ \let\pgf@colnext=\relax%
+ \else%
+ \expandafter\def\expandafter\pgf@colmarshal\expandafter{\pgf@colmarshal{#1}}%
+ \let\pgf@colnext=\pgf@uncomma%
+ \fi%
+ \pgf@colnext%
+}
+
+
+% Set color of fills. This will overrule the normal color.
+%
+% Example:
+%
+% \pgfsetfillcolor{gray}
+
+\def\pgfsetfillcolor#1{%
+ \pgfutil@colorlet{pgffillcolor}{#1}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgffillcolor}}%
+ \expandafter\let\expandafter\pgf@temp\csname\string\color@pgffillcolor\endcsname
+ % for arrow tips:
+ \global\let\pgf@fillcolor@global=\pgf@temp
+ \expandafter\pgf@setfillcolor\pgf@temp
+}
+\def\pgf@setfillcolor#1#2#3#4#5{%
+ \expandafter\ifx\csname pgfsys@color@#4@fill\endcsname\relax%
+ \pgferror{Unsupported color model `#4'. Sorry}%
+ \else%
+ \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4@fill\endcsname}%
+ \pgf@uncomma#5,,%
+ \pgf@colmarshal%
+ \fi}
+
+
+
+% Sets both the stroke and fill color.
+%
+% Example:
+%
+% \pgfsetcolor{blue}
+
+\def\pgfsetcolor#1{%
+ \pgfutil@colorlet{pgfstrokecolor}{#1}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfstrokecolor}}%
+ \expandafter\let\expandafter\pgf@temp\csname\string\color@pgfstrokecolor\endcsname
+ % for arrow tips:
+ \global\let\pgf@strokecolor@global=\pgf@temp
+ \global\let\pgf@fillcolor@global=\pgf@temp
+ \expandafter\pgf@setcolor\pgf@temp%
+}
+\def\pgf@setcolor#1#2#3#4#5{%
+ \expandafter\ifx\csname pgfsys@color@#4\endcsname\relax%
+ \pgferror{Unsupported color model `#4'. Sorry}%
+ \else%
+ \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4\endcsname}%
+ \pgf@uncomma#5,,%
+ \pgf@colmarshal%
+ \fi}
+
+% Code for ensuring the stroke/fill colors are correctly reset.
+\def\XC@bcolor{\pgfsys@color@reset}
+
+% Set a butt line cap.
+%
+% Example:
+%
+% \pgfsetbuttcap
+
+\def\pgfsetbuttcap{\pgfsys@buttcap\ignorespaces}
+
+
+% Set a round line cap.
+%
+% Example:
+%
+% \pgfsetroundcap
+
+\def\pgfsetroundcap{\pgfsys@roundcap\ignorespaces}
+
+
+% Set a rectangular line cap.
+%
+% Example:
+%
+% \pgfsetrectcap
+
+\def\pgfsetrectcap{\pgfsys@rectcap\ignorespaces}
+
+
+% Set a miter line join.
+%
+% Example:
+%
+% \pgfsetmiterjoin
+
+\def\pgfsetmiterjoin{\pgfsys@miterjoin\ignorespaces}
+
+
+% Set a bevel line join.
+%
+% Example:
+%
+% \pgfsetbeveljoin
+
+\def\pgfsetbeveljoin{\pgfsys@beveljoin\ignorespaces}
+
+
+% Set a round line join.
+%
+% Example:
+%
+% \pgfsetroundjoin
+
+\def\pgfsetroundjoin{\pgfsys@roundjoin\ignorespaces}
+
+
+% Sets the even-odd rule for filling and clipping.
+%
+% Example:
+%
+% \pgfseteorule
+
+\def\pgfseteorule{\pgfsys@eoruletrue\ignorespaces}
+
+
+% Sets the non-zero winding number rule for filling and clipping.
+%
+% Example:
+%
+% \pgfsetnonzerorule
+
+\def\pgfsetnonzerorule{\pgfsys@eorulefalse\ignorespaces}
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcoreimage.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreimage.code.tex
new file mode 100644
index 0000000000..fd1c0c48db
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreimage.code.tex
@@ -0,0 +1,242 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcoreimage.code.tex}
+
+
+
+% Declare an image
+%
+% #1 = optional argument: width, height, page specification
+% #2 = name of the image for later use
+% #4 = filename without extension, automatic extensions are .pdf,
+% .jpg, and .png for PDF and .ps, .eps, .epsi for postscript.
+%
+% Description:
+%
+% This command declares an image file for later use. Even if the image
+% is used several times in the document, in PDF it will only be stored
+% once.
+%
+% Example:
+%
+% \pgfdeclareimage[width=2cm,page=2]{myimage}{imagefilename}
+
+\def\pgfdeclareimage{\pgfutil@ifnextchar[{\pgf@declareimage}{\pgf@declareimage[]}}
+\def\pgf@declareimage[#1]#2#3{%
+ \pgfqkeys{/pgf/images}{height=,width=,page=,interpolate=false,mask=,#1}%
+ % Try to find the file
+ \gdef\pgf@filename{}%
+ % If page= parameter is not empty, try that file first:
+ \ifx\pgf@imagepage\pgfutil@empty%
+ \else%
+ \expandafter\pgf@findfile\pgfsys@imagesuffixlist:+{#3.page\pgf@imagepage}%
+ \fi%
+ \ifx\pgf@filename\pgfutil@empty%
+ \expandafter\pgf@findfile\pgfsys@imagesuffixlist:+{#3}%
+ \else%
+ \pgfkeys{/pgf/images/page=}% make page empty
+ \fi%
+ \ifx\pgf@filename\pgfutil@empty%
+ \pgfwarning%
+ {File "#3" not found when defining image "#2".
+ Tried all extensions in "\pgfsys@imagesuffixlist"}%
+ \pgf@declaredraftimage{#2}{#3}%
+ \else%
+ \ifpgf@draftmode%
+ \pgf@declaredraftimage{#2}{#3}%
+ \else%
+ \pgfsys@defineimage%
+ \fi%
+ \fi%
+ \expandafter\global\expandafter\let\csname pgf@image@#2!\endcsname=\pgf@image%
+}
+
+
+\pgfkeys{
+ /pgf/images/draft/.is if=pgf@draftmode,
+ /pgf/images/draft/.default=true}
+\pgfkeys{/pgf/images/width/.estore in=\pgf@imagewidth}
+\pgfkeys{/pgf/images/height/.estore in=\pgf@imageheight}
+\pgfkeys{/pgf/images/page/.estore in=\pgf@imagepage}
+\pgfkeys{/pgf/images/interpolate/.cd,.code=\edef\pgf@imageinterpolate{#1},.default=true}
+\let\pgf@imageinterpolate\pgfutil@empty
+\pgfkeys{/pgf/images/mask/.code=%
+ {%
+ \edef\pgf@imagemask{#1}%
+ \ifx\pgf@imagemask\pgfutil@empty%
+ \else%
+ \pgfutil@ifundefined{pgf@mask@#1}%
+ {\pgferror{Undefined mask "#1".}%
+ \edef\pgf@imagemask{}}%
+ {\edef\pgf@imagemask{\csname pgf@mask@#1\endcsname}%
+ }%
+ \fi%
+ }}
+
+
+\def\pgf@findfile#1:#2+#3{%
+ \pgfutil@IfFileExists{#3#1}%
+ {\xdef\pgf@filename{#3#1}}%
+ {\def\pgf@mightbeempty{#2}%
+ \ifx\pgf@mightbeempty\pgfutil@empty\else%
+ \pgf@findfile#2+{#3}%
+ \fi}}
+
+% #1: image name
+% #2: file name
+\def\pgf@declaredraftimage#1#2{%
+ \ifx\pgf@imagewidth\pgfutil@empty%
+ \pgfwarning{Missing width for image "#1" ("#2") in draft mode. Using 1cm instead}%
+ \edef\pgf@imagewidth{1cm}%
+ \fi%
+ \ifx\pgf@imageheight\pgfutil@empty%
+ \pgfwarning{Missing height for image "#1" ("#2") in draft mode. Using 1cm instead}%
+ \edef\pgf@imageheight{1cm}%
+ \fi%
+ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepagetext{ page \pgf@imagepage}\fi%
+ \edef\pgf@image{%
+ \hbox to \pgf@imagewidth{%
+ \vrule\kern-0.4pt%
+ \vbox to \pgf@imageheight{%
+ \hrule\vfil%
+ \hbox to \pgf@imagewidth{\hskip-10cm\hfil\noexpand\pgfutil@font@tiny#2\pgf@imagepage\hfil\hskip-10cm}%
+ \vfil\hrule}%
+ \kern-0.4pt\vrule}%
+ }%
+}
+
+
+
+% Declare a soft mask
+%
+% #1 = optional argument: matte specification. default matte is
+% white.
+% #2 = name of the mask for later use
+% #3 = filename without extension, automatic extensions are .pdf,
+% .jpg, and .png for PDF. Postscript is not supported.
+%
+% Description:
+%
+% This command declares a soft mask for later masking an image. The
+% declared mask should be used together with an image of exactly the
+% same height/width if matte is defined. Matte should be the
+% preblended background color (see pdf spec for details).
+%
+% Example:
+%
+% \pgfdeclaremask[matte=white]{maskname}{maskfilename}
+% \pgfdeclareimage[mask=maskname]{image}{imagefilename}
+
+\def\pgfdeclaremask{\pgfutil@ifnextchar[\pgf@declaremask{\pgf@declaremask[]}}
+\def\pgf@declaremask[#1]#2#3{%
+ \pgfqkeys{/pgf/images/mask}{matte={1 1 1},#1}% defaults
+ \def\pgf@mask{}%
+ % Try to find the file
+ \gdef\pgf@filename{}%
+ \expandafter\pgf@findfile\pgfsys@imagesuffixlist:+{#3}%
+ \ifx\pgf@filename\pgfutil@empty%
+ \pgfwarning%
+ {File "#3" not found when defining mask "#2".
+ Tried all extensions in "\pgfsys@imagesuffixlist"}%
+ \else%
+ \pgfsys@definemask%
+ \fi%
+ \expandafter\global\expandafter\let\csname pgf@mask@#2\endcsname=\pgf@mask%
+}
+
+\pgfkeys{/pgf/images/mask/matte/.cd,.estore in=\pgf@maskmatte,.value required}
+
+
+
+% Create an alias name for an image
+%
+% #1 = name of the alias
+% #2 = name of the original
+%
+% Example:
+%
+% \pgfdeclareimage{image}{1cm}{1cm}{filename
+% \pgfaliasimage{alias}{image}
+% \pgfuseimage{alias}
+
+\def\pgfaliasimage#1#2{%
+ \expandafter\global\expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@image@#2!\endcsname%
+ \expandafter\global\expandafter\let\csname pgf@image@#1!\endcsname=\pgf@temp%
+ }
+
+
+% Use an image
+%
+% #1 = name of a previously declared image
+%
+% Example:
+%
+% \pgfputat{\pgforigin}{\pgfbox[left,base]{\pgfuseimage{myimage}}}
+
+\def\pgfuseimage#1{%
+ \def\pgf@imagename{pgf@image@#1}%
+ \pgf@tryextensions{\pgf@imagename}{\pgfalternateextension}%
+ \expandafter\pgfutil@ifundefined\expandafter{\pgf@imagename}%
+ {\pgferror{Undefined image "#1"}}%
+ {{\leavevmode\csname\pgf@imagename\endcsname}}}
+
+\def\pgf@tryextensions#1#2{%
+ \edef\pgf@args{[#2!]}\expandafter\pgf@@tryextensions\pgf@args{#1}}
+\def\pgf@@tryextensions[#1!#2]#3{%
+ \expandafter\pgfutil@ifundefined\expandafter{#3#1!#2}%
+ {\def\pgf@temp{#2}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \edef#3{#3!}%
+ \else%
+ \pgf@@tryextensions[#2]{#3}%
+ \fi}%
+ {\edef#3{#3#1!#2}}}
+
+
+% Alternate image
+%
+% Description:
+%
+% When an image is used, pgf first attempts to use the image with the
+% alternate extension added. If this fails, the original image is
+% used. If the alternate extension contains ``!'', then the text up to
+% the ! is successively removed and the remainder is tried as an
+% alternate extension.
+%
+% Example:
+%
+% \def\pgfalternateextension{20!white}
+
+\def\pgfalternateextension{}
+
+
+
+% Directly insert an image
+%
+% #1 = optional argument: width, height, page specification
+% #2 = file name
+%
+% Description:
+%
+% Directly inserts an image without declaration. You can, however,
+% still access this image using the name pgflastimage. By using
+% pgfaliasimage, you can also save this image for later.
+%
+% Example:
+%
+% \pgfimage[height=2cm]{filename}
+
+\def\pgfimage{\pgfutil@ifnextchar[\pgf@imagecom{\pgf@imagecom[]}}
+\def\pgf@imagecom[#1]#2{%
+ \pgfdeclareimage[#1]{pgflastimage}{#2}%
+ \pgfuseimage{pgflastimage}}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorelayers.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorelayers.code.tex
new file mode 100644
index 0000000000..158f33d6ac
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorelayers.code.tex
@@ -0,0 +1,210 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorelayers.code.tex}
+
+
+% Creates a new pgf layer
+%
+% #1 = layer name
+%
+% Declares a new layer for pgf.
+%
+% Example:
+%
+% \pgfdeclarelayer{background}
+
+\def\pgfdeclarelayer#1{%
+ \pgfutil@ifundefined{pgf@layerbox@#1}{%
+ \expandafter\expandafter\csname pgf@newbox\endcsname\csname pgf@layerbox@#1\endcsname%
+ \expandafter\expandafter\csname pgf@newbox\endcsname\csname pgf@layerboxsaved@#1\endcsname%
+ }{}%
+}
+\let\pgf@newbox=\newbox % avoid plain TeX outer problem
+
+% Sets the layers that compose the picture
+%
+% #1 = List of layers
+%
+% Description:
+%
+% Sets the list of layers that make up the picture. The layers will be
+% put on top of each other in the order given.
+%
+% This command can also be given inside of a picture in which case it
+% applies only to that very picture.
+%
+% Example:
+%
+% \pgfsetlayers{background,main}
+
+\def\pgfsetlayers#1{%
+ \let\pgf@layerlist\pgfutil@empty%
+ \pgf@dosetlayer#1,,\relax%
+}
+
+\def\pgf@dosetlayer#1,#2,\relax{%
+ \ifx\pgf@layerlist\pgfutil@empty%
+ \edef\pgf@layerlist{\pgfutil@trimspaces{#1}}%
+ \else
+ \edef\pgf@layerlist{\pgf@layerlist,\pgfutil@trimspaces{#1}}%
+ \fi
+ \def\pgf@test{#2}%
+ \ifx\pgf@test\pgfutil@empty%
+ \else%
+ \pgf@dosetlayer#2,\relax%
+ \fi%
+}
+
+\pgfsetlayers{main}
+
+% Adds code to a layer
+%
+% #1 = layer name
+%
+% Note:
+%
+% You cannot add anything to the ``main'' layer using this command.
+%
+% Example:
+%
+% \begin{pgfonlayer}{background}
+% \fill[red] (0,0) -- (1,1);
+% \end{pgfonlayer}
+
+\def\pgfonlayer@name{main}
+
+\def\pgfonlayer#1{%
+ \pgfutil@ifundefined{pgf@layerbox@#1}{%
+ \pgferror{Sorry, the requested layer '#1' could not be found. Maybe you misspelled it?}%
+ \bgroup
+ \begingroup
+ }{%
+ \begingroup
+ \edef\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfonlayer@name
+ % we are already on this layer.
+ \def\pgf@temp{%
+ \bgroup
+ \begingroup
+ }%
+ \else
+ \let\pgfonlayer@name=\pgf@temp
+ \pgfonlayer@assert@is@active
+ \def\pgf@temp{%
+ \expandafter\global\expandafter%
+ \setbox\csname pgf@layerbox@#1\endcsname=\hbox to 0pt%
+ \bgroup%
+ \expandafter\box\csname pgf@layerbox@#1\endcsname%
+ \begingroup%
+ }%
+ \fi
+ \pgfsetlinewidth{0.4pt}% always reset the line width
+ \pgf@temp
+ }%
+}
+\def\endpgfonlayer{%
+ \endgroup%
+ \hss
+ \egroup%
+ \endgroup
+}
+
+\let\startpgfonlayer=\pgfonlayer
+\let\stoppgfonlayer=\endpgfonlayer
+
+\def\pgfdiscardlayername{discard}
+
+\def\pgfonlayer@assert@is@active{%
+ \ifx\pgfonlayer@name\pgfdiscardlayername
+ % this special layer name can be used as /dev/null without
+ % warning.
+ \else
+ \begingroup
+ \def\pgfonlayer@isactive{0}%
+ \expandafter\pgf@assert@layer@is@active@loop\pgf@layerlist,,\relax%
+ \if0\pgfonlayer@isactive
+ \pgfonlayer@assert@fail
+ \fi
+ \endgroup
+ \fi
+}%
+\def\pgfonlayer@assert@fail{%
+ \pgferror{Sorry, the requested layer '\pgfonlayer@name' is not
+ part of the layer list. Please verify that you provided
+ \string\pgfsetlayers\space and that '\pgfonlayer@name' is part of this list}%
+}%
+\def\pgf@assert@layer@is@active@loop#1,#2,\relax{%
+ \edef\pgf@test{#1}%
+ \ifx\pgf@test\pgfonlayer@name
+ \def\pgfonlayer@isactive{1}%
+ \else
+ \def\pgf@test{#2}%
+ \ifx\pgf@test\pgfutil@empty%
+ \else%
+ \pgf@assert@layer@is@active@loop#2,\relax%
+ \fi%
+ \fi
+}
+
+% Hooks into the scoping:
+
+\def\pgf@insertlayers{%
+ \expandafter\pgf@dolayer\pgf@layerlist,,\relax%
+}
+\def\pgf@maintext{main}%
+\def\pgf@dolayer#1,#2,\relax{%
+ \def\pgf@test{#1}%
+ \ifx\pgf@test\pgf@maintext%
+ \box\pgf@layerbox@main%
+ \else%
+ \pgfsys@beginscope%
+ \expandafter\box\csname pgf@layerbox@#1\endcsname%
+ \pgfsys@endscope%
+ \fi%
+ \def\pgf@test{#2}%
+ \ifx\pgf@test\pgfutil@empty%
+ \else%
+ \pgf@dolayer#2,\relax%
+ \fi%
+}
+
+\def\pgf@savelayers{%
+ \expandafter\pgf@dosavelayer\pgf@layerlist,,\relax%
+}
+\def\pgf@dosavelayer#1,#2,\relax{%
+ \def\pgf@test{#1}%
+ \ifx\pgf@test\pgf@maintext%
+ \else%
+ \setbox\csname pgf@layerboxsaved@#1\endcsname=\box\csname pgf@layerbox@#1\endcsname%
+ \fi%
+ \def\pgf@test{#2}%
+ \ifx\pgf@test\pgfutil@empty%
+ \else%
+ \pgf@dosavelayer#2,\relax%
+ \fi%
+}
+
+\def\pgf@restorelayers{%
+ \expandafter\pgf@dorestorelayer\pgf@layerlist,,\relax%
+}
+\def\pgf@dorestorelayer#1,#2,\relax{%
+ \def\pgf@test{#1}%
+ \ifx\pgf@test\pgf@maintext%
+ \else%
+ \global\setbox\csname pgf@layerbox@#1\endcsname=\box\csname pgf@layerboxsaved@#1\endcsname%
+ \fi%
+ \def\pgf@test{#2}%
+ \ifx\pgf@test\pgfutil@empty%
+ \else%
+ \pgf@dorestorelayer#2,\relax%
+ \fi%
+}
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcoreobjects.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreobjects.code.tex
new file mode 100644
index 0000000000..6906a9d987
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreobjects.code.tex
@@ -0,0 +1,101 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcoreobjects.code.tex}
+
+
+% Object reuse
+
+
+% Define a pgf object for reuse. Such objects will be stored
+% efficiently internally.
+%
+% #1 = name for later reuse
+% #2 = lower left corner point of bounding box
+% #3 = upper right left corner point of bounding box
+% #4 = pure pgf code (nothing too fancy!)
+%
+% Description:
+%
+% Used to define reusable objects. The object must be composed of
+% basic pgf graphic primitives. Nothing fancy can be used. The
+% created object will be stored as an xform object in pdf or as a
+% postscript procedure in postscript.
+%
+% Example:
+%
+% \pgfdefobject{myrect}{\pgfpoint{-1pt}{-1pt}}{\pgfpoint{11pt}{11pt}}
+% {\pgfpathqmoveto{0pt}{0pt}
+% \pgfpathqmoveto{10pt}{0pt}
+% \pgfpathqmoveto{10pt}{10pt}
+% \pgfpathqmoveto{0pt}{10pt}
+% \pgfpathclose
+% \pgfusepath{stroke}}
+%
+% \begin{pgfpicture}{0cm}{0cm}{1cm}{1cm}
+% \pgfuseobject{myrect}
+% \end{pgfpicture}
+
+\def\pgfdefobject#1#2#3#4{%
+ \pgfinterruptpath%
+ \pgf@relevantforpicturesizefalse%
+ \pgfsys@defobject{#1}{#2}{#3}{#4}%
+ \endpgfinterruptpath%
+ \ignorespaces%
+}
+
+
+% Use an object that was previously defined using pgfdefobject
+%
+% #1 = name of previously defined object
+%
+% Example:
+%
+% \pgfdefobject{myrect}{\pgfpoint{-1pt}{-1pt}}{\pgfpoint{11pt}{11pt}}
+% {\pgfqmoveto{0}{0}
+% \pgfqmoveto{10}{0}
+% \pgfqmoveto{10}{10}
+% \pgfqmoveto{0}{10}
+% \pgfclosestroke}
+%
+% \begin{pgfpicture}{0cm}{0cm}{1cm}{1cm}
+% \pgfuseobject{myrect}
+% \end{pgfpicture}
+
+\def\pgfuseobject#1{\pgfsys@beginscope\pgfsys@useobject{#1}{}\pgfsys@endscope}
+
+
+% Use an object that was previously defined using pgfdefobject, but
+% magnify the object by the current x and y register values
+%
+% #1 = name of previously defined object
+%
+% Example:
+%
+% \pgfdefobject{myrect}{\pgfpoint{-1pt}{-1pt}}{\pgfpoint{11pt}{11pt}}
+% {\pgfqmoveto{0}{0}
+% \pgfqmoveto{10}{0}
+% \pgfqmoveto{10}{10}
+% \pgfqmoveto{0}{10}
+% \pgfclosestroke}
+%
+% \begin{pgfpicture}{0cm}{0cm}{1cm}{1cm}
+% \pgf@x=2pt% Scale by factor two in x-direction
+% \pgf@y=2pt% Scale by factor two in y-direction
+% \pgfuseobjectmagnify{myrect}
+% \end{pgfpicture}
+
+\def\pgfuseobjectmagnify#1{%
+ \pgfsys@beginscope%
+ \pgfsys@useobject{#1}{\pgfsys@transformxyscale{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}}%
+ \pgfsys@endscope%
+}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathconstruct.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathconstruct.code.tex
new file mode 100644
index 0000000000..cafc532938
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathconstruct.code.tex
@@ -0,0 +1,1477 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorepathconstruct.code.tex}
+
+
+\newdimen\pgf@path@lastx
+\newdimen\pgf@path@lasty
+
+\let\pgfgetpath=\pgfsyssoftpath@getcurrentpath
+\let\pgfsetpath=\pgfsyssoftpath@setcurrentpath
+
+
+
+% Replace corners by arcs.
+%
+% #1 = in-size of arc
+% #2 = out-size of arc
+%
+% Description:
+%
+% This command influences path construction command like
+% \pgfpathlineto or \pgfpatharc. It will cause the corners at the end
+% of these commands to be replaced by little arcs. If the
+% corner is a 90 degrees corner and if #1=#2, a quarter-circle of
+% radius #1 is put in place of the corner. If #1 and #2 are different,
+% the quarter circle will instead by a quarter ellipse. If the angle
+% is different from 90 degrees, a deformed quarter circle will
+% result, which may or may not be desirable. For a ``perfect'' arc you
+% must use the \pgfpatharc command.
+%
+%
+% Example: One rounded corner.
+%
+% \pgfpathmoveto{\pgfpointxy{0}{0}}
+% \pgfsetcornersarced{4pt}{4pt}
+% \pgfpathlineto{\pgfpointxy{0}{1}}
+% \pgfpathlineto{\pgfpointxy{1}{1}}
+% \pgfstroke
+%
+% Example: A rounded rectangle
+%
+% \pgfsetcornersarced{4pt}{4pt}
+% \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{1cm}{1cm}}
+% \pgfstroke
+%
+% Example: A rounded triangles
+%
+% \pgfsetcornersarced{4pt}{4pt}
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathlineto{\pgfpoint{1cm}{0cm}}
+% \pgfpathlineto{\pgfpoint{1cm}{1cm}}
+% \pgfpathclose
+% \pgfstroke
+
+\newif\ifpgf@arccorners
+
+\def\pgfsetcornersarced#1{%
+ \pgf@process{#1}%
+ \edef\pgf@corner@arc{{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@arccornerstrue%
+ \ifdim\pgf@x=0pt%
+ \ifdim\pgf@y=0pt\relax%
+ \pgf@arccornersfalse%
+ \fi%
+ \fi%
+}
+
+\def\pgf@roundcornerifneeded{%
+ \ifpgf@arccorners\expandafter\pgfsyssoftpath@specialround\pgf@corner@arc\fi%
+}
+
+
+
+% The following protocol the passed sizes and all the corresponding
+% softpath commands. The nonlinear transformation (nlt) module
+% overwrites these commands.
+
+\def\pgf@lt@moveto#1#2{%
+ \pgf@protocolsizes{#1}{#2}%
+ \pgfsyssoftpath@moveto{\the#1}{\the#2}%
+}
+\def\pgf@lt@lineto#1#2{%
+ \pgf@protocolsizes{#1}{#2}%
+ \pgfsyssoftpath@lineto{\the#1}{\the#2}%
+}
+\def\pgf@lt@curveto#1#2#3#4#5#6{%
+ \pgf@protocolsizes{#1}{#2}%
+ \pgf@protocolsizes{#3}{#4}%
+ \pgf@protocolsizes{#5}{#6}%
+ \pgfsyssoftpath@curveto{\the#1}{\the#2}{\the#3}{\the#4}{\the#5}{\the#6}%
+}
+
+\let\pgf@lt@closepath\pgfsyssoftpath@closepath
+
+\let\pgf@nlt@moveto\pgf@lt@moveto
+\let\pgf@nlt@lineto\pgf@lt@lineto
+\let\pgf@nlt@curveto\pgf@lt@curveto
+\let\pgf@nlt@closepath\pgf@lt@closepath
+
+\let\pgf@nlt@list\pgfutil@empty % If non-empty, the nlt module is active
+
+
+% Move current point to #1.
+%
+% #1 = new current point
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfxy(0,0)}
+% \pgfpathlineto{\pgfxy(0,1)}
+% \pgfstroke
+
+\def\pgfpathmoveto#1{%
+ \pgfpointtransformed{#1}%
+ \pgf@nlt@moveto{\pgf@x}{\pgf@y}%
+ \global\pgf@path@lastx=\pgf@x%
+ \global\pgf@path@lasty=\pgf@y%
+}
+
+\def\pgf@protocolsizes#1#2{%
+ \ifpgf@relevantforpicturesize%
+ \ifdim#1<\pgf@picminx\global\pgf@picminx#1\fi%
+ \ifdim#1>\pgf@picmaxx\global\pgf@picmaxx#1\fi%
+ \ifdim#2<\pgf@picminy\global\pgf@picminy#2\fi%
+ \ifdim#2>\pgf@picmaxy\global\pgf@picmaxy#2\fi%
+ \ifpgf@size@hooked%
+ \let\pgf@size@hook@x#1\let\pgf@size@hook@y#2\pgf@path@size@hook%
+ \fi%
+ \fi%
+ \ifdim#1<\pgf@pathminx\global\pgf@pathminx#1\fi%
+ \ifdim#1>\pgf@pathmaxx\global\pgf@pathmaxx#1\fi%
+ \ifdim#2<\pgf@pathminy\global\pgf@pathminy#2\fi%
+ \ifdim#2>\pgf@pathmaxy\global\pgf@pathmaxy#2\fi%
+}
+\newif\ifpgf@size@hooked
+\let\pgf@path@size@hook=\pgfutil@empty%
+
+\def\pgf@resetpathsizes{%
+ \global\pgf@pathmaxx=-16000pt\relax%
+ \global\pgf@pathminx=16000pt\relax%
+ \global\pgf@pathmaxy=-16000pt\relax%
+ \global\pgf@pathminy=16000pt\relax%
+}
+
+\def\pgf@getpathsizes#1{%
+ \edef#1{{\the\pgf@pathmaxx}{\the\pgf@pathminx}{\the\pgf@pathmaxy}{\the\pgf@pathminy}}%
+}
+\def\pgf@setpathsizes#1{%
+ \expandafter\pgf@@setpathsizes#1%
+}
+\def\pgf@@setpathsizes#1#2#3#4{%
+ \global\pgf@pathmaxx=#1\relax%
+ \global\pgf@pathminx=#2\relax%
+ \global\pgf@pathmaxy=#3\relax%
+ \global\pgf@pathminy=#4\relax%
+}
+
+
+
+
+
+% Append a line from the current point to #1 to the current path.
+%
+% #1 = end of line
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfxy(0,0)}
+% \pgfpathlineto{\pgfxy(0,1)}
+% \pgfstroke
+
+\def\pgfpathlineto#1{%
+ \pgfpointtransformed{#1}%
+ \pgf@roundcornerifneeded%
+ \pgf@nlt@lineto{\pgf@x}{\pgf@y}%
+ \global\pgf@path@lastx=\pgf@x%
+ \global\pgf@path@lasty=\pgf@y%
+}
+
+
+
+% Close the current path.
+%
+% Example:
+%
+% % Draws two triangles
+% \pgfpathmoveto{\pgfxy(0,0)}
+% \pgfpathlineto{\pgfxy(0,1)}
+% \pgfpathlineto{\pgfxy(1,0)}
+% \pgfclosepath
+% \pgfpathmoveto{\pgfxy(2,0)}
+% \pgfpathlineto{\pgfxy(2,1)}
+% \pgfpathlineto{\pgfxy(3,0)}
+% \pgfpathclose
+% \pgfstroke
+
+\def\pgfpathclose{%
+ \pgf@roundcornerifneeded%
+ \pgf@nlt@closepath%
+}
+
+
+% Append a cubic bezier spline from the current point to #3 with control
+% points #1 and #2 to the current path.
+%
+% #1 = first control point
+% #2 = second control point
+% #3 = end point
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointxy{0}{0}}
+% \pgfpathcurveto{\pgfpointxy{0}{1}}{\pgfpointxy{1}{1}}{\pgfpointxy{1}{2}}
+% \pgfstroke
+
+\def\pgfpathcurveto#1#2#3{%
+ \pgfpointtransformed{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgfpointtransformed{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgfpointtransformed{#1}%
+ \pgf@roundcornerifneeded%
+ \pgf@nlt@curveto{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}{\pgf@xb}{\pgf@yb}%
+ \global\pgf@path@lastx=\pgf@xb%
+ \global\pgf@path@lasty=\pgf@yb%
+}
+
+
+
+% Append a quadratic bezier spline from the current point to #2 with
+% control point #1 to the current path.
+%
+% #1 = control point
+% #2 = end point
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointxy{0}{0}}
+% \pgfpathquadraticcurveto{\pgfpointxy{1}{1}}{\pgfpointxy{2}{0}}
+% \pgfstroke
+
+\def\pgfpathquadraticcurveto#1#2{%
+ \pgfpointtransformed{#2}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgfpointtransformed{#1}%
+ \pgf@xc=.6666666\pgf@x%
+ \pgf@yc=.6666666\pgf@y%
+ % compute second control point:
+ \pgf@xa=.33333333\pgf@xb%
+ \pgf@ya=.33333333\pgf@yb%
+ \advance\pgf@xa by\pgf@xc%
+ \advance\pgf@ya by\pgf@yc%
+ % compute first control point
+ \advance\pgf@xc by.3333333\pgf@path@lastx%
+ \advance\pgf@yc by.3333333\pgf@path@lasty%
+ \pgf@roundcornerifneeded%
+ \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@xa}{\pgf@ya}{\pgf@xb}{\pgf@yb}%
+ \global\pgf@path@lastx=\pgf@xb%
+ \global\pgf@path@lasty=\pgf@yb%
+}
+
+
+
+
+% Append an arc to the current point, where the current point is at
+% angle #1 and the end is at angle #2. If #2 > #1, the arc is drawn
+% counter-clockwise, otherwise it is clockwise.
+%
+% #1 = angle of first point
+% #2 = angle of second point
+% #3 = radius or x-radius/y-radius
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfxy(0,0)}
+% \pgfpatharc{0}{90}{2cm}
+% \pgfstroke
+
+\def\pgfpatharc#1#2#3{%
+ {%
+ \pgfmathparse{#1}\let\pgf@temp@a=\pgfmathresult%
+ \pgfmathparse{#2}\let\pgf@temp@b=\pgfmathresult%
+ \pgfutil@in@{and }{#3}%
+ \ifpgfutil@in@%
+ \pgf@arc@get@radii#3\pgf@arc@stop%
+ \else
+ \pgf@arc@get@radii#3and #3\pgf@arc@stop%
+ \fi%
+ \pgf@arc@local@angle@a=\pgf@temp@a pt%
+ \pgf@arc@local@angle@b=\pgf@temp@b pt%
+ \loop%
+ \pgfutil@tempdima=\pgf@arc@local@angle@a%
+ \advance\pgfutil@tempdima by-\pgf@arc@local@angle@b\relax%
+ \ifdim\pgfutil@tempdima<0pt\relax%
+ \pgfutil@tempdima=-\pgfutil@tempdima\relax%
+ \fi%
+ \ifdim\pgfutil@tempdima>90pt\relax%
+ \ifdim\pgfutil@tempdima>115pt\relax%
+ \pgf@arc@temp=90pt% big skip
+ \else%
+ \pgf@arc@temp=60pt% smaller skip to ensure wide segments
+ % (important shortened end segments because
+ % of arrow tips)
+ \fi%
+ \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax%
+ {%
+ \pgf@arc@local@angle@b=\pgf@arc@local@angle@a\relax%
+ \advance\pgf@arc@local@angle@b by\pgf@arc@temp\relax%
+ \pgf@arc%
+ }
+ \advance\pgf@arc@local@angle@a by\pgf@arc@temp\relax%
+ \else
+ {%
+ \pgf@arc@local@angle@b=\pgf@arc@local@angle@a\relax%
+ \advance\pgf@arc@local@angle@b by-\pgf@arc@temp\relax%
+ \pgf@arc%
+ }%
+ \advance\pgf@arc@local@angle@a by-\pgf@arc@temp\relax%
+ \fi%
+ \repeat%
+ \pgf@roundcornerifneeded%
+ \pgf@arc%
+ }%
+}
+\dimendef\pgf@arc@local@angle@a=0
+\dimendef\pgf@arc@local@angle@b=1
+\dimendef\pgf@arc@temp=2
+
+\def\pgf@arc@get@radii#1and #2\pgf@arc@stop{%
+ \pgfmathparse{#1}\let\pgf@arc@radius@a=\pgfmathresult%
+ \pgfmathparse{#2}\let\pgf@arc@radius@b=\pgfmathresult%
+}
+
+
+\def\pgf@arc{%
+ {%
+ \pgfutil@tempdima=\pgf@arc@radius@a pt%
+ \pgfutil@tempdimb=\pgf@arc@radius@b pt%
+ %
+ \pgf@xa=\pgf@arc@local@angle@a\relax%
+ \pgf@xb=\pgf@arc@local@angle@b\relax%
+ \advance\pgf@xb by-\pgf@xa\relax%
+ \ifdim\pgf@xb<0pt\relax%
+ \pgf@xb=-\pgf@xb\relax%
+ \fi%
+ \ifdim\pgf@xb=90.0pt%
+ \def\pgfmathresult{0.55228475}%
+ \else%
+ \pgfmathparse{1.333333333*tan(.25*\pgf@sys@tonumber{\pgf@xb})}% many thanks to Ken Starks
+ \fi%
+ \pgfutil@tempdima=\pgfmathresult\pgfutil@tempdima%
+ \pgfutil@tempdimb=\pgfmathresult\pgfutil@tempdimb%
+ %.. controls +(\pgf@xa+90:\pgfutil@tempdima) and +(\pgf@xb-90:\pgfutil@tempdima) .. +(-(#1:#3)+(#2:#3))%
+ % store first support vector in xa/ya:
+ \pgf@xa=\pgf@arc@local@angle@a\relax%
+ \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax%
+ \advance\pgf@xa by 90pt\relax%
+ \else%
+ \advance\pgf@xa by -90pt\relax%
+ \fi%
+ \edef\pgf@arc@angle{\pgf@sys@tonumber{\pgf@xa}}%
+ \pgfpointtransformed{\pgfpointpolar{\pgf@arc@angle}{\pgfutil@tempdima and \pgfutil@tempdimb}}%
+ \advance\pgf@x by-\pgf@pt@x%
+ \advance\pgf@y by-\pgf@pt@y%
+ \pgf@xa=\pgf@path@lastx%
+ \pgf@ya=\pgf@path@lasty%
+ \advance\pgf@xa by \pgf@x%
+ \advance\pgf@ya by \pgf@y%
+ % store target in xb/yb:
+ \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@a}}{\pgf@arc@radius@a pt and \pgf@arc@radius@b pt}}%
+ \pgf@xb=\pgf@path@lastx%
+ \pgf@yb=\pgf@path@lasty%
+ \advance\pgf@xb by -\pgf@x%
+ \advance\pgf@yb by -\pgf@y%
+ \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@b}}{\pgf@arc@radius@a pt and \pgf@arc@radius@b pt}}%
+ \advance\pgf@xb by \pgf@x%
+ \advance\pgf@yb by \pgf@y%
+ % store second support xc/yc:
+ \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax%
+ \advance\pgf@arc@local@angle@b by -90pt\relax%
+ \else%
+ \advance\pgf@arc@local@angle@b by 90pt\relax%
+ \fi%
+ \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@b}}{\pgfutil@tempdima and \pgfutil@tempdimb}}%
+ \advance\pgf@x by-\pgf@pt@x%
+ \advance\pgf@y by-\pgf@pt@y%
+ \pgf@xc=\pgf@xb\relax%
+ \pgf@yc=\pgf@yb\relax%
+ \advance \pgf@xc by \pgf@x\relax%
+ \advance \pgf@yc by \pgf@y\relax%
+ \pgf@nlt@curveto{\pgf@xa}{\pgf@ya}{\pgf@xc}{\pgf@yc}{\pgf@xb}{\pgf@yb}%
+ \global\pgf@path@lastx=\pgf@xb%
+ \global\pgf@path@lasty=\pgf@yb%
+ }%
+}
+
+
+% Append an arc to the current point, where the arc is on an ellipse
+% given by two axis vectors.
+%
+% #1 = angle of first point
+% #2 = angle of second point
+% #3 = first axis
+% #4 = second axis
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfxy(0,0)}
+% \pgfpatharcaxes{0}{90}{\pgfpointxy{2}{0}}{\pgfpointxy{0}{2}}
+% \pgfstroke
+
+\def\pgfpatharcaxes#1#2#3#4{%
+ {%
+ \pgftransformtriangle{\pgfpointorigin}{#3}{#4}%
+ \pgfpatharc{#1}{#2}{1pt}%
+ }%
+}
+
+
+
+% Append an arc to the current point that ends at a given position.
+%
+% #1 = x-radius
+% #2 = y-radius
+% #3 = x-axis-rotation (in degrees)
+% #4 = large-arc-sweep-flag (0 or 1)
+% #5 = sweep-flag (0 or 1)
+% #6 = target point
+%
+% Description:
+%
+% This command implements an arc drawing where a given target
+% coordinate (#6) is given and the task is to draw an arc of an
+% ellipse with the given radii. The center point of the ellipse is not
+% give, but computed automatically.
+%
+% This kind of "endpoint parameterization" of an arc is exactly the
+% same as the one specified by the SVG-specification for the "A" and
+% "a" path commands. Please see the SVG-specification for details.
+%
+% Note that the problem is internally converted to drawing an arc
+% using \pgfpatharc. This means that there may be a heavy loss of
+% accuracy.
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpoint{1cm}{1cm}}
+% \pgfpatharcto{1cm}{1cm}{0}{0}{0}{\pgfpoint{0cm}{2cm}}
+
+\def\pgfpatharcto#1#2#3#4#5#6{%
+ {%
+ % The following code is based on the transformation described in svg
+ % 1.1 specification Section F.6.5
+ %
+ % Step 1: store the simple parameters (xa=x1 since TeX does not
+ % allow numbers in names)
+ %
+ \pgfmathsetmacro\pgf@arcto@rx{abs(#1)}%
+ \pgfmathsetmacro\pgf@arcto@ry{abs(#2)}%
+ \ifdim\pgf@arcto@rx pt=0pt% special rule: zero radius=straight line
+ \gdef\pgf@marshal{\pgfpathlineto{#6}}%
+ \else
+ \ifdim\pgf@arcto@ry pt=0pt% special rule: zero radius=straight line
+ \gdef\pgf@marshal{\pgfpathlineto{#6}}%
+ \else
+ \pgfmathsetmacro\pgf@arcto@phi{#3}%
+ \pgfmathsetmacro\pgf@arcto@fA{#4}%
+ \ifdim\pgf@arcto@fA pt=0pt
+ \else
+ \pgfmathsetmacro\pgf@arcto@fA{1.0} % Special rule: every non-zero value is 1.
+ \fi
+ \pgfmathsetmacro\pgf@arcto@fS{#5}%
+ \ifdim\pgf@arcto@fS pt=0pt
+ \else
+ \pgfmathsetmacro\pgf@arcto@fS{1.0} % Special rule: every non-zero value is 1.
+ \fi
+ \pgf@process{#6}
+ \edef\pgf@arcto@xb{\the\pgf@x}%
+ \edef\pgf@arcto@yb{\the\pgf@y}%
+ %
+ % Step 2: x1,y1 is more complicated to compute: It is given by lastx
+ % and lasty, but these are transformed coordinates, we need the
+ % untransformed ones. So, we inverse the transformation (arghh...)
+ %
+ \pgftransforminvert%
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{\pgf@path@lastx}{\pgf@path@lasty}}}
+ \edef\pgf@arcto@xa{\the\pgf@x}
+ \edef\pgf@arcto@ya{\the\pgf@y}
+ \edef\pgf@temp@a{\pgf@arcto@xa,\pgf@arcto@ya}
+ \edef\pgf@temp@b{\pgf@arcto@xb,\pgf@arcto@yb}
+ \ifx\pgf@temp@a\pgf@temp@b% special rule: skip!
+ \global\let\pgf@marshal\pgfutil@empty
+ \else
+ %
+ % Ok, now we got all the parameters setup. Now comes the
+ % computation...
+ %
+ %
+ % Step 3: Start with a new coordinate system and rotate everything
+ % by the negated phi.
+ %
+ \pgftransformreset
+ \pgftransformrotate{-\pgf@arcto@phi}
+ % Ok, using \pgfpointtransformed we now get transformed points...
+ %
+ % Step 4: Compute x1' and y1' (xaprime and yaprime)
+ %
+ \pgf@process{
+ \pgfpointtransformed{\pgfpointscale{.5}{\pgfpointdiff
+ {\pgfqpoint{\pgf@arcto@xb}{\pgf@arcto@yb}}
+ {\pgfqpoint{\pgf@arcto@xa}{\pgf@arcto@ya}}
+ }
+ }
+ }
+ \edef\pgf@arcto@xaprime{\pgf@sys@tonumber\pgf@x}
+ \edef\pgf@arcto@yaprime{\pgf@sys@tonumber\pgf@y}
+ %
+ % Compute Lambda
+ %
+ \pgfmathsetmacro\pgf@arcto@frac@x{\pgf@arcto@xaprime/\pgf@arcto@rx}
+ \pgfmathsetmacro\pgf@arcto@frac@y{\pgf@arcto@yaprime/\pgf@arcto@ry}
+ \pgfmathsetmacro\pgf@arcto@lambda{
+ \pgf@arcto@frac@x*\pgf@arcto@frac@x+\pgf@arcto@frac@y*\pgf@arcto@frac@y
+ }
+ \ifdim\pgf@arcto@lambda pt>1pt%
+ \pgfmathsetmacro\pgf@arcto@sqrt@lambda{sqrt(\pgf@arcto@lambda)}
+ \pgfmathsetmacro\pgf@arcto@rx{\pgf@arcto@sqrt@lambda*\pgf@arcto@rx}
+ \pgfmathsetmacro\pgf@arcto@ry{\pgf@arcto@sqrt@lambda*\pgf@arcto@ry}
+ \fi
+ %
+ % Do some scaling
+ %
+ \pgfmathsetmacro\pgf@arcto@xaprime@abs{abs(\pgf@arcto@xaprime)}
+ \pgfmathsetmacro\pgf@arcto@yaprime@abs{abs(\pgf@arcto@yaprime)}
+ \pgfmathmax@{\pgf@arcto@rx,\pgf@arcto@ry,\pgf@arcto@xaprime@abs,\pgf@arcto@yaprime@abs}
+ \pgfmathsetmacro\pgf@arcto@scaling{20/\pgfmathresult}
+ \pgfmathsetmacro\pgf@arcto@rx@scaled{\pgf@arcto@scaling*\pgf@arcto@rx}
+ \pgfmathsetmacro\pgf@arcto@ry@scaled{\pgf@arcto@scaling*\pgf@arcto@ry}
+ \pgfmathsetmacro\pgf@arcto@xaprime@scaled{\pgf@arcto@scaling*\pgf@arcto@xaprime}
+ \pgfmathsetmacro\pgf@arcto@yaprime@scaled{\pgf@arcto@scaling*\pgf@arcto@yaprime}
+ %
+ % Step 5: Now comes the messy computation of c1' and c2'.
+ %
+ \ifdim\pgf@arcto@rx pt>\pgf@arcto@ry pt%
+ \pgfmathsetmacro\pgf@arcto@rx@over@ry{\pgf@arcto@rx/\pgf@arcto@ry}
+ \pgfmathsetmacro\pgf@arcto@ry@over@rx{\pgf@arcto@ry/\pgf@arcto@rx}
+ \pgfmathsetmacro\pgf@arcto@temp{\pgf@arcto@ry@over@rx*\pgf@arcto@xaprime@scaled}
+ \pgfmathsetmacro\pgf@arcto@numerator{
+ \pgf@arcto@ry@scaled*\pgf@arcto@ry@scaled-
+ \pgf@arcto@yaprime@scaled*\pgf@arcto@yaprime@scaled-
+ \pgf@arcto@temp*\pgf@arcto@temp
+ }
+ \pgfmathsetmacro\pgf@arcto@denominator{
+ \pgf@arcto@yaprime@scaled*\pgf@arcto@yaprime@scaled+
+ \pgf@arcto@temp*\pgf@arcto@temp
+ }
+ \else
+ \pgfmathsetmacro\pgf@arcto@rx@over@ry{\pgf@arcto@rx/\pgf@arcto@ry}
+ \pgfmathsetmacro\pgf@arcto@ry@over@rx{\pgf@arcto@ry/\pgf@arcto@rx}
+ \pgfmathsetmacro\pgf@arcto@temp{\pgf@arcto@rx@over@ry*\pgf@arcto@yaprime@scaled}
+ \pgfmathsetmacro\pgf@arcto@numerator{
+ \pgf@arcto@rx@scaled*\pgf@arcto@rx@scaled-
+ \pgf@arcto@xaprime@scaled*\pgf@arcto@xaprime@scaled-
+ \pgf@arcto@temp*\pgf@arcto@temp
+ }
+ \pgfmathsetmacro\pgf@arcto@denominator{
+ \pgf@arcto@xaprime@scaled*\pgf@arcto@xaprime@scaled+
+ \pgf@arcto@temp*\pgf@arcto@temp
+ }
+ \fi
+ \pgfmathsetmacro\pgf@arcto@frac{
+ \pgf@arcto@numerator/\pgf@arcto@denominator
+ }
+ \ifdim\pgf@arcto@frac pt<0pt
+ \pgfmathsetmacro\pgf@arcto@factor{0}
+ \else
+ \pgfmathsetmacro\pgf@arcto@factor{sqrt(\pgf@arcto@frac)}
+ \fi
+ \ifx\pgf@arcto@fA\pgf@arcto@fS
+ \pgfmathsetmacro\pgf@arcto@factor{-\pgf@arcto@factor}
+ \fi
+ \pgfmathsetmacro\pgf@arcto@cxprime{
+ \pgf@arcto@factor*\pgf@arcto@rx@over@ry*\pgf@arcto@yaprime
+ }
+ \pgfmathsetmacro\pgf@arcto@cyprime{
+ -\pgf@arcto@factor*\pgf@arcto@ry@over@rx*\pgf@arcto@xaprime
+ }
+ %
+ % Step 6: Ok, now compute cx,cy
+ %
+ \pgftransformreset
+ \pgftransformrotate{\pgf@arcto@phi}
+ \pgf@process{
+ \pgfpointtransformed{\pgfqpoint{\pgf@arcto@cxprime pt}{\pgf@arcto@cyprime pt}}
+ }
+ \edef\pgf@arcto@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgf@process{\pgfpointadd{\pgf@arcto@temp}{
+ \pgfpointscale{.5}{
+ \pgfpointadd
+ {\pgfqpoint{\pgf@arcto@xa}{\pgf@arcto@ya}}
+ {\pgfqpoint{\pgf@arcto@xb}{\pgf@arcto@yb}} }
+ }
+ }
+ \edef\pgf@arcto@cx{\the\pgf@x}
+ \edef\pgf@arcto@cy{\the\pgf@y}
+ %
+ % Step 7: Compute start angle:
+ %
+ \pgfmathsetmacro\pgf@arcto@vec@x{(\pgf@arcto@xaprime-\pgf@arcto@cxprime)/\pgf@arcto@rx}
+ \pgfmathsetmacro\pgf@arcto@vec@y{(\pgf@arcto@yaprime-\pgf@arcto@cyprime)/\pgf@arcto@ry}
+ \pgfmathsetmacro\pgf@arcto@denominator{veclen(\pgf@arcto@vec@x,\pgf@arcto@vec@y)}
+ \pgfmathsetmacro\pgf@arcto@frac{\pgf@arcto@vec@x/\pgf@arcto@denominator}
+ \pgfmathsetmacro\pgf@arcto@theta@start{acos(\pgf@arcto@frac)}
+ \ifdim\pgf@arcto@vec@y pt<0pt
+ \pgfmathsetmacro\pgf@arcto@theta@start{-\pgf@arcto@theta@start}
+ \fi
+ %
+ % Step 8: Compute end angle:
+ %
+ \pgfmathsetmacro\pgf@arcto@vec@x{(-\pgf@arcto@xaprime-\pgf@arcto@cxprime)/\pgf@arcto@rx}
+ \pgfmathsetmacro\pgf@arcto@vec@y{(-\pgf@arcto@yaprime-\pgf@arcto@cyprime)/\pgf@arcto@ry}
+ \pgfmathsetmacro\pgf@arcto@denominator{veclen(\pgf@arcto@vec@x,\pgf@arcto@vec@y)}
+ \pgfmathsetmacro\pgf@arcto@frac{\pgf@arcto@vec@x/\pgf@arcto@denominator}
+ \pgfmathsetmacro\pgf@arcto@theta@end{acos(\pgf@arcto@frac)}
+ \ifdim\pgf@arcto@vec@y pt<0pt
+ \pgfmathsetmacro\pgf@arcto@theta@end{-\pgf@arcto@theta@end}
+ \fi
+ \pgfmathsetmacro\pgf@arcto@delta@theta{abs(\pgf@arcto@theta@start-\pgf@arcto@theta@end)}
+ \ifdim\pgf@arcto@fA pt=0pt%
+ \ifdim\pgf@arcto@delta@theta pt>180pt%
+ % Ok, we need to adjust the angle!
+ \ifdim\pgf@arcto@theta@end pt>\pgf@arcto@theta@start pt
+ \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end-360}
+ \else
+ \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end+360}
+ \fi
+ \fi
+ \else
+ \ifdim\pgf@arcto@delta@theta pt<180pt%
+ % Ok, we need to adjust the angle!
+ \ifdim\pgf@arcto@theta@end pt>\pgf@arcto@theta@start pt
+ \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end-360}
+ \else
+ \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end+360}
+ \fi
+ \fi
+ \fi
+ \xdef\pgf@marshal{\noexpand
+ \pgfpatharcaxes{\pgf@arcto@theta@start}{\pgf@arcto@theta@end}
+ {\noexpand\pgfpointpolar{\pgf@arcto@phi}{\pgf@arcto@rx}}
+ {\noexpand\pgfpointpolar{\pgf@arcto@phi+90}{\pgf@arcto@ry}}
+ }
+ \fi\fi\fi
+ }
+ \pgf@marshal
+}
+
+
+
+% the quality of arc approximation by means of Bezier splines is
+% controlled by a mesh width.
+%
+% The mesh width is provided in (full!) degrees. The smaller the mesh
+% width, the more precise the arc approximation.
+%
+% Use an empty value to disable spline approximation (uses a single
+% cubic polynomial for the complete arc).
+%
+% The value must be an integer!
+\def\pgfpatharctomaxstepsize{45}
+
+% A specialized arc operation for an arc on an (axis--parallel) ellipse.
+%
+% In contrast to \pgfpatharc, it explicitly interpolates start- and end points.
+%
+% In contrast to \pgfpatharcto, this routine is numerically stable and
+% quite fast since it relies on a lot of precomputed information.
+%
+% #1 center of ellipse
+% #2 angle of last path position inside of the ellipse
+% #3 end angle
+% #4 end point (a \pgfpoint)
+% #5 xradius
+% #6 yradius
+% #7 the ratio xradius/yradius of the ellipse
+% #8 the ratio yradius/xradius of the ellipse
+% Example:
+% \def\cx{1cm}% center x
+% \def\cy{1cm}% center y
+% \def\startangle{0}%
+% \def\endangle{45}%
+% \def\a{5cm}% xradius
+% \def\b{10cm}% yradius
+% \pgfmathparse{\a/\b}\let\abratio=\pgfmathresult
+% \pgfmathparse{\b/\a}\let\baratio=\pgfmathresult
+%
+% \pgfpathmoveto{\pgfpoint{\cx+\a*cos(\startangle)}{\cy+\b*sin(\startangle)}}%
+% \pgfpatharctoprecomputed
+% {\pgfpoint{\cx}{\cy}}
+% {\startangle}
+% {\endangle}
+% {\pgfpoint{\cx+\a*cos(\endangle)}{\cy+\b*sin(\endangle)}}%
+% {\a}
+% {\b}
+% {\abratio}
+% {\baratio}
+%
+\def\pgfpatharctoprecomputed#1#2#3#4#5#6#7#8{%
+ \begingroup
+ % Implementation idea:
+ %
+ % let
+ % m = center (#1)
+ % \gamma_0 = start angle
+ % \gamma_1 = end angle
+ % a = x radius
+ % b = y radius
+ %
+ % an axis parallel ellipse is parameterized by
+ % C(\gamma) = m + ( a cos(\gamma), b sin(\gamma) ), \gamma in [0,360].
+ %
+ % Now, consider the segment \gamma(t),
+ % \gamma:[0,1] -> [\gamma_0,\gamma_1],
+ % t -> \gamma_0 + t(\gamma_1 - \gamma_0)
+ % and
+ % C(\gamma(t)) which is defined on [0,1].
+ %
+ % I'd like to approximate the arc by one or more cubic bezier
+ % splines which interpolate through the last and first provided
+ % points.
+ %
+ % In general, a Bezier spline C:[0,1] -> \R of order n fulfills
+ % C'(0) = n ( P_1 - P_0 ),
+ % C'(1) = n ( P_n - P_{n-1} ).
+ % For n=3 and given P_0 and P_3, I can directly compute P_1 and P_2 once I know
+ % the derivatives at t=0 and t=1.
+ %
+ % The derivatives in our case are
+ % ( C \circ \gamma )'(t) = C'[\gamma(t)] * \gamma'(t)
+ % = ( -a pi/180 sin(\gamma(t)), b pi/180 cos(\gamma(t)) ) * (\gamma_1 - \gamma_0).
+ % The pi/180 comes into play since we are working with degrees.
+ %
+ % Expression (C\circ\gamma)'(0) using P_0 and (C \circ \gamma)'(1)
+ % using P_3 yields the expressions
+ % (C \circ \gamma)'(0) =
+ % pi/180 * (\gamma_1 - \gamma_0)* [ - a/b(P_0^y - my), b/a (P_0^x - mx) ]
+ % (C \circ \gamma)'(1) =
+ % pi/180 * (\gamma_1 - \gamma_0)* [ - a/b(P_3^y - my), b/a (P_3^x - mx) ]
+ %
+ % defining
+ % scaleA = a/b * pi / (3*180) * (\gamma_1 - \gamma_0)
+ % and
+ % scaleB = b/a * pi / (3*180) * (\gamma_1 - \gamma_0)
+ % yields the direct expressions for the intermediate bezier
+ % control points
+ %
+ % P_1 = [
+ % P_0^x - scaleA* ( P_0^y -my),
+ % P_0^y + scaleB* ( P_0^x -mx) ]
+ % and
+ % P_2 = [
+ % P_3^x + scaleA* ( P_3^y -my),
+ % P_3^y - scaleB* ( P_3^x -mx) ].
+ %
+ % This works fast, with few operations, if
+ % - a/b and b/a are known in advance
+ % - P_0 and P_3 are known in advance
+ % - \gamma_0 and \gamma_1 are known.
+ %
+ % It is also reliable if (\gamma_1 - \gamma_0) is small
+ %
+ \pgf@process{#1}%
+ \edef\pgfpath@center@x{\the\pgf@x}%
+ \edef\pgfpath@center@y{\the\pgf@y}%
+ \def\pgfpath@completearcend{#4}%
+ % compute scale (#3-#2) * pi/(3*180) = (#3 - #2) * pi/27 * 1/20
+ % splitting pi/(3*180) into two scales has higher TeX accuracy
+ \pgf@xa=#2pt
+ \pgf@xb=#3pt
+ \edef\pgfpath@startangle{#2pt}%
+ \edef\pgfpath@endangle{\pgf@sys@tonumber\pgf@xb}%
+ %
+ \pgf@ya=\pgf@xb
+ \advance\pgf@ya by-\pgf@xa
+ %
+ \ifx\pgfpatharctomaxstepsize\pgfutil@empty
+ \def\pgfpath@N{1}%
+ \pgf@xc=\pgf@ya
+ \else
+ \pgf@xc=\pgf@ya% compute N = floor((gamma_1 - gamma_0) / max) +1
+ \ifdim\pgf@xc<0pt
+ \multiply\pgf@xc by-1
+ \fi
+ \divide\pgf@xc by\pgfpatharctomaxstepsize\relax
+ \afterassignment\pgfutil@gobble@until@relax
+ \c@pgf@counta=\the\pgf@xc\relax
+ \advance\c@pgf@counta by1
+ \edef\pgfpath@N{\the\c@pgf@counta}%
+ %
+ \pgf@xc=\pgf@ya
+ \divide\pgf@xc by\c@pgf@counta
+ \fi
+ %
+ \edef\pgfpath@h{\pgf@sys@tonumber\pgf@xc}%
+ %
+%\message{pgfpathellipse: using N =\pgfpath@N\space spline points y0 = \pgfpath@startangle, y0+i*h, yN=\pgfpath@endangle, i=1,...,(\pgfpath@N-1), with h=\pgfpath@h\space mesh width (total arc angle \pgf@sys@tonumber\pgf@ya).}%
+ %
+ %
+ \pgf@xc=0.116355283466289\pgf@xc % pi/27
+ \divide\pgf@xc by20
+ \pgf@xa=#7\pgf@xc
+ \edef\pgfpath@scale@A{\pgf@sys@tonumber\pgf@xa}%
+ \pgf@xa=#8\pgf@xc
+ \edef\pgfpath@scale@B{\pgf@sys@tonumber\pgf@xa}%
+ %
+ % compute intermediate spline segments for
+ % i = 1,...,N-1
+ % this is a no-op for N=1.
+ \c@pgf@countd=1
+ \pgfutil@loop
+ \ifnum\c@pgf@countd<\pgfpath@N\relax
+ %
+ \pgf@xa=\pgfpath@startangle % compute \pgf@xa = y_0 + i*h
+ \pgf@xb=\pgfpath@h pt
+ \multiply\pgf@xb by\c@pgf@countd
+ \advance\pgf@xa by\pgf@xb
+ \edef\pgfpath@angle@i{\pgf@sys@tonumber\pgf@xa}%
+%\message{angle \the\c@pgf@countd: \pgfpath@angle@i...}%
+ %
+ \pgfpatharcofellipse@{%
+ \pgfpoint
+ {\pgfpath@center@x + #5*cos(\pgfpath@angle@i)}
+ {\pgfpath@center@y + #6*sin(\pgfpath@angle@i)}%
+ }%
+ %
+ \advance\c@pgf@countd by1
+ \pgfutil@repeat
+ %
+ % compute final spline segment. It only differs insofar as the
+ % final point is already known explicitly and should be
+ % interpolated without additional math error.
+%\message{angle \pgfpath@N: \pgfpath@endangle...}%
+ \pgfpatharcofellipse@{\pgfpath@completearcend}%
+ \endgroup
+}%
+\def\pgfpatharcofellipse@#1{%
+ \begingroup
+ \pgf@process{#1}%
+ \edef\pgfpath@endpt{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
+ %
+ \pgfpathcurveto{
+ \begingroup
+ \global\pgf@x=\pgf@path@lastx
+ \global\pgf@y=\pgf@path@lasty
+ \pgf@xa=\pgf@x \advance\pgf@xa by-\pgfpath@center@x
+ \pgf@ya=\pgf@y \advance\pgf@ya by-\pgfpath@center@y
+ \global\advance\pgf@x by-\pgfpath@scale@A\pgf@ya
+ \global\advance\pgf@y by \pgfpath@scale@B\pgf@xa
+ \endgroup
+ }{%
+ \begingroup
+ \pgfpath@endpt
+ \pgf@xa=\pgf@x \advance\pgf@xa by-\pgfpath@center@x
+ \pgf@ya=\pgf@y \advance\pgf@ya by-\pgfpath@center@y
+ \global\advance\pgf@x by \pgfpath@scale@A\pgf@ya
+ \global\advance\pgf@y by-\pgfpath@scale@B\pgf@xa
+ \endgroup
+ }{%
+ \pgfpath@endpt
+ }%
+ \endgroup
+}
+
+
+
+
+
+
+
+
+
+% Append an ellipse to the current path.
+%
+% #1 = center
+% #2 = first axis
+% #3 = second axis
+%
+% Example:
+%
+% % Add a circle of radius 3cm around the origin
+% \pgfpathellipse{\pgforigin}{\pgfxy(2,0)}{\pgfxy(0,1)}
+%
+% % Draw a non-filled circle of radius 1cm around the point (1,1)
+% \pgfpathellipse{\pgfxy(1,1)}{\pgfxy(1,1)}{\pgfxy(-2,2)}
+% \pgfstroke
+
+\def\pgfpathellipse#1#2#3{%
+ \pgfpointtransformed{#1}% store center in xc/yc
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfpointtransformed{#2}%
+ \pgf@xa=\pgf@x% store first axis in xa/ya
+ \pgf@ya=\pgf@y%
+ \advance\pgf@xa by-\pgf@pt@x%
+ \advance\pgf@ya by-\pgf@pt@y%
+ \pgfpointtransformed{#3}%
+ \pgf@xb=\pgf@x% store second axis in xb/yb
+ \pgf@yb=\pgf@y%
+ \advance\pgf@xb by-\pgf@pt@x%
+ \advance\pgf@yb by-\pgf@pt@y%
+ {%
+ \advance\pgf@xa by\pgf@xc%
+ \advance\pgf@ya by\pgf@yc%
+ \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}%
+ }%
+ \pgf@x=0.55228475\pgf@xb% first arc
+ \pgf@y=0.55228475\pgf@yb%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
+ \pgf@x=0.55228475\pgf@xa%
+ \pgf@y=0.55228475\pgf@ya%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ {%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \advance\pgf@xb by\pgf@xc%
+ \advance\pgf@yb by\pgf@yc%
+ \pgf@temp%
+ \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}%
+ }%
+ \pgf@xa=-\pgf@xa% flip first axis
+ \pgf@ya=-\pgf@ya%
+ \pgf@x=0.55228475\pgf@xa% second arc
+ \pgf@y=0.55228475\pgf@ya%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
+ \pgf@x=0.55228475\pgf@xb%
+ \pgf@y=0.55228475\pgf@yb%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ {%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \advance\pgf@xa by\pgf@xc%
+ \advance\pgf@ya by\pgf@yc%
+ \pgf@temp%
+ \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}%
+ }%
+ \pgf@xb=-\pgf@xb% flip second axis
+ \pgf@yb=-\pgf@yb%
+ \pgf@x=0.55228475\pgf@xb% third arc
+ \pgf@y=0.55228475\pgf@yb%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
+ \pgf@x=0.55228475\pgf@xa%
+ \pgf@y=0.55228475\pgf@ya%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ {%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \advance\pgf@xb by\pgf@xc%
+ \advance\pgf@yb by\pgf@yc%
+ \pgf@temp%
+ \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}%
+ }%
+ \pgf@xa=-\pgf@xa% flip first axis once more
+ \pgf@ya=-\pgf@ya%
+ \pgf@x=0.55228475\pgf@xa% fourth arc
+ \pgf@y=0.55228475\pgf@ya%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
+ \pgf@x=0.55228475\pgf@xb%
+ \pgf@y=0.55228475\pgf@yb%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ {%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \advance\pgf@xa by\pgf@xc%
+ \advance\pgf@ya by\pgf@yc%
+ \pgf@temp%
+ \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}%
+ }%
+ \pgf@nlt@closepath%
+ \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}%
+}
+
+
+
+% Append a circle to the current path
+%
+% #1 = center
+% #2 = radius
+%
+% Example:
+%
+% % Append a circle of radius 3cm around the point (1,1)
+% \pgfpathcircle{\pgxy(1,1)}{3cm}
+
+\def\pgfpathcircle#1#2{\pgfpathellipse{#1}{\pgfpoint{#2}{0pt}}{\pgfpoint{0pt}{#2}}}
+
+
+
+
+% Append a rectangle to the current path
+%
+% #1 = lower left corner point of rectangle
+% #2 = width and height vector
+%
+% Example:
+%
+% % A rectangle with corners (2,2) and (3,3)
+% \pgfpathrectangle{\pgfpointxy{2}{2}}{\pgfpointxy{1}{1}}
+
+\def\pgfpathrectangle{%
+ \let\pgfrect@next=\pgf@specialrect%
+ \ifpgf@pt@identity%
+ \ifpgf@arccorners%
+ \else%
+ \ifx\pgf@nlt@list\pgfutil@empty%
+ \let\pgfrect@next=\pgf@normalrect%
+ \fi%
+ \fi%
+ \fi%
+ \pgfrect@next%
+}
+
+\def\pgf@normalrect#1#2{%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgfpointtransformed{#1}%
+ \pgfsyssoftpath@rect{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \advance\pgf@x by\pgf@xa\relax%
+ \advance\pgf@y by\pgf@ya\relax%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+}
+
+\def\pgf@specialrect#1#2{%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#1}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \advance\pgf@xa by\pgf@xb%
+ \advance\pgf@ya by\pgf@yb%
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
+ \pgfpathclose%
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+}
+
+% Append a rectangle to the current path
+%
+% #1 = one corner of the rectangle
+% #2 = opposite corner of the rectangle
+%
+% Example:
+%
+% % A rectangle with corners (2,2) and (3,3)
+% \pgfpathrectanglecorners{\pgfpointxy{2}{2}}{\pgfpointxy{3}{3}}
+
+\def\pgfpathrectanglecorners#1#2{%
+ \pgf@process{#2}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{#1}%
+ \advance\pgf@xc by-\pgf@x%
+ \advance\pgf@yc by-\pgf@y%
+ \pgfpathrectangle{#1}{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+}
+
+
+% Append a grid to the current path.
+%
+% #1 = first corner point of grid
+% #2 = second corner point of grid
+%
+% Options:
+%
+% stepx = x-step dimension (default 1cm)
+% stepy = y-step dimension (default 1cm)
+% step = dimension vector
+%
+% Example:
+%
+% \pgfsetlinewidth{0.8pt}
+% \pgfgrid{\pgfxy(0,0)}{\pgfxy(3,2)}
+% \pgfsetlinewidth{0.4pt}
+% \pgfgrid[stepx=1cm,stepy=1cm]{\pgfxy(0,0)}{\pgfxy(3,2)}
+
+\pgfkeys{
+ /pgf/stepx/.initial=1cm,
+ /pgf/stepy/.initial=1cm,
+ /pgf/step/.code={\pgf@process{#1}\pgfkeysalso{/pgf/stepx/.expanded=\the\pgf@x,/pgf/stepy/.expanded=\the\pgf@y}},
+ /pgf/step/.value required
+}
+
+\def\pgfpathgrid{\pgfutil@ifnextchar[{\pgf@pathgrid}{\pgf@pathgrid[]}}
+\def\pgf@pathgrid[#1]#2#3{%
+ \pgfset{#1}%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/stepx}}%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/stepy}}%
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ % Swap coordinates if one of them is smaller than the other:
+ \ifdim\pgf@xa>\pgf@xb%
+ \pgf@x=\pgf@xb%
+ \pgf@xb=\pgf@xa%
+ \pgf@xa=\pgf@x%
+ \fi%
+ \ifdim\pgf@ya>\pgf@yb%
+ \pgf@y=\pgf@yb%
+ \pgf@yb=\pgf@ya%
+ \pgf@ya=\pgf@y%
+ \fi%
+ \ifdim \pgf@yc > .01pt\relax% if to draw horizontal lines
+ \c@pgf@counta=\pgf@ya\relax%
+ \c@pgf@countb=\pgf@yc\relax%
+ \divide\c@pgf@counta by\c@pgf@countb\relax%
+ \pgfutil@tempdima=\c@pgf@counta\pgf@yc\relax%
+ \ifdim\pgfutil@tempdima<\pgf@ya%
+ \advance\pgfutil@tempdima by\pgf@yc%
+ \fi%
+ \pgfutil@tempdimb\pgf@x
+ \pgfutil@loop% horizontal lines
+ {%
+ \pgf@xa=\pgfutil@tempdimb%
+ \pgf@ya=\pgfutil@tempdima%
+ \pgf@pos@transform{\pgf@xa}{\pgf@ya}
+ \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}%
+ \pgf@xa=\pgf@xb%
+ \pgf@ya=\pgfutil@tempdima%
+ \pgf@pos@transform{\pgf@xa}{\pgf@ya}
+ \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}%
+ }%
+ \advance\pgfutil@tempdima by\pgf@yc%
+ \ifdim\pgfutil@tempdima<\pgf@yb%
+ \pgfutil@repeat%
+ \advance\pgfutil@tempdima by-0.01pt\relax%
+ \ifdim\pgfutil@tempdima<\pgf@yb%
+ {%
+ \pgf@xa=\pgfutil@tempdimb%
+ \pgf@ya=\pgfutil@tempdima%
+ \pgf@pos@transform{\pgf@xa}{\pgf@ya}
+ \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}%
+ \pgf@xa=\pgf@xb%
+ \pgf@ya=\pgfutil@tempdima%
+ \pgf@pos@transform{\pgf@xa}{\pgf@ya}
+ \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}%
+ }%
+ \fi%
+ \fi%
+ \ifdim \pgf@xc > .01pt\relax% if to draw vertical lines
+ \c@pgf@counta=\pgf@xa\relax%
+ \c@pgf@countb=\pgf@xc\relax%
+ \divide\c@pgf@counta by\c@pgf@countb\relax%
+ \pgfutil@tempdimb=\c@pgf@counta\pgf@xc\relax%
+ \ifdim\pgfutil@tempdimb<\pgf@xa%
+ \advance\pgfutil@tempdimb by\pgf@xc%
+ \fi%
+ \pgfutil@loop% vertical lines
+ {%
+ \pgf@xc=\pgfutil@tempdimb%
+ \pgf@yc=\pgf@ya%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}
+ \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}%
+ \pgf@xc=\pgfutil@tempdimb%
+ \pgf@yc=\pgf@yb%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}
+ \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}%
+ }%
+ \advance\pgfutil@tempdimb by\pgf@xc%
+ \ifdim\pgfutil@tempdimb<\pgf@xb%
+ \pgfutil@repeat%
+ \advance\pgfutil@tempdimb by-0.01pt\relax%
+ \ifdim\pgfutil@tempdimb<\pgf@xb%
+ {%
+ \pgf@xc=\pgfutil@tempdimb%
+ \pgf@yc=\pgf@ya%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}
+ \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}%
+ \pgf@xc=\pgfutil@tempdimb%
+ \pgf@yc=\pgf@yb%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}
+ \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}%
+ }%
+ \fi%
+ \fi%
+ \pgf@process{#3}%
+ \pgf@pos@transform{\pgf@x}{\pgf@y}%
+ \pgf@nlt@moveto{\pgf@x}{\pgf@y}%
+}
+
+
+
+% Append two half-parabolas to the path
+%
+% #1 = bend (relative to current point)
+% #2 = end point (relative to bend point)
+%
+% Description:
+%
+% This command appends a half-parabola that starts at the current point
+% and has its bend at #1+current point. Then, a second parabola is
+% appended that starts at #1+current point, where it also has its
+% minimum/maximum, and ends at #1+current point+#2, which becomes the
+% new current point.
+%
+% By setting #2 = (0,0) you draw only a half parabola that goes from the
+% current point to the bend; by setting #1 = (0,0)
+% you draw a half parabola that going to current point + #2 and has its
+% bend at the current point.
+%
+% Examples:
+%
+% % Half-parabola going ``up and right''
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathparabola{\pgfpointorigin}{\pgfpoint{2cm}{4cm}}
+%
+% % Half-parabola going ``down and right''
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathparabola{\pgfpoint{-2cm}{4cm}}}{\pgfpointorigin}
+%
+% % Full parabola
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathparabola{\pgfpoint{-2cm}{4cm}}{\pgfpoint{2cm}{4cm}}
+
+\def\pgfpathparabola#1#2{%
+ {%
+ \pgf@process{#2}% untransformed
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{#1}% untransformed
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfutil@tempswatrue%
+ \ifdim\pgf@xb=0pt\relax%
+ \ifdim\pgf@yb=0pt\relax%
+ \pgfutil@tempswafalse%
+ \fi%
+ \fi%
+ {%
+ \ifpgfutil@tempswa%
+ \pgf@arccornersfalse
+ \else%
+ \fi%
+ \pgfutil@tempswatrue%
+ \ifdim\pgf@xc=0pt\relax%
+ \ifdim\pgf@yc=0pt\relax%
+ \pgfutil@tempswafalse%
+ \fi%
+ \fi%
+ \ifpgfutil@tempswa
+ {%
+ \pgf@pt@x=\pgf@path@lastx%
+ \pgf@pt@y=\pgf@path@lasty%
+ \pgfpathcurveto%
+ {\pgfqpoint{.1125\pgf@xc}{.225\pgf@yc}}% found by trial and error
+ {\pgfqpoint{.5\pgf@xc}{\pgf@yc}}% found by trial and error
+ {\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ }%
+ \fi%
+ }%
+ \ifpgfutil@tempswa%
+ \pgf@xc=\pgf@xb%
+ \pgf@yc=\pgf@yb%
+ {%
+ \pgf@pt@x=\pgf@path@lastx%
+ \pgf@pt@y=\pgf@path@lasty%
+ \pgfpathcurveto%
+ {\pgfqpoint{.5\pgf@xc}{0\pgf@yc}}% found by trial and error
+ {\pgfqpoint{.8875\pgf@xc}{.775\pgf@yc}}% found by trial and error
+ {\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ }%
+ \fi%
+ }%
+}
+
+
+
+
+% Append a sine curve between 0 and \pi/2 to the path.
+%
+% #1 = vector, describing the width and height of the curve
+%
+% Description:
+%
+% This command appends a sine curve in the interval 0 and \pi/2 to the
+% current path. The sine curve ends at currentpoint+#1.
+%
+% Examples:
+%
+% % One complete sine in the interval [0,\pi]
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathsine{\pgfpoint{1.57cm}{1cm}}
+% \pgfpathcosine{\pgfpoint{3.141cm}{0cm}}
+
+\def\pgfpathsine#1{%
+ {%
+ \pgf@process{#1}% untransformed
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@pt@x=\pgf@path@lastx% evil trickery to transform to the last point
+ \pgf@pt@y=\pgf@path@lasty%
+ \pgfpathcurveto%
+ {\pgfqpoint{.3260\pgf@xc}{.5120\pgf@yc}}%
+ {\pgfqpoint{.6380\pgf@xc}{\pgf@yc}}%
+ {\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ }%
+}
+
+% Append a cosine curve between 0 and \pi/2 to the path.
+%
+% #1 = vector, describing the width and height of the curve
+%
+% Examples:
+%
+% % One complete sine in the interval [0,\pi]
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathsine{\pgfpoint{1.57cm}{1cm}}
+% \pgfpathcosine{\pgfpoint{3.141cm}{0cm}}
+
+\def\pgfpathcosine#1{%
+ {%
+ \pgf@process{#1}% untransformed
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@pt@x=\pgf@path@lastx% evil trickery to transform to the last point
+ \pgf@pt@y=\pgf@path@lasty%
+ \pgfpathcurveto%
+ {\pgfqpoint{.3620\pgf@xc}{0pt}}%
+ {\pgfqpoint{.6740\pgf@xc}{.4880\pgf@yc}}%
+ {\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ }%
+}
+
+
+
+% Draw part of a curve between two specified times s and t.
+%
+% #1 - a start time s.
+% #2 - an end time t.
+% #3 - start point of the curve
+% #4 - first control
+% #5 - second control
+% #6 - end point of the curve
+%
+% There are two versions, \pgfpathcurvebetweentime and
+% \pgfpathcurvebetweentimecontinue. The latter does not insert a
+% moveto to the first point.
+%
+\def\pgfpathcurvebetweentime{\pgf@ignoremovetofalse\pgf@@pathcurvebetweentime}
+\def\pgfpathcurvebetweentimecontinue{\pgf@ignoremovetotrue\pgf@@pathcurvebetweentime}
+\newif\ifpgf@ignoremoveto
+
+\def\pgf@@pathcurvebetweentime#1#2#3#4#5#6{%
+ \pgfmathparse{#1}%
+ \let\pgf@time@s=\pgfmathresult%
+ \pgfmathparse{#2}%
+ \let\pgf@time@t=\pgfmathresult%
+ \ifdim\pgf@time@s pt>\pgf@time@t pt\relax%
+ \pgfmathsetmacro\pgf@time@s{1-#1}%
+ \pgfmathsetmacro\pgf@time@t{1-#2}%
+ \pgf@@@pathcurvebetweentime{\pgf@time@t}{#6}{#5}{#4}{#3}%
+ \else%
+ \pgf@@@pathcurvebetweentime{\pgf@time@t}{#3}{#4}{#5}{#6}%
+ \fi%
+}
+
+\def\pgf@@@pathcurvebetweentime#1#2#3#4#5{%
+ % Q1 = P1.
+ \pgf@process{#2}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ % Q2 = P1 + t*(P2-P1).
+ \pgf@process{%
+ \pgf@process{#3}%
+ \pgf@xa=#1\pgf@x%
+ \pgf@ya=#1\pgf@y%
+ \pgf@process{#2}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \advance\pgf@x by-#1\pgf@xb%
+ \advance\pgf@y by-#1\pgf@yb%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ }%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ % Q3 = Q2 + t*((P2 + t*(P3-P2)) - Q2).
+ \pgf@process{%
+ \pgf@process{#4}%
+ \pgf@xa=#1\pgf@x%
+ \pgf@ya=#1\pgf@y%
+ %
+ \pgf@process{#3}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xc by-#1\pgf@x%
+ \advance\pgf@yc by-#1\pgf@y%
+ %
+ \pgf@x=\pgf@xb%
+ \pgf@y=\pgf@yb%
+ \advance\pgf@x by#1\pgf@xa%
+ \advance\pgf@y by#1\pgf@ya%
+ \advance\pgf@x by-#1\pgf@xb%
+ \advance\pgf@y by-#1\pgf@yb%
+ \advance\pgf@x by#1\pgf@xc%
+ \advance\pgf@y by#1\pgf@yc%
+ }%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ % Q4 = (1-t)^3*P1 + 3*t(1-t)^2*P2 + 3*t^2(1-t)*P3 + t^3*P4.
+ \pgf@process{\pgfpointcurveattime{#1}{#2}{#3}{#4}{#5}}%
+ \ifx#1\pgf@time@t%
+ % First time round...
+ \pgfmathdivide@{\pgf@time@s}{\pgf@time@t}%
+ \pgfmathadd@{-\pgfmathresult}{1}%
+ \let\pgf@time@s=\pgfmathresult%
+ \edef\pgf@marshal{%
+ \noexpand\pgf@@@pathcurvebetweentime{\noexpand\pgf@time@s}%
+ {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ }%
+ \else%
+ % ...second time round.
+ \ifpgf@ignoremoveto%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ }%
+ \else%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpathmoveto{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ }%
+ \fi%
+ \fi%
+ \pgf@marshal%
+}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathprocessing.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathprocessing.code.tex
new file mode 100644
index 0000000000..e33f0653ce
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathprocessing.code.tex
@@ -0,0 +1,563 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorepathprocessing.code.tex}
+
+
+% Split a path at the last subpath of a path
+%
+% #1 = a macro that stores a path
+%
+% Description:
+%
+% This command will split the path into two parts:
+%
+% \pgfprocessresultpathprefix
+% The part of the path before the last subpath.
+%
+% \pgfprocessresultpathsuffix
+% The last subpath on the path.
+%
+% #1 will always be equal to the contents of the two above macros
+% concatenated. Normally, your objective will be to modify the
+% \pgfprocessresultpathsuffix and then concatenate the result.
+
+\def\pgfprocesssplitpath#1{%
+ \let\pgfprocessresultpathprefix\pgfutil@empty%
+ \let\pgfprocessresultpathsuffix\pgfutil@empty%
+ \let\pgf@next\pgf@process@split%
+ \expandafter\pgf@process@split#1\pgfsyssoftpath@movetotoken{}{}\pgf@stop%
+}
+
+\def\pgf@process@split#1\pgfsyssoftpath@movetotoken#2#3#4{%
+ \ifx#4\pgf@stop% ok, end reached!
+ \expandafter\def\expandafter\pgfprocessresultpathsuffix\expandafter{\pgfprocessresultpathsuffix#1}%
+ \let\pgf@next\pgfutil@gobble%
+ \else%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgfprocessresultpathprefix%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix#1}%
+ \def\pgfprocessresultpathsuffix{\pgfsyssoftpath@movetotoken{#2}{#3}}%
+ \fi%
+ \pgf@next#4%
+}
+
+
+
+% Split a subpath at the end
+%
+% #1 = a macro that stores an open subpath that contains at least two
+% path commands (so, not just a moveto);
+%
+% Description:
+%
+% Splits the subpath into two parts:
+%
+% \pgfprocessresultsubpathsuffix
+% This macro contains the last two "relevant" path commands: The end
+% of the path command that led to the last path command and this
+% last path command. In essence, this macro contains everything you
+% "need to modify" if you wish to modify the end of the path.
+%
+% \pgfprocessresultsubpathprefix
+% Everything before the previous macro on the subpath.
+
+\def\pgfprocesssplitsubpath#1{%
+ % First, we need to find the end:
+ \let\pgf@tempa\pgfutil@emtpy%
+ \let\pgf@tempb\pgfutil@emtpy%
+ \let\pgf@tempc\pgfutil@emtpy%
+ \let\pgf@tempd\pgfutil@emtpy%
+ \let\pgfprocessresultsubpathprefix\pgfutil@empty%
+ \let\pgfprocessresultsubpathsuffix\pgfutil@empty%
+ \let\pgf@next\pgf@split@subpath%
+ \expandafter\pgf@split@subpath#1\pgf@stop%
+}
+
+\newif\ifpgf@split@move
+
+\def\pgf@split@subpath#1#2#3#4{%
+ \ifx#4\pgf@stop%
+ \expandafter\def\expandafter\pgfprocessresultsubpathsuffix\expandafter{\pgfprocessresultsubpathsuffix#1{#2}{#3}}%
+ \let\pgf@next\pgfutil@gobble%
+ \else%
+ \pgf@split@movetrue%
+ \ifx#1\pgfsyssoftpath@curvetosupportatoken%
+ \pgf@split@movefalse%
+ \else
+ \ifx#1\pgfsyssoftpath@curvetosupportbtoken%
+ \pgf@split@movefalse%
+ \fi%
+ \fi%
+ \ifpgf@split@move%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgfprocessresultsubpathprefix%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}%
+ \def\pgfprocessresultsubpathsuffix{#1{#2}{#3}}%
+ \else%
+ \expandafter\def\expandafter\pgfprocessresultsubpathsuffix\expandafter{\pgfprocessresultsubpathsuffix#1{#2}{#3}}%
+ \fi%
+ \fi%
+ \pgf@next#4%
+}
+
+
+
+
+% Extract start and end vectors of a path
+%
+% #1 = a macro that stores a path
+%
+% Description:
+%
+% This command will extract the first and second coordinate on the
+% path as well as the last and second-last. These coordinates will be
+% put in the pgfpoint-macros \pgfpointfirstonpath,
+% \pgfpointsecondonpath, \pgfpointsecondlastonpath, and
+% \pgfpointlastonpath. If the path is empty, these macros are set to
+% \pgfpointorigin.
+%
+% Example:
+%
+% \pgfsyssoftpath@moveto{0}{0}
+% \pgfsyssoftpath@lineto{10}{10}
+% \pgfsyssoftpath@curveto{20}{20}{30}{30}{40}{40}
+% \pgfsyssoftpath@getcurrentpath\mypath
+% \pgfprocesspathextractpoints\mypath
+%
+% % \pgfpointfirstonpath is now \pgfpoint{0}{0}
+% % \pgfpointsecondonpath is now \pgfpoint{10bp}{10bp}
+% % \pgfpointsecondlastonpath is now \pgfpoint{30bp}{30bp}
+% % \pgfpointlastonpath is now \pgfpoint{40bp}{40bp}
+
+\def\pgfprocesspathextractpoints#1{%
+ \ifx#1\pgfutil@empty%
+ \let\pgfpointfirstonpath=\pgfpointorigin%
+ \let\pgfpointsecondonpath=\pgfpointorigin%
+ \let\pgfpointsecondlastonpath=\pgfpointorigin%
+ \let\pgfpointlastonpath=\pgfpointorigin%
+ \else%
+ \expandafter\pgf@extractprocessorfirst#1\pgf@stop%
+ \fi%
+}
+
+\def\pgf@extractprocessorfirst#1#2#3#4{%
+ \def\pgfpointfirstonpath{\pgfqpoint{#2}{#3}}%
+ \ifx#4\pgf@stop%
+ % pretty short path...
+ \let\pgfpointsecondonpath=\pgfpointfirstonpath%
+ \let\pgfpointsecondlastonpath=\pgfpointfirstonpath%
+ \let\pgfpointlastonpath=\pgfpointfirstonpath%
+ \let\next=\pgfutil@gobble%
+ \else
+ \let\next=\pgf@extractprocessorsecond%
+ \fi%
+ \next#4%
+}
+
+\def\pgf@extractprocessorsecond#1{%
+ \ifx#1\pgfsyssoftpath@movetotoken%
+ % Reset things...
+ \let\pgf@next=\pgf@extractprocessorfirst%
+ \else%
+ \let\pgf@next=\pgf@@extractprocessorsecond%
+ \fi%
+ \pgf@next#1%
+}
+\def\pgf@@extractprocessorsecond#1#2#3#4{%
+ \def\pgfpointsecondonpath{\pgfqpoint{#2}{#3}}%
+ \let\pgfpointsecondlastonpath=\pgfpointfirstonpath%
+ \let\pgfpointlastonpath=\pgfpointsecondonpath%
+ \ifx#4\pgf@stop%
+ % short path...
+ \let\next=\pgfutil@gobble%
+ \else
+ \let\next=\pgf@extractprocessorother%
+ \fi%
+ \next#4%
+}
+
+\def\pgf@extractprocessorother#1{%
+ \ifx#1\pgfsyssoftpath@movetotoken%
+ % Reset things...
+ \let\pgf@next=\pgf@extractprocessorfirst%
+ \else%
+ \let\pgf@next=\pgf@@extractprocessorother%
+ \fi%
+ \pgf@next#1%
+}
+\def\pgf@@extractprocessorother#1#2#3#4{%
+ \let\pgfpointsecondlastonpath=\pgfpointlastonpath%
+ \def\pgfpointlastonpath{\pgfqpoint{#2}{#3}}%
+ \ifx#4\pgf@stop%
+ % end!
+ \let\next=\pgfutil@gobble%
+ \fi%
+ \next#4%
+}
+
+
+
+% Check for closepath and rectangles
+%
+% #1 = a macro that stores a path
+% #2 = command to be executed when a closepath or a rectangle is encountered
+%
+% Example:
+%
+% \pgfsyssoftpath@moveto{0}{0}
+% \pgfsyssoftpath@lineto{10}{10}
+% \pgfsyssoftpath@curveto{20}{20}{30}{30}{40}{40}
+% \pgfsyssoftpath@getcurrentpath\mypath
+% \pgfprocesscheckclosed{\mypath}{\pgf@drawarrowsfalse}
+
+\def\pgfprocesscheckclosed#1#2{%
+ {%
+ \global\let\pgf@proc@todo=\relax%
+ \let\pgfsyssoftpath@movetotoken=\pgfutil@gobbletwo%
+ \let\pgfsyssoftpath@linetotoken=\pgfutil@gobbletwo%
+ \let\pgfsyssoftpath@curvetosupportatoken=\pgfutil@gobbletwo%
+ \let\pgfsyssoftpath@curvetosupportbtoken=\pgfutil@gobbletwo%
+ \let\pgfsyssoftpath@curvetotoken=\pgfutil@gobbletwo%
+ \def\pgfsyssoftpath@rectcornertoken{\gdef\pgf@proc@todo{#2}\pgfutil@gobbletwo}%
+ \def\pgfsyssoftpath@rectsizetoken{\gdef\pgf@proc@todo{#2}\pgfutil@gobbletwo}%
+ \def\pgfsyssoftpath@closepathtoken{\gdef\pgf@proc@todo{#2}\pgfutil@gobbletwo}%
+ #1%
+ }%
+ \pgf@proc@todo%
+}
+
+
+% Resolve specialround
+%
+% #1 = a macro that stores a path
+% #2 = a macro that stores the new path
+%
+% Description:
+%
+% Resolves all specialround tokens. When such a token is encountered,
+% the objective is to replace the next corner by a rounded corner.
+%
+
+\def\pgfprocessround#1#2{%
+ % first, check whether #1 contains \pgfsyssoftpath@specialroundtoken.
+ % if not, do quick assignment!
+ \expandafter\pgf@processroundcheck\expandafter#1\expandafter#2#1\pgfsyssoftpath@specialroundtoken\pgf@stop%
+}
+
+\def\pgf@processroundcheck#1#2#3\pgfsyssoftpath@specialroundtoken#4\pgf@stop{%
+ \def\pgf@test{#4}%
+ \ifx\pgf@test\pgfutil@empty%
+ % ok, nothing to be done!
+ \let#2=#1%
+ \else%
+ % very well...
+ \pgf@@processround#1#2%
+ \fi%
+}
+
+
+\def\pgf@@processround#1#2{%
+ \let\pgfprocess@newpath\pgfutil@empty%
+ \let\pgfprocess@moveto\pgfutil@empty%
+ \let\pgfprocess@firstto\pgfutil@empty%
+ \let\pgfprocess@segment\pgfutil@empty%
+ \pgf@xa=0pt%
+ \pgf@ya=0pt%
+ \expandafter\pgfprocess@round#1\pgf@stop{0pt}{0pt}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@newpath\expandafter{\pgfprocess@moveto}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@newpath\expandafter{\pgfprocess@segment}%
+ \let#2=\pgfprocess@newpath%
+}
+
+\def\pgfprocess@round#1#2#3{%
+ \ifx#1\pgf@stop%
+ \let\next=\relax%
+ \else%
+ \ifx#1\pgfsyssoftpath@specialroundtoken%
+ \def\pgfprocess@savex{#2}%
+ \def\pgfprocess@savey{#3}%
+ \let\next=\pgfprocess@specialround%
+ \ifdim#2=0pt%
+ \ifdim#3=0pt%
+ \let\next=\pgfprocess@round% skip!
+ \fi%
+ \fi%
+ \else%
+ \ifx\pgfprocess@firstto\pgfutil@empty%
+ \def\pgfprocess@firstto{{#2}{#3}}%
+ \fi%
+ \pgf@xa=#2%
+ \pgf@ya=#3%
+ \ifx#1\pgfsyssoftpath@movetotoken%
+ % ok, move old segment to newpath
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@newpath\expandafter{\pgfprocess@moveto}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@newpath\expandafter{\pgfprocess@segment}%
+ \def\pgfprocess@moveto{#1{#2}{#3}}%
+ \let\pgfprocess@firstto=\pgfutil@empty%
+ \let\pgfprocess@segment=\pgfutil@empty%
+ \else%
+ \pgfutil@g@addto@macro\pgfprocess@segment{#1{#2}{#3}}%
+ \fi%
+ \let\next=\pgfprocess@round%
+ \fi%
+ \fi%
+ \next%
+}
+
+\def\pgfprocess@specialround#1#2#3{%
+ \ifx\pgfprocess@firstto\pgfutil@empty%
+ \def\pgfprocess@firstto{{#2}{#3}}%
+ \fi%
+ \let\next=\pgfprocess@round% default: do nothing
+ \ifx#1\pgfsyssoftpath@linetotoken%
+ % Ok, round a lineto
+ \let\next=\pgfprocess@specialroundcope%
+ \else%
+ \ifx#1\pgfsyssoftpath@curvetosupportatoken%
+ % Ok, round a curveto.
+ \let\next=\pgfprocess@specialroundcurveto%
+ \else%
+ \ifx#1\pgfsyssoftpath@closepathtoken%
+ % Ok, round a closepath (this is tricky...)
+ \let\next=\pgfprocess@specialroundclose%
+ \fi%
+ \fi%
+ \fi%
+ \next#1{#2}{#3}%
+}%
+
+\def\pgfprocess@specialroundcope#1#2#3#4#5#6{%
+ \let\next=\pgfprocess@round% do nothing by default
+ \let\pgfprocess@continueafterrounding=\pgfprocess@round%
+ \ifx#4\pgfsyssoftpath@linetotoken%
+ % ok, let's get kicking...
+ \pgf@xc=#5%
+ \pgf@yc=#6%
+ \let\next=\pgfprocess@@specialround%
+ \else%
+ \ifx#4\pgfsyssoftpath@curvetosupportatoken%
+ \pgf@xc=#5%
+ \pgf@yc=#6%
+ \let\next=\pgfprocess@@specialround%
+ \else%
+ \ifx#4\pgfsyssoftpath@closepathtoken%
+ \pgf@xc=#5%
+ \pgf@yc=#6%
+ \let\next=\pgfprocess@@specialround%
+ \else
+ \ifx#4\pgfsyssoftpath@specialroundtoken%
+ \let\next=\pgfprocess@@findrightcoordinates%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \next#1{#2}{#3}#4{#5}{#6}%
+}
+
+\def\pgfprocess@@findrightcoordinates#1#2#3#4#5#6#7#8#9{%
+ \pgf@xc=#8%
+ \pgf@yc=#9%
+ \pgfprocess@@specialround#1{#2}{#3}#4{#5}{#6}#7{#8}{#9}%
+}
+
+\def\pgfprocess@@specialround#1#2#3{%
+ \pgfutil@g@addto@macro\pgfprocess@segment{#1}%
+ % calculate start coordinate of the curve
+ \pgf@xb=#2%
+ \pgf@yb=#3%
+ %
+ \edef\pgf@marshal%
+ {\noexpand\pgfpointlineatdistance{\pgfprocess@savex}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}%
+ {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}}%
+ \pgf@process{\pgf@marshal}%
+ \pgf@xa=\pgf@x% save start point of added curve
+ \pgf@ya=\pgf@y%
+ \edef\pgfprocess@addition{{\the\pgf@x}{\the\pgf@y}}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@segment\expandafter{\pgfprocess@addition}%
+ %
+ % now add curve
+ %
+ \edef\pgf@marshal%
+ {\noexpand\pgfpointlineatdistance{\pgfprocess@savey}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}%
+ {\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}}%
+ \pgf@process{\pgf@marshal}%
+ \pgf@xc=\pgf@x% save end point of added curve
+ \pgf@yc=\pgf@y%
+ % calculate first support:
+ {%
+ \pgf@x=\pgf@xb%
+ \pgf@y=\pgf@yb%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \advance\pgf@xa by 0.5522847\pgf@x%
+ \advance\pgf@ya by 0.5522847\pgf@y%
+ \edef\pgfprocess@addition{\noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@segment\expandafter{\pgfprocess@addition}%
+ }%
+ % calculate second support:
+ {%
+ \pgf@x=\pgf@xb%
+ \pgf@y=\pgf@yb%
+ \advance\pgf@x by-\pgf@xc%
+ \advance\pgf@y by-\pgf@yc%
+ \advance\pgf@xc by 0.5522847\pgf@x%
+ \advance\pgf@yc by 0.5522847\pgf@y%
+ \edef\pgfprocess@addition{\noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xc}{\the\pgf@yc}}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@segment\expandafter{\pgfprocess@addition}%
+ }%
+ % add end:
+ \edef\pgfprocess@addition{\noexpand\pgfsyssoftpath@curvetotoken{\the\pgf@xc}{\the\pgf@yc}}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfprocess@segment\expandafter{\pgfprocess@addition}%
+ %
+ % continue!
+ %
+ \pgf@xa=#2%
+ \pgf@ya=#3%
+ \pgfprocess@continueafterrounding%
+}
+
+\def\pgfprocess@specialroundcurveto#1#2#3#4#5#6{%
+ \pgfutil@g@addto@macro\pgfprocess@segment{#1{#2}{#3}#4{#5}{#6}}% supports
+ \pgf@xa=#5%
+ \pgf@ya=#6%
+ \pgfprocess@specialroundcope}
+
+\def\pgfprocess@specialroundclose{%
+ \let\next=\pgfprocess@round%
+ \ifx\pgfprocess@moveto\pgfutil@empty%
+ \else%
+ \ifx\pgfprocess@firstto\pgfutil@empty%
+ \else%
+ \expandafter\pgfprocess@@specialclosetarget\pgfprocess@firstto%
+ \let\pgfprocess@continueafterrounding=\pgfprocess@cleanupafterclose%
+ \edef\next{%
+ \noexpand\pgfprocess@@specialround%
+ \expandafter\expandafter\expandafter\noexpand\expandafter\pgfprocess@@specialclosemoveto\pgfprocess@moveto%
+ }%
+ \fi%
+ \fi%
+ \next%
+}
+
+\def\pgfprocess@@specialclosetarget#1#2{%
+ \pgf@xc=#1%
+ \pgf@yc=#2%
+}
+
+\def\pgfprocess@@specialclosemoveto#1#2#3{%
+ \pgfsyssoftpath@linetotoken{#2}{#3}%
+}
+
+
+\def\pgfprocess@cleanupafterclose#1#2#3{%
+ \edef\pgfprocess@moveto{\noexpand\pgfsyssoftpath@movetotoken{\the\pgf@xc}{\the\pgf@yc}}%
+ \edef\pgf@marshal{\noexpand\pgfprocess@round\noexpand\pgfsyssoftpath@closepathtoken{\the\pgf@xc}{\the\pgf@yc}}%
+ \pgf@marshal%
+}
+
+
+% Replace start and end coordinates of a path
+%
+% #1 = new start coordinate
+% #2 = new end coordinate
+%
+% Description:
+%
+% This command will replace the first and last coordinates on a path
+% by the given coordinates.
+%
+% Example:
+%
+% \pgfsyssoftpath@moveto{0}{0}
+% \pgfsyssoftpath@lineto{10}{10}
+% \pgfsyssoftpath@curveto{20}{20}{30}{10}{40}{0}
+% \pgfsyssoftpath@getcurrentpath\mypath
+% \pgfsetlinewidth{2pt}
+% \pgfusepath{stroke}
+% \pgfprocesspathextractpoints{\mypath}
+% \pgfprocesspathreplacestartandend{\mypath}
+% {\pgfpointlineatdistance{2pt}{\pgfpointfirstonpath}{\pgfpointsecondonpath}}%
+% {\pgfpointlineatdistance{2pt}{\pgfpointlastonpath}{\pgfpointsecondlastonpath}}%
+% \pgfsyssoftpath@setcurrentpath\mypath
+% \pgfsetlinewidth{1pt}
+% \color{red}
+% \pgfusepath{stroke}
+
+\def\pgfprocesspathreplacestartandend#1#2#3{%
+ \ifx#1\pgfutil@empty%
+ \else%
+ {%
+ % We (mis)use the current path to store (in a buffered manner) the
+ % rest path.
+ \pgfsyssoftpath@getcurrentpath\pgf@replace@origpath%
+ \let\pgf@prepath=\pgfutil@empty%
+ \pgf@process{#3}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#2}%
+ \expandafter\pgf@replaceprocessfirst#1\pgf@stop%
+ \pgfsyssoftpath@getcurrentpath\pgf@restpath%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gdef%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter#1%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
+ \expandafter\expandafter\expandafter\pgf@prepath%
+ \expandafter\pgf@newstart\pgf@restpath}%
+ % Restore current path
+ \pgfsyssoftpath@setcurrentpath\pgf@replace@origpath%
+ }%
+ \fi%
+}
+
+\def\pgf@replaceprocessfirst#1#2#3#4{%
+ \def\pgf@origstart{#1{#2}{#3}}%
+ \edef\pgf@newstart{\noexpand#1{\the\pgf@x}{\the\pgf@y}}%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ \ifx#4\pgf@stop%
+ \let\pgf@next=\pgfutil@gobble%
+ \else%
+ \let\pgf@next=\pgf@replaceprocessother%
+ \let\pgf@@next=\pgf@@replaceprocessother%
+ \fi%
+ \pgf@next#4%
+}
+
+\def\pgf@replaceprocessother#1{%
+ \ifx#1\pgfsyssoftpath@movetotoken%
+ \pgf@replace@handle@move%
+ \fi%
+ \pgf@@next#1%
+}
+\def\pgf@@replaceprocessother#1#2#3#4{%
+ \ifx#4\pgf@stop%
+ \edef\pgf@restpathaddition{{\noexpand#1{\the\pgf@xa}{\the\pgf@ya}}}%
+ \expandafter\pgfsyssoftpath@addtocurrentpath\pgf@restpathaddition%
+ \let\pgf@next=\pgfutil@gobble%
+ \else%
+ \pgfsyssoftpath@addtocurrentpath{#1{#2}{#3}}%
+ \fi%
+ \pgf@next#4%
+}
+
+\def\pgf@replace@handle@move{%
+ \pgfsyssoftpath@getcurrentpath\pgf@restpath%
+ % Arggghh! Must reset everything!
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gdef%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgf@prepath%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
+ \expandafter\expandafter\expandafter\pgf@prepath%
+ \expandafter\pgf@origstart\pgf@restpath}%
+ % Redo first.
+ \let\pgf@@next=\pgf@replaceprocessfirst%
+}
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathusage.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathusage.code.tex
new file mode 100644
index 0000000000..5a9c5fc22b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepathusage.code.tex
@@ -0,0 +1,661 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorepathusage.code.tex}
+
+
+% Stroke/fill/clip/etc. the current path. Depending on the options,
+% the current path will be stroked/filled/clipped/etc. If no options
+% are given, the path is stroked. If multiple options are given, all
+% of them are performed (in a sensible order).
+%
+% #1 = action(s) to be applied to the current path. Valid actions are:
+% stroke - strokes the path.
+% draw - strokes the path and adds arrow tips.
+% tips - adds arrow tips.
+% fill - fills the path.
+% clip - clip the path.
+% discard - Discards the path. Same effect as having an empty
+% options list.
+%
+% Example:
+%
+% % Draws an edge.
+% \pgfpathmoveto{\pgfxy(0,0)}
+% \pgfpathlineto{\pgfxy(0,1)}
+% \pgfpathlineto{\pgfxy(1,0)}
+% \pgfusepath{stroke}
+
+\pgfkeys{
+ /pgf/stroke/.code=\let\pgf@up@stroke\pgf@up@stroke@text\pgf@up@path@neededtrue,
+ /pgf/draw/.code=\let\pgf@up@stroke\pgf@up@stroke@text\pgf@up@path@neededtrue,
+ /pgf/fill/.code=\let\pgf@up@fill\pgf@up@fill@text\pgf@up@path@neededtrue,
+ /pgf/clip/.code=\let\pgf@up@clip\pgf@up@clip@text\pgf@up@path@neededtrue,
+ /pgf/discard/.code=,
+ /pgf/use as bounding box/.code=\let\pgf@up@bb\pgf@do@up@bb,
+ /pgf/arrow keys/flex/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows},
+ /pgf/arrow keys/flex'/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows},
+ /pgf/arrow keys/bend/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows},
+ /pgf/arrow keys/quick/.code=\pgfarrowsaddtooptions{\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@quick},
+}
+
+\pgfkeys{
+ /pgf/.cd,
+ tips/.is choice,
+ tips/.default=true,
+ tips/proper/.code=\let\pgf@tips@mode\pgf@tips@mode@onproper,
+ tips/on proper draw/.code=\let\pgf@tips@mode\pgf@tips@mode@onproperdraw,
+ tips/true/.code=\let\pgf@tips@mode\pgf@tips@mode@true,
+ tips/on draw/.code=\let\pgf@tips@mode\pgf@tips@mode@ondraw,
+ tips/never/.code=\let\pgf@tips@mode\pgf@tips@mode@false,
+ tips/false/.code=\let\pgf@tips@mode\pgf@tips@mode@false,
+}
+\def\pgf@tips@mode@onproper{4}
+\def\pgf@tips@mode@onproperdraw{3}
+\def\pgf@tips@mode@true{2}
+\def\pgf@tips@mode@ondraw{1}
+\def\pgf@tips@mode@false{0}
+\let\pgf@tips@mode\pgf@tips@mode@ondraw
+
+
+% The following can only be set to "true" using the options in the
+% module "bending"
+\newif\ifpgf@precise@shortening
+\def\pgf@arrow@mode@is@quick{0}
+\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@quick
+
+\newif\ifpgf@up@path@needed
+\newif\ifpgf@up@draw@arrows
+\def\pgf@up@stroke@text{stroke}
+\def\pgf@up@fill@text{fill}
+\def\pgf@up@clip@text{clip}
+\def\pgf@do@up@bb{\pgf@relevantforpicturesizefalse}
+
+\def\pgfusepath#1{%
+ \pgf@up@path@neededfalse%
+ \pgf@up@draw@arrowsfalse%
+ \let\pgf@up@stroke\pgfutil@empty%
+ \let\pgf@up@fill\pgfutil@empty%
+ \let\pgf@up@clip\pgfutil@empty%
+ \let\pgf@up@bb\pgfutil@empty%
+ \pgfset{#1}%
+ \expandafter\def\expandafter\pgf@up@action\expandafter{\csname pgfsys@\pgf@up@fill\pgf@up@stroke\endcsname}%
+ \ifnum\pgf@tips@mode=2\relax%
+ \pgf@up@path@neededtrue%
+ \fi%
+ \ifnum\pgf@tips@mode=4\relax%
+ \pgf@up@path@neededtrue%
+ \fi%
+ \ifpgf@up@path@needed%
+ \else%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ \fi%
+ \ifx\pgf@up@stroke\pgfutil@empty%
+ \ifx\pgf@up@fill\pgfutil@empty%
+ \let\pgf@up@action=\pgfutil@empty%
+ \ifx\pgf@up@clip\pgfutil@empty%
+ \else%
+ % only clipping
+ \let\pgf@up@action=\pgfsys@discardpath%
+ \fi%
+ \fi%
+ \fi%
+ \pgfsyssoftpath@getcurrentpath\pgf@last@processed@path
+ \pgfprocessround{\pgf@last@processed@path}{\pgf@last@processed@path}% change the path
+ \pgfsyssoftpath@setcurrentpath\pgf@last@processed@path%
+ %
+ % Check whether the path is stroked. If so, add half the line width
+ % to the bounding box.
+ %
+ \ifpgf@relevantforpicturesize%
+ \ifx\pgf@up@stroke\pgfutil@empty%
+ \else%
+ \ifdim\pgf@picmaxx=-16000pt\relax%
+ \else%
+ \pgf@x=\pgf@pathminx\advance\pgf@x by-.5\pgflinewidth%
+ \ifdim\pgf@x<\pgf@picminx\global\pgf@picminx\pgf@x\fi%
+ \pgf@y=\pgf@pathminy\advance\pgf@y by-.5\pgflinewidth%
+ \ifdim\pgf@y<\pgf@picminy\global\pgf@picminy\pgf@y\fi%
+ \pgf@x=\pgf@pathmaxx\advance\pgf@x by.5\pgflinewidth%
+ \ifdim\pgf@x>\pgf@picmaxx\global\pgf@picmaxx\pgf@x\fi%
+ \pgf@y=\pgf@pathmaxy\advance\pgf@y by.5\pgflinewidth%
+ \ifdim\pgf@y>\pgf@picmaxy\global\pgf@picmaxy\pgf@y\fi%
+ \fi%
+ \fi%
+ \fi%
+ %
+ \ifx\pgf@up@clip\pgfutil@empty%
+ \ifx\pgf@up@stroke\pgfutil@empty%
+ \ifx\pgf@up@action\pgfutil@empty%
+ \ifnum\pgf@tips@mode=2\relax%
+ \pgf@up@draw@arrows@only%
+ \fi%
+ \ifnum\pgf@tips@mode=4\relax%
+ \pgf@up@draw@arrows@only%
+ \fi%
+ \else%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgf@up@action%
+ \fi%
+ \else%
+ \pgfgetpath\pgf@arrowpath%
+ \pgf@path@setup@tempswa%
+ \pgfprocesscheckclosed{\pgf@arrowpath}{\pgfutil@tempswafalse}%
+ \pgf@path@check@proper%
+ \ifpgfutil@tempswa%
+ \pgf@check@for@arrow@and@animation%
+ \pgf@prepare@end@of@path%
+ \begingroup%
+ \pgf@prepare@start@of@path%
+ \fi%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgf@up@action%
+ \ifdim\pgfinnerlinewidth>0pt\relax%
+ \pgf@stroke@inner@line%
+ \fi%
+ \ifpgfutil@tempswa%
+ \pgf@add@arrow@at@start%
+ \endgroup%
+ \pgf@add@arrow@at@end%
+ \fi%
+ \fi%
+ \else%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfsys@clipnext%
+ \pgf@up@action%
+ \pgf@relevantforpicturesizefalse%
+ \fi%
+ \pgf@up@bb%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ \pgf@resetpathsizes%
+ \ignorespaces%
+}
+\def\pgf@path@setup@tempswa{%
+ \ifnum\pgf@tips@mode>0\relax
+ \pgfutil@tempswatrue%
+ \else
+ \pgfutil@tempswafalse%
+ \fi%
+}
+\def\pgf@up@draw@arrows@only{%
+ \pgfgetpath\pgf@arrowpath%
+ \pgfutil@tempswatrue%
+ \pgfprocesscheckclosed{\pgf@arrowpath}{\pgfutil@tempswafalse}%
+ \pgf@path@check@proper%
+ \ifpgfutil@tempswa%
+ \pgf@check@for@arrow@and@animation%
+ \pgf@prepare@end@of@path%
+ \begingroup%
+ \pgf@prepare@start@of@path%
+ \pgf@add@arrow@at@start%
+ \endgroup%
+ \pgf@add@arrow@at@end%
+ \fi%
+}
+
+\def\pgf@check@for@arrow@and@animation{\pgfsys@if@fresh@currentid{\pgf@check@for@arrow@and@animation@}{}}%
+\def\pgf@check@for@arrow@and@animation@{%
+ \expandafter\ifx\csname pgfsysanim@path@is@animated@\pgf@sys@id@current@id @\pgfsys@current@type\endcsname\pgfutil@empty%
+ % Ok, an animation is here!
+ \ifx\pgf@end@tip@sequence\pgfutil@empty%
+ \ifx\pgf@start@tip@sequence\pgfutil@empty%
+ \else%
+ \pgf@check@for@arrow@and@animation@error%
+ \fi%
+ \else%
+ \pgf@check@for@arrow@and@animation@error%
+ \fi%
+ \fi%
+}
+\def\pgf@check@for@arrow@and@animation@error{\pgferror{Animated path may not have normal arrow tips. Use a base path with arrow tips}}
+
+\def\pgf@path@check@proper{%
+ \ifpgfutil@tempswa%
+ \ifnum\pgf@tips@mode>2\relax%
+ \pgf@path@check@proper@%
+ \fi%
+ \fi%
+}
+
+\def\pgf@path@check@proper@{%
+ {%
+ \pgf@x0pt\pgf@y\pgf@x%
+ \pgfutil@tempswatrue%
+ \let\pgfsyssoftpath@movetotoken\pgf@path@proper@init%
+ \let\pgfsyssoftpath@linetotoken\pgf@path@proper@test%%
+ \let\pgfsyssoftpath@curvetosupportatoken\pgf@path@proper@test%
+ \let\pgfsyssoftpath@curvetosupportbtoken=\pgf@path@proper@test%
+ \let\pgfsyssoftpath@curvetotoken\pgf@path@proper@test%
+ \let\pgfsyssoftpath@rectcornertoken\pgf@path@proper@test%
+ \let\pgfsyssoftpath@rectsizetoken\pgf@path@proper@zero@test%
+ \let\pgfsyssoftpath@closepathtoken\pgf@path@proper@test%
+ % Execute the path:
+ \pgf@arrowpath%
+ \expandafter
+ }%
+ \ifpgfutil@tempswa\pgfutil@tempswafalse\else\pgfutil@tempswatrue\fi%
+}
+
+\def\pgf@path@proper@init#1#2{\pgfutil@tempswatrue\pgf@x#1\pgf@y#2}%
+\def\pgf@path@proper@test#1#2{%
+ \ifdim\pgf@x=#1\relax\else\pgfutil@tempswafalse\fi%
+ \ifdim\pgf@y=#2\relax\else\pgfutil@tempswafalse\fi}
+\def\pgf@path@proper@zero@test#1#2{%
+ \ifdim\pgf@x=0pt\relax\else\pgfutil@tempswafalse\fi%
+ \ifdim\pgf@y=0pt\relax\else\pgfutil@tempswafalse\fi}
+
+
+
+
+\def\pgf@stroke@inner@line{%
+ \let\pgf@temp@save=\pgf@strokecolor@global
+ \pgfsys@beginscope%
+ {%
+ \pgfsys@setlinewidth{\pgfinnerlinewidth}%
+ \pgfsetstrokecolor{\pgfinnerstrokecolor}%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfsys@stroke%
+ }%
+ \pgfsys@endscope%
+ \global\let\pgf@strokecolor@global=\pgf@temp@save
+}
+
+\let\pgf@prepare@start@of@path\relax%
+
+
+
+
+% Shorten start/end of paths by a certain amount.
+%
+% #1 = amount by which paths should be shortened.
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathlineto{\pgfpoint{10pt}{0pt}
+%
+% % The following has the same effect:
+% \pgfsetshortenstart{1pt}
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathlineto{\pgfpoint{11pt}{0pt}
+
+\def\pgfsetshortenstart#1{\pgfmathsetlength\pgf@shorten@start@additional{#1}}
+\def\pgfsetshortenend#1{\pgfmathsetlength\pgf@shorten@end@additional{#1}}
+
+\newdimen\pgf@shorten@end@additional
+\newdimen\pgf@shorten@start@additional
+
+
+
+%
+%
+% Handling the end of a path
+%
+%
+% The "handling" consists of first testing whether we need to do
+% anything at all, namely because either an arrow tip should be drawn
+% at the end or because the path should be shortened at the end. If
+% so, we shorten the path if needed and, later on, add the arrow tip.
+%
+
+\newif\ifpgf@worry
+
+
+% Prepare the end of the path: Test whether anything must be done
+% (step 0) and, if so, split the path (step 1), extract the interesting points from
+% the path (step 2), prepare further computations (step 3), shorten
+% the path (step 4) if necessary, and add the arrow tip (step 4 in
+% macro \pgf@add@arrow@at@end, which is called later).
+
+\def\pgf@prepare@end@of@path{%
+ \let\pgfprocessresultpathsuffix\relax% flag that nothing has happened...
+ \let\pgfprocessresultsubpathsuffix\relax%
+ \pgfsyssoftpath@getcurrentpath\pgf@arrowpath%
+ %
+ % Step 0 start:
+ %
+ % Do we need to worry about the end?
+ %
+ \ifx\pgf@arrowpath\pgfutil@empty\else%
+ \pgf@worryfalse%
+ \ifx\pgf@end@tip@sequence\pgfutil@empty%
+ \else%
+ \pgf@worrytrue% Yes, worry if we have to draw an arrow
+ \fi%
+ \pgf@precise@shorteningfalse%
+ \pgf@arrow@compute@shortening\pgf@end@tip@sequence%
+ \advance\pgf@xa by\pgf@shorten@end@additional%
+ \advance\pgf@xb by\pgf@shorten@end@additional%
+ \ifdim\pgf@xa=0pt\relax\else\pgf@worrytrue\fi% Also, worry if shortening is requested
+ \edef\pgf@path@shortening@distance{\the\pgf@xa}%
+ \edef\pgf@arrow@tip@total@length{\the\pgf@xb}%
+ %
+ % Step 0 done.
+ %
+ \ifpgf@worry%
+ % Ok, need to "worry" about the end, either because we need to
+ % shorten it or to draw an arrow head.
+ %
+ % Step 1: Split
+ %
+ \pgfprocesssplitpath{\pgf@arrowpath}%
+ \pgfprocesssplitsubpath{\pgfprocessresultpathsuffix}%
+ %
+ % Step 2: extract
+ %
+ \expandafter\pgf@parse@end\pgfprocessresultsubpathsuffix\pgf@stop\pgf@stop\pgf@stop%
+ %
+ % Step 3: prep
+ %
+ \pgf@prep@end%
+ %
+ % Step 4: shorten
+ %
+ \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@end\fi%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@arrowpath%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix}%
+ \pgfsyssoftpath@setcurrentpath\pgf@arrowpath%
+ \fi%
+ \fi%
+}
+
+\def\pgf@parse@end#1#2#3#4#5#6{%
+ \ifx#4\pgf@stop% Only a moveto! -> do nothing!
+ \def\pgfpointlastonpath{\pgfqpoint{#2}{#3}}%
+ \let\pgf@next\relax%
+ \let\pgf@do@shorten@end\relax%
+ \let\pgf@do@draw@end\pgf@do@draw@straightend%
+ \let\pgf@prep@end\pgf@prep@movetoend%
+ \else\ifx#4\pgfsyssoftpath@curvetosupportatoken% A curve -> this will get complicated...
+ \def\pgfsubpathfourthlasttoken{#1}%
+ \def\pgfpointfourthlastonpath{\pgfqpoint{#2}{#3}}%
+ \def\pgfpointthirdlastonpath{\pgfqpoint{#5}{#6}}%
+ \ifpgf@precise@shortening%
+ \let\pgf@do@shorten@end\pgf@do@shorten@curvedend%
+ \let\pgf@do@draw@end\pgf@do@draw@curvedend%
+ \let\pgf@prep@end\pgf@prep@curveend%
+ \else%
+ \def\pgfsubpathstart{\noexpand#1{#2}{#3}\noexpand#4{#5}{#6}}%
+ \let\pgf@do@shorten@end\pgf@do@shorten@straightend%
+ \let\pgf@do@draw@end\pgf@do@draw@straightend%
+ \let\pgf@prep@end\pgf@prep@straightend%
+ \fi%
+ \let\pgf@next\pgf@parse@end@curve@cont%
+ \else% A straight line -> great!
+ \def\pgfsubpathstart{\noexpand#1{#2}{#3}\noexpand#4}%
+ \def\pgfpointsecondlastonpath{\pgfqpoint{#2}{#3}}%
+ \def\pgfpointlastonpath{\pgfqpoint{#5}{#6}}%
+ \let\pgfpointfourthlastonpath\relax%
+ \let\pgfpointthirdlastonpath\relax%
+ \let\pgf@next\pgf@parse@end@gobble@three%
+ \let\pgf@do@shorten@end\pgf@do@shorten@straightend%
+ \let\pgf@do@draw@end\pgf@do@draw@straightend%
+ \let\pgf@prep@end\pgf@prep@straightend%
+ \fi\fi%
+ \pgf@next% Needed for reading rest of path...
+}
+
+\def\pgf@parse@end@gobble@three#1#2#3{}%
+\def\pgf@parse@end@curve@cont#1#2#3#4#5#6#7#8#9{%
+ \def\pgfpointsecondlastonpath{\pgfqpoint{#2}{#3}}%
+ \def\pgfpointlastonpath{\pgfqpoint{#5}{#6}}%
+ \ifpgf@precise@shortening%
+ \else%
+ \expandafter\def\expandafter\pgfsubpathstart\expandafter{\pgfsubpathstart\noexpand#1{#2}{#3}\noexpand#4}%
+ \fi%
+}
+
+%
+% Preps
+%
+\def\pgf@prep@movetoend{%
+ \pgf@process{\pgfpointlastonpath}%
+ \pgf@xb\pgf@x
+ \pgf@yb\pgf@y
+ \pgf@xc\pgf@x
+ \pgf@yc\pgf@y
+}
+\def\pgf@prep@straightend{%
+ \let\pgf@ref\pgfpointsecondlastonpath
+ \ifx\pgfpointlastonpath\pgfpointsecondlastonpath% degenerate!
+ \ifx\pgfpointthirdlastonpath\relax% cannot help it: really a zero-length path
+ \else%
+ \ifx\pgfpointlastonpath\pgfpointthirdlastonpath% double degenerate!
+ \let\pgf@ref\pgfpointfourthlastonpath% Use third point for reference.
+ \else
+ \let\pgf@ref\pgfpointthirdlastonpath% Use third point for reference.
+ \fi%
+ \fi%
+ \fi%
+ \pgfpointlineatdistance{\pgf@path@shortening@distance}{\pgfpointlastonpath}{\pgf@ref}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+}
+
+
+%
+% Line shortening for straight lines:
+%
+\def\pgf@do@shorten@straightend{%
+ \edef\pgfprocessresultsubpathsuffix{\pgfsubpathstart{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}%
+}
+
+
+%
+% Draw an end arrow by calling an appropriate subfunction, if necessary
+%
+
+\def\pgf@add@arrow@at@end{%
+ \ifx\pgf@arrowpath\pgfutil@empty\else%
+ \ifx\pgf@end@tip@sequence\pgfutil@empty\else%
+ \pgf@do@draw@end%
+ \fi%
+ \fi%
+}
+
+%
+% Draw an end arrow at the end of a straight line
+%
+\def\pgf@do@draw@straightend{%
+ {%
+ \pgftransformreset%
+ \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgf@arrow@draw@arrow\pgf@end@tip@sequence\pgf@arrow@tip@total@length%
+ }%
+}
+
+
+
+
+
+%
+%
+% Handling the start of a path
+%
+%
+% The "handling" is similar to the case for the start of the path. We
+% may be able to skip the splitting if that was done already for the
+% end. Otherwise, things are basically the same.
+%
+
+% Prepare the start of the path: Test whether anything must be done
+% (step 0) and, if so, split the path (step 1) if necessary, extract
+% the interesting points from the path (step 2), prepare computations
+% (step 3) needed for both shortening and tip adding, shorten the path
+% (step 4), and add the arrow tip (step 5 in macro
+% \pgf@add@arrow@at@start, which is called later).
+
+\def\pgf@prepare@start@of@path{%
+ %
+ % Step 0 start:
+ %
+ % Do we need to worry about the start?
+ %
+ \ifx\pgf@arrowpath\pgfutil@empty\else%
+ \pgf@worryfalse%
+ \ifx\pgf@start@tip@sequence\pgfutil@empty\else\pgf@worrytrue\fi% Yes, worry if we have to draw an arrow
+ \pgf@precise@shorteningfalse%
+ \pgf@arrow@compute@shortening\pgf@start@tip@sequence%
+ \advance\pgf@xa by\pgf@shorten@start@additional%
+ \advance\pgf@xb by\pgf@shorten@start@additional%
+ \ifdim\pgf@xa=0pt\relax\else\pgf@worrytrue\fi% Also, worry if shortening is requested
+ \edef\pgf@path@shortening@distance{\the\pgf@xa}%
+ \edef\pgf@arrow@tip@total@length{\the\pgf@xb}%
+ %
+ % Step 0 done.
+ %
+ \ifpgf@worry%
+ % Ok, need to "worry" about the start, either because we need to
+ % shorten it or to draw an arrow head.
+ %
+ % Step 1: Split
+ %
+ \ifx\pgfprocessresultpathsuffix\relax%
+ % Ok, still need to compute the split:
+ \pgfprocesssplitpath{\pgf@arrowpath}%
+ \fi%
+ %
+ % Step 2: extract
+ %
+ \expandafter\pgf@parse@start\pgfprocessresultpathsuffix\pgf@stop\pgf@stop\pgf@stop%
+ %
+ % Step 3: prep
+ %
+ \pgf@prep@start%
+ %
+ % Step 4: shorten
+ %
+ \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@start\fi%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@arrowpath%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix}%
+ \pgfsyssoftpath@setcurrentpath\pgf@arrowpath%
+ \fi%
+ \fi%
+}
+
+\def\pgf@parse@start#1#2#3#4#5#6{%
+ \def\pgfpointfirstonpath{\pgfqpoint{#2}{#3}}%
+ \def\pgfpointsecondonpath{\pgfqpoint{#5}{#6}}%
+ \let\pgfpointthirdonpath\relax%
+ \let\pgfpointfourthonpath\relax%
+ \def\pgfsubpathfirsttoken{\noexpand#1}%
+ \def\pgfsubpathsecondtoken{\noexpand#4}%
+ \ifx#4\pgf@stop% Only a moveto! -> do nothing!
+ \let\pgf@next\relax%
+ \let\pgf@do@shorten@start\relax%
+ \let\pgf@prep@start\pgf@prep@movetostart%
+ \let\pgf@do@draw@start\pgf@do@draw@straightstart%
+ \else\ifx#4\pgfsyssoftpath@curvetosupportatoken% A curve -> this will get complicated...
+ \ifpgf@precise@shortening%
+ \let\pgf@next\pgf@parse@start@curve@cont%
+ \let\pgf@do@shorten@start\pgf@do@shorten@curvedstart%
+ \let\pgf@do@draw@start\pgf@do@draw@curvedstart%
+ \let\pgf@prep@start\pgf@prep@curvedstart%
+ \else% can treat the end like a straight line...
+ \let\pgf@next\pgf@parse@start@curve@cont@straight%
+ \let\pgf@do@shorten@start\pgf@do@shorten@straightstart%
+ \let\pgf@do@draw@start\pgf@do@draw@straightstart%
+ \let\pgf@prep@start\pgf@prep@straightstart%
+ \fi%
+ \else% A straight line -> great!
+ \let\pgf@next\pgf@parse@start@till@stop%
+ \let\pgf@do@shorten@start\pgf@do@shorten@straightstart%
+ \let\pgf@do@draw@start\pgf@do@draw@straightstart%
+ \let\pgf@prep@start\pgf@prep@straightstart%
+ \fi\fi%
+ \pgf@next% Needed for reading rest of path...
+}
+
+\def\pgf@parse@start@till@stop#1\pgf@stop\pgf@stop\pgf@stop{\def\pgfsubpathend{#1}}%
+
+\def\pgf@parse@start@curve@cont#1#2#3#4#5#6#7\pgf@stop\pgf@stop\pgf@stop{%
+ \def\pgfpointthirdonpath{\pgfqpoint{#2}{#3}}%
+ \def\pgfpointfourthonpath{\pgfqpoint{#5}{#6}}%
+ \def\pgfsubpathend{#7}%
+}
+
+\def\pgf@parse@start@curve@cont@straight#1#2#3#4#5#6#7\pgf@stop\pgf@stop\pgf@stop{%
+ \def\pgfpointthirdonpath{\pgfqpoint{#2}{#3}}%
+ \def\pgfpointfourthonpath{\pgfqpoint{#5}{#6}}%
+ \def\pgfsubpathend{#1{#2}{#3}#4{#5}{#6}#7}%
+}
+
+%
+% Preps
+%
+\def\pgf@prep@movetostart{%
+ \pgf@process{\pgfpointfirstonpath}%
+ \pgf@xb\pgf@x
+ \pgf@yb\pgf@y
+ \pgf@xc\pgf@x
+ \pgf@yc\pgf@y
+}
+\def\pgf@prep@straightstart{%
+ \let\pgf@ref\pgfpointsecondonpath
+ \ifx\pgfpointfirstonpath\pgfpointsecondonpath% degenerate!
+ \ifx\pgfpointthirdonpath\relax% cannot help it: really a zero-length path
+ \else%
+ \ifx\pgfpointfirstonpath\pgfpointthirdonpath% double degenerate!
+ \let\pgf@ref\pgfpointfourthonpath% Use third point for reference.
+ \else
+ \let\pgf@ref\pgfpointthirdonpath% Use third point for reference.
+ \fi%
+ \fi%
+ \fi%
+ \pgfpointlineatdistance{\pgf@path@shortening@distance}{\pgfpointfirstonpath}{\pgf@ref}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+}
+
+%
+% Line shortening for straight lines:
+%
+\def\pgf@do@shorten@straightstart{%
+ \edef\pgfprocessresultpathsuffix{\pgfsubpathfirsttoken{\the\pgf@xa}{\the\pgf@ya}\pgfsubpathsecondtoken{\the\pgf@xc}{\the\pgf@yc}}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathsuffix\pgfsubpathend}%
+}
+
+
+%
+% Draw a start arrow by calling an appropriate subfunction, if necessary
+%
+
+\def\pgf@add@arrow@at@start{%
+ \ifx\pgf@arrowpath\pgfutil@empty\else%
+ \ifx\pgf@start@tip@sequence\pgfutil@empty\else%
+ \pgf@do@draw@start%
+ \fi%
+ \fi%
+}
+
+%
+% Draw an start arrow at the start of a straight line
+%
+\def\pgf@do@draw@straightstart{%
+ {%
+ \pgftransformreset%
+ \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgf@arrow@draw@arrow\pgf@start@tip@sequence\pgf@arrow@tip@total@length%
+ }%
+}
+
+
+
+\let\pgf@shorten@end=\pgfutil@empty
+\let\pgf@shorten@start=\pgfutil@empty
+
+
+\endinput%
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorepatterns.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepatterns.code.tex
new file mode 100644
index 0000000000..c2e438dfc4
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepatterns.code.tex
@@ -0,0 +1,301 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorepatterns.code.tex}
+
+% Creates a new uncolored pattern
+%
+% [#1] = optional list of variables.
+% #2 = pattern name
+% #3 = lower left of bounding box
+% #4 = upper right of bounding box
+% #5 = step vector
+% #6 = pattern code
+%
+% Description:
+%
+% Declares a new uncolored pattern. An uncolored pattern is a pattern
+% that has no inherent color. When the pattern is used, a color for
+% the pattern must be supplied.
+%
+% See the pdf-manual for more details on uncolored patterns.
+%
+% Specifying a variable list makes the pattern ``mutable''.
+%
+% The bounding box must be a bounding box of the pattern cell.
+%
+% The step vector must provide the x- and y-step by which the cells
+% are spaced.
+%
+% The pattern code should be pgf code that can be protocolled.
+%
+% The transformation matrix will be reset prior to invoking the
+% pattern code.
+%
+% Example:
+%
+% \pgfdeclarepatternformonly{stars}{\pgfpointorigin}{\pgfpoint{1cm}{1cm}}
+% {\pgfpoint{1cm}{1cm}}{
+% \pgftransformshift{\pgfpoint{.5cm}{.5cm}}
+% \pgfpathmoveto{\pgfpointpolar{0}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{144}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{288}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{72}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{216}{4mm}}
+% \pgfpathclose%
+% \pgfusepath{stroke}
+% }
+%
+\def\pgfdeclarepatternformonly{%
+ \def\pgf@pattern@type{formonly}%
+ \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}%
+}
+
+
+% Creates a new colored pattern
+%
+% [#1] = optional list of variables.
+% #2 = pattern name
+% #3 = lower left of bounding box
+% #4 = upper right of bounding box
+% #5 = step vector
+% #6 = pattern code
+%
+% Description:
+%
+% Declares a new colored pattern. Such patterns have a one or more
+% fixed inherent colors. See the pdf-manual for more details on
+% uncolored patterns.
+%
+% The parameters have the same effect as for uncolored patterns.
+%
+% Example:
+%
+% \pgfdeclarepatterninherentlycolored{red stars}{\pgfpointorigin}{\pgfpoint{1cm}{1cm}}
+% {\pgfpoint{1cm}{1cm}}{
+% \pgfsetfillcolor{red}
+% \pgfsetstrokecolor{black}
+% \pgftransformshift{\pgfpoint{.5cm}{.5cm}}
+% \pgfpathmoveto{\pgfpointpolar{0}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{144}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{288}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{72}{4mm}}
+% \pgfpathlineto{\pgfpointpolar{216}{4mm}}
+% \pgfpathclose%
+% \pgfusepath{stroke,fill}
+% }
+%
+\def\pgfdeclarepatterninherentlycolored{%
+ \def\pgf@pattern@type{inherentlycolored}%
+ \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}%
+}
+
+
+
+
+
+\def\pgf@declarepattern@checkarg[#1]{%
+ \def\pgf@pattern@tempvars{#1}%
+ \ifx\pgf@pattern@tempvars\pgfutil@empty%
+ \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type\endcsname%
+ \else%
+ \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type @mutable\endcsname%
+ \fi%
+ \pgf@next}
+
+\long\def\pgf@declarepatternformonly#1#2#3#4#5{\pgf@declarepattern{#1}{#2}{#3}{#4}{#5}{0}}
+
+\long\def\pgf@declarepatterninherentlycolored#1#2#3#4#5{\pgf@declarepattern{#1}{#2}{#3}{#4}{#5}{1}}
+
+\long\def\pgf@declarepatternformonly@mutable#1#2#3#4#5{%
+ \def\pgf@marshal{\pgf@declarepatternmutable{#1}}%
+ \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{2}%
+}
+
+\long\def\pgf@declarepatterninherentlycolored@mutable#1#2#3#4#5#6{%
+ \def\pgf@marshal{\pgf@declarepatternmutable{#1}}%
+ \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{3}%
+}
+
+\def\pgfsys@patternmatrix{{1.0}{0.0}{0.0}{1.0}{0.0pt}{0.0pt}}
+\def\pgf@declarepattern#1#2#3#4#5#6{%
+ \pgfutil@ifundefined{pgf@pattern@name@#1}{%
+ \pgfsysprotocol@getcurrentprotocol\pgf@pattern@temp%
+ {%
+ \pgfinterruptpath%
+ \pgfpicturetrue%
+ \pgf@relevantforpicturesizefalse%
+ \pgftransformreset%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsys@beginscope%
+ \pgfsetarrows{-}%
+ #5%
+ \pgfsys@endscope%
+ \pgfsysprotocol@getcurrentprotocol\pgf@pattern@code%
+ \global\let\pgf@pattern@code=\pgf@pattern@code%
+ \endpgfinterruptpath%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{#4}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ % Now, build a name for the pattern
+ \pgfutil@tempcnta=\pgf@pattern@number%
+ \advance\pgfutil@tempcnta by1\relax%
+ \xdef\pgf@pattern@number{\the\pgfutil@tempcnta}%
+ \expandafter\xdef\csname pgf@pattern@name@#1\endcsname{\the\pgfutil@tempcnta}%
+ \expandafter\gdef\csname pgf@pattern@type@#1\endcsname{#6}%
+ \xdef\pgf@marshal{\noexpand\pgfsys@declarepattern
+ {\csname pgf@pattern@name@#1\endcsname}% name
+ {\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}% bbox
+ {\the\pgf@xc}{\the\pgf@yc}% x/y step
+ \pgfsys@patternmatrix% transformation matrix
+ {\pgf@pattern@code}{#6}}%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgf@pattern@temp%
+ \expandafter\global\expandafter\let\csname pgf@pattern@instantiate@#1\endcsname=\pgf@marshal%
+ }
+ {%
+ \pgferror{Pattern `#1' already defined}%
+ }%
+}
+
+\def\pgf@pattern@number{0}%
+
+\def\pgf@declarepatternmutable#1#2#3#4#5#6#7{%
+ \pgfutil@ifundefined{pgf@pattern@name@#1}{%
+ \expandafter\gdef\csname pgf@pattern@name@#1\endcsname{#1}%
+ \expandafter\gdef\csname pgf@pattern@variables@#1\endcsname{#2}%
+ \expandafter\gdef\csname pgf@pattern@lowerleft@#1\endcsname{#3}%
+ \expandafter\gdef\csname pgf@pattern@upperright@#1\endcsname{#4}%
+ \expandafter\gdef\csname pgf@pattern@tilesize@#1\endcsname{#5}%
+ \expandafter\long\expandafter\gdef\csname pgf@pattern@code@#1\endcsname{#6}%
+ \expandafter\gdef\csname pgf@pattern@type@#1\endcsname{#7}%
+ }{\pgferror{The pattern `#1' is already defined}}%
+}
+
+\def\pgf@ifpatternisinherentlycolored#1#2#3{%
+ \expandafter\ifodd\csname pgf@pattern@type@#1\endcsname\relax#2\else#3\fi%
+}
+
+\def\pgf@ifpatternismutable#1#2#3{%
+ \expandafter\ifnum\csname pgf@pattern@type@#1\endcsname>1\relax#2\else#3\fi%
+}
+
+\def\pgfpatternreleasename#1{\expandafter\let\csname pgf@pattern@name@#1\endcsname\relax}
+
+
+
+
+
+
+% Set an pattern as fill color
+%
+% #1 = Name of the pattern
+% #2 = Color to be used for the pattern. If the pattern is already
+% colored, this parameter is ignored.
+%
+% Description:
+%
+% Sets the pattern for subsequent filling operations.
+%
+% Example:
+%
+% \pgfsetfillpattern{stars}{red}
+%
+\def\pgfsetfillpattern#1#2{%
+ \pgfutil@ifundefined{pgf@pattern@name@#1}%
+ {%
+ \pgferror{Undefined pattern `#1'}%
+ }%
+ {%
+ \pgf@ifpatternismutable{#1}%
+ {%
+ % So, a mutable pattern. Check to see if the pattern
+ % has been used with the current variable values...
+ \let\pgf@pattern@tempvars\pgfutil@empty%
+ \expandafter\expandafter\expandafter\pgf@pattern@check@vars%
+ \csname pgf@pattern@variables@#1\endcsname,\pgf@stop,%
+ \edef\pgf@pattern@nametemp{pgf@pattern@#1@\pgf@pattern@tempvars}%
+ \expandafter\pgfutil@ifundefined\expandafter{\pgf@pattern@nametemp}%
+ {%
+ % ...Nope. So declare a new instance of the mutable pattern.
+ \pgf@ifpatternisinherentlycolored{#1}%
+ {\let\pgf@set@fillpattern@declare\pgfdeclarepatterninherentlycolored}%
+ {\let\pgf@set@fillpattern@declare\pgfdeclarepatternformonly}%
+ \pgf@set@fillpattern@declare%
+ {\pgf@pattern@nametemp}%
+ {\csname pgf@pattern@lowerleft@#1\endcsname}%
+ {\csname pgf@pattern@upperright@#1\endcsname}%
+ {\csname pgf@pattern@tilesize@#1\endcsname}%
+ {\csname pgf@pattern@code@#1\endcsname}%
+ }%
+ {%
+ % ...Yep. So do nothing.
+ }%
+ \expandafter\pgf@set@fillpattern\expandafter{\pgf@pattern@nametemp}{#2}%
+ \expandafter\gdef\csname\pgf@pattern@nametemp\endcsname{#1}%
+ }%
+ {%
+ % A non-mutable pattern.
+ \pgf@set@fillpattern{#1}{#2}%
+ }%
+ }%
+}
+
+
+\def\pgf@set@fillpattern#1#2{%
+ \pgfutil@ifundefined{pgf@pattern@name@#1}{%
+ \pgferror{Undefined pattern `#1'}}
+ {%
+ \csname pgf@pattern@instantiate@#1\endcsname%
+ \expandafter\global\expandafter\let\csname pgf@pattern@instantiate@#1\endcsname=\relax%
+ \pgf@ifpatternisinherentlycolored{#1}{%
+ \pgfsys@setpatterncolored{\csname pgf@pattern@name@#1\endcsname}%
+ }{%
+ \pgfutil@colorlet{pgf@tempcolor}{#2}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}%
+ \pgfutil@extractcolorspec{pgf@tempcolor}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
+ \expandafter\pgf@set@fill@patternuncolored\pgf@rgbcolor\relax{#1}%
+ }%
+ }%
+}
+
+\def\pgf@set@fill@patternuncolored#1,#2,#3\relax#4{%
+ \pgfsys@setpatternuncolored{\csname pgf@pattern@name@#4\endcsname}{#1}{#2}{#3}%
+}
+
+\def\pgf@pattern@check@vars#1,{%
+ \ifx#1\pgf@stop%
+ \let\pgf@next\relax%
+ \else%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\let\expandafter\pgf@pattern@char#1#1\pgfmath@%
+ \ifx\pgf@pattern@char/%
+ \edef\pgf@pattern@tempvar{(\pgfkeysvalueof{#1})}%
+ \else%
+ \expandafter\ifcat\pgf@pattern@char\relax%
+ \edef\pgf@pattern@tempvar{(\the#1)}%
+ \else%
+ \edef\pgf@pattern@tempvar{(#1)}%
+ \fi%
+ \fi%
+ \edef\pgf@pattern@tempvars{\pgf@pattern@tempvars\pgf@pattern@tempvar}%
+ \let\pgf@next\pgf@pattern@check@vars%
+ \fi%
+ \pgf@next%
+}
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorepoints.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepoints.code.tex
new file mode 100644
index 0000000000..6c28f20b73
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorepoints.code.tex
@@ -0,0 +1,1212 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorepoints.code.tex}
+
+\newdimen\pgf@picminx
+\newdimen\pgf@picmaxx
+\newdimen\pgf@picminy
+\newdimen\pgf@picmaxy
+
+\newdimen\pgf@pathminx
+\newdimen\pgf@pathmaxx
+\newdimen\pgf@pathminy
+\newdimen\pgf@pathmaxy
+
+\newif\ifpgf@relevantforpicturesize
+
+\def\pgf@process#1{{#1\global\pgf@x=\pgf@x\global\pgf@y=\pgf@y}}
+
+% Save a point.
+%
+% #1 = macro for storing point.
+% #2 = code for point (should define x and y)
+%
+% Example:
+%
+% \pgfextract@process\mypoint{\pgf@x=10pt \pgf@y10pt}
+% \pgfextract@process\myarcpoint{\pgfpointpolar{30}{5cm and 2cm}}
+
+\def\pgfextract@process#1#2{%
+ \pgf@process{#2}%
+ \edef#1{\noexpand\global\pgf@x=\the\pgf@x\noexpand\relax\noexpand\global\pgf@y=\the\pgf@y\noexpand\relax}%
+}
+% This needed until old shapes code changed.
+\let\pgfsavepgf@process\pgfextract@process%
+
+
+% Return a point
+%
+% #1 = x-coordinate of the point
+% #2 = y-coordinate of the point
+%
+% x = #1
+% y = #2
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpoint{2pt+3cm}{3cm}}
+
+\def\pgfpoint#1#2{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgfmathsetlength\pgf@y{#2}\ignorespaces}
+
+
+% Quickly a point
+%
+% #1 = x-coordinate of the point (no calculations done)
+% #2 = y-coordinate of the point (no calculations done)
+%
+% x = #1
+% y = #2
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfqpoint{2pt}{3cm}}
+
+\def\pgfqpoint#1#2{\global\pgf@x=#1\relax\global\pgf@y=#2\relax}
+
+
+
+% Return the origin.
+%
+% x = 0
+% y = 0
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointorigin}
+
+\def\pgfpointorigin{\global\pgf@x=0pt \global\pgf@y=\pgf@x\ignorespaces}
+
+
+
+% Return a transformed point
+%
+% #1 = a point
+%
+% Description:
+%
+% This command applies pgf's current transformation matrix to the
+% given point. Normally, this is done automatically by commands like
+% lineto or moveto, but sometimes you may wish to access a transformed
+% point yourself. In the below example, this command is used for a low level
+% coordinate system shift.
+%
+% Example:
+%
+% \begin{pgflowleveltransformshiftscope}{\pgfpointtransformed{\pgfpointorigin}}
+% \pgfbox[center,center]{Hi!}
+% \end{pgflowleveltransformshiftscope}
+
+\def\pgfpointtransformed#1{%
+ \pgf@process{%
+ #1%
+ \pgf@pos@transform@glob%
+ }%
+}
+
+
+% Return the difference vector of two points.
+%
+% #1 = start of vector
+% #2 = end of vector
+%
+% x = x-component of difference
+% y = y-component of difference
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointdiff{\pgfpointxy{1}{1}}{\pgfpointxy{2}{3}}}
+
+\def\pgfpointdiff#1#2{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#2}%
+ \global\advance\pgf@x by-\pgf@xa\relax%
+ \global\advance\pgf@y by-\pgf@ya\relax\ignorespaces}
+
+% Add two vectors.
+%
+% #1 = first vector
+% #2 = second vector
+%
+% x = x-component of addition
+% y = y-component of addition
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointadd{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}}
+
+\def\pgfpointadd#1#2{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#2}%
+ \global\advance\pgf@x by\pgf@xa%
+ \global\advance\pgf@y by\pgf@ya}
+
+
+
+% Multiply a vector by a factor.
+%
+% #1 = factor
+% #2 = vector
+%
+% Example:
+%
+% \pgfpointscale{2}{\pgfpointxy{0}{1}}
+
+\def\pgfpointscale#1#2{%
+ \pgf@process{#2}%
+ \pgfmathparse{#1}%
+ \global\pgf@x=\pgfmathresult\pgf@x%
+ \global\pgf@y=\pgfmathresult\pgf@y%
+}
+% A "quick" variant of \pgfpointscale which doesn't invoke the math parser for '#1'.
+% #1 must be a number without units, no registers are accepted.
+\def\pgfqpointscale#1#2{%
+ \pgf@process{#2}%
+ \global\pgf@x=#1\pgf@x%
+ \global\pgf@y=#1\pgf@y%
+}
+
+
+% The intersection of two lines
+%
+% #1 = point on first line
+% #2 = another point on first line
+% #3 = point on second line
+% #4 = another point on second line
+%
+% Returns the intersection of the two lines. If there is no
+% intersection or if the points #1 and #2 or the points #3 and #4 are
+% identical, the behaviour is not specified.
+%
+% Example:
+%
+% \pgfpointintersectionoflines{\pgfpointxy{0}{1}}{\pgfpointxy{1}{0}}{\pgfpointxy{2}{2}}{\pgfpointxy{3}{4}}
+
+\def\pgfpointintersectionoflines#1#2#3#4{%
+ {%
+ %
+ % Compute orthogonal vector to #1--#2
+ %
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#1}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \pgf@ya=-\pgf@ya%
+ % Normalise a bit
+ \c@pgf@counta=\pgf@xa%
+ \ifnum\c@pgf@counta<0\relax%
+ \c@pgf@counta=-\c@pgf@counta\relax%
+ \fi%
+ \c@pgf@countb=\pgf@ya%
+ \ifnum\c@pgf@countb<0\relax%
+ \c@pgf@countb=-\c@pgf@countb\relax%
+ \fi%
+ \advance\c@pgf@counta by\c@pgf@countb\relax%
+ \divide\c@pgf@counta by 65536\relax%
+ \ifnum\c@pgf@counta>0\relax%
+ \divide\pgf@xa by\c@pgf@counta\relax%
+ \divide\pgf@ya by\c@pgf@counta\relax%
+ \fi%
+ %
+ % Compute projection
+ %
+ \pgf@xc=\pgf@sys@tonumber{\pgf@ya}\pgf@x%
+ \advance\pgf@xc by\pgf@sys@tonumber{\pgf@xa}\pgf@y%
+ %
+ % The orthogonal vector is (\pgf@ya,\pgf@xa)
+ %
+ %
+ % Compute orthogonal vector to #3--#4
+ %
+ \pgf@process{#4}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{#3}%
+ \advance\pgf@xb by-\pgf@x%
+ \advance\pgf@yb by-\pgf@y%
+ \pgf@yb=-\pgf@yb%
+ % Normalise a bit
+ \c@pgf@counta=\pgf@xb%
+ \ifnum\c@pgf@counta<0\relax%
+ \c@pgf@counta=-\c@pgf@counta\relax%
+ \fi%
+ \c@pgf@countb=\pgf@yb%
+ \ifnum\c@pgf@countb<0\relax%
+ \c@pgf@countb=-\c@pgf@countb\relax%
+ \fi%
+ \advance\c@pgf@counta by\c@pgf@countb\relax%
+ \divide\c@pgf@counta by 65536\relax%
+ \ifnum\c@pgf@counta>0\relax%
+ \divide\pgf@xb by\c@pgf@counta\relax%
+ \divide\pgf@yb by\c@pgf@counta\relax%
+ \fi%
+ %
+ % Compute projection
+ %
+ \pgf@yc=\pgf@sys@tonumber{\pgf@yb}\pgf@x%
+ \advance\pgf@yc by\pgf@sys@tonumber{\pgf@xb}\pgf@y%
+ %
+ % The orthogonal vector is (\pgf@yb,\pgf@xb)
+ %
+ % Setup transformation matrix (this is just to use the matrix
+ % inversion)
+ %
+ \pgfsettransform{{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{0pt}{0pt}}%
+ \pgftransforminvert%
+ \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xc}{\pgf@yc}}}%
+ }%
+}
+
+
+% The intersection of two circles
+%
+% #1 = center of first circle
+% #2 = center of second circle
+% #3 = radius of first circle
+% #4 = radius of second circle
+% #5 = solution number
+%
+% Returns the intersection of the two circles. If #5 is to "1", the
+% first intersection is returned, otherwise the second. If the circles
+% do not intersect, an error may occur.
+%
+% Example:
+%
+% \pgfpointintersectionofcircles{\pgfpointxy{0}{1}}{\pgfpointxy{1}{0}}{1cm}{1cm}{1}
+
+\def\pgfpointintersectionofcircles#1#2#3#4#5{%
+ {%
+ % Store first point in (xa,ya) and radius in xc.
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgfmathsetlength{\pgf@xc}{#3}%
+ % Store second point in (xb,yb) and radius in yc.
+ \pgf@process{#2}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgfmathsetlength{\pgf@yc}{#4}%
+ %
+ % Ok, now make numbers smaller, in case they are too large
+ %
+ \c@pgf@counta=1\relax%
+ \loop%
+ \pgf@scale@downfalse%
+ \ifdim\pgf@xc>50pt\relax%
+ \pgf@scale@downtrue%
+ \fi%
+ \ifdim\pgf@yc>50pt\relax%
+ \pgf@scale@downtrue%
+ \fi%
+ \ifpgf@scale@down%
+ \multiply\c@pgf@counta by2\relax%
+ \divide\pgf@xa by2\relax%
+ \divide\pgf@ya by2\relax%
+ \divide\pgf@xb by2\relax%
+ \divide\pgf@yb by2\relax%
+ \divide\pgf@xc by2\relax%
+ \divide\pgf@yc by2\relax%
+ \repeat%
+ % The following code is taken from the Dr. Math internet forum:
+ %
+ % Let the centers be: (a,b), (c,d)
+ % Let the radii be: r, s
+ %
+ % e = c - a [difference in x coordinates]
+ % f = d - b [difference in y coordinates]
+ % p = sqrt(e^2 + f^2) [distance between centers]
+ % k = (p^2 + r^2 - s^2)/(2p) [distance from center 1 to line
+ % joining points of intersection]
+ % x = a + ek/p + (f/p)sqrt(r^2 - k^2)
+ % y = b + fk/p - (e/p)sqrt(r^2 - k^2)
+ % OR
+ % x = a + ek/p - (f/p)sqrt(r^2 - k^2)
+ % y = b + fk/p + (e/p)sqrt(r^2 - k^2)
+ %
+ % Since we are running low on registers, use
+ % \dimen0 for e
+ % \dimen1 for f
+ % \dimen2 for p
+ % \dimen3 for p^2
+ % \dimen4 for k
+ % \dimen5 for 1/p
+ % \dimen6 for sqrt(r^2 - k^2)
+ % \dimen7 for k^2
+ % \dimen8 for k/p
+ % \dimen9 for sqrt(r^2 - k^2)/p
+ % Also note that:
+ % \pgf@xa for a
+ % \pgf@ya for b
+ % \pgf@xb for c
+ % \pgf@yb for d
+ % \pgf@xc for r
+ % \pgf@yc for s
+ %
+ % Now:
+ % e = c - a
+ \dimen0=\pgf@xb%
+ \advance\dimen0 by-\pgf@xa%
+ % f = d - b
+ \dimen1=\pgf@yb%
+ \advance\dimen1 by-\pgf@ya%
+ % p^2 = e^2 + f^2
+ \pgf@x=\dimen0\relax%
+ \pgf@x=\pgf@sys@tonumber{\pgf@x}\pgf@x%
+ \dimen3=\pgf@x%
+ \pgf@x=\dimen1\relax%
+ \advance\dimen3 by\pgf@sys@tonumber{\pgf@x}\pgf@x%
+ % p = sqrt(p^2)
+ \pgfmathparse{sqrt(\the\dimen3)}%
+ \dimen2=\pgfmathresult pt%
+ % 1/p = 1/p
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \dimen5=\pgfmathresult pt%
+ % k = (p^2 + r^2 - s^2)/(2p)
+ \dimen4=\dimen3\relax%
+ \pgf@x=\pgf@xc%
+ \advance\dimen4 by\pgf@sys@tonumber{\pgf@x}\pgf@x\relax%
+ \pgf@x=\pgf@yc%
+ \advance\dimen4 by-\pgf@sys@tonumber{\pgf@x}\pgf@x\relax%
+ \dimen4=.5\dimen4%
+ \dimen4=\pgf@sys@tonumber{\dimen5}\dimen4%
+ % dimen7 is k^2
+ \dimen7=\pgf@sys@tonumber{\dimen4}\dimen4\relax%
+ % dimen6 is sqrt(r^2 - k^2)
+ \pgfmathparse{sqrt(\pgf@sys@tonumber{\pgf@xc}\pgf@xc-\the\dimen7)}%
+ \dimen6=\pgfmathresult pt%
+ % dimen8 is k/p
+ \dimen8=\pgf@sys@tonumber{\dimen4}\dimen5\relax%
+ % dimen9 is sqrt(r^2 - k^2)/p
+ \dimen9=\pgf@sys@tonumber{\dimen6}\dimen5\relax%
+ \ifnum#5=1\relax%
+ % x = a + ek/p + (f/p)sqrt(r^2 - k^2)
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by\pgf@sys@tonumber{\dimen0}\dimen8\relax%
+ \advance\pgf@x by\pgf@sys@tonumber{\dimen1}\dimen9\relax%
+ % y = b + fk/p - (e/p)sqrt(r^2 - k^2)
+ \pgf@y=\pgf@ya%
+ \advance\pgf@y by\pgf@sys@tonumber{\dimen1}\dimen8\relax%
+ %temp
+ \pgf@xb=\pgf@sys@tonumber{\dimen0}\dimen9%
+ \pgf@xb=-\pgf@xb%
+ \advance\pgf@y by\pgf@xb\relax%
+ \else%
+ % x = a + ek/p - (f/p)sqrt(r^2 - k^2)
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by\pgf@sys@tonumber{\dimen0}\dimen8\relax%
+ %temp
+ \pgf@xb=\pgf@sys@tonumber{\dimen1}\dimen9%
+ \pgf@xb=-\pgf@xb%
+ \advance\pgf@x by\pgf@xb\relax%
+ % y = b + fk/p + (e/p)sqrt(r^2 - k^2)
+ \pgf@y=\pgf@ya%
+ \advance\pgf@y by\pgf@sys@tonumber{\dimen1}\dimen8\relax%
+ \advance\pgf@y by\pgf@sys@tonumber{\dimen0}\dimen9\relax%
+ \fi%
+ \pgf@x=\c@pgf@counta\pgf@x%
+ \pgf@y=\c@pgf@counta\pgf@y%
+ \pgf@process{}% get results outside
+ }%
+}
+\newif\ifpgf@scale@down
+
+
+% Returns point on a line from #2 to #3 at time #1.
+%
+% #1 = a time, where 0 is the start and 1 is the end
+% #2 = start point
+% #3 = end point
+%
+% x = x-component of #1*start + (1-#1)*end
+% y = y-component of #1*start + (1-#1)*end
+% xa/ya = #1*start + (1-#1)*end
+% xb/yb = start point
+% xc/yc = end point
+%
+% Example:
+%
+% % Middle of (1,1) and (2,3)
+% \pgfpathmoveto{\pgfpointlineattime{0.5}{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}}
+
+\def\pgfpointlineattime#1#2#3{%
+ \pgf@process{#3}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgf@xc\pgf@x%
+ \pgf@yc\pgf@y%
+ \pgf@process{#2}%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgfmathsetmacro\pgf@temp{#1}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \global\advance\pgf@x by\pgf@temp\pgf@xa%
+ \global\advance\pgf@y by\pgf@temp\pgf@ya%
+}
+
+
+% Move point #2 #1 many units in the direction of #3.
+%
+% #1 = a distance
+% #2 = start point
+% #3 = end point
+%
+% Description:
+%
+% Computes
+%
+% x/y = start + #1*(normalise(end-start))
+%
+% and additionally
+%
+% xa/ya = #1*(normalise(end-start))
+% xb/yb = start
+% xc/yc = end
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointlineatdistance{2pt}{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}}
+% \pgfpathlineto{\pgfpointlineatdistance{3pt}{\pgfpointxy{2}{3}}{\pgfpointxy{0}{1}}}
+
+\def\pgfpointlineatdistance#1#2#3{%
+ \pgfmathsetlength\pgf@xa{#1}%
+ \pgf@process{#2}%
+ \pgf@xb\pgf@x% xb/yb = start point
+ \pgf@yb\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xc\pgf@x%
+ \pgf@yc\pgf@y%
+ \global\advance\pgf@x by-\pgf@xb\relax%
+ \global\advance\pgf@y by-\pgf@yb\relax%
+ \pgf@process{\pgfpointnormalised{}}% x/y = normalised vector
+ \pgf@ya=\pgf@xa\relax%
+ \pgf@xa=\pgf@sys@tonumber{\pgf@x}\pgf@xa%
+ \pgf@ya=\pgf@sys@tonumber{\pgf@y}\pgf@ya%
+ \global\pgf@x=\pgf@xb\relax%
+ \global\pgf@y=\pgf@yb\relax%
+ \global\advance\pgf@x by\pgf@xa\relax%
+ \global\advance\pgf@y by\pgf@ya\relax%
+}
+
+
+% Returns point on a curve from #2 to #5 with controls #3 and #4 at time #1.
+%
+% #1 = a time
+% #2 = start point
+% #3 = first control point
+% #4 = second control point
+% #5 = end point
+%
+% x = x-component of place on the curve at time t
+% y = y-component of place on the curve at time t
+%
+% Additionally, (\pgf@xa,\pgf@ya) and (\pgf@xb,\pgf@yb) will be on a
+% tangent to the point on the curve (this can be useful for computing
+% a label rotation). (\pgf@xc,\pgf@yc) will be equal to the end
+% point. \pgf@time@s will equal the value of #1 and \pgf@time@t will
+% equal 1-#1.
+%
+% Example:
+%
+% % Middle of (1,1) and (2,3)
+% \pgfpathmoveto{\pgfpointcurveattime{0.5}{\pgfpointxy{0}{1}}{\pgfpointxy{1}{1}}{\pgfpointxy{1}{1}}{\pgfpointxy{2}{3}}}
+
+\def\pgfpointcurveattime#1#2#3#4#5{%
+ \pgfmathparse{#1}%
+ \let\pgf@time@s=\pgfmathresult%
+ \global\pgf@x=\pgfmathresult pt%
+ \global\pgf@x=-\pgf@x%
+ \advance\pgf@x by 1pt%
+ \edef\pgf@time@t{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@process{#5}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{#4}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#2}%
+ % First iteration:
+ \global\pgf@x=\pgf@time@t\pgf@x\global\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \global\pgf@y=\pgf@time@t\pgf@y\global\advance\pgf@y by\pgf@time@s\pgf@ya%
+ \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb%
+ \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb%
+ \pgf@xb=\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc%
+ \pgf@yb=\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc%
+ % Second iteration:
+ \global\pgf@x=\pgf@time@t\pgf@x\global\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \global\pgf@y=\pgf@time@t\pgf@y\global\advance\pgf@y by\pgf@time@s\pgf@ya%
+ \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb%
+ \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb%
+ % Save x/y
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ % Third iteration:
+ \global\pgf@x=\pgf@time@t\pgf@x\global\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \global\pgf@y=\pgf@time@t\pgf@y\global\advance\pgf@y by\pgf@time@s\pgf@ya%
+}
+
+
+
+% Returns point on an arc at a certain "time"
+%
+% #1 = a time
+% #2 = center of a ellipse
+% #3 = 0-degree axis of the ellipse
+% #4 = 90-degree axis of the ellipse
+% #5 = start angle of an arc on the ellipse
+% #6 = end angle of an arc on the ellipse
+%
+% Result:
+%
+% \pgf@x = x-component of place on the arc at time t
+% \pgf@y = y-component of place on the arc at time t
+%
+% Additionally, (\pgf@xa,\pgf@ya) will be a tangent to the
+% point on the arc (this can be useful for computing a label rotation).
+%
+% Example:
+%
+% \pgfpointarcaxesattime{0.25}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}{\pgfpoint{0cm}{1cm}}{1cm}{30}{40}
+
+\def\pgfpointarcaxesattime#1#2#3#4#5#6{%
+ \pgfmathsetmacro\pgf@angle@start{#5}%
+ \pgfmathsetmacro\pgf@angle@end{#6}%
+ \pgfmathparse{#1}%
+ \global\pgf@x=\pgfmathresult pt%
+ \global\pgf@x=-\pgf@x%
+ \advance\pgf@x by 1pt%
+ \pgfmathsetmacro\pgf@angle@mid{\pgf@angle@end*\pgfmathresult+\pgf@angle@start*\pgf@sys@tonumber{\pgf@x}}%
+ \pgfmathcos@{\pgf@angle@mid}%
+ \let\pgf@angle@cos\pgfmathresult%
+ \pgfmathsin@{\pgf@angle@mid}%
+ \let\pgf@angle@sin\pgfmathresult%
+ \pgf@process{#3}%
+ \edef\pgf@angle@zero@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgf@process{#4}%
+ \edef\pgf@angle@ninety@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ % Compute tangent
+ \pgf@process{\pgfpointadd{\pgfpointscale{\pgf@angle@sin}{\pgf@angle@zero@axis}}%
+ {\pgfpointscale{-\pgf@angle@cos}{\pgf@angle@ninety@axis}}}%
+ \ifdim\pgf@angle@start pt>\pgf@angle@end pt%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \else%
+ \pgf@xa=-\pgf@x%
+ \pgf@ya=-\pgf@y%
+ \fi%
+ % Compute position
+ \pgf@process{\pgfpointadd{#2}{%
+ \pgfpointadd{\pgfpointscale{\pgf@angle@cos}{\pgf@angle@zero@axis}}%
+ {\pgfpointscale{\pgf@angle@sin}{\pgf@angle@ninety@axis}}}}%
+}
+
+
+
+% Internal registers
+\newdimen\pgf@xx
+\newdimen\pgf@xy
+\newdimen\pgf@yx
+\newdimen\pgf@yy
+\newdimen\pgf@zx
+\newdimen\pgf@zy
+
+
+
+% A polar coordinate
+%
+% #1 = a degree
+% #2 = a radius -- either a dimension or two dimensions separated by
+% " and ".
+%
+% x = (first dimension in #2) * cos(#1)
+% y = (second dimension in #2) * sin(#2)
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointpolar{30}{1cm}}
+% \pgfpathlineto{\pgfpointpolar{30}{1cm and 2cm}}
+
+\def\pgfpointpolar#1#2{%
+ \pgfutil@in@{and }{#2}%
+ \ifpgfutil@in@%
+ \pgf@polar@#2\@@%
+ \else%
+ \pgf@polar@#2 and #2\@@%
+ \fi%
+ \pgfmathparse{#1}%
+ \let\pgfpoint@angle=\pgfmathresult%
+ \pgfmathcos@{\pgfpoint@angle}%
+ \global\pgf@x=\pgfmathresult\pgf@x%
+ \pgfmathsin@{\pgfpoint@angle}%
+ \global\pgf@y=\pgfmathresult\pgf@y%
+}
+
+\def\pgf@polar@#1and #2\@@{%
+ \pgfmathsetlength{\pgf@y}{#2}%
+ \pgfmathsetlength{\pgf@x}{#1}%
+}
+
+% Quick version of the polar coordinate method
+
+\def\pgfqpointpolar#1#2{%
+ \global\pgf@x=#2%
+ \global\pgf@y=\pgf@x%
+ \pgfmathcos@{#1}%
+ \global\pgf@x=\pgfmathresult\pgf@x%
+ \pgfmathsin@{#1}%
+ \global\pgf@y=\pgfmathresult\pgf@y\relax%
+}
+
+
+
+
+% A polar coordinate in the xy plane.
+%
+% #1 = a degree
+% #2 = a radius given as a number or two radii
+%
+% result = (first dim in #2) * x-vector * cos(#1) +
+% (second dim in #2) * y-vector * sin(#1)
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointpolarxy{30}{2}}
+
+\def\pgfpointpolarxy#1#2{%
+ \pgfutil@in@{and }{#2}%
+ \ifpgfutil@in@%
+ \pgf@polarxy@#2\@@%
+ \else%
+ \pgf@polarxy@#2and #2\@@%
+ \fi%
+ \pgfmathparse{#1}%
+ \let\pgfpoint@angle=\pgfmathresult%
+ \pgfmathcos@{\pgfpoint@angle}%
+ \pgf@xa=\pgfmathresult\pgf@xa%
+ \pgfmathsin@{\pgfpoint@angle}%
+ \pgf@ya=\pgfmathresult\pgf@ya%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@xa}\pgf@xx%
+ \global\advance\pgf@x by \pgf@sys@tonumber{\pgf@ya}\pgf@yx%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@xa}\pgf@xy%
+ \global\advance\pgf@y by \pgf@sys@tonumber{\pgf@ya}\pgf@yy}
+
+\def\pgf@polarxy@#1and #2\@@{%
+ \pgfmathsetlength{\pgf@xa}{#1}%
+ \pgfmathsetlength{\pgf@ya}{#2}%
+}
+
+
+
+% A cylindrical coordinate.
+%
+% #1 = a degree
+% #2 = a radius given as a number
+% #3 = a height given as a number
+%
+% result = #2*(x-vector * cos(#1) + y-vector * sin(#1)) + #3*z-vector
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointcylindrical{30}{2}{1}}
+
+\def\pgfpointcylindrical#1#2#3{%
+ \pgfpointpolarxy{#1}{#2}%
+ \pgfmathparse{#3}%
+ \global\advance\pgf@x by \pgfmathresult\pgf@zx%
+ \global\advance\pgf@y by \pgfmathresult\pgf@zy}
+
+
+% A spherical coordinate.
+%
+% #1 = a longitude
+% #2 = a latitude
+% #3 = a radius
+%
+% result = #3*(cos(#2)*(x-vector * cos(#1) + y-vector * sin(#1)) + sin(#2)*z-vector)
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointspherical{30}{30}{2}}
+
+\def\pgfpointspherical#1#2#3{%
+ \pgfmathparse{#1}%
+ \let\pgfpoint@angle=\pgfmathresult%
+ \pgfmathsin@{\pgfpoint@angle}%
+ \pgf@xb=\pgfmathresult\pgf@xx%
+ \pgf@yb=\pgfmathresult\pgf@xy%
+ \pgfmathcos@{\pgfpoint@angle}%
+ \advance\pgf@xb by \pgfmathresult\pgf@yx%
+ \advance\pgf@yb by \pgfmathresult\pgf@yy%
+ %
+ \pgfmathparse{#2}%
+ \let\pgfpoint@angle=\pgfmathresult%
+ \pgfmathcos@{\pgfpoint@angle}%
+ \pgf@xc=\pgfmathresult\pgf@xb%
+ \pgf@yc=\pgfmathresult\pgf@yb%
+ \pgfmathsin@{\pgfpoint@angle}%
+ \advance\pgf@xc by \pgfmathresult\pgf@zx%
+ \advance\pgf@yc by \pgfmathresult\pgf@zy%
+ \pgfmathparse{#3}%
+ \global\pgf@x=\pgfmathresult\pgf@xc%
+ \global\pgf@y=\pgfmathresult\pgf@yc\relax%
+}
+
+
+% Store the vector #1 * x-vec + #2 * y-vec
+%
+% #1 = a factor for the x-vector
+% #2 = a factor for the y-vector
+%
+% x = x-component of result vector
+% y = y-component of result vector
+%
+% Description:
+%
+% This command can be used to create a new coordinate system
+% without using the rotate/translate/scale commands. This
+% may be useful, if you do not want arrows and line width to
+% be scaled/transformed together with the coordinate system.
+%
+% Example:
+%
+% % Create a slanted rectangle
+%
+% \pgfsetxvec{\pgfpoint{1cm}{1cm}}
+% \pgfsetyvec{\pgfpoint{0cm}{1cm}}
+%
+% \pgfpathmoveto{\pgfpointxy{0}{0}}
+% \pgfpathlineto{\pgfpointxy{1}{0}}
+% \pgfpathlineto{\pgfpointxy{1}{1}}
+% \pgfpathlineto{\pgfpointxy{0}{1}}
+% \pgfclosestroke
+
+\def\pgfpointxy#1#2{%
+ \pgfmathparse{#1}%
+ \let\pgftemp@x=\pgfmathresult%
+ \pgfmathparse{#2}%
+ \let\pgftemp@y=\pgfmathresult%
+ \global\pgf@x=\pgftemp@x\pgf@xx%
+ \global\advance\pgf@x by \pgftemp@y\pgf@yx%
+ \global\pgf@y=\pgftemp@x\pgf@xy%
+ \global\advance\pgf@y by \pgftemp@y\pgf@yy}
+
+
+% "Quick" variant for \pgfpointxy.
+%
+% Only numbers without unit are allowed here.
+\def\pgfqpointxy#1#2{%
+ \global\pgf@x=#1\pgf@xx%
+ \global\advance\pgf@x by #2\pgf@yx%
+ \global\pgf@y=#1\pgf@xy%
+ \global\advance\pgf@y by #2\pgf@yy}
+
+% Store the vector #1 * x-vec + #2 * y-vec + #3 * z-vec
+%
+% #1 = a factor for the x-vector
+% #2 = a factor for the y-vector
+% #3 = a factor for the z-vector
+%
+% x = x-component of result vector
+% y = y-component of result vector
+%
+%
+% Description:
+%
+% This command allows you to use a 3d coordinate system.
+%
+%
+% Example:
+%
+% % Draw a cubus
+%
+% \pgfline{\pgfpointxyz{0}{0}{0}}{\pgfpointxyz{0}{0}{1}}
+% \pgfline{\pgfpointxyz{0}{1}{0}}{\pgfpointxyz{0}{1}{1}}
+% \pgfline{\pgfpointxyz{1}{0}{0}}{\pgfpointxyz{1}{0}{1}}
+% \pgfline{\pgfpointxyz{1}{1}{0}}{\pgfpointxyz{1}{1}{1}}
+% \pgfline{\pgfpointxyz{0}{0}{0}}{\pgfpointxyz{0}{1}{0}}
+% \pgfline{\pgfpointxyz{0}{0}{1}}{\pgfpointxyz{0}{1}{1}}
+% \pgfline{\pgfpointxyz{1}{0}{0}}{\pgfpointxyz{1}{1}{0}}
+% \pgfline{\pgfpointxyz{1}{0}{1}}{\pgfpointxyz{1}{1}{1}}
+% \pgfline{\pgfpointxyz{0}{0}{0}}{\pgfpointxyz{1}{0}{0}}
+% \pgfline{\pgfpointxyz{0}{0}{1}}{\pgfpointxyz{1}{0}{1}}
+% \pgfline{\pgfpointxyz{0}{1}{0}}{\pgfpointxyz{1}{1}{0}}
+% \pgfline{\pgfpointxyz{0}{1}{1}}{\pgfpointxyz{1}{1}{1}}
+
+\def\pgfpointxyz#1#2#3{%
+ \pgfmathparse{#1}%
+ \let\pgftemp@x=\pgfmathresult%
+ \pgfmathparse{#2}%
+ \let\pgftemp@y=\pgfmathresult%
+ \pgfmathparse{#3}%
+ \let\pgftemp@z=\pgfmathresult%
+ \global\pgf@x=\pgftemp@x\pgf@xx%
+ \global\advance\pgf@x by \pgftemp@y\pgf@yx%
+ \global\advance\pgf@x by \pgftemp@z\pgf@zx%
+ \global\pgf@y=\pgftemp@x\pgf@xy%
+ \global\advance\pgf@y by \pgftemp@y\pgf@yy%
+ \global\advance\pgf@y by \pgftemp@z\pgf@zy}
+
+% "Quick" variant for \pgfpointxyz.
+%
+% Only numbers without unit are allowed.
+\def\pgfqpointxyz#1#2#3{%
+ \global\pgf@x=#1\pgf@xx%
+ \global\advance\pgf@x by #2\pgf@yx%
+ \global\advance\pgf@x by #3\pgf@zx%
+ \global\pgf@y=#1\pgf@xy%
+ \global\advance\pgf@y by #2\pgf@yy%
+ \global\advance\pgf@y by #3\pgf@zy}
+
+
+
+% Set the x-vector
+%
+% #1 = a point the is the new x-vector
+%
+% Example:
+%
+% \pgfsetxvec{\pgfpoint{1cm}{0cm}}
+
+\def\pgfsetxvec#1{%
+ \pgf@process{#1}%
+ \pgf@xx=\pgf@x%
+ \pgf@xy=\pgf@y%
+ \ignorespaces}
+
+
+% Set the y-vector
+%
+% #1 = a point the is the new y-vector
+%
+% Example:
+%
+% \pgfsetyvec{\pgfpoint{0cm}{1cm}}
+
+\def\pgfsetyvec#1{%
+ \pgf@process{#1}%
+ \pgf@yx=\pgf@x%
+ \pgf@yy=\pgf@y%
+ \ignorespaces}
+
+
+% Set the z-vector
+%
+% #1 = a point the is the new z-vector
+%
+% Example:
+%
+% \pgfsetzvec{\pgfpoint{-0.385cm}{-0.385cm}}
+
+\def\pgfsetzvec#1{%
+ \pgf@process{#1}%
+ \pgf@zx=\pgf@x%
+ \pgf@zy=\pgf@y%
+ \ignorespaces}
+
+
+
+% Default values
+\pgfsetxvec{\pgfpoint{1cm}{0cm}}
+\pgfsetyvec{\pgfpoint{0cm}{1cm}}
+\pgfsetzvec{\pgfpoint{-0.385cm}{-0.385cm}}
+
+
+
+
+% Normalise a point.
+%
+% #1 = point with coordinates (a,b)
+%
+% x = a/\sqrt(a*a+b*b)
+% y = b/\sqrt(a*a+b*b)
+%
+% Example:
+%
+% \pgfpointnormalised{\pgfpointxy{2}{1}}
+
+\def\pgfpointnormalised#1{%
+ \pgf@process{#1}%
+ \pgfmathatantwo{\the\pgf@y}{\the\pgf@x}%
+ \let\pgf@tmp=\pgfmathresult%
+ \pgfmathcos@{\pgf@tmp}%
+ \pgf@x=\pgfmathresult pt\relax%
+ \pgfmathsin@{\pgf@tmp}%
+ \pgf@y=\pgfmathresult pt\relax%
+}
+
+
+
+
+
+% A point on a rectangle in a certain direction.
+%
+% #1 = a point pointing in some direction (length should be about 1pt,
+% but need not be exact)
+% #2 = upper right corner of a rectangle centered at the origin
+%
+% Returns the intersection of a line starting at the origin going in
+% the given direction and the rectangle's border.
+%
+% Example:
+%
+% \pgfpointborderrectangle{\pgfpointnormalised{\pgfpointxy{2}{1}}
+% {\pgfpoint{1cm}{2cm}}
+
+\def\pgfpointborderrectangle#1#2{%
+ \pgf@process{#2}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{#1}%
+ % Ok, let's find out about the direction:
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \ifnum\pgf@xa<0\relax% move into first quadrant
+ \global\pgf@x=-\pgf@x%
+ \fi%
+ \ifnum\pgf@ya<0\relax%
+ \global\pgf@y=-\pgf@y%
+ \fi%
+ \pgf@xc=.125\pgf@x%
+ \pgf@yc=.125\pgf@y%
+ \c@pgf@counta=\pgf@xc%
+ \c@pgf@countb=\pgf@yc%
+ \ifnum\c@pgf@countb<\c@pgf@counta%
+ \ifnum\c@pgf@counta<255\relax%
+ \global\pgf@y=\pgf@yb\relax%
+ \global\pgf@x=0pt\relax%
+ \else%
+ \pgf@xc=8192pt%
+ \divide\pgf@xc by\c@pgf@counta% \pgf@xc = 1/\pgf@x
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@xc}\pgf@y%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@xb}\pgf@y%
+ \ifnum\pgf@y<\pgf@yb%
+ \global\pgf@x=\pgf@xb%
+ \else% rats, calculate intersection on upper side
+ \ifnum\c@pgf@countb<255\relax%
+ \global\pgf@x=\pgf@xb\relax%
+ \global\pgf@y=0pt\relax%
+ \else%
+ \pgf@yc=8192pt%
+ \divide\pgf@yc by\c@pgf@countb% \pgf@xc = 1/\pgf@x
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@yc}\pgf@x%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@yb}\pgf@x%
+ \global\pgf@y=\pgf@yb%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \ifnum\c@pgf@countb<255\relax%
+ \global\pgf@x=\pgf@xb\relax%
+ \global\pgf@y=0pt\relax%
+ \else%
+ \pgf@yc=8192pt%
+ \divide\pgf@yc by\c@pgf@countb% \pgf@xc = 1/\pgf@x
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@yc}\pgf@x%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@yb}\pgf@x%
+ \ifnum\pgf@x<\pgf@xb%
+ \global\pgf@y=\pgf@yb%
+ \else%
+ \ifnum\c@pgf@counta<255\relax%
+ \global\pgf@y=\pgf@yb\relax%
+ \global\pgf@x=0pt\relax%
+ \else%
+ \pgf@xc=8192pt%
+ \divide\pgf@xc by\c@pgf@counta% \pgf@xc = 1/\pgf@x
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@xc}\pgf@y%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@xb}\pgf@y%
+ \global\pgf@x=\pgf@xb%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \ifnum\pgf@xa<0\relax\global\pgf@x=-\pgf@x\fi%
+ \ifnum\pgf@ya<0\relax\global\pgf@y=-\pgf@y\fi%
+}
+
+
+
+
+% An approximation to a point on an ellipse in a certain
+% direction. Will be exact only if the ellipse is a circle.
+%
+% #1 = a point pointing in some direction
+% #2 = upper right corner of a bounding box for the ellipse
+%
+% Returns the intersection of a line starting at the origin going in
+% the given direction and the ellipses border.
+%
+% Example:
+%
+% \pgfpointborderellipse{\pgfpointnormalised{\pgfpointxy{2}{1}}
+% {\pgfpoint{1cm}{2cm}}
+
+\def\pgfpointborderellipse#1#2{%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \ifdim\pgf@xa=\pgf@ya% circle. that's easy!
+ \pgf@process{\pgfpointnormalised{#1}}%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@xa}\pgf@x%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@xa}\pgf@y%
+ \else%
+ \ifdim\pgf@xa<\pgf@ya%
+ % Ok, first, let's compute x/y:
+ \c@pgf@countb=\pgf@ya%
+ \divide\c@pgf@countb by65536\relax%
+ \global\divide\pgf@x by\c@pgf@countb%
+ \global\divide\pgf@y by\c@pgf@countb%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=8192pt%
+ \global\pgf@y=.125\pgf@y%
+ \c@pgf@countb=\pgf@y%
+ \divide\pgf@yc by\c@pgf@countb%
+ \pgf@process{#1}%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@yc}\pgf@y%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@xc}\pgf@y%
+ \pgf@process{\pgfpointnormalised{}}%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@xa}\pgf@x%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@ya}\pgf@y%
+ \else%
+ % Ok, now let's compute y/x:
+ \c@pgf@countb=\pgf@xa%
+ \divide\c@pgf@countb by65536\relax%
+ \global\divide\pgf@x by\c@pgf@countb%
+ \global\divide\pgf@y by\c@pgf@countb%
+ \pgf@yc=\pgf@y%
+ \pgf@xc=8192pt%
+ \global\pgf@x=.125\pgf@x%
+ \c@pgf@countb=\pgf@x%
+ \divide\pgf@xc by\c@pgf@countb%
+ \pgf@process{#1}%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@yc}\pgf@x%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@xc}\pgf@x%
+ \pgf@process{\pgfpointnormalised{}}%
+ \global\pgf@x=\pgf@sys@tonumber{\pgf@xa}\pgf@x%
+ \global\pgf@y=\pgf@sys@tonumber{\pgf@ya}\pgf@y%
+ \fi%
+ \fi%
+}
+
+
+
+
+
+% Extract the x-coordinate of a point to a dimensions
+%
+% #1 = a TeX dimension
+% #2 = a point
+%
+% Example:
+%
+% \newdimen\mydim
+% \pgfextractx{\mydim}{\pgfpoint{2cm}{4pt}}
+% % \mydim is now 2cm
+
+\def\pgfextractx#1#2{%
+ \pgf@process{#2}%
+ #1=\pgf@x\relax}
+
+
+% Extract the y-coordinate of a point to a dimensions
+%
+% #1 = a TeX dimension
+% #2 = a point
+%
+% Example:
+%
+% \newdimen\mydim
+% \pgfextracty{\mydim}{\pgfpoint{2cm}{4pt}}
+% % \mydim is now 4pt
+
+\def\pgfextracty#1#2{%
+ \pgf@process{#2}%
+ #1=\pgf@y\relax}
+
+
+% Stores the most recently used (x,y) coordinates into two macros, #1 and #2.
+\def\pgfgetlastxy#1#2{%
+ \edef#1{\the\pgf@x}%
+ \edef#2{\the\pgf@y}%
+}%
+
+
+\def\pgf@def#1#2#3{\expandafter\def\csname pgf@#1#2\endcsname{#3}}
+\pgf@def{cosfrac}{0}{1}
+\pgf@def{cosfrac}{1}{0.99995} \pgf@def{cosfrac}{2}{0.9998}
+\pgf@def{cosfrac}{3}{0.99955} \pgf@def{cosfrac}{4}{0.999201}
+\pgf@def{cosfrac}{5}{0.998752} \pgf@def{cosfrac}{6}{0.998205}
+\pgf@def{cosfrac}{7}{0.997559} \pgf@def{cosfrac}{8}{0.996815}
+\pgf@def{cosfrac}{9}{0.995974} \pgf@def{cosfrac}{10}{0.995037}
+\pgf@def{cosfrac}{11}{0.994004} \pgf@def{cosfrac}{12}{0.992877}
+\pgf@def{cosfrac}{13}{0.991656} \pgf@def{cosfrac}{14}{0.990342}
+\pgf@def{cosfrac}{15}{0.988936} \pgf@def{cosfrac}{16}{0.987441}
+\pgf@def{cosfrac}{17}{0.985856} \pgf@def{cosfrac}{18}{0.984183}
+\pgf@def{cosfrac}{19}{0.982424} \pgf@def{cosfrac}{20}{0.980581}
+\pgf@def{cosfrac}{21}{0.978653} \pgf@def{cosfrac}{22}{0.976644}
+\pgf@def{cosfrac}{23}{0.974555} \pgf@def{cosfrac}{24}{0.972387}
+\pgf@def{cosfrac}{25}{0.970143} \pgf@def{cosfrac}{26}{0.967823}
+\pgf@def{cosfrac}{27}{0.965429} \pgf@def{cosfrac}{28}{0.962964}
+\pgf@def{cosfrac}{29}{0.960429} \pgf@def{cosfrac}{30}{0.957826}
+\pgf@def{cosfrac}{31}{0.955157} \pgf@def{cosfrac}{32}{0.952424}
+\pgf@def{cosfrac}{33}{0.949629} \pgf@def{cosfrac}{34}{0.946773}
+\pgf@def{cosfrac}{35}{0.943858} \pgf@def{cosfrac}{36}{0.940887}
+\pgf@def{cosfrac}{37}{0.937862} \pgf@def{cosfrac}{38}{0.934784}
+\pgf@def{cosfrac}{39}{0.931655} \pgf@def{cosfrac}{40}{0.928477}
+\pgf@def{cosfrac}{41}{0.925252} \pgf@def{cosfrac}{42}{0.921982}
+\pgf@def{cosfrac}{43}{0.918669} \pgf@def{cosfrac}{44}{0.915315}
+\pgf@def{cosfrac}{45}{0.911922} \pgf@def{cosfrac}{46}{0.90849}
+\pgf@def{cosfrac}{47}{0.905024} \pgf@def{cosfrac}{48}{0.901523}
+\pgf@def{cosfrac}{49}{0.89799} \pgf@def{cosfrac}{50}{0.894427}
+\pgf@def{cosfrac}{51}{0.890835} \pgf@def{cosfrac}{52}{0.887217}
+\pgf@def{cosfrac}{53}{0.883573} \pgf@def{cosfrac}{54}{0.879905}
+\pgf@def{cosfrac}{55}{0.876216} \pgf@def{cosfrac}{56}{0.872506}
+\pgf@def{cosfrac}{57}{0.868777} \pgf@def{cosfrac}{58}{0.865031}
+\pgf@def{cosfrac}{59}{0.861269} \pgf@def{cosfrac}{60}{0.857493}
+\pgf@def{cosfrac}{61}{0.853704} \pgf@def{cosfrac}{62}{0.849903}
+\pgf@def{cosfrac}{63}{0.846092} \pgf@def{cosfrac}{64}{0.842271}
+\pgf@def{cosfrac}{65}{0.838444} \pgf@def{cosfrac}{66}{0.834609}
+\pgf@def{cosfrac}{67}{0.83077} \pgf@def{cosfrac}{68}{0.826927}
+\pgf@def{cosfrac}{69}{0.82308} \pgf@def{cosfrac}{70}{0.819232}
+\pgf@def{cosfrac}{71}{0.815383} \pgf@def{cosfrac}{72}{0.811534}
+\pgf@def{cosfrac}{73}{0.807687} \pgf@def{cosfrac}{74}{0.803842}
+\pgf@def{cosfrac}{75}{0.8} \pgf@def{cosfrac}{76}{0.796162}
+\pgf@def{cosfrac}{77}{0.792329} \pgf@def{cosfrac}{78}{0.788502}
+\pgf@def{cosfrac}{79}{0.784682} \pgf@def{cosfrac}{80}{0.780869}
+\pgf@def{cosfrac}{81}{0.777064} \pgf@def{cosfrac}{82}{0.773268}
+\pgf@def{cosfrac}{83}{0.769481} \pgf@def{cosfrac}{84}{0.765705}
+\pgf@def{cosfrac}{85}{0.761939} \pgf@def{cosfrac}{86}{0.758185}
+\pgf@def{cosfrac}{87}{0.754443} \pgf@def{cosfrac}{88}{0.750714}
+\pgf@def{cosfrac}{89}{0.746997} \pgf@def{cosfrac}{90}{0.743294}
+\pgf@def{cosfrac}{91}{0.739605} \pgf@def{cosfrac}{92}{0.735931}
+\pgf@def{cosfrac}{93}{0.732272} \pgf@def{cosfrac}{94}{0.728628}
+\pgf@def{cosfrac}{95}{0.724999} \pgf@def{cosfrac}{96}{0.721387}
+\pgf@def{cosfrac}{97}{0.717792} \pgf@def{cosfrac}{98}{0.714213}
+\pgf@def{cosfrac}{99}{0.710651} \pgf@def{cosfrac}{100}{0.707107}
+
+
+
+
+% Forward declarations for nonlinear stuff (have no effect till module
+% nonlineartransformations is loaded)
+
+\let\pgfpointtransformednonlinear\pgfpointtransformed
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorequick.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorequick.code.tex
new file mode 100644
index 0000000000..4180440b00
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorequick.code.tex
@@ -0,0 +1,134 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorequick.code.tex}
+
+% Quick version of basic drawing commands. Most high-level commands
+% are not available if these commands are used.
+
+% Move current point to (#1,#2).
+%
+% #1 = x dimension of new current point
+% #2 = y dimension of new current point
+%
+% Example:
+%
+% \pgfpathqmoveto{0pt}{0pt}
+% \pgfpathqlineto{1pt}{1pt}
+% \pgfpathqcurveto{2pt}{1pt}{2pt}{2pt}{3pt}{2pt}
+% \pgfqstroke
+
+\def\pgfpathqmoveto#1#2{\pgfsyssoftpath@moveto{#1}{#2}}
+
+
+% Append a line to (#1,#2) to the current path.
+%
+% #1 = x dimension of target
+% #2 = y dimension of target
+%
+% Example:
+%
+% \pgfpathqmoveto{0pt}{0pt}
+% \pgfpathqlineto{1pt}{1pt}
+% \pgfpathqcurveto{2pt}{1pt}{2pt}{2pt}{3pt}{2pt}
+% \pgfqstroke
+
+\def\pgfpathqlineto#1#2{\pgfsyssoftpath@lineto{#1}{#2}}
+
+
+% Append a bezier spline to the current path.
+%
+% #1 = x dimension of first support point
+% #2 = y dimension of first support point
+% #3 = x dimension of second support point
+% #4 = y dimension of second support point
+% #5 = x dimension of target point
+% #6 = y dimension of target point
+%
+% Example:
+%
+% \pgfpathqmoveto{0pt}{0pt}
+% \pgfpathqlineto{1pt}{1pt}
+% \pgfpathqcurveto{2pt}{1pt}{2pt}{2pt}{3pt}{2pt}
+% \pgfqstroke
+
+\def\pgfpathqcurveto#1#2#3#4#5#6{\pgfsyssoftpath@curveto{#1}{#2}{#3}{#4}{#5}{#6}}
+
+
+
+
+% Append a circle of the given radius around the origin.
+%
+% #1 = radius
+%
+% Example:
+%
+% \pgfpathqcircle{10pt}
+% is quicker than
+% \pgfpathcircle{\pgforigin}{10pt}
+
+\def\pgfpathqcircle#1{%
+ {%
+ \pgf@x=#1%
+ \pgf@y=0.5522847\pgf@x%
+ \pgfsyssoftpath@moveto{\the\pgf@x}{0pt}%
+ \pgfsyssoftpath@curveto{\the\pgf@x}{\the\pgf@y}{\the\pgf@y}{\the\pgf@x}{0pt}{\the\pgf@x}%
+ \pgfsyssoftpath@curveto{-\the\pgf@y}{\the\pgf@x}{-\the\pgf@x}{\the\pgf@y}{-\the\pgf@x}{0pt}%
+ \pgfsyssoftpath@curveto{-\the\pgf@x}{-\the\pgf@y}{-\the\pgf@y}{-\the\pgf@x}{0pt}{-\the\pgf@x}%
+ \pgfsyssoftpath@curveto{\the\pgf@y}{-\the\pgf@x}{\the\pgf@x}{-\the\pgf@y}{\the\pgf@x}{0pt}%
+ \pgfsyssoftpath@closepath%
+ }%
+}
+
+
+
+% Stroke current path. No hooks called.
+%
+% Example:
+%
+% \pgfpathqmoveto{0cm}{0cm}
+% \pgfpathqlineto{1cm}{1cm}
+% \pgfpathqcurveto{2cm}{1cm}{2cm}{2cm}{3cm}{2cm}
+% \pgfqstroke
+
+\def\pgfusepathqstroke{%
+ \pgfsyssoftpath@flushcurrentpath%
+ \pgfsys@stroke%
+ \pgf@resetpathsizes%
+}
+
+
+% Quickly fill current path.
+
+\def\pgfusepathqfill{%
+ \pgfsyssoftpath@flushcurrentpath%
+ \pgfsys@fill%
+ \pgf@resetpathsizes%
+}
+
+
+% Quickly fill and stroke current path.
+
+\def\pgfusepathqfillstroke{%
+ \pgfsyssoftpath@flushcurrentpath%
+ \pgfsys@fillstroke%
+ \pgf@resetpathsizes%
+}
+
+% Quickly clip current path.
+
+\def\pgfusepathqclip{%
+ \pgfsyssoftpath@flushcurrentpath%
+ \pgfsys@clipnext%
+ \pgfsys@discardpath%
+ \pgf@resetpathsizes%
+}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorerdf.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorerdf.code.tex
new file mode 100644
index 0000000000..1069318a4b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorerdf.code.tex
@@ -0,0 +1,228 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorerdf.code.tex}
+
+
+
+%
+%
+% The Resource Description Framework (RDF) is a method of enriching
+% output files with semantic information. In PGF, you can use the
+% following commands to create RDF information that will be inserted
+% into the output, provided the output format allows this (SVG
+% does). You call any of these commands before an ID-scope and it will
+% attach the attribute(s) to this id scope.
+%
+%
+% Example:
+%
+% ...
+% \pgfrdftypeof{http://purl.org/dc/dcmitype/Image}
+% \pgfrdfresource{/paper/figures/1}
+% \pgfidscope
+% % This ID scope will be flagged as the resource "/paper/figures/1"
+% % and typeof "Image" from the Dublin Core.
+% ...
+% \endidscope
+
+
+
+
+
+% Adds the rdf attribute "about" with value #1 to the next
+% idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% The RDF-spec says: "a SafeCURIEorCURIEorIRI, used for stating what
+% the data is about (a 'subject' in RDF terminology);"
+
+\def\pgfrdfabout#1{\pgfsys@rdf@about{#1}}
+
+
+
+% Adds the rdf attribute content with value #1 to the next
+% idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% The RDF-spec says: "a CDATA string, for supplying machine-readable
+% content for a literal (a 'literal object', in RDF terminology);"
+
+\def\pgfrdfcontent#1{\pgfsys@rdf@content{#1}}
+
+
+
+% Adds the rdf attribute datatype with value #1 to the next
+% idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% The RDF-spec says: "a TERMorCURIEorAbsIRI representing a datatype,
+% to express the datatype of a literal;"
+
+\def\pgfrdfdatatype#1{\pgfsys@rdf@datatype{#1}}
+
+
+
+% Adds the rdf attribute href with value #1 to the next idscope
+% The RDF-spec says: "a traditionally navigable IRI for
+% expressing the partner resource of a relationship (a 'resource object', in RDF terminology);"
+
+\def\pgfrdfhref#1{\pgfsys@rdf@href{#1}}
+
+
+
+% Adds the rdf attribute inlist to the next idscope.
+%
+% Description:
+%
+% The RDF-spec says: "An attribute used to indicate that the object
+% associated with a rel or property attribute on the same element is
+% to be added to the list for that predicate. Presence of this
+% attribute causes a list to be created if it does not already exist."
+
+\def\pgfrdfinlist{\pgfsys@rdf@inlist}
+
+
+
+
+% Adds #1 to the list of the rdf prefix attribute to the next
+% idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% Can be called several times, in which case all values of #1 are
+% concatenated with whitespaces. The RDF-spec says: "a white space
+% separated list of prefix-name IRI pairs of the form NCName ':' ' '+
+% xsd:anyURI"
+
+\def\pgfrdfprefix#1{\pgfsys@rdf@prefix{#1}}
+
+
+
+
+% Adds #1 to the list of the rdf property attribute to the next
+% idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% Can be called repeatedly. The RDF-spec says: "a white space
+% separated list of TERMorCURIEorAbsIRIs, used for expressing
+% relationships between a subject and either a resource object if
+% given or some literal text (also a 'predicate');"
+
+\def\pgfrdfproperty#1{\pgfsys@rdf@property{#1}}
+
+
+
+% Adds #1 to the list of the rdf rel attribute to the next
+% next idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% Can be called repeatedly. The RDF-spec says: "a white space
+% separated list of TERMorCURIEorAbsIRIs, used for expressing
+% relationships between two resources ('predicates' in RDF
+% terminology);"
+
+\def\pgfrdfrel#1{\pgfsys@rdf@rel{#1}}
+
+
+% Adds the rdf attribute resource with value #1 to the next idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% The RDF-spec says: "a SafeCURIEorCURIEorIRI for expressing the
+% partner resource of a relationship that is not intended to be
+% navigable (e.g., a 'clickable' link) (also an 'object');"
+
+\def\pgfrdfresource#1{\pgfsys@rdf@resource{#1}}
+
+
+
+
+% Adds #1 to the list of the rdf rev attribute to the next
+% idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% Can be called repeatedly. The RDF-spec says: "a white space
+% separated list of TERMorCURIEorAbsIRIs, used for expressing reverse
+% relationships between two resources (also 'predicates');
+
+\def\pgfrdfrev#1{\pgfsys@rdf@rev{#1}}
+
+
+
+
+% Adds an rdf attribute src with value #1 to the next idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% The RDF-spec says: "an IRI for expressing the partner resource of a
+% relationship when the resource is embedded (also a 'resource object');"
+
+\def\pgfrdfsrc#1{\pgfsys@rdf@src{#1}}
+
+
+
+
+% Adds #1 to the list of the rdf typeof attribute to the next
+% idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% Can be called repeatedly. The RDF-spec says: "a white space
+% separated list of TERMorCURIEorAbsIRIs that indicate the RDF type(s)
+% to associate with a subject;"
+
+\def\pgfrdftypeof#1{\pgfsys@rdf@typeof{#1}}
+
+
+
+
+% Adds an rdf attribute vocab with value #1 to the next idscope.
+%
+% #1 = A URL
+%
+% Description:
+%
+% The RDF-spec says: "an IRI that defines the mapping to use when a
+% TERM is referenced in an attribute value. See General Use of Terms
+% in Attributes and the section on Vocabulary Expansion."
+
+\def\pgfrdfvocab#1{\pgfsys@rdf@vocab{#1}}
+
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcorescopes.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcorescopes.code.tex
new file mode 100644
index 0000000000..75cb1b587d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcorescopes.code.tex
@@ -0,0 +1,771 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcorescopes.code.tex}
+
+% Globals
+
+\newbox\pgfpic
+\newbox\pgf@hbox
+
+\newbox\pgf@layerbox@main
+
+\newcount\pgf@picture@serial@count
+
+
+
+% This if decides whether the position of pictures on the page is
+% protocolled or not. Normally,
+% this is switched off as it works only with certain drivers and it
+% causes external files to be written. When switched on, the position
+% of pgfpictures are protocolled and can be referenced using
+% \pgfsys@getposition{XXX} where XXX is the value of \pgfpictureid
+% inside the picture.
+\newif\ifpgfrememberpicturepositiononpage
+
+
+
+
+% Scopes
+
+
+% Pgf scope environment. All changes of the graphic state are local to
+% the scope.
+%
+% Example:
+%
+% \begin{pgfscope}
+% \pgfsetlinewidth{3pt}
+% \pgfline{\pgfxy(0,0)}{\pgfxy(3,3)}
+% \end{pgfscope}
+
+\def\pgfscope{%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ \pgfsys@beginscope%
+ \pgf@resetpathsizes%
+ \edef\pgfscope@linewidth{\the\pgflinewidth}%
+ \let\pgfscope@stroke@color=\pgf@strokecolor@global%
+ \let\pgfscope@fill@color=\pgf@fillcolor@global%
+ \begingroup}
+\def\endpgfscope{%
+ \endgroup%
+ \global\pgflinewidth=\pgfscope@linewidth%
+ \global\let\pgf@strokecolor@global=\pgfscope@stroke@color%
+ \global\let\pgf@fillcolor@global=\pgfscope@fill@color%
+ \pgfsys@endscope}
+
+
+
+
+% Quickly insert a box can contain normal TeX text at the origin.
+%
+% #1 = box of width/height and depth 0pt
+%
+% Example:
+%
+% \pgfqbox{\mybox}
+
+\def\pgfqbox#1{%
+ \pgfsys@hbox#1%
+}
+
+
+% Insert a box that can contain normal TeX text at the origin, but
+% with the current coordinate transformation matrix synced with the
+% low-level transformation matrix.
+%
+% #1 = box of width/height and depth 0pt
+%
+% In essence, this command does the same as if you first said
+% \pgflowlevelsynccm and then \pgfqbox. However, pgf will use a
+% ``TeX-translation'' for the translation part of the transformation
+% cm. This will ensure that hyperlinks ``survive'' at least
+% translations.
+%
+% Example:
+%
+% \pgfqboxsynced{\mybox}
+
+\def\pgfqboxsynced#1{%
+ \pgfsys@hboxsynced#1%
+}
+
+
+% Puts some text in a box and inserts it with the current
+% transformations applied.
+%
+% #1 = List of optional positioning. Possible values are ``left'', ``right'',
+% ``top'', ``bottom'' and ``base''.
+% #2 = TeX text. May contain verbatims.
+%
+% Example:
+%
+% \pgftransformshift{\pgfpoint{1cm}{0cm}}
+% \pgftext{Hello World!}
+
+\def\pgftext{\pgfutil@ifnextchar[\pgf@text{\pgf@text[]}}%
+\def\pgf@text[#1]{%
+ \def\pgf@text@options{#1}%
+ \pgf@maketext\pgf@after@text}
+\def\pgf@after@text{%
+ {%
+ \def\pgf@text@hshift{center}%
+ \def\pgf@text@vshift{center}%
+ \expandafter\pgf@text@setkeys\expandafter{\pgf@text@options}%
+ \csname pgf@halign\pgf@text@hshift\endcsname%
+ \csname pgf@valign\pgf@text@vshift\endcsname%
+ %
+ \pgfapproximatenonlineartransformation%
+ % Protocol sizes:
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{0pt}{\dp\pgf@hbox}}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{\wd\pgf@hbox}{\dp\pgf@hbox}}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{0pt}{\ht\pgf@hbox}}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{\wd\pgf@hbox}{\ht\pgf@hbox}}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgfqboxsynced{\pgf@hbox}%
+ }%
+}
+\def\pgf@text@setkeys{\pgfqkeys{/pgf/text}}%
+
+\pgfkeys{/pgf/text/left/.code=\def\pgf@text@hshift{left}}
+\pgfkeys{/pgf/text/center/.code=}
+\pgfkeys{/pgf/text/right/.code=\def\pgf@text@hshift{right}}
+\pgfkeys{/pgf/text/top/.code=\def\pgf@text@vshift{top}}
+\pgfkeys{/pgf/text/bottom/.code=\def\pgf@text@vshift{bottom}}
+\pgfkeys{/pgf/text/base/.code=\def\pgf@text@vshift{base}}
+\pgfkeys{/pgf/text/at/.cd,.code=\pgftransformshift{#1},.value required}
+\pgfkeys{/pgf/text/x/.cd,.code=\pgftransformxshift{#1},.value required}
+\pgfkeys{/pgf/text/y/.cd,.code=\pgftransformyshift{#1},.value required}
+\pgfkeys{/pgf/text/rotate/.cd,.code=\pgftransformrotate{#1},.value required}
+
+\def\pgf@halignleft{}% do nothing
+\def\pgf@haligncenter{\pgftransformxshift{+-.5\wd\pgf@hbox}}
+\def\pgf@halignright{\pgftransformxshift{+-\wd\pgf@hbox}}%
+\def\pgf@valignbase{}% do nothing
+\def\pgf@valignbottom{\pgftransformyshift{+\dp\pgf@hbox}}%
+\def\pgf@valigncenter{\pgftransformyshift{+.5\dp\pgf@hbox}\pgftransformyshift{+-.5\ht\pgf@hbox}}%
+\def\pgf@valigntop{\pgftransformyshift{+-\ht\pgf@hbox}}%
+
+
+% Internal function for creating a hbox.
+\def\pgf@maketext#1{%
+ \def\pgf@@maketextafter{#1}%
+ \setbox\pgf@hbox=\hbox\bgroup%
+ \pgfinterruptpicture%
+ \bgroup%
+ \aftergroup\pgf@collectresetcolor%
+ \let\next=%
+}
+\def\pgf@collectresetcolor{%
+ \pgfutil@ifnextchar\reset@color%
+ {\reset@color\afterassignment\pgf@collectresetcolor\let\pgf@temp=}%
+ {\pgf@textdone}%
+}
+\def\pgf@textdone{%
+ \endpgfinterruptpicture%
+ \egroup%
+ \pgf@@maketextafter%
+}
+
+\long\def\pgf@makehbox#1{%
+ \setbox\pgf@hbox=\hbox{{%
+ \pgfinterruptpicture%
+ #1%
+ \endpgfinterruptpicture%
+ }}}
+
+
+
+% Picture environment
+%
+% Example:
+%
+% \begin{pgfpicture}
+% \pgfsetendarrow{\pgfarrowto}
+% \pgfpathmoveto{\pgfpointxy{-0.9}{0.2}}
+% \pgfpathlineto{\pgfpointxy{0.9}{0.4}}
+% \pgfusepath{stroke}
+% \end{pgfpicture}
+
+\def\pgfresetboundingbox{%
+ \global\pgf@picmaxx=-16000pt\relax%
+ \global\pgf@picminx=16000pt\relax%
+ \global\pgf@picmaxy=-16000pt\relax%
+ \global\pgf@picminy=16000pt\relax%
+}%
+
+\def\pgfpicture{%
+ \begingroup%
+ \pgfpicturetrue%
+ \global\advance\pgf@picture@serial@count by1\relax%
+ \edef\pgfpictureid{pgfid\the\pgf@picture@serial@count}%
+ \let\pgf@nodecallback=\pgfutil@gobble%
+ \pgf@picmaxx=-16000pt\relax%
+ \pgf@picminx=16000pt\relax%
+ \pgf@picmaxy=-16000pt\relax%
+ \pgf@picminy=16000pt\relax%
+ \pgf@relevantforpicturesizetrue%
+ \pgf@resetpathsizes%
+ \pgfutil@ifnextchar\bgroup\pgf@oldpicture\pgf@picture}
+\def\pgf@oldpicture#1#2#3#4{%
+ \pgfmathsetlength\pgf@picminx{#1}%
+ \pgfmathsetlength\pgf@picminy{#2}%
+ \pgfmathsetlength\pgf@picmaxx{#3}%
+ \pgfmathsetlength\pgf@picmaxy{#4}%
+ \pgf@relevantforpicturesizefalse%
+ \pgf@picture}
+
+\def\pgf@picture{%
+ \setbox\pgfpic\hbox to0pt\bgroup%
+ \begingroup%
+ \pgfsys@beginpicture%
+ \pgfsys@beginscope%
+ \begingroup%
+ \pgfsetcolor{.}%
+ \pgfsetlinewidth{0.4pt}%
+ \pgftransformreset%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ \begingroup%
+ \let\pgf@setlengthorig=\setlength%
+ \let\pgf@addtolengthorig=\addtolength%
+ \let\pgf@selectfontorig=\selectfont%
+ \let\setlength=\pgf@setlength%
+ \let\addtolength=\pgf@addtolength%
+ \let\selectfont=\pgf@selectfont%
+ \nullfont\spaceskip0pt\xspaceskip0pt%
+ \tracinglostchars=%
+ \ifnum\tracinglostchars>2 2\else\tracinglostchars\fi
+ \setbox\pgf@layerbox@main\hbox to0pt\bgroup%
+ \begingroup%
+ }
+\def\endpgfpicture{%
+ \ifpgfrememberpicturepositiononpage%
+ \hbox to0pt{\pgfsys@markposition{\pgfpictureid}}%
+ \fi%
+ % ok, now let's position the box
+ \ifdim\pgf@picmaxx=-16000pt\relax%
+ % empty picture. make size 0.
+ \global\pgf@picmaxx=0pt\relax%
+ \global\pgf@picminx=0pt\relax%
+ \global\pgf@picmaxy=0pt\relax%
+ \global\pgf@picminy=0pt\relax%
+ \fi%
+ % Shift baseline outside:
+ \pgf@relevantforpicturesizefalse%
+ \pgf@process{\pgf@baseline}%
+ \xdef\pgf@shift@baseline{\the\pgf@y}%
+ %
+ \pgf@process{\pgf@trimleft}%
+ \global\advance\pgf@x by-\pgf@picminx
+ % prepare \hskip\pgf@trimleft@final.
+ % note that \pgf@trimleft@final is also queried
+ % by the pgf image externalization.
+ \xdef\pgf@trimleft@final{-\the\pgf@x}%
+ %
+ \pgf@process{\pgf@trimright}%
+ \global\advance\pgf@x by-\pgf@picmaxx
+ % prepare \hskip\pgf@trimright@final.
+ % note that \pgf@trimright@final is also queried
+ % by the pgf image externalization.
+ \xdef\pgf@trimright@final{\the\pgf@x}%
+ %
+ \pgf@remember@layerlist@globally
+ \endgroup%
+ \hss%
+ \egroup%
+ \pgf@restore@layerlist@from@global
+ \pgf@insertlayers%
+ \endgroup%
+ \pgfsys@discardpath%
+ \endgroup%
+ \pgfsys@endscope%
+ \pgfsys@endpicture%
+ \endgroup%
+ \hss
+ \egroup%
+ \pgfsys@typesetpicturebox\pgfpic%
+ \endgroup%
+}
+
+\def\pgf@remember@layerlist@globally{%
+ \global\let\pgf@layerlist@=\pgf@layerlist
+}%
+\def\pgf@restore@layerlist@from@global{%
+ \let\pgf@layerlist=\pgf@layerlist@
+}%
+\def\pgf@insertlayers{%
+ \box\pgf@layerbox@main%
+}
+
+\def\pgf@selectfont{\pgf@selectfontorig\nullfont}
+
+\def\pgf@setlength#1#2{% these will be used only when \nullfont is active
+ \begingroup% keep font setting local
+ \pgfutil@selectfont% restore font
+ \pgf@setlengthorig#1{#2}% calculate dimension (possibly using calc)
+ \expandafter%
+ \endgroup%
+ \expandafter#1\expandafter=\the#1\relax}
+\def\pgf@addtolength#1#2{%
+ \begingroup% keep font setting local
+ \pgfutil@selectfont% restore font
+ \pgf@addtolengthorig#1{#2}% calculate dimension (possibly using calc)
+ \expandafter%
+ \endgroup%
+ \expandafter#1\expandafter=\the#1\relax}
+
+
+% Sets the baseline at the y-coordinate of a given point
+%
+% #1 = point
+%
+% Sets the baseline of the picture to the y-coordinate of a given
+% point. However, the point will be evaluated *at the end of the
+% picture*.
+%
+% Example:
+%
+% \pgfsetbaselinepointlater{\pgfpointanchor{mynode}{base}}
+
+\def\pgfsetbaselinepointlater#1{\def\pgf@baseline{#1}}
+
+
+% Sets the baseline at the y-coordinate of a given point, now
+%
+% #1 = point
+%
+% Sets the baseline of the picture to the y-coordinate of a given
+% point.
+%
+% Example:
+%
+% \pgfsetbaselinepointnow{\pgfpoint{1cm}{2pt}}
+
+\def\pgfsetbaselinepointnow#1{%
+ \pgf@process{#1}%
+ \edef\pgf@setter@baseline{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfsetbaselinepointlater{\pgf@setter@baseline}%
+}
+
+\def\pgf@default@text{default}%
+
+% Sets the baseline
+%
+% #1 = baseline
+%
+% Sets the baseline of the picture. Default is the lower border, which
+% is the same as \pgf@picminy
+%
+% Example:
+%
+% \pgfsetbaseline{1cm+2pt}
+% \pgfsetbaseline{default}% resets to default value
+
+\def\pgfsetbaseline#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@default@text
+ \pgfsetbaseline{\pgf@picminy}%
+ \else
+ \pgfsetbaselinepointlater{\pgfpoint{0pt}{#1}}%
+ \fi
+}
+\pgfsetbaseline{\pgf@picminy}
+
+% controls how the image externalization implements trim:
+\newif\ifpgf@trim@lowlevel
+\pgfkeys{
+ /pgf/trim lowlevel/.is if=pgf@trim@lowlevel,
+ /pgf/trim lowlevel/.default=true,
+}
+
+% Same as the y-baseline for horizontal alignment.
+% The effect is different, though: it is some kind of trimming which
+% leaves the bounding box intact.
+\def\pgfsettrimleftpointlater#1{\def\pgf@trimleft{#1}}
+\def\pgfsettrimleftpointnow#1{%
+ \pgf@process{#1}%
+ \edef\pgf@setter@baseline{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfsettrimleftpointlater{\pgf@setter@baseline}%
+}
+% \pgfsettrimleft{<x coord>}
+% or
+% \pgfsettrimleft{default}
+\def\pgfsettrimleft#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@default@text
+ \pgfsettrimleft{\pgf@picminx}
+ \else
+ \pgfsettrimleftpointlater{\pgfpoint{#1}{0pt}}%
+ \fi
+}
+\pgfsettrimleft{\pgf@picminx}
+
+\def\pgfsettrimrightpointlater#1{\def\pgf@trimright{#1}}
+\def\pgfsettrimrightpointnow#1{%
+ \pgf@process{#1}%
+ \edef\pgf@setter@baseline{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfsettrimrightpointlater{\pgf@setter@baseline}%
+}
+% \pgfsettrimright{<x coord>}
+% or
+% \pgfsettrimright{default}
+\def\pgfsettrimright#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@default@text
+ \pgfsettrimright{\pgf@picmaxx}%
+ \else
+ \pgfsettrimrightpointlater{\pgfpoint{#1}{0pt}}%
+ \fi
+}
+\pgfsettrimright{\pgf@picmaxx}
+
+
+% Interrupt path
+%
+% Description:
+%
+% The environment can be used to insert some drawing commands while
+% constructing a path. The drawing commands inside the environment
+% will not interfere with the path being constructed ``outside.''
+% However, you must ward against graphic state changes using a scope.
+%
+% Example: Draw two parallel lines
+%
+% \pgfmoveto{\pgfpoint{0cm}{0cm}}
+% \begin{pgfinterruptpath}
+% \pgfmoveto{\pgfpoint{1cm}{0cm}}
+% \pgfmoveto{\pgfpoint{1cm}{1cm}}
+% \pgfusepath{stroke}
+% \end{pgfinterruptpath}
+% \pgflineto{\pgfpoint{0cm}{1cm}}
+% \pgfusepath{stroke}
+
+\def\pgfinterruptpath
+{%
+ \begingroup%
+ % save all sorts of things...
+ \edef\pgf@interrupt@savex{\the\pgf@path@lastx}%
+ \edef\pgf@interrupt@savey{\the\pgf@path@lasty}%
+ \pgf@getpathsizes\pgf@interrupt@pathsizes%
+ \pgfsyssoftpath@getcurrentpath\pgf@interrupt@path%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ \let\pgf@interrupt@lastmoveto=\pgfsyssoftpath@lastmoveto%
+ \begingroup%
+}
+\def\endpgfinterruptpath
+{%
+ \endgroup%
+ \pgfsyssoftpath@setcurrentpath\pgf@interrupt@path%
+ \pgf@setpathsizes\pgf@interrupt@pathsizes%
+ \global\pgf@path@lastx\pgf@interrupt@savex%
+ \global\pgf@path@lasty\pgf@interrupt@savey%
+ \global\let\pgfsyssoftpath@lastmoveto\pgf@interrupt@lastmoveto%
+ \endgroup%
+}
+
+
+
+% Interrupt bounding box
+%
+% Description:
+%
+% The environment can be used to temporarily setup a new bounding box
+% computation. The bounding box will be made empty at the beginning of
+% the environment and will be reset to its old value after the
+% environment.
+%
+% Example:
+%
+% \begin{pgfinterruptboundinbox}
+% \pgfmoveto{\pgfpoint{1cm}{0cm}}
+% \pgfmoveto{\pgfpoint{1cm}{1cm}}
+% \pgfusepath{stroke}
+% \end{pgfinterruptboundinbox}
+
+\def\pgfinterruptboundingbox
+{%
+ \begingroup%
+ \edef\pgf@interrupt@savemaxx{\the\pgf@picmaxx}%
+ \edef\pgf@interrupt@saveminx{\the\pgf@picminx}%
+ \edef\pgf@interrupt@savemaxy{\the\pgf@picmaxy}%
+ \edef\pgf@interrupt@saveminy{\the\pgf@picminy}%
+ \pgf@picmaxx=-16000pt\relax%
+ \pgf@picminx=16000pt\relax%
+ \pgf@picmaxy=-16000pt\relax%
+ \pgf@picminy=16000pt\relax%
+ \pgf@size@hookedfalse%
+ \let\pgf@path@size@hook=\pgfutil@empty%
+}
+\def\endpgfinterruptboundingbox
+{%
+ \global\pgf@picmaxx=\pgf@interrupt@savemaxx%
+ \global\pgf@picmaxy=\pgf@interrupt@savemaxy%
+ \global\pgf@picminx=\pgf@interrupt@saveminx%
+ \global\pgf@picminy=\pgf@interrupt@saveminy%
+ \endgroup%
+}
+
+
+
+
+% Creates an id scope.
+%
+% Description:
+%
+% An id scope is not (conceptually) a graphic scope, but a scope that
+% has a unique name or "id". This id can be used as a reference point
+% for instance for a hyperlink or for an animation (currently, only
+% SVG supports ids, all other drivers ignore id scopes).
+%
+% Prior to using \pgfidscope, call \pgfuseid to install an
+% id (and possibly \pgfusetype). The scope will then get this id and,
+% likely, a graphic scope is installed. If \pgfuseid has not been
+% called or if you try to call \pgfidscope again for the same id,
+% nothing happens (except for a \TeX\ group being established).
+
+\def\pgfidscope{\pgfsys@begin@idscope}
+\def\endpgfidscope{\pgfsys@end@idscope}
+
+\let\startpgfidscope\pgfidscope
+\let\stoppgfidscope\pgfendidscope
+
+
+
+
+% Use an id on the next graphic object
+%
+% #1 = a name
+%
+% The next scope or path can be the target of an animation command or
+% a hyperlink.
+
+\def\pgfuseid#1{%
+ \edef\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgf@lookup@id{#1}%
+ \pgfsys@use@id{\pgf@next@id}%
+ \expandafter\xdef\csname pgf@id@names@#1\endcsname{{\pgf@next@id}{}}%
+ \fi%
+}
+
+\def\pgf@lookup@id#1{%
+ \expandafter\let\expandafter\pgf@id@name\csname pgf@id@names@#1\endcsname%
+ \ifx\pgf@id@name\relax%
+ \let\pgf@prev@id\pgfutil@empty%
+ \let\pgf@next@id\pgfutil@empty%
+ \else%
+ \expandafter\pgf@id@parse\pgf@id@name%
+ \fi%
+ \ifx\pgf@next@id\pgfutil@empty%
+ \pgfsys@new@id\pgf@next@id%
+ \expandafter\xdef\csname pgf@id@names@#1\endcsname{{\pgf@prev@id}{\pgf@next@id}}%
+ \fi%
+}
+\def\pgf@id@parse#1#2{%
+ \def\pgf@prev@id{#1}%
+ \def\pgf@next@id{#2}%
+}
+
+
+
+% Clear the current id
+%
+% Description:
+%
+% Sets the current id to be empty so that it cannot be referenced.
+
+\def\pgfclearid{%
+ \pgfsys@clear@id%
+}
+
+
+% Get the id that will be given to a name upon the next use
+%
+% #1 = a macro
+% #2 = a name
+%
+% Description:
+%
+% #1 will get the id that will be used by \pgfuseid next time for the
+% given name.
+
+\def\pgfidrefnextuse#1#2{%
+ \edef\pgf@temp{#2}\ifx\pgf@temp\pgfutil@empty\pgferror{Missing name reference for ``\string#1''}\fi%
+ \pgf@lookup@id{#2}%
+ \let#1\pgf@next@id%
+}
+
+
+% Get the id was last used
+%
+% #1 = a macro
+% #2 = a name
+%
+% Description:
+%
+% #1 will get the id that was last used by \pgfuseid for #2.
+
+\def\pgfidrefprevuse#1#2{%
+ \edef\pgf@temp{#2}\ifx\pgf@temp\pgfutil@empty\pgferror{Missing name reference for ``\string#1''}\fi%
+ \pgf@lookup@id{#2}%
+ \let#1\pgf@prev@id%
+}
+
+
+% Use a type
+%
+% #1 = an id type; when starting with a dot, it is added to the
+% current type.
+%
+% The next scope or path can be the target of an animation command or
+% a hyperlink.
+
+\def\pgfusetype#1{%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutil@ifnextchar\expandafter.\expandafter\pgf@id@use@type@add\expandafter\pgf@id@use@type@replace\pgf@temp\pgf@stop
+}
+\def\pgf@id@use@type@add.#1\pgf@stop{\pgfsys@append@type{#1}}
+\def\pgf@id@use@type@replace#1\pgf@stop{\pgfsys@use@type{#1}}
+
+% Push the current type on a global stack
+%
+% Description:
+%
+% The current type is pushed onto a global type stack. It can be
+% restored using \pgfpoptype.
+
+\def\pgfpushtype{\pgfsys@push@type}
+
+
+% Pop a type from the type stack
+%
+% Description:
+%
+% Restores the most current value from the type stack.
+
+\def\pgfpoptype{\pgfsys@pop@type}
+
+
+
+
+% Alias an id locally or globally
+%
+% #1 = the alias name
+% #2 = a existing id name
+%
+% Description:
+%
+% Creates an alias of a name
+
+\def\pgfaliasid#1#2{%
+ \expandafter\let\expandafter\pgf@temp\csname pgf@id@names@#2\endcsname%
+ \expandafter\let\csname pgf@id@names@#1\endcsname\pgf@temp%
+}
+\def\pgfgaliasid#1#2{%
+ \expandafter\let\expandafter\pgf@temp\csname pgf@id@names@#2\endcsname%
+ \expandafter\global\expandafter\let\csname pgf@id@names@#1\endcsname\pgf@temp%
+}
+
+
+% Check whether a name has been forward-referenced
+%
+% #1 = a name
+% #2 = what to do, when has been forward-referenced
+% #3 = what to do otherwise
+%
+% Description:
+%
+% Depending on whether #1 has been forward-referenced, #2 or #3 will be executed.
+
+\def\pgfifidreferenced#1#2#3{%
+ \expandafter\let\expandafter\pgf@id@name\csname pgf@id@names@#1\endcsname%
+ \ifx\pgf@id@name\relax%
+ #3%
+ \else
+ \expandafter\pgf@id@parse\pgf@id@name%
+ \ifx\pgf@next@id\pgfutil@empty%
+ #3%
+ \else%
+ #2%
+ \fi%
+ \fi%
+}
+
+
+% Interrupts a picture
+%
+% Description:
+%
+% This environment interrupts a picture and temporarily returns to
+% normal TeX mode. All sorts of things are saved and restored by this
+% environment.
+%
+% WARNING: Using this environment in conjunction with low level
+% transformations can *strongly* upset the typesetting. Typically, the
+% contents of this environment should have size/height/depth 0pt in
+% the end.
+%
+% WARNING: This environment should only be used inside typesetting a
+% box and this box must in turn be inserted using \pgfqbox.
+%
+% Example: Draw two parallel lines
+%
+% \pgfmoveto{\pgfpoint{0cm}{0cm}}
+% \setbox\mybox=\hbox{
+% \begin{pgfinterruptpicture}
+% This is normal text.
+% \begin{pgfpicture} % a subpicture
+% \pgfmoveto{\pgfpoint{1cm}{0cm}}
+% \pgfmoveto{\pgfpoint{1cm}{1cm}}
+% \pgfusepath{stroke}
+% \end{pgfpicture}
+% More text.
+% \end{pgfinterruptpicture}
+% }
+% \ht\mybox=0pt
+% \wd\mybox=0pt
+% \dp\mybox=0pt
+% \pgfqbox{\mybox}%
+% \pgfpathlineto{\pgfpoint{0cm}{1cm}}
+% \pgfusepath{stroke}
+
+\def\pgfinterruptpicture
+{%
+ \begingroup%
+ \csname tikz@inside@picturefalse\endcsname%
+ \pgfinterruptboundingbox%
+ \pgftransformreset%
+ \pgfinterruptpath%
+ \ifx\pgf@selectfontorig\@undefined%
+ \else%
+ \let\setlength\pgf@setlengthorig%
+ \let\addtolength\pgf@addtolengthorig%
+ \let\selectfont\pgf@selectfontorig%
+ \fi%
+ \pgfutil@selectfont%
+ \pgfpicturefalse%
+ \let\pgf@positionnodelater@macro\relax%
+ \pgf@savelayers%
+}
+\def\endpgfinterruptpicture
+{%
+ \pgf@restorelayers%
+ \endpgfinterruptpath%
+ \endpgfinterruptboundingbox%
+ \endgroup%
+}
+
+\let\pgf@savelayers=\relax
+\let\pgf@restorelayers=\relax
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcoreshade.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreshade.code.tex
new file mode 100644
index 0000000000..39a40c54ee
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcoreshade.code.tex
@@ -0,0 +1,974 @@
+% Copyright 2019 by Till Tantau
+% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcoreshade.code.tex}
+
+%
+% Parsing functions
+%
+\newdimen\pgf@max
+\newcount\pgf@sys@shading@range@num
+\def\pgf@parsefunc#1{%
+ \edef\temp{{#1}}%
+ \expandafter\pgf@convertstring\temp%
+ \edef\temp{{\pgf@conv}}%
+ \expandafter\pgf@@parsefunc\temp}
+\def\pgf@@parsefunc#1{%
+ \let\pgf@bounds=\pgfutil@empty%
+ \let\pgf@funcs=\pgfutil@empty%
+ \let\pgf@psfuncs=\pgfutil@empty%
+ \let\pgf@encode=\pgfutil@empty%
+ \let\pgf@sys@shading@ranges=\pgfutil@empty%
+ \pgf@sys@shading@range@num=0\relax%
+ \csname pgf@parsefirst\pgf@shading@model\endcsname[#1; ]%
+ \csname pgf@parselastdom\pgf@shading@model\endcsname[#1; ]%
+ \csname pgf@parsemid\pgf@shading@model\endcsname[#1; ]%
+ \ifx\pgf@bounds\pgfutil@empty%
+ \edef\pgf@pdfparseddomain{0 1}%
+ \edef\pgf@pdfparsedfunction{\pgf@singlefunc\space}%
+ \else%
+ \edef\pgf@pdfparseddomain{\pgf@doma\space\pgf@domb}%
+ \edef\pgf@pdfparsedfunction{%
+ << /FunctionType 3 /Domain [\pgf@doma\space\pgf@domb] /Functions
+ [\pgf@funcs\space] /Bounds [\pgf@bounds] /Encode [0 1 \pgf@encode]
+ >> }% <<
+ \fi%
+ \xdef\pgf@psfuncs{\pgf@psfuncs}%
+ }
+\def\pgf@parsefirstrgb[rgb(#1)=(#2,#3,#4)#5]{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@start@pos{\the\pgf@x}%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@doma{\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
+ \edef\pgf@sys@shading@start@rgb{\pgf@sys@rgb}%
+ \let\pgf@sys@prevcolor=\pgf@sys@shading@start@rgb%
+ \let\pgf@sys@prevpos=\pgf@sys@shading@start@pos%
+ \edef\pgf@prevcolor{\pgf@rgb}%
+ \edef\pgf@firstcolor{\pgf@rgb}}
+\def\pgf@parselastdomrgb[rgb(#1)=(#2,#3,#4); {%
+ \pgfutil@ifnextchar]{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@end@pos{\the\pgf@x}%
+ \pgf@max=\pgf@x\relax%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@domb{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
+ \edef\pgf@sys@shading@end@rgb{\pgf@sys@rgb}%
+ \pgfutil@gobble}{\pgf@parselastdomrgb[}}
+\def\pgf@parsemidrgb[rgb(#1)=(#2,#3,#4); {\pgf@parserestrgb[}
+\def\pgf@parserestrgb[rgb(#1)=(#2,#3,#4); {%
+ \advance\pgf@sys@shading@range@num by1\relax%
+ \pgfutil@ifnextchar]{%
+ \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
+ \edef\pgf@singlefunc{\space%
+ << /FunctionType 2 /Domain [0 1] /C0
+ [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
+ \edef\pgf@funcs{\pgf@funcs\space%
+ << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
+ [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
+ \edef\pgf@psfuncs{\pgf@prevx\space \pgf@rgb\space \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{{\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@rgb}}}%
+ \edef\pgf@sys@prevpos{\the\pgf@x}%
+ \let\pgf@sys@prevcolor=\pgf@sys@rgb%
+ \pgfutil@gobble}{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgf@getrgbtuplewithmixin{#2}{#3}{#4}%
+ \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{{\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@rgb}}}%
+ \edef\pgf@sys@prevpos{\the\pgf@x}%
+ \let\pgf@sys@prevcolor=\pgf@sys@rgb%
+ \edef\pgf@psfuncs{\pgf@prevx\space \pgf@rgb\space \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@bounds{\pgf@bounds\space\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@encode{\pgf@encode\space0 1}%
+ \edef\pgf@singlefunc{\space%
+ << /FunctionType 2 /Domain [0 1] /C0
+ [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
+ \edef\pgf@funcs{\pgf@funcs\space%
+ << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
+ [\pgf@prevcolor] /C1 [\pgf@rgb] /N 1 >> }% <<
+ \edef\pgf@prevcolor{\pgf@rgb}%
+ \pgf@parserestrgb[}}
+
+\def\pgf@getrgbtuplewithmixin#1#2#3{%
+ \pgfutil@definecolor{pgfshadetemp}{rgb}{#1,#2,#3}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfshadetemp}}%
+ \pgfutil@extractcolorspec{pgfshadetemp}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
+ \expandafter\pgf@getrgb@@\pgf@rgbcolor!}
+\def\pgf@getrgb@@#1,#2,#3!{%
+ \def\pgf@rgb{#1 #2 #3}%
+ \def\pgf@sys@rgb{{#1}{#2}{#3}}%
+}
+
+\def\pgf@parsefirstcmyk[cmyk(#1)=(#2,#3,#4,#5)#6]{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@start@pos{\the\pgf@x}%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@doma{\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@getcmyktuplewithmixin{#2}{#3}{#4}{#5}%
+ \edef\pgf@sys@shading@start@cmyk{\pgf@sys@cmyk}%
+ \let\pgf@sys@prevcolor=\pgf@sys@shading@start@cmyk%
+ \let\pgf@sys@prevpos=\pgf@sys@shading@start@pos%
+ \edef\pgf@prevcolor{\pgf@cmyk}%
+ \edef\pgf@firstcolor{\pgf@cmyk}}
+\def\pgf@parselastdomcmyk[cmyk(#1)=(#2,#3,#4,#5); {%
+ \pgfutil@ifnextchar]{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@end@pos{\the\pgf@x}%
+ \pgf@max=\pgf@x\relax%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@domb{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@getcmyktuplewithmixin{#2}{#3}{#4}{#5}%
+ \edef\pgf@sys@shading@end@cmyk{\pgf@sys@cmyk}%
+ \pgfutil@gobble}{\pgf@parselastdomcmyk[}}
+\def\pgf@parsemidcmyk[cmyk(#1)=(#2,#3,#4,#5); {\pgf@parserestcmyk[}
+\def\pgf@parserestcmyk[cmyk(#1)=(#2,#3,#4,#5); {%
+ \advance\pgf@sys@shading@range@num by1\relax%
+ \pgfutil@ifnextchar]{%
+ \pgf@getcmyktuplewithmixin{#2}{#3}{#4}{#5}%
+ \edef\pgf@singlefunc{\space%
+ << /FunctionType 2 /Domain [0 1] /C0
+ [\pgf@prevcolor] /C1 [\pgf@cmyk] /N 1 >> }% <<
+ \edef\pgf@funcs{\pgf@funcs\space%
+ << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
+ [\pgf@prevcolor] /C1 [\pgf@cmyk] /N 1 >> }% <<
+ \edef\pgf@psfuncs{\pgf@prevx\space
+ \pgf@cmyk\space \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{%
+ {\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@cmyk}}}%
+ \edef\pgf@sys@prevpos{\the\pgf@x}%
+ \let\pgf@sys@prevcolor=\pgf@sys@cmyk%
+ \pgfutil@gobble}{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgf@getcmyktuplewithmixin{#2}{#3}{#4}{#5}%
+ \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{%
+ {\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@cmyk}}}%
+ \edef\pgf@sys@prevpos{\the\pgf@x}%
+ \let\pgf@sys@prevcolor=\pgf@sys@cmyk%
+ \edef\pgf@psfuncs{\pgf@prevx\space \pgf@cmyk\space
+ \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@bounds{\pgf@bounds\space\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@encode{\pgf@encode\space0 1}%
+ \edef\pgf@singlefunc{\space%
+ << /FunctionType 2 /Domain [0 1] /C0
+ [\pgf@prevcolor] /C1 [\pgf@cmyk] /N 1 >> }% <<
+ \edef\pgf@funcs{\pgf@funcs\space%
+ << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
+ [\pgf@prevcolor] /C1 [\pgf@cmyk] /N 1 >> }% <<
+ \edef\pgf@prevcolor{\pgf@cmyk}%
+ \pgf@parserestcmyk[}}
+
+\def\pgf@getcmyktuplewithmixin#1#2#3#4{%
+ \pgfutil@definecolor{pgfshadetemp}{cmyk}{#1,#2,#3,#4}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfshadetemp}}%
+ \pgfutil@extractcolorspec{pgfshadetemp}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{cmyk}{\pgf@cmykcolor}%
+ \expandafter\pgf@getcmyk@@\pgf@cmykcolor!}
+\def\pgf@getcmyk@@#1,#2,#3,#4!{%
+ \def\pgf@cmyk{#1 #2 #3 #4}%
+ \def\pgf@sys@cmyk{{#1}{#2}{#3}{#4}}%
+}
+
+\def\pgf@parsefirstgray[gray(#1)=(#2)#3]{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@start@pos{\the\pgf@x}%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@doma{\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@getgraytuplewithmixin{#2}%
+ \edef\pgf@sys@shading@start@gray{\pgf@sys@gray}%
+ \let\pgf@sys@prevcolor=\pgf@sys@shading@start@gray%
+ \let\pgf@sys@prevpos=\pgf@sys@shading@start@pos%
+ \edef\pgf@prevcolor{\pgf@gray}%
+ \edef\pgf@firstcolor{\pgf@gray}}
+\def\pgf@parselastdomgray[gray(#1)=(#2); {%
+ \pgfutil@ifnextchar]{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@end@pos{\the\pgf@x}%
+ \pgf@max=\pgf@x\relax%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@domb{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@getgraytuplewithmixin{#2}%
+ \edef\pgf@sys@shading@end@gray{\pgf@sys@gray}%
+ \pgfutil@gobble}{\pgf@parselastdomgray[}}
+\def\pgf@parsemidgray[gray(#1)=(#2); {\pgf@parserestgray[}
+\def\pgf@parserestgray[gray(#1)=(#2); {%
+ \advance\pgf@sys@shading@range@num by1\relax%
+ \pgfutil@ifnextchar]{%
+ \pgf@getgraytuplewithmixin{#2}%
+ \edef\pgf@singlefunc{\space%
+ << /FunctionType 2 /Domain [0 1] /C0
+ [\pgf@prevcolor] /C1 [\pgf@gray] /N 1 >> }% <<
+ \edef\pgf@funcs{\pgf@funcs\space%
+ << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
+ [\pgf@prevcolor] /C1 [\pgf@gray] /N 1 >> }% <<
+ \edef\pgf@psfuncs{\pgf@prevx\space \pgf@gray\space
+ \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
+ \pgfmathsetlength\pgf@x{#1}%
+ \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{%
+ {\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@gray}}}%
+ \edef\pgf@sys@prevpos{\the\pgf@x}%
+ \let\pgf@sys@prevcolor=\pgf@sys@gray%
+ \pgfutil@gobble}{%
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgf@getgraytuplewithmixin{#2}%
+ \edef\pgf@sys@shading@ranges{\pgf@sys@shading@ranges{%
+ {\pgf@sys@prevpos}{\the\pgf@x}{\pgf@sys@prevcolor}{\pgf@sys@gray}}}%
+ \edef\pgf@sys@prevpos{\the\pgf@x}%
+ \let\pgf@sys@prevcolor=\pgf@sys@gray%
+ \edef\pgf@psfuncs{\pgf@prevx\space \pgf@gray\space
+ \pgf@prevcolor\space pgfshade \pgf@psfuncs}%
+ \pgf@sys@bp@correct\pgf@x%
+ \edef\pgf@prevx{\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@bounds{\pgf@bounds\space\pgf@sys@tonumber{\pgf@x}}%
+ \edef\pgf@encode{\pgf@encode\space0 1}%
+ \edef\pgf@singlefunc{\space%
+ << /FunctionType 2 /Domain [0 1] /C0
+ [\pgf@prevcolor] /C1 [\pgf@gray] /N 1 >> }% <<
+ \edef\pgf@funcs{\pgf@funcs\space%
+ << /FunctionType 2 /Domain [\pgf@doma\space\pgf@domb] /C0
+ [\pgf@prevcolor] /C1 [\pgf@gray] /N 1 >> }% <<
+ \edef\pgf@prevcolor{\pgf@gray}%
+ \pgf@parserestgray[}}
+
+\def\pgf@getgraytuplewithmixin#1{%
+ \pgfutil@definecolor{pgfshadetemp}{gray}{#1}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfshadetemp}}%
+ \pgfutil@extractcolorspec{pgfshadetemp}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{gray}{\pgf@graycolor}%
+ \expandafter\pgf@getgray@@\pgf@graycolor!}
+\def\pgf@getgray@@#1!{%
+ \def\pgf@gray{#1}%
+ \def\pgf@sys@gray{{#1}}%
+}
+
+% Normalized a <color specification> argument for shadings into a
+% series of color specifications in the current xcolor color model and write
+% the result into \pgf@conv.
+%
+% Example:
+% \pgf@convertstring{rgb(0cm)=(1,0,0); rgb(2cm)=(0,1,0); cmyk(4cm)=(1,0,0,0); gray(1cm)=(3); color(2cm)=(green); }
+% ->
+% \pgf@conv = macro:->'rgb(0cm)=(1,0,0); rgb(2cm)=(0,1,0); rgb(4cm)=(0,1,1); rgb(1cm)=(3,3,3); rgb(2cm)=(0,1,0); '
+\def\pgf@convertstring#1{%
+ \def\pgf@conv{}%
+ \pgf@convert#1]%
+ }
+\def\pgf@convert{%
+ \pgfutil@ifnextchar]{\pgfutil@gobble}%done!
+ {%
+ \pgfutil@ifnextchar;{\pgf@grabsemicolor}%
+ {%
+ \pgfutil@ifnextchar c{\pgf@gobblec}%
+ {%
+ \pgfutil@ifnextchar g{\pgf@grabgray}%
+ {%
+ \pgfutil@ifnextchar o{\pgf@grabcolor}%
+ {%
+ \pgfutil@ifnextchar m{\pgf@grabcmyk}%
+ {%
+ \pgfutil@ifnextchar r{\pgf@grabrgb}%
+ {\pgferror{Illformed shading
+ specification}\pgf@convert}%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+}
+\def\pgf@savecolor#1{%
+ \pgfutil@extractcolorspec{pgf@tempcol}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor
+ {\pgf@shading@model}{\pgf@color}%
+ \expandafter\pgf@convget@\expandafter{\pgf@color}{#1}%
+}
+\def\pgf@grabsemicolor;{%
+ \edef\pgf@conv{\pgf@conv; }\pgf@convert}
+\def\pgf@gobblec c{\pgf@convert}
+\def\pgf@grabrgb rgb(#1)=(#2,#3,#4){%
+ \pgfutil@definecolor{pgf@tempcol}{rgb}{#2,#3,#4}%
+ \pgf@savecolor{#1}%
+}
+\def\pgf@grabcmyk myk(#1)=(#2,#3,#4,#5){%
+ \pgfutil@definecolor{pgf@tempcol}{cmyk}{#2,#3,#4,#5}%
+ \pgf@savecolor{#1}%
+}
+\def\pgf@grabgray gray(#1)=(#2){%
+ \pgfutil@definecolor{pgf@tempcol}{gray}{#2}%
+ \pgf@savecolor{#1}%
+}
+\def\pgf@grabcolor olor(#1)=(#2){%
+ \pgfutil@colorlet{pgf@tempcol}{#2}%
+ \pgf@savecolor{#1}%
+}
+\def\pgf@convget@#1#2{%
+ \edef\pgf@conv{\pgf@conv \pgf@shading@model(#2)=(#1)}\pgf@convert}
+
+
+\newcount\pgf@shadingcount
+\pgf@shadingcount=0
+{
+ \catcode`\/=0
+ \catcode`\\=12
+ /gdef/pgf@shadingnum{\/the/pgf@shadingcount\}
+}
+
+% Set up shading properties based on the current xcolor color model. This is
+% called when shadings are declared and used. \ifpgfshadingmodelrgb,
+% \ifpgfshadingmodelcmyk, and \ifpgfshadingmodelgray are set so that the type
+% 4 function in functional shadings can be converted to the current color
+% model. See \pgffuncshading*to* macros.
+
+\newif\ifpgfshadingmodelrgb
+\newif\ifpgfshadingmodelcmyk
+\newif\ifpgfshadingmodelgray
+\def\pgf@setup@shading@model{%
+ \pgfshadingmodelrgbtrue
+ \pgfshadingmodelcmykfalse
+ \pgfshadingmodelgrayfalse
+ \XC@sdef\pgf@mod@test{\XC@tgt@mod{natural}}%
+ \def\pgf@shading@device{/DeviceRGB}%
+ \def\pgf@shading@ps@device{setrgbcolor}%
+ \def\pgf@shading@functional@range{0 1 0 1 0 1}%
+ \def\pgf@shading@model{rgb}%
+ \ifx\pgf@mod@test\XC@mod@cmyk
+ \def\pgf@shading@device{/DeviceCMYK}%
+ \def\pgf@shading@ps@device{setcmykcolor}%
+ \def\pgf@shading@functional@range{0 1 0 1 0 1 0 1}%
+ \def\pgf@shading@model{cmyk}%
+ \pgfshadingmodelrgbfalse
+ \pgfshadingmodelcmyktrue
+ \fi
+ \ifx\pgf@mod@test\XC@mod@gray
+ \def\pgf@shading@device{/DeviceGray}%
+ \def\pgf@shading@ps@device{setgray}%
+ \def\pgf@shading@functional@range{0 1}%
+ \def\pgf@shading@model{gray}%
+ \pgfshadingmodelrgbfalse
+ \pgfshadingmodelgraytrue
+ \fi
+ \edef\pgf@sys@driver@dvisvgm{pgfsys-dvisvgm.def}%
+ \ifx\pgfsysdriver\pgf@sys@driver@dvisvgm
+ \def\pgf@shading@model{rgb}%
+ \fi
+ \edef\pgf@sys@driver@texforht{pgfsys-tex4ht.def}%
+ \ifx\pgfsysdriver\pgf@sys@driver@texforht
+ \def\pgf@shading@model{rgb}%
+ \fi
+}
+
+
+% Declares a horizontal shading for later use. The shading is a
+% horizontal bar that changes its color.
+%
+% #1 = optional dependencies
+% #2 = name of the shading for later use
+% #3 = height of the shading
+% #4 = color specification in the following format: A list of colors
+% that the bar should have at certain points. If the bar should
+% be red at 1cm, this is specified as
+% "rgb(1cm)=(1,0,0)". Multiple specifications are separated by a
+% semicolon and a space. At least two specifications must be
+% given. The specified positions must be given in increasing
+% order.
+%
+% Description:
+%
+% The optional dependencies have the following effect: If present, it
+% should consist of a list of colors, separated by commas. Each time
+% the shading is used, these colors will be reevaluated. It will be
+% checked whether the colors still have their "original meaning". If
+% the colors have changed, a new shading will be created internally to
+% reflect the changed color's values.
+%
+% Example:
+%
+% \pgfdeclarehorizontalshading{redtogreentoblue}{1cm}{%
+% rgb(0cm)=(1,0,0); % red
+% rgb(1cm)=(0,1,0); % green
+% rgb(2cm)=(0,0,1)}
+%
+% \begin{document}
+% The following bar is 2cm long: \pgfuseshading{redtogreentoblue}.
+% \end{document}
+
+\def\pgfdeclarehorizontalshading{%
+ \pgf@setup@shading@model
+ \pgfutil@ifnextchar[%
+ \pgf@declarehorizontalshading{\pgf@declarehorizontalshading[]}}
+\def\pgf@declarehorizontalshading[#1]#2#3#4{%
+ \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
+ \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
+ \global\expandafter\let\csname pgf@num@pgfshading#2!\endcsname\pgfutil@empty
+ \pgfsys@horishading{#2}{#3}{#4}%
+ \else%
+ \global\advance\pgf@shadingcount 1\relax
+ \global\expandafter\edef\csname pgf@num@pgfshading#2!\endcsname{\pgf@shadingnum}%
+ \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfsys@horishading}%
+ \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}}%
+ \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
+ \fi}
+
+
+% Declares a vertical shading for later use.
+%
+% #1 = optional dependencies
+% #2 = name of the shading for later use
+% #3 = height of the shading
+% #4 = color specification
+%
+% Example:
+%
+% \pgfdeclareverticalshading{redtogreentoblue}{1cm}{%
+% rgb(0cm)=(1,0,0); % red
+% rgb(1cm)=(0,1,0); % green
+% rgb(2cm)=(0,0,1)}
+%
+% \begin{document}
+% The following bar is 2cm high: \pgfuseshading{redtogreentoblue}.
+% \end{document}
+
+\def\pgfdeclareverticalshading{%
+ \pgf@setup@shading@model
+ \pgfutil@ifnextchar[%
+ \pgf@declareverticalshading{\pgf@declareverticalshading[]}}
+\def\pgf@declareverticalshading[#1]#2#3#4{%
+ \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
+ \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
+ \global\expandafter\let\csname pgf@num@pgfshading#2!\endcsname=\pgfutil@empty
+ \pgfsys@vertshading{#2}{#3}{#4}%
+ \else%
+ \global\advance\pgf@shadingcount 1\relax
+ \global\expandafter\edef\csname pgf@num@pgfshading#2!\endcsname{\pgf@shadingnum}%
+ \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfsys@vertshading}%
+ \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}}%
+ \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
+ \fi}
+
+
+% Declares a radial shading for later use.
+%
+% #1 = optional dependencies
+% #2 = name of the shading for later use
+% #3 = center of inner circle
+% #4 = color specification
+%
+% Description:
+%
+% A radial shading creates a smooth color transition between two
+% circles. The center of the inner circle is at the give position. Its
+% radius is the start of the color specification. The
+% center of the outer circle is at the center of the whole shading,
+% whose radius is the end of the color specification. For example,
+% suppose the color specification is "rgb(1cm)=(1,1,1); rgb(2cm)=(0,0,0)".
+% Then the shading would be 4cm times 4cm large. The inner circle would
+% have diameter 1cm and the outer circle would have diameter 2cm. The
+% outer circle would be centered in the middle of the shading, whereas
+% the outer circle would be centered at the given position.
+%
+% Example:
+%
+% \pgfdeclareradialshading{redtogreentoblue}{\pgfpoint{2cm}{2cm}}{%
+% rgb(10pt)=(1,0,0); % red
+% rgb(2cm)=(0,1,0); % green
+% rgb(3cm)=(0,0,1)}
+%
+% \begin{document}
+% The following ball has diameter 3cm: \pgfuseshading{redtogreentoblue}.
+% \end{document}
+
+\def\pgfdeclareradialshading{%
+ \pgf@setup@shading@model
+ \pgfutil@ifnextchar[%
+ \pgf@declareradialshading{\pgf@declareradialshading[]}}
+\def\pgf@declareradialshading[#1]#2#3#4{%
+ \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
+ \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
+ \global\expandafter\let\csname pgf@num@pgfshading#2!\endcsname=\pgfutil@empty
+ \pgfsys@radialshading{#2}{#3}{#4}%
+ \else%
+ \global\advance\pgf@shadingcount 1\relax
+ \global\expandafter\edef\csname pgf@num@pgfshading#2!\endcsname{\pgf@shadingnum}%
+ \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfsys@radialshading}%
+ \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}}%
+ \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
+ \fi}
+
+
+
+
+% Declares a functional shading for later use.
+%
+% #1 = optional dependencies
+% #2 = name of the shading for later use
+% #3 = lower left corner of the shading as a pgfpoint.
+% #4 = upper right corner of the shading as a pgfpoint.
+% #5 = Preparation code
+% #6 = a PDF type 4 function (restricted Postscript function), see the
+% PDF-specification 1.7, section 3.9.4
+%
+% Description:
+%
+% This command creates a so-called functional shading. For such a
+% shading the color of each point is calculated by calling a function
+% for each point that gets the coordinates as input and yields the
+% color as an output. Note that the function is evaluated by the
+% *renderer*, not by PGF or TeX or someone else at compile-time. This
+% means that the evaluation of this function has to be done *extremely
+% quickly* and the function should be *very simple*. For this reason,
+% only a very restricted set of operations are possible in the
+% function (see 3.9.4 of the PDF-spec 1.7). Also functions should be
+% kept small. Any errors in the function will only be noticed by the
+% renderer.
+%
+% The function gets the coordinates of a point as input (as bp). This
+% input consists of the top two elements of an otherwise empty
+% (virtual, PostScript) stack. The function should then replace these
+% two values by one value representing the gray color of the point for a
+% grayscale shading, three values, representing the red, green, and blue color
+% of the point for an RGB shading, or four values, representing the cyan,
+% magenta, yellow, and black color of the point for a CMYK shading. The
+% numbers should be real values, not integers since Apple's PDF renderer is
+% broken in this regard (use cvr at the end if necessary).
+%
+% Conceptually, the function will be evaluated once for each point of
+% the rectangle (#3) to (#4). A renderer may choose to evaluate the
+% function at less points, but, in principle, the function will be
+% evaluated for each pixel independently.
+%
+% Because of the rather difficult PostScript syntax, use this macro
+% only *if you know what you are doing* (or if you are adventurous, of
+% course).
+%
+% As for other shadings, the optional dependencies argument is used to
+% determine whether a shading needs to be recalculated when a color
+% has changed.
+%
+% The code #5 is executed each time a shading is
+% (re)calculated. Typically, it will contain code to extract
+% coordinates from colors (see below).
+%
+% Inside the PostScript function #6 you cannot use colors
+% directly. Rather, you must push the color components on the
+% stack. For this, it is useful to call \pgfshadecolortorgb,
+% \pgfshadecolortocmyk, or \pgfshadecolortogray in the startup
+% code #4. The macro takes a color name as input and stores the color's
+% component real numbers between 0.0 and 1.0 separated
+% by spaces (which is exactly what you need if you want to push it on
+% a stack) in a macro.
+%
+% Example:
+%
+%\pgfdeclarefunctionalshading{twospots}{\pgfpointorigin}{\pgfpoint{200bp}{200bp}}{}{
+% 2 copy
+% 90 sub dup mul exch
+% 80 sub dup mul add sqrt
+% dup mul neg 1.0005 exch exp 1.0 exch sub
+% 3 1 roll
+% 120 sub dup mul exch
+% 100 sub dup mul add sqrt
+% dup mul neg 1.002 exch exp 1.0 exch sub
+% 1.0
+%}
+%
+% \pgfdeclarefunctionalshading[mycol]{sweep}{\pgfpointorigin}{\pgfpoint{100bp}{100bp}}
+% {\pgfshadecolortorgb{mycol}{\myrgb}}{
+% add 150 div % not very useful...
+% dup
+% \myrgb % push mycol
+% 5 4 roll % multiply all components by calculated value
+% mul
+% 3 1 roll
+% 3 index
+% mul
+% 3 1 roll
+% 4 3 roll
+% mul
+% 3 1 roll
+% }
+%
+% \begin{document}
+% Have a look at this: \pgfuseshading{twospots}.
+% Here is \colorlet{mycol}{green!50}\pgfuseshading{sweep} in green
+% and in \colorlet{mycol}{red!50!blue}\pgfuseshading{sweep} in red/blue.
+% \end{document}
+
+\def\pgfdeclarefunctionalshading{%
+ \pgf@setup@shading@model
+ \pgfutil@ifnextchar[%
+ \pgf@declarefunctionalshading{\pgf@declarefunctionalshading[]}}
+\def\pgf@declarefunctionalshading[#1]#2#3#4#5#6{%
+ \expandafter\def\csname pgf@deps@pgfshading#2!\endcsname{#1}%
+ \expandafter\ifx\csname pgf@deps@pgfshading#2!\endcsname\pgfutil@empty%
+ \global\expandafter\let\csname pgf@num@pgfshading#2!\endcsname=\pgfutil@empty
+ \pgfshade@functionaldo{#2}{#3}{#4}{#5}{#6}%
+ \else%
+ \global\advance\pgf@shadingcount 1\relax
+ \global\expandafter\edef\csname pgf@num@pgfshading#2!\endcsname{\pgf@shadingnum}%
+ \expandafter\def\csname pgf@func@pgfshading#2!\endcsname{\pgfshade@functionaldo}%
+ \expandafter\def\csname pgf@args@pgfshading#2!\endcsname{{#3}{#4}{#5}{#6}}%
+ \expandafter\let\csname @pgfshading#2!\endcsname=\pgfutil@empty%
+ \fi}
+\def\pgfshade@functionaldo#1#2#3#4#5{%
+ \begingroup
+ #4%
+ \pgfsys@functionalshading{#1}{#2}{#3}{#5}%
+ \expandafter\pgfmath@smuggleone\csname @pgfshading#1!\endcsname
+ \endgroup
+}
+
+\def\pgfshadecolortorgb#1#2{%
+ \pgfutil@colorlet{pgf@tempcol}{#1}%
+ \pgfutil@extractcolorspec{pgf@tempcol}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
+ \expandafter\pgfshading@rgb\pgf@rgbcolor\relax%
+ \edef#2{\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@xc}\space}%
+ \c@pgf@counta\escapechar%
+ \escapechar-1\relax%
+ \expandafter\edef\csname\string#2red\endcsname{\pgf@sys@tonumber{\pgf@xa}\space}%
+ \expandafter\edef\csname\string#2green\endcsname{\pgf@sys@tonumber{\pgf@xb}\space}%
+ \expandafter\edef\csname\string#2blue\endcsname{\pgf@sys@tonumber{\pgf@xc}\space}%
+ \escapechar\c@pgf@counta%
+}
+\def\pgfshading@rgb#1,#2,#3\relax{%
+ \pgf@xa=#1pt%
+ \pgf@xb=#2pt%
+ \pgf@xc=#3pt%
+}
+
+\def\pgfshadecolortocmyk#1#2{%
+ \pgfutil@colorlet{pgf@tempcol}{#1}%
+ \pgfutil@extractcolorspec{pgf@tempcol}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{cmyk}{\pgf@cmykcolor}%
+ \expandafter\pgfshading@cmyk\pgf@cmykcolor\relax%
+ \edef#2{\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space
+ \pgf@sys@tonumber{\pgf@xc}\space\pgf@sys@tonumber{\pgf@xd}\space}%
+ \c@pgf@counta\escapechar%
+ \escapechar-1\relax%
+ \expandafter\edef\csname\string#2cyan\endcsname{%
+ \pgf@sys@tonumber{\pgf@xa}\space}%
+ \expandafter\edef\csname\string#2magenta\endcsname{%
+ \pgf@sys@tonumber{\pgf@xb}\space}%
+ \expandafter\edef\csname\string#2yellow\endcsname{%
+ \pgf@sys@tonumber{\pgf@xc}\space}%
+ \expandafter\edef\csname\string#2black\endcsname{%
+ \pgf@sys@tonumber{\pgf@xd}\space}%
+ \escapechar\c@pgf@counta
+}
+\def\pgfshading@cmyk#1,#2,#3,#4\relax{%
+ \pgf@xa=#1pt%
+ \pgf@xb=#2pt%
+ \pgf@xc=#3pt%
+ \pgf@xd=#4pt%
+}
+
+\def\pgfshadecolortogray#1#2{%
+ \pgfutil@colorlet{pgf@tempcol}{#1}%
+ \pgfutil@extractcolorspec{pgf@tempcol}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{gray}{\pgf@graycolor}%
+ \expandafter\pgfshading@gray\pgf@graycolor\relax
+ \edef#2{\pgf@sys@tonumber{\pgf@xa}\space}%
+ \c@pgf@counta\escapechar
+ \escapechar-1\relax
+ \expandafter\edef\csname\string#2gray\endcsname{%
+ \pgf@sys@tonumber{\pgf@xa}\space}%
+ \escapechar\c@pgf@counta
+}
+\def\pgfshading@gray#1\relax{%
+ \pgf@xa=#1pt%
+}
+
+% Functions to convert between color models in the type 4 PostScript data of
+% functional shadings.
+
+\def\pgffuncshadingrgbtocmyk{%
+ 1.0 exch sub 3 1 roll
+ 1.0 exch sub 3 1 roll
+ 1.0 exch sub 3 1 roll
+ 3 copy
+ 2 copy gt { exch } if pop
+ 2 copy gt { exch } if pop
+ dup 3 1 roll sub
+ 0.0 2 copy lt { exch } if pop
+ 1.0 2 copy gt { exch } if pop
+ 4 1 roll
+ dup 3 1 roll sub
+ 0.0 2 copy lt { exch } if pop
+ 1.0 2 copy gt { exch } if pop
+ 4 1 roll
+ dup 3 1 roll sub
+ 0.0 2 copy lt { exch } if pop
+ 1.0 2 copy gt { exch } if pop
+ 4 1 roll
+}
+
+\def\pgffuncshadingrgbtogray{%
+ 0.11 mul exch 0.59 mul add exch 0.3 mul add
+}
+
+\def\pgffuncshadingcmyktorgb{%
+ % covert to CMY
+ dup 3 1 roll add
+ 1.0 2 copy gt { exch } if pop
+ 4 1 roll
+ dup 3 1 roll add
+ 1.0 2 copy gt { exch } if pop
+ 4 1 roll
+ add
+ 1.0 2 copy gt { exch } if pop
+ 3 1 roll
+ % covert to RGB
+ 1.0 exch sub
+ 3 1 roll
+ 1.0 exch sub
+ 3 1 roll
+ 1.0 exch sub
+ 3 1 roll
+}
+
+\def\pgffuncshadingcmyktogray{%
+ exch 0.11 mul add exch 0.59 mul add exch 0.3 mul add
+ 1.0 2 copy gt { exch } if pop
+ 1.0 exch sub
+}
+
+\def\pgffuncshadinggraytorgb{%
+ dup dup
+}
+
+\def\pgffuncshadinggraytocmyk{%
+ 0.0 0.0 0.0
+ 4 3 roll
+}
+
+% Inserts a box into the text that contains a previously defined
+% shading.
+%
+% #1 = Name of a shading
+%
+% Example:
+%
+% \pgfuseshading{redtogreentoblue}
+
+\def\pgfuseshading#1{%
+ \edef\pgf@shadingname{@pgfshading#1}%
+ \pgf@tryextensions{\pgf@shadingname}{\pgfalternateextension}%
+ \expandafter\pgfutil@ifundefined\expandafter{\pgf@shadingname}%
+ {\pgferror{Undefined shading "#1"}}%
+ {%
+ \edef\pgf@shade@adds{\csname pgf@num\pgf@shadingname\endcsname}%
+ \pgfutil@ifundefined{pgf@deps\pgf@shadingname}%
+ {}%
+ {%
+ \pgf@setup@shading@model
+ \begingroup
+ \pgfutil@globalcolorsfalse
+ \edef\@list{\csname pgf@deps\pgf@shadingname\endcsname}%
+ \pgfutil@for\@temp:=\@list\do{%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{\@temp}}%
+ \pgfutil@extractcolorspec{\@temp}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{\pgf@shading@model}{\pgf@color}%
+ \edef\pgf@shade@adds{\pgf@shade@adds,\pgf@color}%
+ }%
+ \pgfmath@smuggleone\pgf@shade@adds
+ \endgroup
+ }%
+ \expandafter\pgf@strip@shadename\pgf@shadingname!!%
+ \edef\pgf@shadingxname{@pgfshading\pgf@basename\pgf@shade@adds!}%
+ \pgfutil@ifundefined{\pgf@shadingxname}%
+ {%
+ \begingroup
+ \edef\@temp{\expandafter\noexpand\csname pgf@func\pgf@shadingname\endcsname}%
+ \edef\@args{{\pgf@basename\pgf@shade@adds}}%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter\@@args
+ \expandafter\expandafter\expandafter{\csname pgf@args\pgf@shadingname\endcsname}%
+ \expandafter\expandafter\expandafter\@temp\expandafter\@args\@@args
+ \expandafter\pgfmath@smuggleone\csname\pgf@shadingxname\endcsname
+ \endgroup
+ }%
+ {}%
+ \pgf@invokeshading{\csname\pgf@shadingxname\endcsname}%
+ }%
+}
+
+\def\pgf@strip@shadename @pgfshading#1!!!{\def\pgf@basename{#1}}
+
+\def\pgf@invokeshading#1{%
+ \ifpgfpicture%
+ \pgfsys@shadinginsidepgfpicture{#1}%
+ \else%
+ \pgfsys@shadingoutsidepgfpicture{#1}%
+ \fi%
+}
+
+
+% Create an alias name for a shading
+%
+% #1 = name of the alias
+% #2 = name of the original
+%
+% Example:
+%
+% \pgfaliasshading{shading!25}{shadingshaded}
+
+\def\pgfaliasshading#1#2{%
+ \expandafter\let\expandafter\pgf@temp\expandafter=\csname @pgfshading#2!\endcsname%
+ \expandafter\let\csname @pgfshading#1!\endcsname=\pgf@temp%
+ \expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@num@pgfshading#2!\endcsname%
+ \expandafter\let\csname pgf@num@pgfshading#1!\endcsname=\pgf@temp%
+ \expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@deps@pgfshading#2!\endcsname%
+ \expandafter\let\csname pgf@deps@pgfshading#1!\endcsname=\pgf@temp%
+ \expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@func@pgfshading#2!\endcsname%
+ \expandafter\let\csname pgf@func@pgfshading#1!\endcsname=\pgf@temp%
+ \expandafter\let\expandafter\pgf@temp\expandafter=\csname pgf@args@pgfshading#2!\endcsname%
+ \expandafter\let\csname pgf@args@pgfshading#1!\endcsname=\pgf@temp%
+}
+
+
+
+
+% Shades the current path, but does not discard it.
+%
+% #1 - a shading (see below)
+% #2 - an angle
+%
+% Description:
+%
+% \pgfshadepath ``tries'' to fill the
+% current path with a shading. The shading's original size should
+% completely cover the area between (0,0) and (100bp,100bp). The
+% shading will be rotated by #2 and then rescaled so that it
+% completely covers the path. Then the path will be used (locally) for
+% clipping and the shading is drawn.
+%
+% In addition to the rotation, any transformation set by the
+%\pgfsetadditionalshadetransform will also be applied.
+%
+% After all this, the path can still be used for the normal
+% stroking/clipping operations.
+%
+% The shading is rotated around its middle. If no rotation occurs, the
+% lower left corner of the path will lie on (25bp, 25bp), the upper
+% right corner on (75bp, 75bp).
+%
+% Example:
+%
+% \pgfdeclareverticalshading{myshading}{100bp}{color(0pt)=(red); color(100bp)=(green)}
+%
+% \pgfpathmoveto{\pgforigin}
+% \pgfpathlineto{\pgfxy(1,0)}
+% \pgfpathlineto{\pgfxy(1,1)}
+% \pgfshadepath{myshading}{0}
+% \pgfusepath{stroke}
+
+\def\pgfshadepath#1#2{%
+ \ifdim\pgf@pathminx=16000pt%
+ \pgfwarning{No path specified that can be filled}%
+ \else%
+ \begingroup%
+ % Calculate center:
+ \pgf@xb=.5\pgf@pathmaxx%
+ \advance\pgf@xb by.5\pgf@pathminx%
+ \pgf@yb=.5\pgf@pathmaxy%
+ \advance\pgf@yb by.5\pgf@pathminy%
+ % Calculate rotation:
+ \pgfmathparse{#2}%
+ \let\pgfshade@angle=\pgfmathresult
+ \pgfmathsin@\pgfshade@angle
+ \let\pgfshade@sin=\pgfmathresult
+ \pgfmathcos@\pgfshade@angle
+ \let\pgfshade@cos=\pgfmathresult
+ % width and height of the bounding box
+ \pgf@xa=\pgf@pathmaxx
+ \advance\pgf@xa by-\pgf@pathminx
+ \pgf@ya=\pgf@pathmaxy
+ \advance\pgf@ya by-\pgf@pathminy
+ % Calculate scaling:
+ % xscale = 1pt/50bp * (w*|cos(a)|+h*|sin(a)|)/(|cos(a)|+|sin(a)|)
+ % yscale = 1pt/50bp * (w*|sin(a)|+h*|cos(a)|)/(|cos(a)|+|sin(a)|)
+ % 1pt/50bp = .01992528
+ \pgfmathabs@\pgfshade@sin
+ \let\pgfshade@abssin=\pgfmathresult
+ \pgfmathabs@\pgfshade@cos
+ \let\pgfshade@abscos=\pgfmathresult
+ \pgf@xc=\pgfshade@abscos\pgf@xa
+ \advance\pgf@xc by\pgfshade@abssin\pgf@ya
+ \pgf@yc=\pgfshade@abssin\pgf@xa
+ \advance\pgf@yc by\pgfshade@abscos\pgf@ya
+ \pgfmathadd@\pgfshade@abscos\pgfshade@abssin
+ \pgfmathdivide@{.01992528}{\pgfmathresult}%
+ \pgf@xc=\pgfmathresult\pgf@xc
+ \pgf@yc=\pgfmathresult\pgf@yc
+ \ifdim\pgf@xc<0.0001pt
+ \ifdim\pgf@xc>-0.0001pt
+ \pgf@no@shadetrue
+ \fi
+ \fi
+ \ifdim\pgf@yc<0.0001pt
+ \ifdim\pgf@yc>-0.0001pt
+ \pgf@no@shadetrue
+ \fi
+ \fi
+ \ifpgf@no@shade\else
+ \pgfsys@beginscope
+ \pgfsyssoftpath@invokecurrentpath
+ \pgfsys@clipnext
+ \pgfsys@discardpath
+ % Compute new transformation matrix:
+ % shift
+ \pgfsys@transformcm{1}{0}{0}{1}{\the\pgf@xb}{\the\pgf@yb}%
+ % rotation
+ \pgf@x=\pgfshade@sin pt%
+ \pgf@xa=-\pgf@x%
+ \pgfsys@transformcm{\pgfshade@cos}{\pgfshade@sin}{\pgf@sys@tonumber{\pgf@xa}}{\pgfshade@cos}{0pt}{0pt}%
+ % scaling
+ \pgfsys@transformcm{\pgf@sys@tonumber{\pgf@xc}}{0}{0}{\pgf@sys@tonumber{\pgf@yc}}{0pt}{0pt}%
+ % This will actually be the first transformation of the shading.
+ % Should it be applied first so that it becomes the last one?
+ \ifx\pgf@shade@extra@transform\pgfutil@empty%
+ \else%
+ \pgflowlevel{\pgf@shade@extra@transform}%
+ \fi%
+ \pgfuseshading{#1}%
+ \pgfsys@endscope%
+ \fi%
+ \endgroup%
+ \fi%
+}
+
+\newif\ifpgf@no@shade
+
+% Additionally transform shade paths
+%
+% #1 = Transformation code that is used in addition to the normal
+% shading transformation.
+%
+% Example:
+%
+% \pgfsetadditionalshadetransform{\pgftransformrotate{30}}
+
+\def\pgfsetadditionalshadetransform#1{\def\pgf@shade@extra@transform{#1}}
+\let\pgf@shade@extra@transform=\pgfutil@empty
+
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcoretransformations.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcoretransformations.code.tex
new file mode 100644
index 0000000000..be252065c1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcoretransformations.code.tex
@@ -0,0 +1,819 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcoretransformations.code.tex}
+
+
+% Position transformations
+
+\newdimen\pgf@pt@x
+\newdimen\pgf@pt@y
+
+\newdimen\pgf@pt@temp
+
+\newif\ifpgf@pt@identity
+\pgf@pt@identitytrue
+
+\def\pgf@pt@aa{1.0} \def\pgf@pt@ab{0.0}
+\def\pgf@pt@ba{0.0} \def\pgf@pt@bb{1.0}
+
+
+
+% Store the current transformation matrix in a macro.
+%
+% #1 = macro name
+%
+% Example:
+%
+% \pgfgettransform\mytransform
+
+\def\pgfgettransform#1{%
+ \edef#1{{\pgf@pt@aa}{\pgf@pt@ab}{\pgf@pt@ba}{\pgf@pt@bb}{\the\pgf@pt@x}{\the\pgf@pt@y}}%
+}
+
+% Store the current transformation matrix in a set of macros, one for
+% each single entry.
+%
+% #1-#4 are macro which store the matrix entries (0,0), (0,1), (1,0),
+% (1,1) (in this order). It is the same order as for \pgftransformcm.
+%
+% #5 is a macro which will be filled with the x shift and
+% #6 is a macro which will be filled with the y shift.
+%
+% Example:
+% \pgfgettransformentries\aa\ab\ba\bb\shiftx\shifty
+%
+% ->
+%
+% \pgftransformcm\aa\ab\ba\bb{\pgfqpoint{\shiftx}{\shifty}}
+%
+% or
+%
+% \pgfsettransformentries\aa\ab\ba\bb\shiftx\shifty
+\def\pgfgettransformentries#1#2#3#4#5#6{%
+ \edef#1{\pgf@pt@aa}%
+ \edef#2{\pgf@pt@ab}% attention: this is (1,0), i.e. the point which is usually labelled 'ba'!
+ \edef#3{\pgf@pt@ba}% attention: this is (0,1), i.e. the point which is usually labelled 'ab'!
+ \edef#4{\pgf@pt@bb}%
+ \edef#5{\the\pgf@pt@x}%
+ \edef#6{\the\pgf@pt@y}%
+}%
+\def\pgfsettransformentries#1#2#3#4#5#6{%
+ \pgfsettransform{{#1}{#2}{#3}{#4}{#5}{#6}}%
+}%
+
+% Restore the current transformation matrix from a macro.
+%
+% #1 = macro name, previously used with \pgfgettransform
+%
+% Example:
+%
+% \pgfsettransform\mytransform
+
+\def\pgfsettransform#1{%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgf@settransform\pgf@temp%
+}
+\def\pgf@settransform#1#2#3#4#5#6{%
+ \def\pgf@pt@aa{#1}%
+ \def\pgf@pt@ab{#2}%
+ \def\pgf@pt@ba{#3}%
+ \def\pgf@pt@bb{#4}%
+ \pgf@pt@x=#5%
+ \pgf@pt@y=#6%
+ \edef\pgf@idtest{#1,#2,#3,#4}%
+ \ifx\pgf@idtest\pgf@idmatrixtext%
+ \pgf@pt@identitytrue%
+ \else%
+ \pgf@pt@identityfalse%
+ \fi%
+}
+
+\def\pgf@idmatrixtext{1.0,0.0,0.0,1.0}
+\def\pgf@zerozerotext{0.0,0.0}
+\def\pgf@one@text{1.0}
+\def\pgf@zero@text{0.0}
+
+% Transformation command
+%
+% #1 = x dimension
+% #2 = y dimension
+%
+% Description:
+%
+% Applies the pgfs transformation matrix to the point (#1,#2). The
+% result is once more stored in the point.
+%
+%
+% Example:
+%
+% \pgf@pos@transform{\pgf@x}{\pgf@y}
+
+\def\pgf@pos@transform#1#2{%
+ \ifpgf@pt@identity%
+ \else%
+ \pgf@pt@temp=#1%
+ #1=\pgf@pt@aa#1%
+ \advance#1 by\pgf@pt@ba#2%
+ #2=\pgf@pt@bb#2%
+ \advance#2 by\pgf@pt@ab\pgf@pt@temp%
+ \fi%
+ \advance#1 by\pgf@pt@x%
+ \advance#2 by\pgf@pt@y%
+}
+\def\pgf@pos@transform@glob{%
+ \ifpgf@pt@identity%
+ \else%
+ \pgf@pt@temp=\pgf@x%
+ \global\pgf@x=\pgf@pt@aa\pgf@x%
+ \global\advance\pgf@x by\pgf@pt@ba\pgf@y%
+ \global\pgf@y=\pgf@pt@bb\pgf@y%
+ \global\advance\pgf@y by\pgf@pt@ab\pgf@pt@temp%
+ \fi%
+ \global\advance\pgf@x by\pgf@pt@x%
+ \global\advance\pgf@y by\pgf@pt@y%
+}
+
+
+% Invert the current transformation matrix
+%
+% Description:
+%
+% This command replaces the current transformation matrix by its
+% inverse. The inversion is not very exact if the matrix is nearly
+% singular.
+%
+% Example:
+%
+% \pgftransforminvert
+
+\def\pgftransforminvert{%
+ % First, invert the shift. That's easy
+ \pgf@pt@x=-\pgf@pt@x
+ \pgf@pt@y=-\pgf@pt@y
+ \ifpgf@pt@identity%
+ \else%
+ % Sigh. Have to calculate the inverse of the matrix.
+ % Perhaps we are lucky and ba and bb are zero?
+ \edef\pgf@zerotest{\pgf@pt@ab,\pgf@pt@ba}%
+ \ifx\pgf@zerotest\pgf@zerozerotext%
+ % Ha! Just invert aa and bb
+ \pgfmathreciprocal@{\pgf@pt@aa}%
+ \let\pgf@pt@aa\pgfmathresult%
+ \pgfmathreciprocal@{\pgf@pt@bb}%
+ \let\pgf@pt@bb\pgfmathresult%
+ \else%
+ % Start with determinant
+ % Matrix = (aa ab
+ % ba bb)
+ {%
+ \pgfutil@tempdima=\pgf@pt@aa pt%
+ \pgfutil@tempdima=\pgf@pt@bb\pgfutil@tempdima% aa * bb
+ \pgfutil@tempdimb=\pgf@pt@ba pt%
+ \pgfutil@tempdimb=\pgf@pt@ab\pgfutil@tempdimb% ba * ab
+ \advance\pgfutil@tempdima by -\pgfutil@tempdimb% aa*bb - ba*ab
+ % Invert
+ \pgfmathreciprocal@{\pgf@sys@tonumber{\pgfutil@tempdima}}%
+ \pgfutil@tempdima=\pgfmathresult pt%
+ \pgf@x=\pgf@pt@bb\pgfutil@tempdima% bb/(det A)
+ \xdef\pgf@new@pt@aa{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@x=\pgf@pt@aa\pgfutil@tempdima% aa/(det A)
+ \xdef\pgf@new@pt@bb{\pgf@sys@tonumber{\pgf@x}}%
+ \pgfutil@tempdima=-\pgfutil@tempdima%
+ \pgf@x=\pgf@pt@ba\pgfutil@tempdima% -ba/(det A)
+ \xdef\pgf@new@pt@ba{\pgf@sys@tonumber{\pgf@x}}%
+ \pgf@x=\pgf@pt@ab\pgfutil@tempdima% -ab/(det A)
+ \xdef\pgf@new@pt@ab{\pgf@sys@tonumber{\pgf@x}}%
+ }%
+ \let\pgf@pt@aa\pgf@new@pt@aa%
+ \let\pgf@pt@ab\pgf@new@pt@ab%
+ \let\pgf@pt@ba\pgf@new@pt@ba%
+ \let\pgf@pt@bb\pgf@new@pt@bb%
+ \fi%
+ \pgf@pt@temp=\pgf@pt@x%
+ \pgf@pt@x=\pgf@pt@aa\pgf@pt@x%
+ \advance\pgf@pt@x by\pgf@pt@ba\pgf@pt@y%
+ \pgf@pt@y=\pgf@pt@bb\pgf@pt@y%
+ \advance\pgf@pt@y by\pgf@pt@ab\pgf@pt@temp%
+ \fi%
+}
+
+
+
+
+% PGF-Level concatenation of the transformation matrix with a given
+% matrix.
+%
+% #1 - #5 = a concatenation matrix (see pdf spec). Entry #5 is a
+% translation point.
+%
+% Description:
+%
+% All coordinates given to subsequent path construction commands will
+% be transformed additionally by the given transformation matrix. If
+% the command is followed by a 6th argument, the transformation is
+% only applied to this argument.
+%
+%
+% Example:
+%
+% \pgftransformcm{1}{0}{0}{1}{\pgfpoint{100pt}{0pt}} % 100pt to the right.
+%
+% \pgftransformcm{2}{0}{0}{2}{\pgfpointorigin} % double in size
+% \pgfpathmoveto{\pgfpoint{0cm}{0cm}}
+% \pgfpathlineto{\pgflineto{1cm}{1cm}} % actually 2cm/2cm
+
+\def\pgftransformcm#1#2#3#4#5{%
+ \edef\pgf@marshal{\noexpand\pgf@transformcm{#1}{#2}{#3}{#4}}%
+ \pgf@marshal{#5}%
+}
+\def\pgf@transformcm#1#2#3#4#5{%
+ {%
+ \pgf@process{#5}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ %
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgfmathsetlength\pgf@y{#2}%
+ %
+ \pgf@xa=\pgf@pt@aa\pgf@x%
+ \advance\pgf@xa by \pgf@pt@ba\pgf@y%
+ %
+ \pgf@ya=\pgf@pt@ab\pgf@x%
+ \advance\pgf@ya by \pgf@pt@bb\pgf@y%
+ %
+ \pgfmathsetlength\pgf@x{#3}%
+ \pgfmathsetlength\pgf@y{#4}%
+ %
+ \pgf@xb=\pgf@pt@aa\pgf@x%
+ \advance\pgf@xb by \pgf@pt@ba\pgf@y%
+ %
+ \pgf@yb=\pgf@pt@ab\pgf@x%
+ \advance\pgf@yb by \pgf@pt@bb\pgf@y%
+ %
+ \pgf@x=\pgf@pt@aa\pgf@xc%
+ \advance\pgf@x by\pgf@pt@ba\pgf@yc%
+ \advance\pgf@x by\pgf@pt@x%
+ %
+ \pgf@y=\pgf@pt@ab\pgf@xc%
+ \advance\pgf@y by\pgf@pt@bb\pgf@yc%
+ \advance\pgf@y by\pgf@pt@y%
+ %
+ \global\pgf@x=\pgf@x%
+ \global\pgf@y=\pgf@y%
+ \xdef\pgf@tempaa{\pgf@sys@tonumber{\pgf@xa}}%
+ \xdef\pgf@tempab{\pgf@sys@tonumber{\pgf@ya}}%
+ \xdef\pgf@tempba{\pgf@sys@tonumber{\pgf@xb}}%
+ \xdef\pgf@tempbb{\pgf@sys@tonumber{\pgf@yb}}%
+ }%
+ \pgf@pt@x=\pgf@x%
+ \pgf@pt@y=\pgf@y%
+ \let\pgf@pt@aa=\pgf@tempaa%
+ \let\pgf@pt@ba=\pgf@tempba%
+ \let\pgf@pt@ab=\pgf@tempab%
+ \let\pgf@pt@bb=\pgf@tempbb%
+ \edef\pgf@idtest{\pgf@pt@aa,\pgf@pt@ba,\pgf@pt@ab,\pgf@pt@bb}%
+ \ifx\pgf@idtest\pgf@idmatrixtext%
+ \pgf@pt@identitytrue%
+ \else%
+ \pgf@pt@identityfalse%
+ \fi%
+}
+
+
+
+% Transformation into a given triangle. The three corners of the
+% triangle are called "origin", "x" and "y" are given. After this
+% transformation has been applied, the canvas origin is at "origin",
+% the vector (1pt,0pt) lies at "x" and the vector (0pt,1pt) lies at
+% "y".
+%
+% #1 = origin
+% #2 = x
+% #3 = y
+%
+% Example:
+%
+% \pgftransformtriangle{\pgfpointorigin}{\pgfpoint{1cm}{1cm}}{\pgfpoint{-1cm}{1cm}}
+
+\def\pgftransformtriangle#1#2#3{%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{#1}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \advance\pgf@xb by-\pgf@x%
+ \advance\pgf@yb by-\pgf@y%
+ \pgftransformcm%
+ {\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@ya}%
+ {\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@yb}%
+ {\pgfpoint{\pgf@x}{\pgf@y}}%
+}
+
+
+
+% Undo all transformations
+%
+% Example:
+%
+% \pgftansformreset
+
+\def\pgftransformreset{%
+ \pgf@pt@x=0pt%
+ \pgf@pt@y=0pt%
+ \let\pgf@pt@aa\pgf@one@text%
+ \let\pgf@pt@ba\pgf@zero@text%
+ \let\pgf@pt@ab\pgf@zero@text%
+ \let\pgf@pt@bb\pgf@one@text%
+ \pgf@pt@identitytrue%
+}
+
+
+% Undo all slanting/rotation, but not translations
+%
+% Example:
+%
+% \pgftransformresetnontranslations
+
+\def\pgftransformresetnontranslations{%
+ \let\pgf@pt@aa\pgf@one@text%
+ \let\pgf@pt@ba\pgf@zero@text%
+ \let\pgf@pt@ab\pgf@zero@text%
+ \let\pgf@pt@bb\pgf@one@text%
+ \pgf@pt@identitytrue%
+}
+
+
+
+
+% Shifting command and environment
+%
+% #1 = vector by which all subsequent points should be moved.
+%
+% Example:
+%
+% \pgftansformshift{\pgfpoint{1cm}{1cm}}
+
+\def\pgftransformshift#1{\pgftransformcm{1}{0}{0}{1}{#1}}
+\def\pgftransformxshift#1{\pgftransformcm{1}{0}{0}{1}{\pgfpoint{#1}{+0pt}}}
+\def\pgftransformyshift#1{\pgftransformcm{1}{0}{0}{1}{\pgfpoint{+0pt}{#1}}}
+
+
+
+
+% Scaling commands
+%
+% #1 = scaling for all subsequent points.
+%
+% Example:
+%
+% \pgftransformscale{2}
+% \pgftransformxscale{2}
+% \pgftransformyscale{2}
+
+\def\pgftransformscale#1{\pgftransformcm{#1}{0}{0}{#1}{\pgfpointorigin}}
+\def\pgftransformxscale#1{\pgftransformcm{#1}{0}{0}{1.0}{\pgfpointorigin}}
+\def\pgftransformyscale#1{\pgftransformcm{1.0}{0}{0}{#1}{\pgfpointorigin}}
+
+
+
+% Slanting commands
+%
+% #1 = slanting in x-direction. 1 means 45 degrees.
+%
+% Example:
+%
+% \pgftransformxslant{2}
+% \pgftransformyslant{2}
+
+\def\pgftransformxslant#1{\pgftransformcm{1.0}{0}{#1}{1.0}{\pgfpointorigin}}
+\def\pgftransformyslant#1{\pgftransformcm{1.0}{#1}{0}{1.0}{\pgfpointorigin}}
+
+
+
+% Rotation commands
+%
+% #1 = degrees for the rotation
+%
+% Example:
+%
+% \pgftransformrotate{30}
+
+\def\pgftransformrotate#1{%
+ \pgfmathparse{#1}%
+ \let\pgftransform@angle=\pgfmathresult%
+ \pgfmathsin@{\pgftransform@angle}%
+ \let\pgftransform@sin=\pgfmathresult%
+ \pgfmathcos@{\pgftransform@angle}%
+ \let\pgftransform@cos=\pgfmathresult%
+ \pgf@x=\pgftransform@sin pt%
+ \pgf@xa=-\pgf@x%
+ \pgftransformcm{\pgftransform@cos}{\pgftransform@sin}{\pgf@sys@tonumber{\pgf@xa}}{\pgftransform@cos}{\pgfpointorigin}%
+}
+
+
+
+% The following if's have the following effect:
+%
+% \ifpgfslopedattime decides whether the coordinate system of an
+% xxxattime transformation command should be rotated such that text
+% drawn on the line should be tangent to the line
+%
+% \ifpgfallowupsidedowattime decides whether the transformation should
+% be done in such a way that the text is always ``upright,'' that is,
+% text drawn in this coordinate system is never upside-down.
+%
+% \ifpgfresetnontranslationattime decides whether the coordinate
+% system of an xxxattime transformation command should be reset
+% (concerning the non-translations) before a possible rotation is
+% applied. This is useful, for example, if the main coordinate system
+% is scaled by, say, a factor of 2 and you do not want that to apply
+% to the text, but you do want the rotation to apply.
+
+\newif\ifpgfslopedattime
+\newif\ifpgfallowupsidedownattime
+\newif\ifpgfresetnontranslationattime
+
+
+% Transform to the coordinate system of a point on a line
+%
+% #1 = a time fraction of line where to put the label, where 0 means start,
+% 1 means end, and for example 0.5 means the middle.
+% #2 = start of line
+% #3 = end of line
+%
+% Example:
+%
+% {
+% \pgftransformlineattime{.5}{\pgfxy(0,0)}{\pgfxy(3,2)}
+% \pgftext{Hi!}
+% }
+%
+% {
+% \pgftransformlineattime{.75}{\pgfxy(0,0)}{\pgfxy(3,2)}
+% \pgftransformresetnontranslations
+% \pgftext{Hi!}
+% }
+%
+\def\pgftransformlineattime#1#2#3{%
+ \pgf@process{#2}%
+ \pgf@xb=\pgf@x% xb/yb = start point
+ \pgf@yb=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xc=\pgf@x% xc/yc = end point
+ \pgf@yc=\pgf@y%
+ \pgftransformshift{\pgfpointlineattime{#1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
+ \ifpgfresetnontranslationattime%
+ \pgftransformresetnontranslations%
+ \fi%
+ \ifpgfslopedattime%
+ \advance\pgf@xc by-\pgf@xb%
+ \advance\pgf@yc by-\pgf@yb%
+ \ifpgfallowupsidedownattime%
+ \else%
+ \ifdim\pgf@xc<0pt%
+ \pgf@xc=-\pgf@xc%
+ \pgf@yc=-\pgf@yc%
+ \fi%
+ \fi%
+ \pgf@x=\pgf@xc%
+ \pgf@y=\pgf@yc%
+ \pgfpointnormalised{}% x/y = normalised vector
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm%
+ {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
+ {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}%
+ \fi%
+}
+
+
+% Transform to the coordinate system of a point on an arc
+%
+% #1 = a time fraction of line where to put the label, where 0 means start,
+% 1 means end, and for example 0.5 means the middle.
+% #2 = center of an ellipse
+% #3 = 0-degree axis of the ellipse
+% #4 = 90-degree axis of the ellipse
+% #4 = start angle of the arc on this ellipse
+% #5 = end angle of the arc on this ellipse
+%
+% Example:
+%
+% {
+% \pgftransformlineattime{.5}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}{\pgfpoint{0cm}{1cm}}{30}{40}
+% \pgftext{Hi!}
+% }
+
+\def\pgftransformarcaxesattime#1#2#3#4#5#6{%
+ \pgfpointarcaxesattime{#1}{#2}{#3}{#4}{#5}{#6}%
+ \pgftransformshift{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \ifpgfresetnontranslationattime%
+ \pgftransformresetnontranslations%
+ \fi%
+ \ifpgfslopedattime%
+ \pgf@x=\pgf@xa%
+ \pgf@y=\pgf@ya%
+ \pgf@process{\pgfpointnormalised{}}%
+ \ifpgfallowupsidedownattime%
+ \else%
+ \ifdim\pgf@x<0pt%
+ \pgf@x=-\pgf@x%
+ \pgf@y=-\pgf@y%
+ \fi%
+ \fi%
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm%
+ {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
+ {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}%
+ \fi%
+}
+
+
+
+
+% Transform to the coordinate system of a point on a curve
+%
+% #1 = a time fraction of line where to put the label, where 0 means start,
+% 1 means end, and for example 0.5 means the middle.
+% #2 = start of line
+% #3 = first control
+% #4 = second control
+% #5 = end of line
+%
+% Example:
+%
+% {
+% \pgftransformcurveattime{.5}{\pgfxy(0,0)}{\pgfxy(3,2)}
+% \pgftext{Hi!}
+% }
+%
+% {
+% \pgftransformcurveattime{.75}{\pgfxy(0,0)}{\pgfxy(3,2)}
+% \pgftransformresetnontranslations
+% \pgftext{Hi!}
+% }
+%
+\def\pgftransformcurveattime#1#2#3#4#5{%
+ \pgfpointcurveattime{#1}{#2}{#3}{#4}{#5}%
+ \pgftransformshift{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \ifpgfresetnontranslationattime%
+ \pgftransformresetnontranslations%
+ \fi%
+ \ifpgfslopedattime%
+ \pgf@x=\pgf@xa%
+ \pgf@y=\pgf@ya%
+ \advance\pgf@x by-\pgf@xb%
+ \advance\pgf@y by-\pgf@yb%
+ \ifpgfallowupsidedownattime%
+ \else%
+ \ifdim\pgf@x<0pt%
+ \pgf@x=-\pgf@x%
+ \pgf@y=-\pgf@y%
+ \fi%
+ \fi%
+ \pgfpointnormalised{}% x/y = normalised vector
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm%
+ {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
+ {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}%
+ \fi%
+}
+
+
+
+
+
+% Transform to the coordinate system of an arrow at the end of the
+% line going from point #1 to point #2 with the correct rotation.
+%
+% #1 = a start point an (invisible) line
+% #2 = an end point an (invisible) line
+%
+% Example:
+%
+% \pgftransformarrow{\pgfpointorigin}{\pgfpoint{1cm}{0cm}}
+
+\def\pgftransformarrow#1#2{%
+ \pgf@process{#2}%
+ \pgftransformshift{}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#1}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \pgf@x=\pgf@xa%
+ \pgf@y=\pgf@ya%
+ \pgfpointnormalised{}%
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm%
+ {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
+ {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfqpoint{0pt}{0pt}}%
+}
+
+
+
+
+% Computes transformations adjustments for the current transformation
+% matrix
+%
+% Description:
+%
+% This command is used when you install a transformation matrix that
+% scales everything by a certain factor, but you still wish to draw
+% something with "an absolute size". Suppose for instance that you
+% install a transformation matrix that scales everything by a factor
+% of 4 and you now wish to draw a horizontal line of length 1cm. Then,
+% if you do not reset the transformation matrix, you can draw a line
+% of logical length 2.5mm, which will then get scaled to a line of
+% 1cm.
+%
+% Things get more difficult in case you scale things only, say,
+% vertically. In this case, the adjustment necessary for horizontal
+% lines is different from the one needed for vertical lines.
+%
+% This function computes the necessary scaling factors and puts them
+% in the macros \pgfhorizontaltransformationadjustment and
+% \pgfverticaltransformationadjustment.
+%
+% Note that the "right" way to draw a line of absolute length 1cm in a
+% transformed coordinate system is to first compute the start point
+% and to then reset the transformation matrix. The transformation
+% adjustments computed here are important only in situations where you
+% cannot do this, for instance when an "outer xsep" must be set.
+
+\def\pgftransformationadjustments{%
+ \ifpgf@pt@identity%
+ \let\pgfhorizontaltransformationadjustment\pgf@one@text%
+ \let\pgfverticaltransformationadjustment\pgf@one@text%
+ \else%
+ {%
+ \pgf@pt@x0pt%
+ \pgf@pt@y0pt%
+ \pgfpointtransformed{\pgfqpoint{1pt}{0pt}}%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \global\let\pgf@temp@hori\pgfmathresult
+ \pgfpointtransformed{\pgfqpoint{0pt}{1pt}}%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \global\let\pgf@temp@vert\pgfmathresult
+ \xdef\pgf@marshal@b{\def\noexpand\pgfverticaltransformationadjustment{\pgfmathresult}}
+ }%
+ \let\pgfhorizontaltransformationadjustment\pgf@temp@hori%
+ \let\pgfverticaltransformationadjustment\pgf@temp@vert%
+ \fi%
+}
+
+\let\pgfhorizontaltransformationadjustment\pgf@one@text
+\let\pgfverticaltransformationadjustment\pgf@one@text
+
+
+% Low-level transformations
+
+% Causes the current high-level transformation command to be applied
+% to the low-level.
+%
+% Description:
+%
+% All subsequent drawing will be transformed additionally by the
+% current high-level transformation. Thus, the high-level
+% transformation becomes the low-level transformation. The high-level
+% transformation is reset at this point.
+
+\def\pgflowlevelsynccm{%
+ \pgfsys@transformcm%
+ {\pgf@pt@aa}{\pgf@pt@ab}%
+ {\pgf@pt@ba}{\pgf@pt@bb}%
+ {\pgf@pt@x}{\pgf@pt@y}%
+ \pgftransformreset%
+ \pgf@relevantforpicturesizefalse%
+}
+
+
+
+% Causes a transformation command to be applied to the ``lowlevel''
+% transformation matrix.
+%
+% #1 - a high-level transformation command
+%
+% Description:
+%
+% All subsequent drawing will be transformed additionally by the given
+% transformation matrix. Note that PGF will no longer be able to
+% ``keep track'' of the coordinates. Also, transformations are applied
+% to *everything*, including line thickness and line endings. Most
+% often, this is not desirable.
+%
+% Example:
+%
+% \pgflowlevel{\pgftransformcm{1}{0}{0}{1}{\pgfpoint{100pt}{0pt}}} % 100bp to the right.
+%
+% \begin{pgflowlevelscope}{\pgftransformcm{2}{0}{0}{2}{\pgfpointorigin}} % double in size
+% \pgfmoveto{\pgfpoint{0cm}{0cm}}
+% \pgflineto{\pgflineto{1cm}{1cm}} % actually 2cm/2cm
+% \end{pgflowlevelscope}
+
+\def\pgflowlevel#1{%
+ {%
+ \pgftransformreset%
+ #1%
+ \pgflowlevelsynccm%
+ }%
+ \pgf@relevantforpicturesizefalse%
+}
+
+\def\pgflowlevelscope#1{\pgfscope\pgflowlevel{#1}}
+\def\endpgflowlevelscope{\endpgfscope}
+
+\long\def\pgflowlevelobj#1#2{\pgfscope{\pgflowlevel{#1}#2}\endpgfscope}
+
+
+
+% View boxes
+
+% Establishes a view box scope
+%
+% #1 and #2 = two opposite corners of the source rectangle
+% #3 and #4 = two opposite corners of the target rectangle
+% #5 = "meet" or "slice"
+%
+% Description:
+%
+% Inside the viewbox scope, the source rectangle will be translated
+% and scaled so that it becomes centered on the target rectangle and
+% will, for "meet", be as large as possible so that it fits inside the
+% target and, for "slice", be as small as possible so that it
+% encompasses the target.
+
+\def\pgfviewboxscope#1#2#3#4#5{%
+ {% Compute rectangle corners
+ \pgf@process{#1}%
+ \pgf@pos@transform@glob
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#2}%
+ \pgf@pos@transform@glob
+ \ifdim\pgf@x<\pgf@xa%
+ \pgf@xb\pgf@x%
+ \pgf@xc\pgf@xa%
+ \else%
+ \pgf@xb\pgf@xa%
+ \pgf@xc\pgf@x%
+ \fi%
+ \ifdim\pgf@y<\pgf@ya%
+ \pgf@yb\pgf@y%
+ \pgf@yc\pgf@ya%
+ \else%
+ \pgf@yb\pgf@ya%
+ \pgf@yc\pgf@y%
+ \fi%
+ \pgf@process{#3}%
+ \pgf@pos@transform@glob
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#4}%
+ \pgf@pos@transform@glob
+ \ifdim\pgf@x<\pgf@xa%
+ \else%
+ \pgfutil@tempdima\pgf@x
+ \pgf@x\pgf@xa%
+ \pgf@xa\pgfutil@tempdima%
+ \fi%
+ \ifdim\pgf@y<\pgf@ya%
+ \else%
+ \pgfutil@tempdima\pgf@y
+ \pgf@y\pgf@ya%
+ \pgf@ya\pgfutil@tempdima%
+ \fi%
+ \pgfusetype{.view}%
+ \edef\pgf@marshal{\expandafter\noexpand\csname pgfsys@viewbox#5\endcsname{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}}%
+ \pgf@marshal%
+ }%
+ \pgf@relevantforpicturesizefalse%
+}
+
+\def\endpgfviewboxscope{\pgfsys@endviewbox}
+
+\let\startpgfviewboxscope=\pgfviewboxscope
+\let\stoppgfviewboxscope=\endpgfviewboxscope
+
+% Forward declarations for nonlinear stuff (have no effect till module
+% nonlineartransformations is loaded)
+
+\let\pgfapproximatenonlineartranslation\relax
+\let\pgfapproximatenonlineartransformation\relax
+\def\pgftransformnonlinear#1{\pgferror{You need to say
+ \string\usepgfmodule{nonlineartransformations} to use nonlinear transformations}}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/basiclayer/pgfcoretransparency.code.tex b/graphics/pgf/base/tex/generic/basiclayer/pgfcoretransparency.code.tex
new file mode 100644
index 0000000000..7da8f5a378
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/basiclayer/pgfcoretransparency.code.tex
@@ -0,0 +1,312 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcoretransparency.code.tex}
+
+
+% Sets the opacity of stroking operations.
+%
+% #1 = opacity, where 1 means fully opaque and 0 means fully
+% transparent.
+%
+% Example:
+%
+% \pgfsetstrokeopacity{0.5}
+
+\def\pgfsetstrokeopacity#1{%
+ \pgfmathparse{#1}%
+ \expandafter\pgfsys@stroke@opacity\expandafter{\pgfmathresult}}
+
+
+% Sets the opacity of stroking operations.
+%
+% #1 = opacity, where 1 means fully opaque and 0 means fully
+% transparent.
+%
+% Example:
+%
+% \pgfsetfillopacity{0.5}
+
+\def\pgfsetfillopacity#1{%
+ \pgfmathparse{#1}%
+ \expandafter\pgfsys@fill@opacity\expandafter{\pgfmathresult}}
+
+
+
+% Sets the current blend mode. See Section 7.2.4 of the PDF
+% Specification 1.7 for an introduction to blend modes in general.
+%
+% #1 = One of the following modes, see also section 7.2.4 of the
+% PDF Specification 1.7. (The PGF names, which are all lowercase with
+% spaces as usual, must be mapped to the PDF or SVG by the drivers.)
+%
+% normal
+% multiply
+% screen
+% overlay
+% darken
+% lighten
+% color dodge
+% color burn
+% hard light
+% soft light
+% difference
+% exclusion
+% saturation
+% color
+% hue
+% luminosity
+%
+% Example:
+%
+% \pgfsetblendmode{multiply}
+
+\def\pgfsetblendmode#1{\pgfsys@blend@mode{#1}}
+
+
+% Declares a new fading based on the contents of a box.
+%
+% #1 = name of the fading
+% #2 = content of a TeX box that specifies the fading
+%
+% Description:
+%
+% This command declares a new fading based on the contents of
+% the TeX box. The mask can later be used to mask other graphics.
+%
+% The box is used to determine where the mask is opaque: At the
+% beginning, the mask is completely transparent. Wherever the box
+% contains something (like text or a picture or whatever), the
+% luminosity of the text/graphic is used to determine how opaque the
+% point will be. The greater the luminosity, the more opaque. The net
+% effect is that white corresponds to "completely opaque" and black to
+% "completely transparent". This is rather counterintuitive. Because
+% of this, the special color "pgftransparent" is defined, which is the
+% same as black. By setting the color to, say,
+% \color{pgftransparent!10} you get something that is 10% transparent
+% and \color{pgftransparent!90} gives you 90% transparency.
+%
+% By default, the drawing color is set to opaque.
+%
+% Example:
+%
+% \pgfdeclarefading{mymask}{
+% \fontsize{200}{200}\bfseries
+% Ti\emph{k}Z
+% }
+% \pgfdeclarefading{myothermask}{
+% \tikz \shade [left color=transparent,right color=transparent!0]
+% (0,0) rectangle (5,5);
+% }
+
+\def\pgfdeclarefading#1#2{%
+ \setbox\pgfutil@tempboxa=\hbox{{\pgfsys@beginscope\pgfutil@color{white}\ignorespaces#2\pgfsys@endscope}}%
+ \pgfsys@fadingfrombox{#1}\pgfutil@tempboxa%
+}
+
+\pgfutil@colorlet{pgftransparent}{black}
+
+
+% Use a previously declared fading.
+%
+% #1 = name of the fading
+% #2 = transformation code
+%
+% Description:
+%
+% The command should be used *inside* a pgfpicture to install a
+% fading. The fading is a part of the graphic state. (This command
+% works much like \pgfsetstrokeopacity).
+%
+% The mask will be centered on the origin. The transformation code #2 is
+% applied to the mask (but not the contents of the actual picture).
+
+\def\pgfsetfading#1#2{%
+ {%
+ \pgftransformreset%
+ #2%
+ \pgfgettransform{\pgftrans@temp}%
+ \edef\pgf@marshal{\noexpand\pgfsys@usefading{#1}\pgftrans@temp}%
+ \pgf@marshal%
+ }%
+}
+
+
+
+% Use a previously declared fading scaled for the current path.
+%
+% #1 - an fading
+% #2 - extra transformations
+%
+% Description:
+%
+% This command works a bit like \pgfshadepath. "Works a bit like"
+% means the following: The masks's original size should
+% completely cover the area between (0,0) and (100bp,100bp). The
+% mask is then rescaled so that it completely covers the path. Then
+% the additional transformation #2 is applied. Finally, the mask is
+% made part of the graphic state (as with \pgfsetfading). The path
+% used for computation purposes only -- it is not drawn or otherwise
+% used.
+%
+% If no transformations occur, the lower left corner of the path will
+% lie on (25bp, 25bp), the upper right corner on (75bp, 75bp).
+%
+% If the path was empty, the fading will be used at its natural size,
+% centered on the origin.
+%
+% Example:
+%
+% \pgfdeclarefading{fade right}
+% {\tikz[left color=transparent!0,right color=transparent!100]
+% (0,0) rectangle (100bp,100bp);}
+%
+% \pgfpathmoveto{\pgforigin}
+% \pgfpathlineto{\pgfxy(1,0)}
+% \pgfpathlineto{\pgfxy(1,1)}
+% \pgfsetfadingforcurrentpath{fade right}{}
+% \pgfusepath{fill}
+
+\def\pgfsetfadingforcurrentpath#1#2{%
+ \ifdim\pgf@pathminx=16000pt%
+ % Path was empty -> use natural size
+ \pgfsetfading{#1}{#2}%
+ \else%
+ \pgfsetfading{#1}{%
+ % Calculate center:
+ \pgf@xb=.5\pgf@pathmaxx%
+ \advance\pgf@xb by.5\pgf@pathminx%
+ \pgf@yb=.5\pgf@pathmaxy%
+ \advance\pgf@yb by.5\pgf@pathminy%
+ % Calculate scaling:
+ \pgf@xc=\pgf@pathmaxx%
+ \advance\pgf@xc by-\pgf@pathminx%
+ \ifdim\pgf@xc<0.1pt\pgf@xc=0.1pt\fi%
+ \pgf@yc=\pgf@pathmaxy%
+ \advance\pgf@yc by-\pgf@pathminy%
+ \ifdim\pgf@yc<0.1pt\pgf@yc=0.1pt\fi%
+ \pgf@xc=.02\pgf@xc%
+ \pgf@yc=.02\pgf@yc%
+ % Compute new transformation matrix:
+ \pgftransformcm{1}{0}{0}{1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgftransformcm{\pgf@sys@tonumber{\pgf@xc}}{0}{0}{\pgf@sys@tonumber{\pgf@yc}}{\pgfpointorigin}%
+ \pgfsys@clipfading%
+ #2%
+ }%
+ \fi%
+}
+
+
+
+
+% Use a previously declared fading scaled for the current path.
+%
+% #1 - an fading
+% #2 - extra transformations
+%
+% Description:
+%
+% This command works like \pgfsetfadingforcurrentpath, only it takes
+% the current line width into account: Before the path is considered,
+% it is enlarged by half the line width in all directions.
+
+\def\pgfsetfadingforcurrentpathstroked#1#2{%
+ \ifdim\pgf@pathminx=16000pt%
+ % Path was empty -> use natural size
+ \pgfsetfading{#1}{#2}%
+ \else%
+ \pgfsetfading{#1}{%
+ % Calculate center:
+ \pgf@xb=.5\pgf@pathmaxx%
+ \advance\pgf@xb by.5\pgf@pathminx%
+ \pgf@yb=.5\pgf@pathmaxy%
+ \advance\pgf@yb by.5\pgf@pathminy%
+ % Calculate scaling:
+ \pgf@xc=\pgf@pathmaxx%
+ \advance\pgf@xc by-\pgf@pathminx%
+ \advance\pgf@xc by\pgflinewidth%
+ \ifdim\pgf@xc<0.1pt\pgf@xc=0.1pt\fi%
+ \pgf@yc=\pgf@pathmaxy%
+ \advance\pgf@yc by-\pgf@pathminy%
+ \advance\pgf@yc by\pgflinewidth%
+ \ifdim\pgf@yc<0.1pt\pgf@yc=0.1pt\fi%
+ \pgf@xc=.02\pgf@xc%
+ \pgf@yc=.02\pgf@yc%
+ % Compute new transformation matrix:
+ \pgftransformcm{1}{0}{0}{1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgftransformcm{\pgf@sys@tonumber{\pgf@xc}}{0}{0}{\pgf@sys@tonumber{\pgf@yc}}{\pgfpointorigin}%
+ \pgfsys@clipfading%
+ #2%
+ }%
+ \fi%
+}
+
+
+% Group things in a a transparency group
+%
+% Description:
+%
+% This takes groups pgf commands inside a pgfpicture in a transparency
+% group. This means that any transparency settings apply to commands a
+% whole. For instance, if a box contains two overlapping black
+% circles and you draw them normally with 50% transparency, then the
+% overlap will be darker than the rest. By comparison, if the circles
+% are part of a transparency group, the overlap will get the same
+% color as the rest.
+%
+%
+
+\def\pgftransparencygroup{%
+ \pgfutil@ifnextchar[{\pgftransparencygroup@}{\pgftransparencygroup@[]}%
+}
+\def\pgftransparencygroup@[#1]{%
+ \begingroup%
+ \pgfkeys{/pgf/transparency group options/.cd,%
+ isolated=false,
+ knockout=false,
+ #1}%
+ \setbox\pgfutil@tempboxa=\hbox\bgroup%
+}
+\pgfkeys{
+ /pgf/transparency group options/.cd,
+ isolated/.is if=pgfsys@transparency@group@isolated,
+ knockout/.is if=pgfsys@transparency@group@knockout
+}
+
+\def\endpgftransparencygroup{%
+ \egroup%
+ % Now compute the correct position. This is a bit tricky...
+ \ifdim\pgf@picminx=16000pt%
+ % Nothing needs to be done
+ \else%
+ % Safety margin to avoid clipping:
+ \advance\pgf@picminx by-1cm%
+ \advance\pgf@picmaxx by1cm%
+ \advance\pgf@picminy by-1cm%
+ \advance\pgf@picmaxy by1cm%
+ % Ok, set the box size to current picture size.
+ \setbox\pgfutil@tempboxa=\hbox{%
+ \vrule width0pt height\pgf@picmaxy depth-\pgf@picminy%
+ \hskip-\pgf@picminx%
+ \box\pgfutil@tempboxa%
+ \hskip\pgf@picmaxx%
+ }%
+ \pgfsys@transparencygroupfrombox\pgfutil@tempboxa%
+ \wd\pgfutil@tempboxa=0pt%
+ \ht\pgfutil@tempboxa=0pt%
+ \dp\pgfutil@tempboxa=0pt%
+ \hskip\pgf@picminx\box\pgfutil@tempboxa\hskip-\pgf@picminx%
+ \fi%
+ \endgroup%
+}
+
+\let\startpgftransparencygroup=\pgftransparencygroup
+\let\stoppgftransparencygroup=\endpgftransparencygroup
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex
new file mode 100644
index 0000000000..1a9173fddc
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex
@@ -0,0 +1,264 @@
+% Copyright 2019 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{calc,decorations.markings}%
+
+
+%
+% Indicate that the picture contains a circuit
+%
+\tikzset{
+ circuit/.style={
+ every circuit/.try,
+ /utils/exec=\tikz@lib@circ@on@tofalse,
+ execute at begin to={
+ \tikz@lib@circ@on@totrue
+ \let\tikz@lib@circ@start@node\pgfutil@empty
+ \def\tikz@lib@circ@end{-- (\tikztotarget) \tikztonodes}
+ }
+ }
+}%
+
+\newif\iftikz@lib@circ@on@to
+
+
+%
+% General management
+%
+
+\tikzset{
+ circuit handle symbol/.code={%
+ \global\advance\tikz@lib@circ@count by1\relax%
+ \iftikz@lib@circ@on@to
+ {%
+ % Compute the tikz@time...
+ \pgfkeys{
+ /pgf/key filters/active families or no family/.install key filter={/pgf/key filters/false}{/pgf/key filters/false},
+ /tikz/circuits/pos grabber/.activate family}
+ \pgfqkeysfiltered{/tikz}{pos=.5,#1}%
+ \expandafter%
+ }%
+ \expandafter\def\expandafter\tikz@lib@circ@pos\expandafter{\tikz@time}%
+ \pgfkeysalso{to path={
+ \pgfextra{\tikz@lib@circ@on@tofalse}
+ decorate [decoration={markings,mark connection node=mark node}]
+ {
+ \tikz@lib@circ@start@node
+ \tikz@lib@circ@end
+ }
+ }}
+ \ifdim\tikz@lib@circ@pos pt=0pt\relax%
+ \def\tikz@lib@circ@start@node{%
+ {\pgfextra{\tikz@lib@circ@compute@direction{\tikz@lib@circ@start}}%
+ node[alias=tikz@lib@circ@node@start,at={(0,0)},#1,pos=]{}}(tikz@lib@circ@node@start)}%
+ \else%
+ \ifdim\tikz@lib@circ@pos pt=1pt\relax%
+ \def\tikz@lib@circ@end{
+ {\pgfextra{\tikz@lib@circ@compute@direction{\tikz@lib@circ@target}}%
+ node[alias=tikz@lib@circ@node\the\tikz@lib@circ@count,at={(0,0)},#1,pos=]{}}
+ --(tikz@lib@circ@node\the\tikz@lib@circ@count)\tikztonodes
+ }%
+ \else%
+ \edef\tikz@marshal{mark=at position \tikz@lib@circ@pos\space with}%
+ \def\tikz@marshala{decoration=}%
+ \expandafter\expandafter\expandafter\tikzset%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@marshala\expandafter{\tikz@marshal{\node[alias=mark node,#1,pos=]{};}}}
+ \fi%
+ \fi%
+ \else
+ \pgfkeysalso{#1}
+ \fi
+ }
+}%
+\newcount\tikz@lib@circ@count
+
+\def\tikz@lib@circ@compute@direction#1{%
+ \tikz@scan@one@point\tikz@lib@circ@save@start(\tikztostart)%
+ \tikz@scan@one@point\tikz@lib@circ@save@target(\tikztotarget)%
+ \pgf@process{\pgfpointnormalised{\pgfpointdiff{\tikz@lib@circ@start}{\tikz@lib@circ@target}}}%
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm{\the\pgf@x}{\the\pgf@y}{\the\pgf@ya}{\the\pgf@x}{#1}%
+}%
+\def\tikz@lib@circ@save@start#1{\def\tikz@lib@circ@start{#1}}%
+\def\tikz@lib@circ@save@target#1{\def\tikz@lib@circ@target{#1}}%
+
+\tikzset{
+ circuits/pos grabber/.is family,
+ pos/.belongs to family=/tikz/circuits/pos grabber,
+ at start/.belongs to family=/tikz/circuits/pos grabber,
+ very near start/.belongs to family=/tikz/circuits/pos grabber,
+ near start/.belongs to family=/tikz/circuits/pos grabber,
+ midway/.belongs to family=/tikz/circuits/pos grabber,
+ near end/.belongs to family=/tikz/circuits/pos grabber,
+ very near end/.belongs to family=/tikz/circuits/pos grabber,
+ at end/.belongs to family=/tikz/circuits/pos grabber
+}%
+
+
+%
+% Declaring a new symbol
+%
+\tikzset{
+ circuit declare symbol/.style args={#1}{
+ % Declares a new circuit symbol.
+ %
+ % #1 = name
+ % #2 = factor for default minimum width
+ % #3 = factor for default minimum height
+ %
+ % The following styles are defined:
+ %
+ % #1
+ % Can be given as an option to a "node" command or to a "to"
+ % command. It takes a set of options as parameter that will be
+ % passed to the option.
+ %
+ % set #1 graphic
+ % This keys can be set to the necessary options to make a normal
+ % node look like the symbol. For instance, for a resistor that is
+ % rendered as a rectangle, this keys can be set, basically, to
+ % "rectangle,draw". Set this key to use a different appearance for
+ % symbols of kind #1.
+ %
+ % every #1
+ % This style will be included with every symbols of this kind and
+ % can be used to configure them further.
+ %
+ % every circuit symbol
+ % This style is also included with every symbol.
+ #1/.style={circuit handle symbol={
+ inner sep=0.5pt,
+ every circuit symbol,
+ #1/graphic,
+ every #1/.try,
+ ##1}
+ },
+ #1/graphic/.style={},
+ set #1 graphic/.style={#1/graphic/.style={##1}}
+ },
+ circuit symbol unit/.code=\pgfmathsetlength\tikzcircuitssizeunit{#1},
+ circuit symbol size/.style args={width #1 height #2}{
+ minimum width={(#1)*\tikzcircuitssizeunit},
+ minimum height={(#2)*\tikzcircuitssizeunit}
+ },
+ huge circuit symbols/.style={circuit symbol unit=10pt},
+ large circuit symbols/.style={circuit symbol unit=8pt},
+ medium circuit symbols/.style={circuit symbol unit=7pt},
+ small circuit symbols/.style={circuit symbol unit=6pt},
+ tiny circuit symbols/.style={circuit symbol unit=5pt},
+}%
+
+\newdimen\tikzcircuitssizeunit
+\tikzcircuitssizeunit=7pt
+
+
+%
+% Annotations
+%
+
+\tikzset{
+ circuit declare annotation/.style args={#1#2#3}{%
+ #1/.style={
+ append after command={%
+ \bgroup
+ [current point is local=true]
+ [every circuit annotation/.try]
+ [every #1/.try]
+ [shift={(\tikzlastnode.north)}]
+ [annotation arrow,->]
+ [label distance=#2,##1]
+ #3
+ \tikz@after@path%
+ \egroup%
+ }
+ },
+ #1'/.style={
+ append after command={%
+ \bgroup
+ [current point is local=true]
+ [every circuit annotation/.try]
+ [every #1/.try]
+ [shift={(\tikzlastnode.south)},yscale=-1]
+ [annotation arrow,->]
+ [label distance=#2,##1]
+ #3
+ \tikz@after@path%
+ \egroup%
+ }
+ }
+ },
+ annotation arrow/.style = {
+ /utils/exec={\pgfsetarrowoptions{direction ee}{.4*\the\tikzcircuitssizeunit+.3*\the\pgflinewidth}},
+ >=direction ee
+ }
+}%
+
+
+
+%
+% Rotating symbols
+%
+\tikzset{
+ point up/.style={rotate=90},
+ point down/.style={rotate=-90},
+ point left/.style={rotate=180},
+ point right/.style={}
+}%
+
+
+
+%
+% Basic theming
+%
+
+\tikzset{
+ every circuit symbol/.style={},
+ circuit symbol open/.style={draw},
+ circuit symbol filled/.style={draw,fill=black},
+ circuit symbol lines/.style={draw},
+ circuit symbol wires/.style={draw},
+}%
+
+
+
+
+
+%
+% Labels
+%
+
+\tikzset{
+ info/.code={\pgfutil@ifnextchar[\tikz@lib@circ@lab@plain{\tikz@lib@circ@lab@plain[]}#1\pgf@stop},%}
+ info'/.code={\pgfutil@ifnextchar[\tikz@lib@circ@labp@plain{\tikz@lib@circ@labp@plain[]}#1\pgf@stop},%}
+ info sloped/.code={\pgfutil@ifnextchar[\tikz@lib@circ@lab@sloped@plain{\tikz@lib@circ@lab@sloped@plain[]}#1\pgf@stop},%}
+ info' sloped/.code={\pgfutil@ifnextchar[\tikz@lib@circ@lab@slopedp@plain{\tikz@lib@circ@lab@slopedp@plain[]}#1\pgf@stop},%}
+ circuit declare unit/.style 2 args={
+ %
+ % Defines four styles that can be used to add labels to a node.
+ %
+ #1/.code={\pgfutil@ifnextchar[\tikz@lib@circ@lab{\tikz@lib@circ@lab[]}##1\pgf@stop{#2}{#1}},%}
+ #1 sloped/.code={\pgfutil@ifnextchar[\tikz@lib@circ@lab@sloped{\tikz@lib@circ@lab@sloped[]}##1\pgf@stop{#2}{#1}},%}
+ #1'/.code={\pgfutil@ifnextchar[\tikz@lib@circ@labp{\tikz@lib@circ@labp[]}##1\pgf@stop{#2}{#1}},%}
+ #1' sloped/.code={\pgfutil@ifnextchar[\tikz@lib@circ@lab@slopedp{\tikz@lib@circ@lab@slopedp[]}##1\pgf@stop{#2}{#1}}%}
+ }
+}%
+
+\def\tikz@lib@circ@lab[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,#1]$\mathrm{#2#3}$}}}%
+\def\tikz@lib@circ@lab@sloped[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,transform shape,#1]$\mathrm{#2#3}$}}}%
+\def\tikz@lib@circ@labp[#1]#2\pgf@stop#3#4{\tikzset{label={[label position=below,every info/.try,every #4/.try,#1]$\mathrm{#2#3}$}}}%
+\def\tikz@lib@circ@lab@slopedp[#1]#2\pgf@stop#3#4{\tikzset{label={[label position=below,every info/.try,every #4/.try,transform shape,#1]$\mathrm{#2#3}$}}}%
+
+\def\tikz@lib@circ@lab@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,#1]#2}}}%
+\def\tikz@lib@circ@lab@sloped@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,transform shape,#1]#2}}}%
+\def\tikz@lib@circ@labp@plain[#1]#2\pgf@stop{\tikzset{label={[label position=below,every info/.try,#1]#2}}}%
+\def\tikz@lib@circ@lab@slopedp@plain[#1]#2\pgf@stop{\tikzset{label={[label position=below,every info/.try,transform shape,#1]#2}}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.IEC.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.IEC.code.tex
new file mode 100644
index 0000000000..9d1cfcfcea
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.IEC.code.tex
@@ -0,0 +1,442 @@
+% Copyright 2019 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{arrows}%
+\usetikzlibrary{circuits.ee}%
+
+\usepgflibrary{shapes.gates.ee.IEC}%
+
+
+%
+% When this lib is loaded, all symbols default to IEC
+%
+
+\tikzset{
+ circuit ee IEC/.style=
+ {
+ circuit ee,
+ set resistor graphic = resistor IEC graphic,
+ set inductor graphic = inductor IEC graphic,
+ set capacitor graphic = capacitor IEC graphic,
+ set contact graphic = contact IEC graphic,
+ set ground graphic = ground IEC graphic,
+ set battery graphic = battery IEC graphic,
+ set diode graphic = diode IEC graphic,
+ set Zener diode graphic = Zener diode IEC graphic,
+ set tunnel diode graphic = tunnel diode IEC graphic,
+ set backward diode graphic = backward diode IEC graphic,
+ set Schottky diode graphic = Schottky diode IEC graphic,
+ set breakdown diode graphic = breakdown diode IEC graphic,
+ set bulb graphic = bulb IEC graphic,
+ set voltage source graphic = voltage source IEC graphic,
+ set current source graphic = current source IEC graphic,
+ set make contact graphic = make contact IEC graphic,
+ set break contact graphic = break contact IEC graphic,
+ set amperemeter graphic = amperemeter graphic,
+ set voltmeter graphic = voltmeter graphic,
+ set ohmmeter graphic = ohmmeter graphic,
+ set ac source graphic = ac source graphic,
+ set dc source graphic = dc source graphic,
+ },
+}%
+
+
+%
+% Resistors
+%
+
+\tikzset{
+ resistor IEC graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 4 height 1,
+ shape=rectangle ee,
+ transform shape,
+ },
+ var resistor IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width 4.8 height 0.8,
+ shape=var resistor IEC,
+ transform shape,
+ outer sep=0pt,
+ cap=round,
+ },
+}%
+
+
+
+%
+% Inductors
+%
+
+\tikzset{
+ inductor IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width 4 height .5,
+ transform shape,
+ shape=inductor IEC,
+ outer sep=0pt,
+ cap=round,
+ },
+ var inductor IEC graphic/.style={
+ circuit symbol filled,
+ circuit symbol size=width 4 height 1,
+ transform shape,
+ shape=rectangle ee,
+ },
+}%
+
+
+
+%
+% Capacitors
+%
+
+\tikzset{
+ capacitor IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width .5 height 2,
+ transform shape,
+ shape=capacitor IEC,
+ },
+}%
+
+
+
+%
+% Ground
+%
+
+\tikzset{
+ ground IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width .75 height 2,
+ transform shape,
+ shape=ground IEC,
+ },
+}%
+
+
+
+
+%
+% Battery
+%
+
+\tikzset{
+ battery IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width .5 height 2.5,
+ transform shape,
+ shape=battery IEC,
+ transform shape,
+ },
+}%
+
+
+
+%
+% Diodes
+%
+
+\tikzset{
+ %
+ % normal diode
+ %
+ diode IEC graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 1.25 height 1.25,
+ transform shape,
+ shape=generic diode IEC,
+ /pgf/generic diode IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{0pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1pt}}
+ \pgfusepathqstroke
+ },
+ },
+ var diode IEC graphic/.style={
+ diode IEC graphic,
+ circuit symbol filled,
+ },
+}%
+
+\tikzset{
+ %
+ % Zener diode
+ %
+ Zener diode IEC graphic/.style={
+ diode IEC graphic,
+ /pgf/generic diode IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{-.5pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1pt}}
+ \pgfusepathqstroke
+ },
+ },
+ var Zener diode IEC graphic/.style={
+ Zener diode IEC graphic,
+ circuit symbol filled,
+ },
+}%
+
+\tikzset{
+ %
+ % Schottky diode
+ %
+ Schottky diode IEC graphic/.style={
+ diode IEC graphic,
+ /pgf/generic diode IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{-.4pt}{-.6pt}}
+ \pgfpathlineto{\pgfqpoint{-.4pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1pt}}
+ \pgfpathlineto{\pgfqpoint{.4pt}{1pt}}
+ \pgfpathlineto{\pgfqpoint{.4pt}{.6pt}}
+ \pgfusepathqstroke
+ },
+ },
+ var Schottky diode IEC graphic/.style={
+ Schottky diode IEC graphic,
+ circuit symbol filled,
+ },
+}%
+
+\tikzset{
+ %
+ % tunnel diode
+ %
+ tunnel diode IEC graphic/.style={
+ diode IEC graphic,
+ /pgf/generic diode IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{-.5pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1pt}}
+ \pgfpathlineto{\pgfqpoint{-.5pt}{1pt}}
+ \pgfusepathqstroke
+ },
+ },
+ var tunnel diode IEC graphic/.style={
+ tunnel diode IEC graphic,
+ circuit symbol filled,
+ },
+}%
+
+\tikzset{
+ %
+ % backward diode
+ %
+ backward diode IEC graphic/.style={
+ diode IEC graphic,
+ /pgf/generic diode IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{-.5pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{.5pt}{-1pt}}
+ \pgfpathmoveto{\pgfqpoint{0pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1pt}}
+ \pgfpathmoveto{\pgfqpoint{-.5pt}{1pt}}
+ \pgfpathlineto{\pgfqpoint{.5pt}{1pt}}
+ \pgfusepathqstroke
+ },
+ },
+ var backward diode IEC graphic/.style={
+ backward diode IEC graphic,
+ circuit symbol filled,
+ },
+}%
+
+
+\tikzset{
+ %
+ % breakdown diode
+ %
+ breakdown diode IEC graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 2.5 height 1.25,
+ transform shape,
+ shape=breakdown diode IEC,
+ },
+ var breakdown diode IEC graphic/.style={
+ breakdown diode IEC graphic,
+ circuit symbol filled,
+ },
+}%
+
+
+
+%
+% Contacts
+%
+
+\tikzset{
+ contact IEC graphic/.style={
+ circuit symbol filled,
+ circuit symbol size=width .5 height .5,
+ shape=circle ee,
+ outer sep=.25\pgflinewidth,
+ },
+% connection IEC graphic/.style={
+% circuit symbol open,
+% circuit symbol size=width 1 height 1,
+% shape=circle ee,
+% outer sep=.25\pgflinewidth,
+% },
+}%
+
+
+%
+% Bulbs
+%
+
+\tikzset{
+ bulb IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width 1.5 height 1.5,
+ shape=generic circle IEC,
+ /pgf/generic circle IEC/before background={
+ \pgfpathmoveto{\pgfpointpolar{-135}{1pt}}
+ \pgfpathlineto{\pgfpointpolar{45}{1pt}}
+ \pgfpathmoveto{\pgfpointpolar{-45}{1pt}}
+ \pgfpathlineto{\pgfpointpolar{135}{1pt}}
+ \pgfusepathqstroke
+ },
+ transform shape,
+ },
+}%
+
+
+%
+% Current and voltage sources
+%
+
+\tikzset{
+ current source IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width 2 height 2,
+ shape=generic circle IEC,
+ /pgf/generic circle IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{0pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1pt}}
+ \pgfusepathqstroke
+ },
+ transform shape,
+ },
+ voltage source IEC graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width 2 height 2,
+ shape=generic circle IEC,
+ /pgf/generic circle IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{-1pt}{0pt}}
+ \pgfpathlineto{\pgfqpoint{1pt}{0pt}}
+ \pgfusepathqstroke
+ },
+ transform shape,
+ },
+}%
+
+
+
+%
+% Contacts
+%
+
+\tikzset{
+ make contact IEC graphic/.style={
+ circuit symbol wires,
+ circuit symbol size=width 2 height 1,
+ transform shape,
+ shape=make contact IEC,
+ outer sep=0pt,
+ cap=round,
+ },
+ var make contact IEC graphic/.style={
+ circuit symbol wires,
+ circuit symbol size=width 2.4 height 1,
+ transform shape,
+ shape=var make contact IEC,
+ outer sep=0pt,
+ cap=round,
+ },
+}%
+
+
+\tikzset{
+ break contact IEC graphic/.style={
+ circuit symbol wires,
+ circuit symbol size=width 2 height 1,
+ transform shape,
+ shape=break contact IEC,
+ outer sep=0pt,
+ cap=round,
+ },
+}%
+
+
+
+%
+% Measurement devices
+%
+
+\tikzset{
+ amperemeter graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 2 height 2,
+ transform shape,
+ shape=generic circle IEC,
+ info=center:A,
+ },
+ voltmeter graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 2 height 2,
+ transform shape,
+ shape=generic circle IEC,
+ info=center:V,
+ },
+ ohmmeter graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 2 height 2,
+ transform shape,
+ shape=generic circle IEC,
+ info=center:$\Omega$,
+ },
+}%
+
+
+
+%
+% AC/DC
+%
+
+\tikzset{
+ ac source graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width 2 height 2,
+ shape=generic circle IEC,
+ /pgf/generic circle IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{0.7pt}{0pt}}
+ \pgfpathquadraticcurveto{\pgfqpoint{ 0.35pt}{-0.5pt}}{\pgfqpoint{0pt}{0pt}}
+ \pgfpathquadraticcurveto{\pgfqpoint{-0.35pt}{ 0.5pt}}{\pgfqpoint{-0.7pt}{0pt}}
+ \pgfusepathqstroke
+ },
+ transform shape,
+ },
+ dc source graphic/.style={
+ circuit symbol lines,
+ circuit symbol size=width 2 height 2,
+ shape=generic circle IEC,
+ /pgf/generic circle IEC/before background={
+ \pgfpathmoveto{\pgfqpoint{ 0.7pt}{ 0.2pt}}
+ \pgfpathlineto{\pgfqpoint{-0.7pt}{ 0.2pt}}
+ \pgfusepathqstroke
+ \pgfpathmoveto{\pgfqpoint{ 0.7pt}{-0.2pt}}
+ \pgfpathlineto{\pgfqpoint{-0.7pt}{-0.2pt}}
+ \pgfusepathqstroke
+ },
+ transform shape,
+ },
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex
new file mode 100644
index 0000000000..2e065d7dda
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex
@@ -0,0 +1,148 @@
+
+% Copyright 2019 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{circuits}%
+\usepgflibrary{shapes.gates.ee}%
+
+
+%
+% Setting up an ee circuit
+%
+\tikzset{
+ circuit ee/.style={
+ circuit,
+ every circuit ee/.try
+ }
+}%
+
+
+%
+% The default symbols (you need to load a sublib to install the actual rendering).
+%
+
+\tikzset{
+ circuit declare symbol = resistor,
+ circuit declare symbol = inductor,
+ circuit declare symbol = capacitor,
+ circuit declare symbol = contact,
+ circuit declare symbol = ground,
+ circuit declare symbol = battery,
+ circuit declare symbol = diode,
+ circuit declare symbol = Zener diode,
+ circuit declare symbol = Schottky diode,
+ circuit declare symbol = tunnel diode,
+ circuit declare symbol = backward diode,
+ circuit declare symbol = breakdown diode,
+ circuit declare symbol = bulb,
+ circuit declare symbol = current source,
+ circuit declare symbol = voltage source,
+ circuit declare symbol = current direction,
+ circuit declare symbol = current direction',
+ circuit declare symbol = make contact,
+ circuit declare symbol = break contact,
+ circuit declare symbol = amperemeter,
+ circuit declare symbol = voltmeter,
+ circuit declare symbol = ohmmeter,
+ circuit declare symbol = ac source,
+ circuit declare symbol = dc source,
+ %
+ set current direction graphic = current direction ee graphic,
+ set current direction' graphic = current direction' ee graphic,
+}%
+
+
+%
+% The default labels
+%
+
+\tikzset{
+ circuit declare unit={ampere}{A},
+ circuit declare unit={volt}{V},
+ circuit declare unit={ohm}{\Omega},
+ circuit declare unit={siemens}{S},
+ circuit declare unit={henry}{H},
+ circuit declare unit={farad}{F},
+ circuit declare unit={coulomb}{C},
+ circuit declare unit={voltampere}{VA},
+ circuit declare unit={watt}{W},
+ circuit declare unit={hertz}{Hz},
+}%
+
+
+
+%
+% The direction and arrow settings
+%
+
+\tikzset{
+ % These styles should set the end-arrow.
+ %
+ % This arrow will generally be used to indicate current directions in a circuit:
+ current direction arrow/.style = {
+ /utils/exec={\pgfsetarrowoptions{direction ee}{1.3065*.5*\the\tikzcircuitssizeunit+1.3065*.3*\the\pgflinewidth}},
+ >=direction ee,
+ direction ee arrow = direction ee,
+ }
+}%
+
+
+
+
+\tikzset{
+ current direction ee graphic/.style = {
+ shape=direction ee,
+ circuit symbol filled,
+ current direction arrow,
+ minimum width = .5*\the\tikzcircuitssizeunit+.3*\the\pgflinewidth,
+ minimum height = .5*\the\tikzcircuitssizeunit+.3*\the\pgflinewidth,
+ transform shape
+ },
+ current direction' ee graphic/.style = {
+ current direction ee graphic,
+ rotate=180
+ }
+}%
+
+
+
+%
+% Annotations
+%
+
+\tikzset{
+ circuit declare annotation={direction info}{.5\tikzcircuitssizeunit}
+ {
+ (-1.25\tikzcircuitssizeunit,.3333\tikzcircuitssizeunit) edge[line to] (1.25\tikzcircuitssizeunit,.3333\tikzcircuitssizeunit)
+ },
+ circuit declare annotation={light emitting}{1.75\tikzcircuitssizeunit}
+ {
+ (-.2\tikzcircuitssizeunit,.65\tikzcircuitssizeunit) edge[line to] ++(45:1.25\tikzcircuitssizeunit)
+ (.2\tikzcircuitssizeunit,.25\tikzcircuitssizeunit) edge[line to] ++(45:1.25\tikzcircuitssizeunit)
+ },
+ circuit declare annotation={light dependent}{1.75\tikzcircuitssizeunit}
+ {
+ [shift=(135:1.25\tikzcircuitssizeunit)]
+ (.2\tikzcircuitssizeunit,.65\tikzcircuitssizeunit) edge[line to] ++(-45:1.25\tikzcircuitssizeunit)
+ (-.2\tikzcircuitssizeunit,.25\tikzcircuitssizeunit) edge[line to] ++(-45:1.25\tikzcircuitssizeunit)
+ },
+ circuit declare annotation={adjustable}{1.5\tikzcircuitssizeunit}
+ {
+ [shift=(\tikzlastnode.center)]
+ (-1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit)
+ },
+ circuit declare annotation={adjustable'}{1.5\tikzcircuitssizeunit}
+ {
+ [shift=(\tikzlastnode.center)]
+ (-1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit)
+ }
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.CDH.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.CDH.code.tex
new file mode 100644
index 0000000000..743bc24be8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.CDH.code.tex
@@ -0,0 +1,28 @@
+% Copyright 2018 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{circuits.logic.US}%
+
+\tikzset{
+ circuit logic CDH/.style =
+ {
+ circuit logic US,
+ set and gate graphic = and gate CDH graphic,
+ set nand gate graphic = nand gate CDH graphic,
+ }
+}%
+
+\tikzset{
+ circuit logic US make graphic=and gate CDH,
+ circuit logic US make graphic=nand gate CDH,
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.IEC.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.IEC.code.tex
new file mode 100644
index 0000000000..3d74ccd197
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.IEC.code.tex
@@ -0,0 +1,75 @@
+% Copyright 2018 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{circuits.logic}%
+\usepgflibrary{shapes.gates.logic.IEC}%
+
+
+%
+% When this lib is loaded, all symbols default to IEC
+%
+
+\tikzset{
+ circuit logic IEC/.style=
+ {
+ circuit logic,
+ set and gate graphic = and gate IEC graphic,
+ set nand gate graphic = nand gate IEC graphic,
+ set or gate graphic = or gate IEC graphic,
+ set nor gate graphic = nor gate IEC graphic,
+ set xor gate graphic = xor gate IEC graphic,
+ set xnor gate graphic = xnor gate IEC graphic,
+ set not gate graphic = not gate IEC graphic,
+ set buffer gate graphic = buffer gate IEC graphic,
+ %
+ and gate IEC symbol = {$\scriptstyle\char`\&$},
+ nand gate IEC symbol = {$\scriptstyle\char`\&$},
+ or gate IEC symbol = {$\scriptstyle\geq1$},
+ nor gate IEC symbol = {$\scriptstyle\geq1$},
+ xor gate IEC symbol = {$\scriptstyle=1$},
+ xnor gate IEC symbol = {$\scriptstyle=1$},
+ not gate IEC symbol = {$\scriptstyle1$},
+ buffer gate IEC symbol = {$\scriptstyle1$},
+ },
+}%
+
+
+%
+% The logical gate graphics are all nearly identical, so we provide a
+% simple style for creating them:
+%
+\tikzset{
+ circuit logic IEC make graphic/.style=
+ {
+ #1 graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 2.5 height 4,
+ shape=#1,
+ inner sep=.5ex
+ }
+ }
+}%
+
+
+\tikzset{
+ circuit logic IEC make graphic=and gate IEC,
+ circuit logic IEC make graphic=nand gate IEC,
+ circuit logic IEC make graphic=or gate IEC,
+ circuit logic IEC make graphic=nor gate IEC,
+ circuit logic IEC make graphic=xor gate IEC,
+ circuit logic IEC make graphic=xnor gate IEC,
+ circuit logic IEC make graphic=not gate IEC,
+ circuit logic IEC make graphic=buffer gate IEC,
+ circuit logic IEC make graphic=and gate CDH,
+ circuit logic IEC make graphic=nand gate CDH,
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.US.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.US.code.tex
new file mode 100644
index 0000000000..b20b4d58ba
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.US.code.tex
@@ -0,0 +1,64 @@
+% Copyright 2018 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{circuits.logic}%
+\usepgflibrary{shapes.gates.logic.US}%
+
+
+%
+% When this lib is loaded, all symbols default to IEC
+%
+
+\tikzset{
+ circuit logic US/.style=
+ {
+ circuit logic,
+ set and gate graphic = and gate US graphic,
+ set nand gate graphic = nand gate US graphic,
+ set or gate graphic = or gate US graphic,
+ set nor gate graphic = nor gate US graphic,
+ set xor gate graphic = xor gate US graphic,
+ set xnor gate graphic = xnor gate US graphic,
+ set not gate graphic = not gate US graphic,
+ set buffer gate graphic = buffer gate US graphic
+ }
+}%
+
+
+%
+% The logical gate graphics are all nearly identical, so we provide a
+% simple style for creating them:
+%
+\tikzset{
+ circuit logic US make graphic/.style=
+ {
+ #1 graphic/.style={
+ circuit symbol open,
+ circuit symbol size=width 0 height 2.5,
+ shape=#1,
+ transform shape
+ }
+ }
+}%
+
+
+\tikzset{
+ circuit logic US make graphic=and gate US,
+ circuit logic US make graphic=nand gate US,
+ circuit logic US make graphic=or gate US,
+ circuit logic US make graphic=nor gate US,
+ circuit logic US make graphic=xor gate US,
+ circuit logic US make graphic=xnor gate US,
+ circuit logic US make graphic=not gate US,
+ circuit logic US make graphic=buffer gate US,
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.code.tex
new file mode 100644
index 0000000000..390d022a8a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.code.tex
@@ -0,0 +1,45 @@
+% Copyright 2018 by Till Tantau and Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{circuits}%
+
+
+
+%
+% Provides a shortcut to the "logic gates inputs" key.
+%
+
+\tikzset{
+ circuit logic/.style={
+ circuit,
+ inputs/.style={logic gate inputs={##1}},
+ logic gate inverted radius=.25\tikzcircuitssizeunit,
+ every circuit logic/.try,
+ }
+}%
+
+
+
+%
+% The default symbols (you need to load a sublib to install the actual rendering).
+%
+
+\tikzset{
+ circuit declare symbol = and gate,
+ circuit declare symbol = nand gate,
+ circuit declare symbol = or gate,
+ circuit declare symbol = nor gate,
+ circuit declare symbol = xor gate,
+ circuit declare symbol = xnor gate,
+ circuit declare symbol = not gate,
+ circuit declare symbol = buffer gate
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.3d.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.3d.code.tex
new file mode 100644
index 0000000000..df08b507d5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.3d.code.tex
@@ -0,0 +1,79 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarydatavisualization.3d.code.tex}
+
+\usetikzlibrary{datavisualization}%
+
+
+
+% The following is not yet really implement. But you might get the idea...
+
+
+
+% A 3d version of the school book plot
+
+\tikzdatavisualizationset{
+ school book 3d plot/.style={
+ xyz Cartesian,
+ x axis={
+ visualize axis={y axis={goto=0},z axis={goto=0},styling/.style=->},
+ visualize ticks={common={y axis={goto=0},z axis={goto=0},direction axis=y axis},only ticks={tick text at min extend}},
+% visualize ticks={common={y axis={goto=0},z axis={goto=0},direction axis=z axis}},
+ },
+ y axis={
+ visualize axis={x axis={goto=0},z axis={goto=0},styling/.style=->},
+ visualize ticks={common={x axis={goto=0},z axis={goto=0},direction axis=x axis},only ticks={tick text at min extend}},
+% visualize ticks={common={x axis={goto=0},z axis={goto=0},direction axis=z axis}},
+ },
+ z axis={
+ visualize axis={x axis={goto=0},y axis={goto=0},styling/.style=->},
+ visualize ticks={common={x axis={goto=0},y axis={goto=0},direction axis=x axis},only ticks={tick text at min extend}},
+% visualize ticks={common={x axis={goto=0},y axis={goto=0},direction axis=y axis}}
+ },
+ new line plot,
+ every school book plot/.try,
+ },
+}%
+
+
+% A 3d version of the scientific plot
+%
+% Here, a "length" is used for the length of the three
+% axes, rather than a predetermined rectangle (this does not really
+% make sense for the z-axis. You overrule these settings easily.
+
+\tikzdatavisualizationset{
+ scientific 3d plot/length/.initial=100pt,
+ scientific 3d plot/.style={
+ xyz Cartesian,
+ x axis={
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific 3d plot/length},
+ visualize axis={y axis={goto=min},z axis={goto=min}},
+ visualize axis={y axis={goto=max},z axis={goto=min}},
+ visualize axis={y axis={goto=min},z axis={goto=max}},
+ visualize axis={y axis={goto=max},z axis={goto=max}},
+ },
+ y axis={
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific 3d plot/length},
+ visualize axis={x axis={goto=min},z axis={goto=min}},
+ visualize axis={x axis={goto=max},z axis={goto=min}},
+ visualize axis={x axis={goto=min},z axis={goto=max}},
+ visualize axis={x axis={goto=max},z axis={goto=max}},
+ },
+ z axis={
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific 3d plot/length},
+ visualize axis={x axis={goto=min},y axis={goto=min}},
+ visualize axis={x axis={goto=max},y axis={goto=min}},
+ visualize axis={x axis={goto=min},y axis={goto=max}},
+ visualize axis={x axis={goto=max},y axis={goto=max}},
+ },
+ new line plot,
+ },
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.barcharts.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.barcharts.code.tex
new file mode 100644
index 0000000000..3780a4638a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.barcharts.code.tex
@@ -0,0 +1,43 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarydatavisualization.barcharts.code.tex}
+
+\usetikzlibrary{datavisualization}%
+\usepgflibrary{datavisualization.barcharts}%
+
+
+\tikzdatavisualizationset{%
+ candle stick plot/.style={
+ new object={
+ store=/tikz/data visualization/count,
+ class=count,
+ arg1=day
+ },
+ new axis=y axis,
+ y axis/source=dax,
+ y axis/source max=100,
+ y axis/vec=\pgfqpoint{0cm}{1cm},
+ new object={
+ store=/tikz/data visualization/x line trans,
+ class=line transformer,
+ arg1=day,
+ arg2=\pgfqpoint{3mm}{0mm}
+ },
+ new object={
+ store=/tikz/data visualization/index,
+ class=candle stick visualizer,
+ arg1 from key=index/source
+ },
+ },
+ index/source/.initial=index,
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex
new file mode 100644
index 0000000000..04dae1e6b5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex
@@ -0,0 +1,2733 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarydatavisualization.code.tex}
+
+\usepgfmodule{datavisualization}%
+\usetikzlibrary{backgrounds}%
+
+
+\tikzset{/tikz/data visualization/.is family,
+ /tikz/data visualization/.unknown/.code={
+ \let\tikz@dv@key\pgfkeyscurrentname%
+ \pgfkeys{/tikz/\tikz@dv@key/.try={#1}}%
+ \ifpgfkeyssuccess%
+ \else%
+ \edef\pgf@temp{/errors/unknown key={/tikz/data visualization/\tikz@dv@key}}%
+ \expandafter\pgfkeys\expandafter{\pgf@temp{#1}}%
+ \fi%
+ },
+ /tikz/data visualization/data/.unknown/.code={%
+ % Redirect to /pgf/data
+ \let\tikz@dv@key\pgfkeyscurrentname%
+ \pgfkeys{/pgf/data/\tikz@dv@key/.try={#1}}%
+ \ifpgfkeyssuccess%
+ \else%
+ \edef\pgf@temp{/errors/unknown key={/pgf/data/\tikz@dv@key}}%
+ \expandafter\pgfkeys\expandafter{\pgf@temp{#1}}%
+ \fi%
+ },
+}%
+
+\def\tikzdatavisualizationset{\pgfqkeys{/tikz/data visualization}}%
+
+
+
+
+% The main \datavisualization command
+%
+% This command must, as always, be given inside a tikz picture. It
+% will add a data visualization to the picture; use "shift" option and
+% friends to place the data visualization somewhere other than at the
+% origin.
+%
+% The \datavisualization is followed by a sequence of blocks and ended
+% with a semicolon. Each block may be one of the following:
+%
+% "data" blocks.
+%
+% Syntax: data [options] % options specify an external source
+% Syntax: data [options] { inline data }
+%
+% The optional arguments may either specify an
+% external data source or the data may follow inline.
+%
+% The options are executed for the path /pgf/data. The style
+% /tikz/every data is executed for each data, which can be useful to
+% generally set, say, a certain data format.
+%
+%
+% "data set" blocks.
+%
+% Syntax: data set [options] {name} = { ... }
+% Syntax: data set [options] {name} += { ... }
+% Syntax: data set [options] {name}
+%
+% The first syntax allows you to define a data set. The data block
+% inside {...} will be stored inside the data set
+% "name". Subsequently, the data set can be referenced by using the
+% third syntax. The second syntax allows you to extend the
+% definition of an already defined data set.
+%
+%
+% "info" and "info'" blocks.
+%
+% Syntax: info [options] {code}
+% Syntax: info' [options] {code}
+%
+% A block starting with "info" or "info'" may contain any code. It
+% will be executed after the visualization (info) or before the
+% visualization (info').
+%
+%
+% Options blocks.
+%
+% Syntax: [options]
+%
+% The options will be executed immediately.
+%
+% Scope blocks.
+%
+% Syntax: scope[options] { blocks }
+%
+% The blocks are executed inside a scope for which the options are
+% set. This can be used to group data blocks.
+%
+% Examples:
+%
+% \datavisualization[schoolbook plot]
+% data [source=my_data_file.csv]
+% ;
+%
+% \datavisualization[schoolbook plot]
+% data [format=key value pairs]
+% {
+% x=0, y=0
+% x=1, y=1
+% x=2, y=4
+% x=3, y=9
+% };
+%
+% \datavisualization[schoolbook plot]
+% data [format=function]
+% {
+% var x: interval [0:3];
+% func y = \value x*\value x;
+% }
+% [at begin visualization={
+% \fill [black!10] (visualization cs:x=0,y=0) -- (visualization cs:x=3,y=9);
+% }]
+% info[red]
+% {
+% \draw (visualization cs:x=0,y=0) -- (visualization cs:x=3,y=9);
+% };
+%
+% \datavisualization[schoolbook plot]
+% data [/data point/label=first experiment,source=file_1]
+% data [/data point/label=second experiment,source=file_2]
+% data [/data point/label=third experiment,source=file_3]
+% data [/data point/label=prediction,format=function]
+% { var x: interval [0,1]; func y = rand(\value x); }
+% ;
+
+\def\tikz@lib@datavisualization{
+ \begingroup%
+ \let\tikz@path@do@at@end=\relax%
+ % Ok, first, start a new data visualization
+ \pgfoonew \tikz@main@dv=new data visualization()%
+ % Next, create a scope for the dv
+ \pgfset{local bounding box=data visualization bounding box}%
+ % Clear the axis list
+ \pgfkeyslet{/tikz/data visualization/axes list}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/axes actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/label actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/legend actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/grid actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/major grid actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/minor grid actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/subminor grid actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/ticks actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/major ticks actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/minor ticks actions}\pgfutil@empty%
+ \pgfkeyslet{/tikz/data visualization/subminor ticks actions}\pgfutil@empty%
+ \tikz@main@dv.before visualization(%
+ )%
+ \tikz@main@dv.after visualization(%
+ \tikz@lib@dv@alias@dv@bb
+ \pgfkeysvalueof{/tikz/data visualization/grid actions}
+ \pgfkeysvalueof{/tikz/data visualization/subminor grid actions}
+ \pgfkeysvalueof{/tikz/data visualization/minor grid actions}
+ \pgfkeysvalueof{/tikz/data visualization/major grid actions}
+ \pgfkeysvalueof{/tikz/data visualization/ticks actions}
+ \pgfkeysvalueof{/tikz/data visualization/subminor ticks actions}
+ \pgfkeysvalueof{/tikz/data visualization/minor ticks actions}
+ \pgfkeysvalueof{/tikz/data visualization/major ticks actions}
+ \pgfkeysvalueof{/tikz/data visualization/axes actions}
+ \pgfkeysvalueof{/tikz/data visualization/label actions}
+ \pgfkeysvalueof{/tikz/data visualization/legend actions}
+ )%
+ %
+ \pgfset{/pgf/data/continue code=\tikz@lib@dv@parse@loop}%
+ % Now enter parse loop
+ \tikz@lib@dv@parse@loop
+}%
+
+\def\tikz@lib@dv@parse@loop{%
+ \pgfutil@ifnextchar d\tikz@lib@dv@handle@data{%
+ \pgfutil@ifnextchar ;\tikz@lib@dv@parse@end{%
+ \pgfutil@ifnextchar \par\tikz@lib@dv@handle@par{%
+ \pgfutil@ifnextchar s\tikz@lib@dv@handle@beginscope{%
+ \pgfutil@ifnextchar i\tikz@lib@dv@handle@info{%
+ \pgfutil@ifnextchar [\tikz@lib@dv@handle@options{%
+ \pgfutil@ifnextchar \egroup\tikz@lib@dv@handle@endscope{%
+ \tikzerror{Semicolon expected}%
+ \endgroup%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+}%
+\def\tikz@lib@dv@parse@end;{%
+ % Go!
+ \tikz@main@dv.survey()%
+ \tikz@main@dv.visualize()%
+ \endgroup%
+ \tikz@path@do@at@end%
+}%
+\def\tikz@lib@dv@handle@par\par{\tikz@lib@dv@parse@loop}%
+
+\def\tikz@lib@dv@handle@options[#1]{%
+ \tikzdatavisualizationset{#1}%
+ \tikz@lib@dv@parse@loop%
+}%
+
+\def\tikz@lib@dv@handle@beginscope scope{%
+ \begingroup%
+ \pgfutil@ifnextchar[\tikz@lib@dv@beg@opt{\tikz@lib@dv@beg@opt[]}%}
+}%
+\def\tikz@lib@dv@beg@opt[#1]{%
+ \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})}%
+ \pgfutil@ifnextchar\bgroup{
+ \afterassignment\tikz@lib@dv@parse@loop%
+ \let\tikz@dummy=%get rid of \bgroup
+ }{%
+ \tikzerror{Opening brace expected}%
+ \tikz@lib@dv@parse@loop%
+ }%
+}%
+\def\tikz@lib@dv@handle@endscope{%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\endgroup)}%
+ \endgroup%
+ \afterassignment\tikz@lib@dv@parse@loop%
+ \let\tikz@dummy=%get rid of \egroup
+}%
+
+\def\tikz@lib@dv@handle@data data{%
+ \pgfutil@ifnextchar g{\tikz@lib@dv@handle@data@group}{%
+ \pgfutil@ifnextchar p{\tikz@lib@dv@handle@data@point}{%
+ \pgfdata}}}%
+
+\def\tikz@lib@dv@handle@data@group group{\pgfutil@ifnextchar[{\tikz@lib@dv@handle@data@group@opt}{\tikz@lib@dv@handle@data@group@opt[]}}%}%
+
+\def\tikz@lib@dv@handle@data@group@opt[#1]#2{%
+ \pgfutil@ifnextchar={\tikz@lib@dv@handle@data@group@def{#1}{#2}}{%
+ \pgfutil@ifnextchar+{\tikz@lib@dv@handle@data@group@extend{#1}{#2}}{%
+ \tikz@lib@dv@handle@data@group@use{#1}{#2}}}}%
+
+\def\tikz@lib@dv@handle@data@group@def#1#2={%
+ \pgfkeys{/pgf/data/new group={#2}}%
+ \tikz@lib@dv@handle@data@group@extend{#1}{#2}+=%
+}%
+
+\def\tikz@lib@dv@handle@data@group@extend#1#2+={%
+ \pgfutil@ifnextchar\bgroup{
+ \begingroup%
+ \pgfkeys{/pgf/data/store in group={#2}}%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})}%
+ \afterassignment\tikz@lib@dv@parse@loop%
+ \let\tikz@dummy=%get rid of \bgroup
+ }{%
+ \tikzerror{Opening brace expected}%
+ \tikz@lib@dv@parse@loop%
+ }%
+}%
+
+\def\tikz@lib@dv@handle@data@group@use#1#2{%
+ \pgfdata[#1,use group=#2]%
+}%
+
+\def\tikz@lib@dv@handle@data@point point{\pgfutil@ifnextchar[{\tikz@lib@dv@handle@data@point@opt}{\tikz@lib@dv@handle@data@point@opt[]}}%]%
+\def\tikz@lib@dv@handle@data@point@opt[#1]{%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\bgroup\pgfkeys{/data point/.cd,#1}\pgfdatapoint\egroup}})}%
+ \tikz@lib@dv@parse@loop%
+}%
+
+\def\tikz@lib@dv@handle@info info{%
+ \pgfutil@ifnextchar'{\tikz@lib@dv@handle@info@prime}{\tikz@lib@dv@handle@info@noprime}}%
+\def\tikz@lib@dv@handle@info@noprime{%
+ \pgfutil@ifnextchar[{\tikz@lib@dv@handle@info@block@opt}{\tikz@lib@dv@handle@info@block@opt[]}}%}%
+\def\tikz@lib@dv@handle@info@block@opt[#1]#2{%
+ \tikz@main@dv.after visualization({\scope[#1]#2\endscope})%
+ \tikz@lib@dv@parse@loop
+}%
+\def\tikz@lib@dv@handle@info@prime'{%
+ \pgfutil@ifnextchar[{\tikz@lib@dv@handle@info@block@opt@prime}{\tikz@lib@dv@handle@info@block@opt@prime[]}}%}%
+\def\tikz@lib@dv@handle@info@block@opt@prime[#1]#2{%
+ \tikz@main@dv.before visualization({\scope[#1]#2\endscope})%
+ \tikz@lib@dv@parse@loop
+}%
+
+
+\pgfset{/pgf/every data/.style={/tikz/every data/.try,/tikz/data visualization/every data/.try}}%
+
+
+%
+% Performing before/after stuff via keys
+%
+
+\tikzdatavisualizationset{
+ before survey/.code=\tikz@main@dv.before survey({#1}),
+ after survey/.code=\tikz@main@dv.after survey({#1}),
+ before visualization/.code=\tikz@main@dv.before visualization({#1}),
+ after visualization/.code=\tikz@main@dv.after visualization({#1}),
+ at start survey/.code=\tikz@main@dv.at start survey({#1}),
+ at end survey/.code=\tikz@main@dv.at end survey({#1}),
+ at start visualization/.code=\tikz@main@dv.at start visualization({#1}),
+ at end visualization/.code=\tikz@main@dv.at end visualization({#1}),
+}%
+
+
+\def\tikz@lib@dv@alias@dv@bb{
+ \pgfnodealias{data bounding box}{data visualization bounding box}%
+ \pgfkeys{/pgf/freeze local bounding box=data bounding box}%
+}%
+
+%
+% The data point key
+%
+\tikzdatavisualizationset{
+ data point/.code={
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\bgroup\pgfkeys{/data point/.cd,#1}\pgfdatapoint\egroup}})}%
+ }
+}%
+
+
+%
+% Object setup
+%
+
+% The following key is used to create objects for the rendering
+% pipeline. They cannot be created "directly" because when it is known
+% that the objects needs to be created, in principle, many keys may
+% not yet be known.
+%
+% The following options are used:
+%
+% store = key that will store the object (handle)
+% class = class of the object
+% arg1 = argument1 of the constructor
+% ...
+% arg8 = argument8 of the constructor
+% when = specifies when the object will be created. Defaults to
+% "before survey", other possible values are "after survey" and
+% "before/after visualization"
+% before creation = code to be executed just before the object is
+% created
+% after creation = code to be executed just after the object has been created
+%
+% The following styles may be useful:
+%
+% arg1 from key = use the contents of the given key as arg1. Similar
+% for other args
+% arg1 handle from key = the contents of the given key should contain
+% an object. Then arg1 will be a handle to this
+% object. Similar for other args
+
+\tikzdatavisualizationset{%
+ new object/.code={%
+ \def\tikz@dv@grabbed@when{before survey}%
+ \let\tikz@dv@grabbed@store\pgfutil@empty
+ \pgfkeys{/tikz/data visualization/new object/grab/.cd,#1}%
+ \ifx\tikz@dv@grabbed@store\pgfutil@empty
+ \else
+ \pgfkeyslet{\tikz@dv@grabbed@store}\pgfutil@empty%
+ \fi
+ \edef\tikz@marshal{\noexpand\tikz@main@dv.\tikz@dv@grabbed@when(\noexpand\tikz@dv@newobject{\tikz@dv@grabbed@store}}%
+ \tikz@marshal{#1})%
+ },
+ new object/grab/store/.store in=\tikz@dv@grabbed@store,
+ new object/grab/when/.store in=\tikz@dv@grabbed@when,
+ new object/grab/.unknown/.code={},%ignore
+}%
+
+\def\tikz@dv@newobject#1#2{%
+ \def\tikz@dv@new@obj@store{#1}%
+ \ifx\tikz@dv@new@obj@store\pgfutil@empty%
+ \let\tikz@dv@new@obj=\pgfutil@empty%
+ \else%
+ \pgfkeysgetvalue\tikz@dv@new@obj@store\tikz@dv@new@obj%
+ \fi%
+ \ifx\tikz@dv@new@obj\pgfutil@empty
+ \let\tikz@dv@arg@a=\tikz@lib@notused%
+ \let\tikz@dv@arg@b=\tikz@lib@notused%
+ \let\tikz@dv@arg@c=\tikz@lib@notused%
+ \let\tikz@dv@arg@d=\tikz@lib@notused%
+ \let\tikz@dv@arg@e=\tikz@lib@notused%
+ \let\tikz@dv@arg@f=\tikz@lib@notused%
+ \let\tikz@dv@arg@g=\tikz@lib@notused%
+ \let\tikz@dv@arg@h=\tikz@lib@notused%
+ \let\tikz@dv@new@after=\relax%
+ \pgfkeys{/tikz/data visualization/new object/parse/.cd,#2}
+ \edef\pgf@marshal{\noexpand\pgfoonew\noexpand\tikzdvobj=new \tikz@dv@new@class(}%
+ \tikz@dv@add@arg{}\tikz@dv@arg@a%
+ \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@b%
+ \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@c%
+ \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@d%
+ \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@e%
+ \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@f%
+ \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@g%
+ \tikz@dv@add@arg{\expandafter,}\tikz@dv@arg@h%
+ \expandafter\def\expandafter\pgf@marshal\expandafter{\pgf@marshal)}%
+ \pgf@marshal%
+ \tikzdvobj.default connects()%
+ \ifx\tikz@dv@new@obj@store\pgfutil@empty%
+ \else%
+ \pgfkeyslet\tikz@dv@new@obj@store\tikzdvobj%
+ \fi%
+ \tikz@dv@new@after%
+ \fi
+}%
+\def\tikz@lib@notused{\tikz@lib@notused}%
+
+\def\tikz@dv@add@arg#1#2{%
+ \ifx#2\tikz@lib@notused%
+ \else%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@marshal%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@marshal#1#2}%
+ \fi%
+}%
+
+\tikzdatavisualizationset{%
+ new object/parse/.cd,
+ store/.code=,% ignore
+ when/.code=,% ignore
+ class/.store in=\tikz@dv@new@class,
+ before creation/.code={#1},
+ after creation/.store in=\tikz@dv@new@after,
+ arg1/.store in=\tikz@dv@arg@a,
+ arg2/.store in=\tikz@dv@arg@b,
+ arg3/.store in=\tikz@dv@arg@c,
+ arg4/.store in=\tikz@dv@arg@d,
+ arg5/.store in=\tikz@dv@arg@e,
+ arg6/.store in=\tikz@dv@arg@f,
+ arg7/.store in=\tikz@dv@arg@g,
+ arg8/.store in=\tikz@dv@arg@h,
+ arg1 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@a},
+ arg2 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@b},
+ arg3 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@c},
+ arg4 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@d},
+ arg5 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@e},
+ arg6 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@f},
+ arg7 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@g},
+ arg8 from key/.code=\pgfkeysgetvalue{#1}{\tikz@dv@arg@h}
+ arg1 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@a}{\tikz@dv@arg@a},
+ arg2 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@b}{\tikz@dv@arg@b},
+ arg3 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@c}{\tikz@dv@arg@c},
+ arg4 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@d}{\tikz@dv@arg@d},
+ arg5 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@e}{\tikz@dv@arg@e},
+ arg6 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@f}{\tikz@dv@arg@f},
+ arg7 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@g}{\tikz@dv@arg@g},
+ arg8 handle from key/.code=\tikz@dv@handle@from@key{#1}{\tikz@dv@handle@h}{\tikz@dv@arg@h}
+}%
+
+\def\tikz@dv@handle@from@key#1#2#3{%
+ \pgfkeysvalueof{#1}.get handle(#2)%
+ \def#3{#2}%
+}%
+
+
+
+
+%
+% Data visualization coordinate system
+%
+%
+% This cs is used to refer to points in a datavisualization. The
+% parameters are keys that are set in the /data point key
+% directory. Then, a (virtual) data point is created and the
+% calculated position is returned
+
+\tikzdeclarecoordinatesystem{visualization}
+{%
+ \tikzset{/data point/.cd,#1}%
+ \pgfpointdvlocaldatapoint%
+}%
+
+
+
+
+%
+%
+% Axes
+%
+%
+
+
+
+%
+% Axis base
+%
+
+\tikzdatavisualizationset{%
+ new axis base/.style={
+ new object={
+ class=scaling mapper,
+ store=/tikz/data visualization/#1/scaling mapper,
+ before creation={
+ \pgfkeysgetvalue{/tikz/data visualization/#1/scaling}\tikz@temp
+ \ifx\tikz@temp\pgfutil@empty%
+ \pgfkeysgetvalue{/tikz/data visualization/#1/scaling/default}\tikz@temp
+ \fi
+ \expandafter\tikz@dv@lib@parse@scaling\tikz@temp\pgf@stop%
+ \pgfkeyslet{/tikz/data visualization/#1/scaling}\tikz@temp
+ },
+ arg1 from key=/tikz/data visualization/#1/attribute,
+ arg2/.expanded=\pgfkeysvalueof{/tikz/data visualization/#1/attribute}/scaled,
+ arg3 from key=/tikz/data visualization/#1/scaling,
+ arg4 from key=/tikz/data visualization/#1/function
+ },
+ #1/attribute/.initial={#1},
+ #1/function/.initial=,
+ #1/scaling/.initial=,
+ #1/scaling/default/.initial=0 at 0 and 1 at 1,
+ #1/ticks at/.initial=,
+ #1/default ticks at/.initial=,
+ #1/major ticks/.initial=,
+ #1/minor ticks/.initial=,
+ #1/subminor ticks/.initial=,
+ #1/grid at/.initial=,
+ #1/default grid at/.initial=,
+ #1/major grid/.initial=,
+ #1/minor grid/.initial=,
+ #1/subminor grid/.initial=,
+ #1/label/.initial=,
+ #1/padding min/.initial=,
+ #1/padding max/.initial=,
+ #1/.code={
+ \let\tikz@temp\tikz@dv@axis%
+ \def\tikz@dv@axis{/tikz/data visualization/#1}%
+ \expandafter\tikz@do@axis@options\expandafter{\tikz@temp}{##1}%
+ },
+ #1/@compute at positions/.initial=\tikz@lib@dv@compute@at@linear,
+ axes list/.append={\tikz@lib@dv@do@axis{#1}}
+ },
+ all axes/.code={
+ \def\tikz@lib@dv@args{#1}%
+ \pgfkeysvalueof{/tikz/data visualization/axes list}%
+ },
+ % General styling
+ styling/.style=,
+ style/.style={styling/.append style={#1}},
+ @node styling/.initial=,
+ node styling/.style={%
+ /utils/exec={\pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@temp\expandafter\tikzset\expandafter{\tikz@temp}}},
+ node style/.style={/tikz/data visualization/@node styling/.append={,#1}},
+ % General extends (both axes, grid and ticks)
+ low/.initial=0,
+ high/.initial=0,
+ padded/.style={low=padded min,high=padded max},
+ tick length/.style={low={-#1},high={#1}},
+ % General tick and grid keys:
+ common/.initial=,
+ major/.initial=,
+ minor/.initial=,
+ subminor/.initial=,
+ @setup at setters/.style={
+ common/.code=\tikz@lib@dv@add@{common}{##1},
+ major/.code=\tikz@lib@dv@add@{major}{##1},
+ minor/.code=\tikz@lib@dv@add@{minor}{##1},
+ subminor/.code=\tikz@lib@dv@add@{subminor}{##1}
+ },
+ @setup at setters,
+ % Tick keys
+ direction axis/.initial=,
+ % Tick text modifiers
+ tick text low even padding/.initial=0pt,
+ tick text high even padding/.initial=0pt,
+ tick text low odd padding/.initial=0pt,
+ tick text high odd padding/.initial=0pt,
+ tick text odd padding/.style={tick text low odd padding={-#1},tick text high odd padding={#1}},
+ tick text even padding/.style={tick text low even padding={-#1},tick text high even padding={#1}},
+ tick text padding/.style={tick text odd padding={#1},tick text even padding={#1}},
+ stack/.style={tick text even padding={#1}},
+ stack'/.style={tick text odd padding={#1}},
+ stack/.default=1em,
+ stack'/.default=1em,
+ tick text at low/.is if=tikz@dv@min@tick@node,
+ tick text at high/.is if=tikz@dv@max@tick@node,
+ no tick text/.style={tick text at low=false,tick text at high=false},
+ %
+ every major ticks/.style={style={line cap=round},tick length=2pt},
+ every minor ticks/.style={style={solid, help lines,thin,line cap=round},tick length=1.4pt},
+ every subminor ticks/.style={style={solid, help lines,line cap=round},tick length=0.8pt},
+ clean ticks/.style={node style={fill=white}},
+ % Default grid styles
+ every grid/.style={high=max,low=min},
+ every major grid/.style={style={solid, help lines,thin,black!25}},
+ every minor grid/.style={style={solid, help lines,black!25}},
+ every subminor grid/.style={style={solid, help lines,black!10}},
+ at default ticks/.code={%
+ \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@default@at}},
+ at ticks/.code={%
+ \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@default@at}%
+ \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@at}},
+}%
+
+\def\tikz@lib@dv@add@#1#2{\pgfkeysaddvalue{/tikz/data visualization/#1}{}{,#2}}%
+
+\def\tikz@dv@lib@parse@scaling#1 at#2and #3 at#4\pgf@stop{%
+ \pgfmathsetmacro{\tikz@dv@lib@min@at}{#2}
+ \pgfmathsetmacro{\tikz@dv@lib@max@at}{#4}
+ \edef\tikz@temp{#1 at \tikz@dv@lib@min@at and #3 at \tikz@dv@lib@max@at}%
+}%
+
+
+% Ticks at
+\tikzdatavisualizationset{
+ at/.code={\def\tikz@dv@at@list{#1}},
+ also at/.code={\expandafter\def\expandafter\tikz@dv@at@list\expandafter{\tikz@dv@at@list,#1}},
+ major at/.style={major={at={#1}}},
+ minor at/.style={minor={at={#1}}},
+ subminor at/.style={subminor={at={#1}}},
+ major also at/.style={major={also at={#1}}},
+ minor also at/.style={minor={also at={#1}}},
+ subminor also at/.style={subminor={also at={#1}}},
+ options at/.code={\expandafter\def\expandafter\tikz@dv@style@at@list\expandafter{\tikz@dv@style@at@list,{#1}}},
+ no tick text at/.style={options at={#1 as [no tick text]}}
+}%
+
+
+\def\tikz@lib@dv@do@axis#1{%
+ \def\tikz@marshal{#1=}
+ \expandafter\expandafter\expandafter\tikzdatavisualizationset%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@marshal\expandafter{\tikz@lib@dv@args}}
+}%
+
+\def\tikz@do@axis@options#1#2{
+ \pgfkeys{/tikz/data visualization/axis options/.cd,#2}
+ \def\tikz@dv@axis{#1}
+}%
+\let\tikz@dv@axis\pgfutil@empty
+
+\tikzdatavisualizationset{
+ every ticks/.style={
+ node style={%
+ font=\pgfutil@font@footnotesize,
+ inner sep=1pt,
+ outer sep=.1666em,
+ rounded corners=1.5pt
+ }
+ },
+ every data set label/.style={
+ every ticks,
+ node style={
+ font=\pgfutil@font@small,
+ }
+ },
+ @color of visualizer labels/.style={text=black},
+ every label in legend/.style={
+ node style={
+ fill=none,
+ }
+ },
+ every axis label/.style={
+ node style={%
+ font=\pgfutil@font@small,
+ }
+ }
+}%
+
+
+\tikzset{
+ /tikz/data visualization/axis options/.cd,
+ %
+ % Basic setters
+ %
+ attribute/.style={\tikz@dv@axis/attribute={#1}},
+ function/.style={\tikz@dv@axis/function={#1}},
+ scaling/.style={\tikz@dv@axis/scaling={#1}},
+ padding min/.style={\tikz@dv@axis/padding min={#1}},
+ padding max/.style={\tikz@dv@axis/padding max={#1}},
+ padding/.style={padding min={-#1},padding max={#1}},
+ label/.code={%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\tikz@lib@dv@auto@attribute%
+ \tikzdatavisualizationset{\tikz@dv@axis/label/.expanded=$\noexpand\mathit{\pgfkeysvalueof{\tikz@dv@axis/attribute}}$}%
+ \else
+ \tikzdatavisualizationset{\tikz@dv@axis/label={#1}}%
+ \fi
+ },
+ label/.default=\tikz@lib@dv@auto@attribute,
+ %
+ % Strategies
+ %
+ tick placement strategy/.style={\tikz@dv@axis/@compute at positions={#1}},
+ linear steps/.style={tick placement strategy=\tikz@lib@dv@compute@at@linear},
+ %
+ % Attribute setter
+ %
+ goto/.code={\tikz@dv@goto{\tikz@dv@axis}{#1}},
+ goto pos/.code={\tikz@dv@goto@pos{\tikz@dv@axis}{#1}},
+ anchor at min/.code={\tikz@lib@dv@special@at{\tikz@dv@axis}{\tikz@dv@min@anchor}},
+ anchor at max/.code={\tikz@lib@dv@special@at{\tikz@dv@axis}{\tikz@dv@max@anchor}},
+ %
+ % Visualization setters
+ %
+ visualize axis/.code=\expandafter\tikz@lib@dv@av\expandafter{\tikz@dv@axis}{#1},
+ %
+ % Ticks settings
+ %
+ ticks/.style={\tikz@dv@axis/ticks at/.append={,#1}},
+ ticks/.default=some,
+ visualize ticks/.code=\expandafter\tikz@lib@dv@tv\expandafter{\tikz@dv@axis}{#1},
+ %
+ % Grid settings
+ %
+ grid/.style={\tikz@dv@axis/grid at/.append={,#1}},
+ grid/.default=at default ticks,
+ visualize grid/.code=\expandafter\tikz@lib@dv@gv\expandafter{\tikz@dv@axis}{#1},
+ %
+ ticks and grid/.style={\tikz@dv@axis/ticks at/.append={,#1},\tikz@dv@axis/grid at/.append={,#1}},
+ %
+ % Visualizing axis labels
+ %
+ visualize label/.code=\expandafter\tikz@lib@dv@lv\expandafter{\tikz@dv@axis}{#1},
+}%
+
+\def\tikz@lib@dv@auto@attribute{\tikz@lib@dv@auto@attribute}%
+
+
+% Range options
+\tikzdatavisualizationset{
+ axis options/.cd,
+ %
+ % Including a value in the range
+ %
+ include value/.style={%
+ /tikz/data visualization/before survey/.expanded={%
+ \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper%
+ \noexpand\foreach \noexpand\tikz@lib@dv@temp in {#1} {%
+ \noexpand\tikz@dv@axis@mapper.include in value(\noexpand\tikz@lib@dv@temp)%
+ }%
+ }%
+ },
+ %
+ % Directly setting the min or max
+ %
+ min value/.style={
+ /tikz/data visualization/at end survey/.expanded={%
+ \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper%
+ \noexpand\tikz@lib@dv@set\noexpand\tikz@dv@axis@mapper{#1}{min}%
+ }
+ },
+ max value/.style={
+ /tikz/data visualization/at end survey/.expanded={%
+ \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper%
+ \noexpand\tikz@lib@dv@set\noexpand\tikz@dv@axis@mapper{#1}{max}%
+ }
+ },
+}%
+
+\def\tikz@lib@dv@set#1#2#3{%
+ \pgfdvmathenter{\pgf@dv@value}{#2}%
+ #1.get in range interval()%
+ \pgfdvinrangeinterval.let #3(\pgf@dv@value)%
+}%
+
+% Layer options
+\tikzdatavisualizationset{
+ axis layer/.style=on background layer,
+ ticks layer/.style=on background layer,
+ ticks node layer/.style=,
+ grid layer/.style=on background layer,
+}%
+
+
+% Axis visualization
+%
+% #1 = name of the to-be-visualized axis name
+% #2 = options for the visualization
+
+\def\tikz@lib@dv@av#1#2{
+ \tikzdatavisualizationset{
+ axes actions/.append={\tikz@lib@dv@show@axis{#1}{#2}}
+ }
+}%
+
+\def\tikz@lib@dv@show@axis#1#2{%
+ \scope[data visualization/axis layer,/tikz/data visualization/.cd,low=min,high=max,every axis/.try,#2]
+ \pgfkeysgetvalue{#1/scaling mapper}\tikz@dv@axis@mapper%
+ % Ok, calculate direction vector:
+ \tikzpointandanchordirection{\tikz@dv@axis@mapper.set in to(min)}{\tikz@dv@axis@mapper.set in to(max)}
+ \xdef\tikz@dv@axis@dir{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \path[draw,/tikz/data visualization/styling]
+ \pgfextra{
+ {
+ \tikz@dv@goto{#1}{\pgfkeysvalueof{/tikz/data visualization/low}}%
+ \pgfpathdvmoveto%
+ }
+ {
+ \tikz@dv@goto{#1}{\pgfkeysvalueof{/tikz/data visualization/high}}%
+ \pgfpathdvlineto%
+ }
+ };
+ \endscope
+}%
+
+\def\tikz@dv@goto#1#2{%
+ \edef\pgf@@temp{#2}%
+ \ifx\pgf@@temp\tikz@lib@dv@padded@min@text%
+ \pgfkeysvalueof{#1/scaling mapper}.set in to(min)%
+ \pgfkeysvalueof{#1/scaling mapper}.get out()%
+ \pgfkeysgetvalue{#1/padding min}\pgf@temp%
+ \pgfmathparse{\pgf@temp}%
+ \pgfkeyslet{/data point/\pgfdvout/offset}\pgfmathresult%
+ \else%
+ \ifx\pgf@@temp\tikz@lib@dv@padded@max@text%
+ \pgfkeysvalueof{#1/scaling mapper}.set in to(max)%
+ \pgfkeysvalueof{#1/scaling mapper}.get out()%
+ \pgfkeysgetvalue{#1/padding max}\pgf@temp%
+ \pgfmathparse{\pgf@temp}%
+ \pgfkeyslet{/data point/\pgfdvout/offset}\pgfmathresult%
+ \else%
+ \pgfkeysvalueof{#1/scaling mapper}.set in to(#2)%
+ \fi%
+ \fi%
+}%
+
+\def\tikz@dv@goto@pos#1#2{%
+ \pgfkeyssetvalue{/data point/\pgfkeysvalueof{#1/attribute}/out pos}{#2}%
+}%
+
+\def\tikz@lib@dv@padded@min@text{padded min}%
+\def\tikz@lib@dv@padded@max@text{padded max}%
+
+\def\tikz@lib@dv@special@at#1#2{%
+ % Ok, calculate direction vector:
+ \tikzpointandanchordirection{\pgfkeysvalueof{#1/scaling mapper}.set in to(min)}{\pgfkeysvalueof{#1/scaling mapper}.set in to(max)}
+ \tikzset{anchor/.expanded={#2}}
+}%
+
+
+% Ticks visualization
+%
+% #1 = name of axis on which ticks should be shown
+% #2 = options for the visualization
+
+\def\tikz@lib@dv@tv#1#2{
+ \tikzdatavisualizationset{
+ ticks actions/.append={\tikz@lib@dv@default@action{ticks}{#1}{#2}},
+ major ticks actions/.append={\tikz@lib@dv@show@ticks{major}{#1}{#2}},
+ minor ticks actions/.append={\tikz@lib@dv@show@ticks{minor}{#1}{#2}},
+ subminor ticks actions/.append={\tikz@lib@dv@show@ticks{subminor}{#1}{#2}}
+ }
+}%
+
+\def\tikz@lib@dv@default@action#1#2#3{%
+ \let\tikz@marshal\pgfutil@empty%
+ {%
+ \let\tikz@lib@dv@ticks@at\pgfutil@empty%
+ \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@ticks@default@at%
+ \pgfkeysgetvalue{#2/#1 at}\tikz@lib@dv@settings%
+ \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper
+ % Normal minor etc. have no effect.
+ \tikzdatavisualizationset{major/.code=,minor/.code=,subminor/.code=,common/.code=}
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}%
+ \tikzdatavisualizationset{@setup at setters}%
+ \pgfkeysgetvalue{/tikz/data visualization/compute step}\tikz@temp@step%
+ \ifx\tikz@temp@step\pgfutil@empty%
+ % do nothing
+ \else%
+ \pgfkeysvalueof{#2/@compute at positions}%
+ \xdef\tikz@marshal{
+ major={\pgfkeysvalueof{/tikz/data visualization/major}},
+ minor={\pgfkeysvalueof{/tikz/data visualization/minor}},
+ subminor={\pgfkeysvalueof{/tikz/data visualization/subminor}}}
+ \fi
+ }%
+ \pgfkeyslet{#2/default #1 at}\tikz@marshal
+}%
+
+\def\tikz@lib@dv@show@ticks#1#2#3{%
+ % First, check whether there is anything to do at all:
+ \pgfkeysgetvalue{#2/default ticks at}\tikz@lib@dv@default@settings%
+ \ifx\tikz@lib@dv@default@settings\pgfutil@empty%
+ \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@settings%
+ \else%
+ \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@settings%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@dv@settings%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@dv@default@settings\expandafter,\tikz@lib@dv@settings}
+ \fi%
+ \ifx\tikz@lib@dv@settings\pgfutil@empty%
+ % Great, nothing to do
+ \else
+ {%
+ \let\tikz@dv@at@list\pgfutil@empty%
+ \let\tikz@dv@style@at@list\pgfutil@empty%
+ \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper
+ \scope[/tikz/data visualization/.cd,every ticks/.try,every #1 ticks/.try,#3]%
+ % Setup options
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}%
+ \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
+ \pgfkeysgetvalue{/tikz/data visualization/#1}\tikz@temp
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
+ \pgfkeysgetvalue{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/direction axis}/scaling mapper}\pgf@dv@tick@dir@mapper
+ % Ok, now it's time to draw the ticks!
+ \foreach \tikz@dv@tick@pos[count=\tikz@dv@tick@count] in \tikz@dv@at@list
+ {
+ \ifx\tikz@dv@tick@pos\pgfutil@empty
+ \c@pgf@counta=\tikz@dv@tick@count\relax%
+ \advance\c@pgf@counta by-1\relax%
+ \edef\tikz@dv@tick@count{\the\c@pgf@counta}%
+ \else
+ \expandafter\tikz@lib@dv@parse\tikz@dv@tick@pos\pgf@stop%
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}%
+ \tikz@lib@dv@mapper.set in to(\tikz@dv@tick@pos)%
+ % First, compute position of tick:
+ \pgf@process{\pgfpointdvlocaldatapoint}
+ \xdef\pgf@dv@tick@origin{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ % Ok, calculate direction vector:
+ \tikzpointandanchordirection{\pgf@dv@tick@dir@mapper.set in to(min)}{\pgf@dv@tick@dir@mapper.set in to(max)}
+ \xdef\pgf@dv@tick@dir{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ % Now, show something:
+ \tikz@lib@handle@at@style%
+ \pgfkeysgetvalue{/tikz/data visualization/high}\tikz@dv@max@val%
+ \pgfkeysgetvalue{/tikz/data visualization/low}\tikz@dv@min@val%
+ \iftikz@dv@max@tick@node\pgfmathsetmacro\tikz@dv@max@val{%
+ \tikz@dv@max@val+(\pgfkeysvalueof{%
+ /tikz/data visualization/tick text high
+ \ifodd\tikz@dv@tick@count odd \else even \fi padding}%
+ )}%
+ \fi%
+ \iftikz@dv@min@tick@node\pgfmathsetmacro\tikz@dv@min@val{%
+ \tikz@dv@min@val+(\pgfkeysvalueof{%
+ /tikz/data visualization/tick text low
+ \ifodd\tikz@dv@tick@count odd \else even \fi padding}%
+ )}%
+ \fi%
+ \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\tikz@dv@max@val}{\pgf@dv@tick@dir}}}
+ \xdef\tikz@dv@max@tick{\the\pgf@x,\the\pgf@y}
+ \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\tikz@dv@min@val}{\pgf@dv@tick@dir}}}
+ \xdef\tikz@dv@min@tick{\the\pgf@x,\the\pgf@y}
+ \scope[data visualization/ticks layer]
+ \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try}
+ \draw [/tikz/data visualization/styling] (\tikz@dv@min@tick) -- (\tikz@dv@max@tick);
+ \endscope
+ \iftikz@dv@min@tick@node
+ \scope[data visualization/ticks node layer]
+ \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try}
+ \path [/tikz/data visualization/styling] (\tikz@dv@min@tick) \tikz@dv@handle@tick{\tikz@dv@min@anchor};
+ \endscope
+ \fi
+ \iftikz@dv@max@tick@node
+ \scope[data visualization/ticks node layer]
+ \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try}
+ \path [/tikz/data visualization/styling] (\tikz@dv@max@tick) \tikz@dv@handle@tick{\tikz@dv@max@anchor};
+ \endscope
+ \fi
+ \fi
+ }
+ \endscope
+ }
+ \fi
+}%
+
+\def\tikz@lib@dv@parse#1\pgf@stop{%
+ \pgfutil@in@{as}{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@dv@parse@as#1\pgf@stop%
+ \else%
+ \tikz@lib@dv@parse@as#1as\tikz@lib@dv@typeset\pgf@stop%
+ \fi%
+}%
+\def\tikz@lib@dv@parse@as#1as{%
+ \def\tikz@dv@tick@pos{#1}%
+ \pgfutil@ifnextchar[{\tikz@lib@dv@parse@as@opt}{\tikz@lib@dv@parse@as@opt[]}%]
+}%
+\def\tikz@lib@dv@parse@as@opt[#1]{%
+ \def\tikz@lib@dv@tick@opt{#1}%
+ \pgfutil@ifnextchar\pgf@stop{\tikz@lib@dv@parse@as@text\tikz@lib@dv@typeset}{\tikz@lib@dv@parse@as@text}
+}%
+\def\tikz@lib@dv@parse@as@text#1\pgf@stop{%
+ \def\tikz@lib@dv@tick@text{#1}%
+}%
+
+\def\tikz@lib@dv@typeset{%
+ \pgfdvmathenter{\tikz@lib@dv@typesetnum}{\tikz@dv@tick@pos}%
+ \pgfdvmathexitbyscientificformat{\tikz@lib@dv@typesetnum}{\tikz@lib@dv@typesetnum}% hmm... not sure about this...
+ \pgfkeysvalueof{/tikz/data visualization/tick prefix}%
+ \pgfkeys{/tikz/data visualization/tick typesetter=\tikz@lib@dv@typesetnum}%
+ \pgfkeysvalueof{/tikz/data visualization/tick suffix}%
+}%
+
+\newif\iftikz@dv@min@tick@node
+\newif\iftikz@dv@max@tick@node
+
+\def\tikz@dv@handle@tick#1{%
+ \pgfextra{
+ \ifx\tikz@lib@dv@tick@text\pgfutil@empty%
+ \global\let\tikz@dv@tick@marshal=\pgfutil@empty% Skip!
+ \else
+ \def\tikz@dv@tick@marshal{node[anchor=#1,/tikz/data visualization/node styling]}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\tikz@dv@tick@marshal\expandafter{\expandafter{\tikz@lib@dv@tick@text}}
+ \fi
+ \expandafter}%
+ \tikz@dv@tick@marshal
+}%
+
+
+\def\tikz@lib@handle@at@style{%
+ \ifx\tikz@dv@style@at@list\pgfutil@empty% nothing to do
+ \else%
+ \let\tikz@dv@lib@this@at@style=\pgfutil@empty%
+ \pgfdvmathenter{\tikz@temp}{\tikz@dv@tick@pos}%
+ \pgfdvmathexitbyscientificformat{\tikz@dv@compare@to}{\tikz@temp}%
+ \foreach \tikz@dv@at@style in \tikz@dv@style@at@list {%
+ \ifx\tikz@dv@at@style\pgfutil@empty%
+ \else%
+ \expandafter\tikz@dv@lib@handle@one@at@style\tikz@dv@at@style\tikz@stop%
+ \fi%
+ }
+ \ifx\tikz@dv@lib@this@at@style\pgfutil@empty%
+ \else%
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@dv@lib@this@at@style}%
+ \fi%
+ \fi%
+}%
+
+\def\tikz@dv@lib@handle@one@at@style#1as#2[#3]#4\tikz@stop{%
+ \pgfdvmathenter{\tikz@lib@dv@at@math@var}{#1}%
+ \pgfdvmathexitbyscientificformat{\tikz@dv@temp}{\tikz@lib@dv@at@math@var}%
+ \ifx\tikz@dv@temp\tikz@dv@compare@to%
+ % Bingo!
+ \expandafter\gdef\expandafter\tikz@dv@lib@this@at@style\expandafter{\tikz@dv@lib@this@at@style,#3}%
+ \fi%
+}%
+
+
+% Help function
+\def\tikzpointandanchordirection#1#2{%
+ % This function works like pgfpointdvdirection, but also computes
+ % appropriate "min" and "max" anchors.
+ \pgf@process{\pgfpointdvdirection{#1}{#2}}
+ {
+ \pgf@ya=\pgf@y
+ \pgf@y=-\pgf@x
+ \pgf@x=\pgf@ya
+ \tikz@auto@anchor
+ \xdef\tikz@dv@max@anchor{\tikz@anchor}
+ \tikz@auto@anchor@prime
+ \xdef\tikz@dv@min@anchor{\tikz@anchor}
+ }
+}%
+
+
+
+
+% Grid visualization
+%
+% #1 = name of axis on which grid lines should be shown
+% #2 = options for the visualization
+
+\def\tikz@lib@dv@gv#1#2{
+ \tikzdatavisualizationset{
+ grid actions/.append={\tikz@lib@dv@default@action{grid}{#1}{#2}},
+ major grid actions/.append={\tikz@lib@dv@show@grid{major}{#1}{#2}},
+ minor grid actions/.append={\tikz@lib@dv@show@grid{minor}{#1}{#2}},
+ subminor grid actions/.append={\tikz@lib@dv@show@grid{subminor}{#1}{#2}},
+ }
+}%
+
+\def\tikz@lib@dv@show@grid#1#2#3{%
+ % First, check whether there is anything to do at all:
+ \pgfkeysgetvalue{#2/default grid at}\tikz@lib@dv@default@settings%
+ \ifx\tikz@lib@dv@default@settings\pgfutil@empty%
+ \pgfkeysgetvalue{#2/grid at}\tikz@lib@dv@settings%
+ \else%
+ \pgfkeysgetvalue{#2/grid at}\tikz@lib@dv@settings%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@dv@settings%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@dv@default@settings\expandafter,\tikz@lib@dv@settings}
+ \fi%
+ \ifx\tikz@lib@dv@settings\pgfutil@empty%
+ % Great, nothing to do
+ \else
+ {%
+ \let\tikz@dv@at@list\pgfutil@empty
+ \let\tikz@dv@style@at@list\pgfutil@empty
+ \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper
+ \let\tikz@lib@dv@ticks@default@at\pgfutil@empty%
+ \scope[data visualization/grid layer,/tikz/data visualization/.cd,every #1 grid/.try,every grid,#3]
+ % Setup options
+ \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@ticks@at%
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}%
+ \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
+ \pgfkeysgetvalue{/tikz/data visualization/#1}\tikz@temp
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp}
+ \edef\tikz@lib@dv@dir@axis{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/direction axis}}%
+ % Ok, now it's time to draw the grid!
+ \foreach \tikz@dv@grid@pos in \tikz@dv@at@list
+ {
+ \ifx\tikz@dv@grid@pos\pgfutil@empty
+ \else
+ \expandafter\tikz@lib@dv@parse\tikz@dv@grid@pos\pgf@stop%
+ \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}%
+ \tikz@lib@dv@mapper.set in to(\tikz@dv@tick@pos)%
+ \draw[/tikz/data visualization/styling]
+ \pgfextra{
+ % First, compute start of grid:
+ \tikz@dv@goto{\tikz@lib@dv@dir@axis}{\pgfkeysvalueof{/tikz/data visualization/low}}%
+ \pgfpathdvmoveto%
+ \tikz@dv@goto{\tikz@lib@dv@dir@axis}{\pgfkeysvalueof{/tikz/data visualization/high}}%
+ \pgfpathdvlineto%
+ };
+ \fi
+ }
+ \endscope
+ }
+ \fi
+}%
+
+
+
+
+
+
+
+
+
+%
+% Label visualization
+%
+
+\def\tikz@lib@dv@lv#1#2{
+ \tikzdatavisualizationset{
+ label actions/.append={\tikz@lib@dv@show@label{#1}{#2}}
+ }
+}%
+
+\def\tikz@lib@dv@show@label#1#2{%
+ % First, check whether there is anything to do at all:
+ \pgfkeysgetvalue{#1/label}\tikz@dv@lib@label%
+ \ifx\tikz@dv@lib@label\pgfutil@empty%
+ % Great, nothing to do
+ \else
+ \scope[anchor=center,/tikz/data visualization/.cd,every axis label/.try,#2]
+ \expandafter\tikz@lib@dv@parse@node\tikz@dv@lib@label\pgf@stop
+ \endscope
+ \fi
+}%
+
+\def\tikz@lib@dv@parse@node{\pgfutil@ifnextchar[\tikz@lib@dv@parse@node@opt{\tikz@lib@dv@parse@node@opt[]}}%}%
+\def\tikz@lib@dv@parse@node@opt[#1]#2\pgf@stop{
+ \tikzdatavisualizationset{#1}
+ \pgftransformshift{\pgfpointdvlocaldatapoint}%
+ \node [/tikz/data visualization/node styling] {#2};
+}%
+
+
+
+%
+% Tick placement strategies
+%
+
+\tikzdatavisualizationset{
+ compute step/.initial=,
+ step/.style={compute step=\def\tikz@lib@dv@step{#1}},
+ minor steps between steps/.initial=,
+ minor steps between steps/.default=9,
+ phase/.initial=0,
+ tick typesetter/.code=\pgfmathprintnumber{#1},
+ tick prefix/.initial=,
+ tick suffix/.initial=,
+ tick unit/.style={tick suffix={$\,\pgfutil@font@normalfont#1$}},% this is an alias
+}%
+
+\def\tikz@lib@dv@compute@at@linear{%
+ % Setup about:
+ \let\tikz@lib@dv@compute@about=\tikz@lib@dv@about@linear%
+ \let\tikz@lib@dv@step\relax%
+ \pgfkeysvalueof{/tikz/data visualization/compute step}
+ \ifx\tikz@lib@dv@step\relax%
+ \else%
+ % Gather interesting values
+ \tikz@lib@dv@mapper.get in range interval()%
+ \pgfdvinrangeinterval.get min and max()%
+ \pgfkeysgetvalue{/tikz/data visualization/phase}\tikz@temp
+ \pgfdvmathenter{\tikz@dv@lib@phase}{\tikz@temp}
+ \pgfdvmathenter{\tikz@dv@lib@step}{\tikz@lib@dv@step}
+ \pgfdvmathifless{\pgfdvmathalwayszero}{\tikz@dv@lib@step}{%
+ % Compute start:
+ \pgfdvmathsub{\tikz@dv@lib@temp}{\pgfdvmin}{\tikz@dv@lib@phase}% temp = dvmin - phase
+ \pgfdvmathdiv{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% temp = temp/step
+ \pgfdvmathfloor{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}% temp = floor(temp)
+ \pgfdvmathmul{\tikz@lib@dv@current}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% current = temp*step ...
+ \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@phase}% + phase
+ \let\tikz@lib@dv@ats\pgfutil@empty%
+ \let\tikz@lib@dv@minor@ats\pgfutil@empty%
+ \tikz@lib@dv@mapper.get function(\tikz@temp)%
+ \ifx\tikz@temp\pgfutil@empty%
+ \pgfdvmathenter{\tikz@one@hundreth}{0.001}%
+ \pgfdvmathsub{\tikz@lib@temp}{\pgfdvmax}{\pgfdvmin}%
+ \pgfdvmathmul{\tikz@lib@dv@epsilon}{\tikz@lib@temp}{\tikz@one@hundreth}% epsilon = (max - min)/1000
+ \else
+ \let\tikz@lib@dv@epsilon\pgfdvmathalwayszero
+ \fi
+ \pgfdvmathsub{\tikz@lib@dv@min@minus@epsilon}{\pgfdvmin}{\tikz@lib@dv@epsilon}%
+ \pgfdvmathadd{\tikz@lib@dv@max@plus@epsilon}{\pgfdvmax}{\tikz@lib@dv@epsilon}%
+ \pgfkeysgetvalue{/tikz/data visualization/minor steps between steps}\tikz@lib@dv@substeps%
+ \ifx\tikz@lib@dv@substeps\pgfutil@empty
+ \else
+ \pgfmathsetmacro\tikz@temp{\tikz@lib@dv@substeps+1}%
+ \pgfdvmathenter{\tikz@dv@lib@substeps}{\tikz@temp}%
+ \pgfdvmathdiv{\tikz@lib@dv@substep}{\tikz@dv@lib@step}{\tikz@dv@lib@substeps}%
+ \fi
+ \loop%
+ \ifx\tikz@lib@dv@substeps\pgfutil@empty%
+ \else%
+ \let\tikz@lib@dv@subcurrent=\tikz@lib@dv@current%
+ \pgfmathsetcount{\c@pgf@counta}{\tikz@lib@dv@substeps}%
+ \let\tikz@lib@dv@next=\tikz@lib@dv@subloop%
+ \tikz@lib@dv@subloop
+ \fi%
+ \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@min@minus@epsilon}{}{%
+ \pgfdvmathexitbyserializing{\tikz@temp}{\tikz@lib@dv@current}%
+ \edef\tikz@lib@dv@ats{\tikz@lib@dv@ats,\tikz@temp}%
+ }
+ \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@step}%
+ \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@max@plus@epsilon}{\tikz@lib@dv@continuetrue}{\tikz@lib@dv@continuefalse}%
+ \iftikz@lib@dv@continue%
+ \repeat%
+ \tikzdatavisualizationset{major/.expanded={at={\tikz@lib@dv@ats}},minor/.expanded={at={\tikz@lib@dv@minor@ats}}}%
+ }{%
+ \pgfdvmathexitbyserializing{\tikz@temp}{\pgfdvmin}%
+ \tikzdatavisualizationset{major/.expanded={at={\tikz@temp}}}%
+ }%
+ \fi%
+}%
+\newif\iftikz@lib@dv@continue
+
+\def\tikz@lib@dv@subloop{
+ \pgfdvmathadd{\tikz@lib@dv@subcurrent}{\tikz@lib@dv@subcurrent}{\tikz@lib@dv@substep}%
+ \pgfdvmathifless{\tikz@lib@dv@subcurrent}{\pgfdvmin}{}{%
+ \pgfdvmathifless{\tikz@lib@dv@subcurrent}{\pgfdvmax}{%
+ \pgfdvmathexitbyserializing{\tikz@temp}{\tikz@lib@dv@subcurrent}%
+ \edef\tikz@lib@dv@minor@ats{\tikz@lib@dv@minor@ats,\tikz@temp}
+ }{}}
+ \advance\c@pgf@counta by-1\relax%
+ \ifnum\c@pgf@counta=0\relax%
+ \let\tikz@lib@dv@next=\relax
+ \fi
+ \tikz@lib@dv@next
+}%
+
+
+
+%
+% Ticks about settings
+%
+
+\tikzdatavisualizationset{
+ about/.style={compute step=\tikz@lib@dv@compute@about{#1}},
+ about strategy/.initial=,
+ standard about strategy/.style={about strategy={1.5/1.0,2.3/2.0,4/2.5,7/5,11/10}},
+ standard about strategy,
+ euro about strategy/.style={about strategy={1.5/1.0,3/2.0,7/5,11/10}},
+ decimal about strategy/.style={about strategy={3/1.0,11/10}},
+ half about strategy/.style={about strategy={2/1.0,7/5,11/10}},
+ quarter about strategy/.style={about strategy={1.8/1.0,4/2.5,7/5,11/10}},
+ int about strategy/.style={about strategy={1.5/1.0,2.5/2.0,3.5/3.0,4.5/4.0,7/5,11/10}},
+ none/.style={compute step=},
+ few/.style={about=3},
+ some/.style={about=5},
+ many/.style={about=10},
+}%
+
+\def\tikz@lib@dv@about@linear#1{%
+ \tikz@lib@dv@mapper.get in range interval()%
+ \pgfdvinrangeinterval.get min and max()%
+ \pgfdvmathsub{\tikz@lib@dv@diff}{\pgfdvmax}{\pgfdvmin}
+ \pgfdvmathenter{\tikz@lib@dv@about@val}{#1}%
+ \pgfdvmathdiv{\tikz@lib@dv@around}{\tikz@lib@dv@diff}{\tikz@lib@dv@about@val}%
+ % Make mantisse sensible
+ \pgfmathfloattomacro{\tikz@lib@dv@around}{\tikz@lib@dv@flags}{\tikz@lib@dv@mant}{\tikz@lib@dv@exp}%
+ \pgf@xc=\tikz@lib@dv@mant pt %
+ \pgfkeysgetvalue{/tikz/data visualization/about strategy}\tikz@lib@dv@strat
+ \foreach \tikz@lib@dv@threshold/\tikz@lib@replace in \tikz@lib@dv@strat
+ {
+ \ifdim\pgf@xc<\tikz@lib@dv@threshold pt%
+ \global\pgf@xc=\tikz@lib@replace pt%
+ \breakforeach
+ \fi
+ }%
+ \ifdim\pgf@xc<10pt%
+ \pgfmathfloatcreate{\tikz@lib@dv@flags}{\pgf@sys@tonumber{\pgf@xc}}{\tikz@lib@dv@exp}%
+ \else
+ \begingroup
+ \c@pgf@countd=\tikz@lib@dv@exp
+ \advance\c@pgf@countd by1
+ \edef\tikz@lib@dv@exp{\the\c@pgf@countd}%
+ \pgfmath@smuggleone\tikz@lib@dv@exp
+ \endgroup
+ \divide\pgf@xc by 10\relax
+ \pgfmathfloatcreate{\tikz@lib@dv@flags}{\pgf@sys@tonumber{\pgf@xc}}{\tikz@lib@dv@exp}%
+ \fi
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \let\tikz@lib@dv@step=\pgfmathresult
+}%
+
+
+
+
+
+%
+% Logarithmic axes
+%
+
+\tikzset{
+ /tikz/data visualization/axis options/.cd,
+ exponential steps/.style={tick placement strategy=\tikz@lib@dv@compute@at@log},
+ %
+ % Basic setters
+ %
+ logarithmic/.style={
+ \tikz@dv@axis/function=\pgfdvmathln{\pgfvalue}{\pgfvalue},
+ \tikz@dv@axis/scaling/default=1 at 0 and 10 at 1,
+ exponential steps
+ }
+}%
+
+\def\tikz@lib@dv@compute@at@log{%
+ % Setup about:
+ \let\tikz@lib@dv@compute@about=\tikz@lib@dv@about@log%
+ \let\tikz@lib@dv@step\relax%
+ \pgfkeysvalueof{/tikz/data visualization/compute step}
+ \ifx\tikz@lib@dv@step\relax%
+ \else%
+ % Gather interesting values
+ \tikz@lib@dv@mapper.get in range interval()%
+ \pgfdvinrangeinterval.get min and max()%
+ \pgfdvmathlog{\pgfdvminlog}{\pgfdvmin}%
+ \pgfdvmathlog{\pgfdvmaxlog}{\pgfdvmax}%
+ \pgfkeysgetvalue{/tikz/data visualization/phase}\tikz@temp
+ \pgfdvmathenter{\tikz@dv@lib@phase}{\tikz@temp}
+ \pgfdvmathenter{\tikz@dv@lib@step}{\tikz@lib@dv@step}
+ % Compute start:
+ \pgfdvmathsub{\tikz@dv@lib@temp}{\pgfdvminlog}{\tikz@dv@lib@phase}% temp = dvmin - phase
+ \pgfdvmathdiv{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% temp = temp/step
+ \pgfdvmathfloor{\tikz@dv@lib@temp}{\tikz@dv@lib@temp}% temp = floor(temp)
+ \pgfdvmathmul{\tikz@lib@dv@current}{\tikz@dv@lib@temp}{\tikz@dv@lib@step}% current = temp*step ...
+ \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@phase}% + phase
+ \let\tikz@lib@dv@ats\pgfutil@empty%
+ \let\tikz@lib@dv@minor@ats\pgfutil@empty%
+ \pgfdvmathenter{\tikz@one@hundreth}{0.001}%
+ \pgfdvmathsub{\tikz@lib@temp}{\pgfdvmaxlog}{\pgfdvminlog}%
+ \pgfdvmathmul{\tikz@lib@dv@epsilon}{\tikz@lib@temp}{\tikz@one@hundreth}% epsilon = (max - min)/100
+ \pgfdvmathsub{\tikz@lib@dv@min@minus@epsilon}{\pgfdvminlog}{\tikz@lib@dv@epsilon}%
+ \pgfdvmathadd{\tikz@lib@dv@max@plus@epsilon}{\pgfdvmaxlog}{\tikz@lib@dv@epsilon}%
+ \pgfkeysgetvalue{/tikz/data visualization/minor steps between steps}\tikz@lib@dv@substeps%
+ \ifx\tikz@lib@dv@substeps\pgfutil@empty
+ \else
+ \pgfmathsetmacro\tikz@temp{\tikz@lib@dv@substeps+1}%
+ \pgfdvmathenter{\tikz@dv@lib@substeps}{\tikz@temp}%
+ \fi
+ \loop%
+ \ifx\tikz@lib@dv@substeps\pgfutil@empty%
+ \else%
+ \let\tikz@lib@dv@subcurrent=\tikz@lib@dv@current%
+ \pgfdvmathadd{\tikz@lib@dv@subcurrent@next}{\tikz@lib@dv@subcurrent}{\tikz@dv@lib@step}%
+ \pgfdvmathpowten{\tikz@lib@dv@subcurrent}{\tikz@lib@dv@subcurrent}%
+ \pgfdvmathpowten{\tikz@lib@dv@subcurrent@max}{\tikz@lib@dv@subcurrent@next}%
+ \pgfdvmathsub{\tikz@lib@dv@subcurrent@diff}{\tikz@lib@dv@subcurrent@max}{\tikz@lib@dv@subcurrent}%
+ \pgfdvmathdiv{\tikz@lib@dv@substep}{\tikz@lib@dv@subcurrent@diff}{\tikz@dv@lib@substeps}%
+ \pgfmathsetcount{\c@pgf@counta}{\tikz@lib@dv@substeps}%
+ \let\tikz@lib@dv@next=\tikz@lib@dv@subloop%
+ \tikz@lib@dv@subloop
+ \fi%
+ \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@min@minus@epsilon}{}{%
+ \pgfdvmathpowten{\tikz@lib@dv@current@pow}{\tikz@lib@dv@current}%
+ \pgfdvmathexitbyserializing{\tikz@temp}{\tikz@lib@dv@current@pow}%
+ \edef\tikz@lib@dv@ats{\tikz@lib@dv@ats,\tikz@temp}%
+ }
+ \pgfdvmathadd{\tikz@lib@dv@current}{\tikz@lib@dv@current}{\tikz@dv@lib@step}%
+ \pgfdvmathifless{\tikz@lib@dv@current}{\tikz@lib@dv@max@plus@epsilon}{\tikz@lib@dv@continuetrue}{\tikz@lib@dv@continuefalse}%
+ \iftikz@lib@dv@continue%
+ \repeat%
+ \tikzdatavisualizationset{major/.expanded={at={\tikz@lib@dv@ats}},minor/.expanded={at={\tikz@lib@dv@minor@ats}}}%
+ \fi%
+}%
+
+
+\def\tikz@lib@dv@about@log#1{%
+ \tikz@lib@dv@mapper.get in range interval()%
+ \pgfdvinrangeinterval.get min and max()%
+ \pgfdvmathlog{\pgfdvmin}{\pgfdvmin}%
+ \pgfdvmathlog{\pgfdvmax}{\pgfdvmax}%
+ \pgfdvmathsub{\tikz@lib@dv@diff}{\pgfdvmax}{\pgfdvmin}
+ \pgfdvmathenter{\tikz@lib@dv@about@val}{#1}%
+ \pgfdvmathdiv{\tikz@lib@dv@around}{\tikz@lib@dv@diff}{\tikz@lib@dv@about@val}%
+ % Make mantisse sensible
+ \pgfmathfloattomacro{\tikz@lib@dv@around}{\tikz@lib@dv@flags}{\tikz@lib@dv@mant}{\tikz@lib@dv@exp}
+ \ifdim\tikz@lib@dv@exp pt<0pt%
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \else
+ \pgf@xc=\tikz@lib@dv@mant pt\relax%
+ \ifdim\pgf@xc<2.5pt
+ \pgfmathfloatcreate{1}{1.0}{\tikz@lib@dv@exp}
+ \else\ifdim\pgf@xc<5.1pt
+ \pgfmathfloatcreate{1}{3.0}{\tikz@lib@dv@exp}
+ \else
+ \pgfmathfloatcreate{1}{6.0}{\tikz@lib@dv@exp}
+ \fi\fi
+ \fi%
+ \pgfmathfloattofixed{\pgfmathresult}
+ \let\tikz@lib@dv@step=\pgfmathresult
+}%
+
+
+
+
+
+
+
+%
+% Cartesian axes
+%
+
+\tikzdatavisualizationset{%
+ new Cartesian axis/.style={
+ new axis base={#1},
+ new object={
+ class=linear transformer,
+ store=/tikz/data visualization/#1/linear transformer,
+ arg1/.expanded=\pgfkeysvalueof{/tikz/data visualization/#1/attribute}/scaled,
+ arg2 from key=/tikz/data visualization/#1/unit vector,
+ },
+ #1/scaling/default/.initial=0 at 0 and 1 at 1cm,
+ #1/unit vector/.initial=\pgfqpoint{1pt}{0pt},
+ }
+}%
+
+\tikzset{
+ /tikz/data visualization/axis options/.cd,
+ unit vector/.code=\tikz@scan@one@point\tikz@lib@dv@uv#1,
+ length/.style={\tikz@dv@axis/scaling=min at 0 and max at {#1}},
+ unit length/.code={\tikz@dv@parse@unit@length{#1}},
+ power unit length/.style={\tikz@dv@axis/scaling=1 at 0 and 10 at {#1}}
+}%
+
+\def\tikz@lib@dv@uv#1{%
+ \pgfkeyssetvalue{\tikz@dv@axis/unit vector}{#1}
+}%
+
+\def\tikz@dv@parse@unit@length#1{
+ \pgfutil@in@{per}{#1}
+ \ifpgfutil@in@%
+ \tikz@dv@parse@unit@length@#1\pgf@stop%
+ \else%
+ \tikz@dv@parse@unit@length@#1per1units\pgf@stop%
+ \fi%
+}%
+\def\tikz@dv@parse@unit@length@#1per#2units\pgf@stop{
+ \pgfkeysalso{\tikz@dv@axis/scaling=0 at 0 and {#2} at {#1}}
+}%
+
+
+%
+% Common visualizer interface
+%
+
+\tikzdatavisualizationset{
+ new visualizer/.style n args={3}{
+ #1/.code={
+ \def\tikz@visualizer{#1}%
+ \pgfkeys{/tikz/data visualization/visualizer options/.cd,##1}
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgfkeys{/data point/set={#1}})}%
+ },
+ /utils/exec={
+ \advance\tikzdvvisualizercounter by 1\relax
+ \edef\tikz@temp{/data point/set/#1/.initial=\the\tikzdvvisualizercounter}
+ \expandafter\tikzset\expandafter{\tikz@temp}
+ },
+ /data point/#1/execute at begin/.initial={
+ \pgfkeyssetvalue{/data point/set}{#1}
+ \scope[
+ #2,
+ /tikz/data visualization/every visualizer/.try,
+ /tikz/data visualization/visualizers/#1/signal,
+ /tikz/data visualization/visualizers/#1/styling/.try]
+ },
+ /data point/#1/execute at end/.initial={
+ \path; % invokes every path implicitly
+ \endscope
+ },
+ /tikz/data visualization/visualizers/#1/signal/.code=\pgf@signalstyle.emit(),
+ /tikz/data visualization/visualizers/#1/styling/.style=,
+ /tikz/data visualization/visualizers/#1/label in legend options/.style={#3},
+ },
+ style sheet/.style={/data point/set/.style sheet={#1}},
+ /pgf/data/set/.style={/data point/set={#1}},
+}%
+
+\tikzdatavisualizationset{
+ new sub visualizer/.style n args={4}{
+ #4/#1/.code={
+ \def\tikz@visualizer{#4/#1}%
+ \pgfkeys{/tikz/data visualization/visualizer options/.cd,##1}
+ },
+ /data point/#4/#1/execute at begin/.initial={
+ \pgfkeyssetvalue{/data point/set}{#4}
+ \scope[
+ #2,
+ /tikz/data visualization/every visualizer/.try,
+ /tikz/data visualization/visualizers/#4/signal,
+ /tikz/data visualization/visualizers/#4/styling/.try,
+ /tikz/data visualization/visualizers/#4/#1/styling/.try]
+ },
+ /data point/#4/#1/execute at end/.initial={
+ \path; % invokes every path implicitly
+ \endscope
+ },
+ /tikz/data visualization/visualizers/#4/#1/styling/.style=,
+ /tikz/data visualization/visualizers/#4/#1/label in legend options/.style={#3},
+ }
+}%
+
+
+\def\tikz@do@visualizer#1#2{%
+ \tikzdatavisualizationset{
+ #2={#1}
+ }
+}%
+
+\newcount\tikzdvvisualizercounter
+
+\newif\iftikz@dv@visualizer@label@inline
+
+\tikzdatavisualizationset{visualizer options/.cd,
+ @set/.style 2 args={
+ /tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={/utils/exec={\let\tikz@dv@plot@handler=#1}},
+ /tikz/data visualization/visualizers/\tikz@visualizer/label in legend options/.append style={#2}
+ },
+ no lines/.style={@set={\pgfplothandlerdiscard}{default label in legend mark}},
+ smooth line/.style={@set={\pgfplothandlercurveto}{default label in legend path}},
+ smooth cycle/.style={@set={\pgfplothandlerclosedcurve}{default label in legend closed path}},
+ straight line/.style={@set={\pgfplothandlerlineto}{default label in legend path}},
+ straight cycle/.style={@set={\pgfplothandlerpolygon}{default label in legend closed path}},
+ polygon/.style={straight cycle},% alias
+ gap line/.style={@set={\pgfplothandlergaplineto}{default label in legend path}},
+ gap cycle/.style={@set={\pgfplothandlergapcycle}{gap circular label in legend line}}
+}%
+
+
+
+%
+% Label visualizer
+%
+
+\tikzdatavisualizationset{
+ new label visualizer/.style 2 args={
+ new object={
+ when=before visualization,
+ class=label visualizer,
+ before creation={
+ \begingroup
+ \def\tikz@visualizer{#1}%
+ \pgfkeys{/tikz/data visualization/visualizer label options/.cd,
+ #2}
+ \pgfkeysgetvalue{/tikz/data visualization/visualizer label options/text}\tikz@dv@temp@lab
+ \def\tikz@tempa{
+ \scope[
+ /utils/exec=\def\tikz@visualizer{#1},%
+ /tikz/data visualization/visualizer label options/.cd,
+ #2]
+ \tikzdatavisualizationset{every data set label/.try}
+ \path [
+ /data point/set={#1},/utils/exec=\pgf@signalstyle.emit(),
+ /tikz/data visualization/.cd,every label in data/.try]
+ (label visualizer coordinate') --
+ (label visualizer coordinate)
+ node [
+ auto,
+ at end,
+ /tikz/data visualization/node styling]
+ }
+ \expandafter\def\expandafter\tikz@tempb\expandafter{\expandafter{\tikz@dv@temp@lab};}%
+ \expandafter\expandafter\expandafter\gdef%
+ \expandafter\expandafter\expandafter\tikz@dv@label@code%
+ \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\relax%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@tempa\tikz@tempb\endscope}}
+ \global\let\tikz@dv@label@attribute=\tikz@dv@label@attribute
+ \global\let\tikz@dv@label@threshold=\tikz@dv@label@threshold
+ \endgroup
+ },
+ arg1/.expand once=\tikz@dv@label@attribute,
+ arg2=\tikz@dv@label@threshold,
+ arg3/.expand once=\tikz@dv@label@code,
+ arg4=\pgfdvvisualizerfilter{#1}
+ },
+ /utils/exec=\tikz@create@label@count{#1}
+ },
+ % Label style
+ text colored/.style={node style={text=visualizer color}}
+}%
+
+\def\tikz@create@label@count#1{
+ \tikzdatavisualizationset{
+ new object={
+ when=before survey,
+ store=/tikz/data visualization/visualizers/#1/count/obj,
+ class=count,
+ arg1=set/#1/count,
+ after creation={\tikzdvobj.set filter(\pgfdvvisualizerfilter{#1})}
+ }
+ }
+}%
+
+\pgfkeys{
+ /tikz/data visualization/visualizer label options/.cd,
+ when/.code args={#1 is#2}{%
+ \def\tikz@dv@label@attribute{#1}%
+ \def\tikz@dv@label@threshold{#2}%
+ },
+ index/.code={%
+ \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}%
+ \def\tikz@dv@label@threshold{#1}%
+ },
+ pos/.code={%
+ \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}%
+ \pgfkeysvalueof{/tikz/data visualization/visualizers/\tikz@visualizer/count/obj}.get max(\tikz@lib@max)
+ \edef\tikz@dv@label@threshold{(#1*\tikz@lib@max)}%
+ },
+ auto/.code={%
+ \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}%
+ \pgfkeysvalueof{/tikz/data visualization/visualizers/\tikz@visualizer/count/obj}.get max(\tikz@lib@max)
+ \edef\tikz@dv@label@threshold{({(\pgfkeysvalueof{/data point/set/\tikz@visualizer}-0.5)/\the\tikzdvvisualizercounter*\tikz@lib@max})}
+ },
+ text/.initial=,
+ text'/.style={text={#1},node style=swap,/utils/exec=\def\tikz@lib@dv@pin@sign{-}},
+ node style/.style={/tikz/data visualization/node style={#1}},
+ text colored/.style=/tikz/data visualization/text colored,
+ pin angle/.store in=\tikz@lib@dv@pin@dir,
+ pin length/.style={node style={pin distance={#1}}},
+}%
+
+\let\tikz@lib@dv@pin@sign\pgfutil@empty
+
+\let\tikz@dv@label@attribute\pgfutil@empty
+\let\tikz@dv@label@threshold\pgfutil@empty
+\let\tikz@dv@label@code\pgfutil@empty
+
+
+
+
+%
+% Legend handling
+%
+
+\tikzdatavisualizationset{
+ new legend/.code={
+ \pgfkeysifdefined{/tikz/data visualization/#1/at}{}
+ {\tikzdatavisualizationset{
+ new object={
+ class=legend,
+ store=/tikz/data visualization/#1/obj,
+ arg1 from key=/tikz/data visualization/#1/@columns or rows,
+ arg2 from key=/tikz/data visualization/#1/@ideal,
+ arg3 from key=/tikz/data visualization/#1/max entries,
+ arg4 from key=/tikz/data visualization/#1/@strategy,
+ after creation={
+ \tikzdatavisualizationset{
+ legend actions/.append={
+ \pgfkeysgetvalue{/tikz/data visualization/#1/obj}\pgf@dv@legend%
+ {
+ \pgf@dv@legend.get arrangement(\pgf@dv@temp)%
+ \pgfkeysgetvalue{/tikz/data visualization/#1/at}\pgf@dv@at%
+ \pgfkeysgetvalue{/tikz/data visualization/#1/anchor}\pgf@dv@anchor%
+ \let\pgfdvnextcell=\pgfmatrixnextcell%
+ \let\pgfdvendrow=\pgfmatrixendrow%
+ \def\pgf@marshal{
+ \matrix[at/.expand once=\pgf@dv@at,matrix anchor/.expand
+ once=\pgf@dv@anchor,/tikz/data visualization/#1/matrix node styling]
+ }
+ \expandafter\pgf@marshal\expandafter{\pgf@dv@temp};
+ }
+ }
+ }
+ }
+ },
+ #1/@columns or rows/.initial=columns,
+ #1/@ideal/.initial=1,
+ #1/max entries/.initial=100,
+ #1/@strategy/.initial=down then right,
+ #1/anchor/.initial=west,
+ #1/at/.initial=(data visualization bounding box.east),
+ #1/matrix node styling/.style={row sep=0pt,column sep=.8em},
+ %
+ %
+ %
+ #1/.code={
+ \let\tikz@temp\tikz@dv@legend%
+ \def\tikz@dv@legend{/tikz/data visualization/#1}%
+ \expandafter\tikz@do@legend@options\expandafter{\tikz@temp}{##1}%
+ },
+ #1={every new legend}
+ }}},
+ new legend/.default=main legend,
+ legend/.style={
+ new legend,
+ main legend={#1}
+ }
+}%
+
+\def\tikz@do@legend@options#1#2{
+ \pgfkeys{/tikz/data visualization/legend options/.cd,#2}
+ \def\tikz@dv@legend{#1}
+}%
+\let\tikz@dv@legend\pgfutil@empty
+
+
+\tikzset{
+ /tikz/data visualization/legend options/.cd,
+ %
+ % How to arrange the entries in the legend
+ %
+ ideal number of columns/.style={\tikz@dv@legend/@columns or rows=columns,\tikz@dv@legend/@ideal={#1}},
+ ideal number of rows/.style={\tikz@dv@legend/@columns or rows=rows,\tikz@dv@legend/@ideal={#1}},
+ columns/.style={ideal number of columns={#1}},% alias
+ rows/.style={ideal number of rows={#1}},% alias
+ max rows/.style={\tikz@dv@legend/@columns or rows=columns,\tikz@dv@legend/max entries={#1}},
+ max columns/.style={\tikz@dv@legend/@columns or rows=rows,\tikz@dv@legend/max entries={#1}},
+ down then right/.style={\tikz@dv@legend/@strategy=down then right},
+ down then left/.style={\tikz@dv@legend/@strategy=down then left},
+ up then right/.style={\tikz@dv@legend/@strategy=up then right},
+ up then left/.style={\tikz@dv@legend/@strategy=up then left},
+ right then down/.style={\tikz@dv@legend/@strategy=right then down},
+ left then down/.style={\tikz@dv@legend/@strategy=left then down},
+ right then up/.style={\tikz@dv@legend/@strategy=right then up},
+ left then up/.style={\tikz@dv@legend/@strategy=left then up},
+ %
+ % Where to put the legend
+ %
+ anchor/.style={\tikz@dv@legend/anchor={#1}},
+ at/.style={\tikz@dv@legend/at={#1}},
+ % Outer placements
+ right/.style={east outside},
+ left/.style={west outside},
+ above/.style={north outside},
+ below/.style={south outside},
+ east outside/.style={
+ columns=1,
+ at={([xshift=.8em]data visualization bounding box.east)},
+ anchor=west,
+ },
+ north east outside/.style={
+ columns=1,
+ at={([xshift=.8em]data visualization bounding box.north east|-
+ data bounding box.north)},
+ anchor=north west,
+ },
+ south east outside/.style={
+ columns=1,
+ at={([xshift=.8em]data visualization bounding box.south east |-
+ data bounding box.south)},
+ anchor=south west,
+ },
+ west outside/.style={
+ columns=1,
+ label style=text left,
+ at={([xshift=-.8em]data visualization bounding box.west)},
+ anchor=east,
+ },
+ north west outside/.style={
+ columns=1,
+ label style=text left,
+ at={([xshift=-.8em]data visualization bounding box.north west |-
+ data bounding box.north)},
+ anchor=north east,
+ },
+ south west outside/.style={
+ columns=1,
+ label style=text left,
+ at={([xshift=-.8em]data visualization bounding box.south west |-
+ data bounding box.south)},
+ anchor=south east,
+ },
+ south outside/.style={
+ rows=1,
+ at={([yshift=-.5em]data visualization bounding box.south)},
+ anchor=north,
+ },
+ north outside/.style={
+ rows=1,
+ at={([yshift=.5em]data visualization bounding box.north)},
+ anchor=south,
+ },
+ every new legend/.style={east outside,label style=text right},
+ %
+ % Inner placements
+ %
+ % First, styling
+ every legend inside/.style={
+ opaque=white,
+ label style={node style={font=\pgfutil@font@footnotesize}}
+ },
+ opaque/.style={
+ matrix node style={
+ inner sep=.333ex,
+ outer sep=.5ex,
+ rounded corners=3pt,
+ execute at begin cell={\tikzset{sharp corners}}, % get rid of
+ % rounded corners in cells of the
+ % legend matrix
+ fill=#1
+ },
+ },
+ opaque/.default=white,
+ transparent/.style={matrix node style={fill=none}},
+ % Second, the placements
+ north east inside/.style={
+ columns=1,
+ at={([xshift=-.3em]data bounding box.north east)},
+ anchor=north east,
+ every legend inside
+ },
+ south west inside/.style={
+ columns=1,
+ at={([xshift=.3em]data bounding box.south west)},
+ anchor=south west,
+ every legend inside
+ },
+ north west inside/.style={
+ columns=1,
+ at={([xshift=.3em]data bounding box.north west)},
+ anchor=north west,
+ every legend inside
+ },
+ south east inside/.style={
+ columns=1,
+ at={([xshift=-.3em]data bounding box.south east)},
+ anchor=south east,
+ every legend inside
+ },
+ west inside/.style={
+ columns=1,
+ at={([xshift=.3em]data bounding box.west)},
+ anchor=west,
+ every legend inside
+ },
+ east inside/.style={
+ columns=1,
+ at={([xshift=.3em]data bounding box.east)},
+ anchor=east,
+ every legend inside
+ },
+ north inside/.style={
+ rows=1,
+ at={(data bounding box.north)},
+ anchor=north,
+ every legend inside
+ },
+ south inside/.style={
+ rows=1,
+ at={(data bounding box.south)},
+ anchor=south,
+ every legend inside
+ },
+ % Additional inner placements
+ at values/.style={
+ at={(visualization cs:#1)},
+ anchor=center,
+ every legend inside
+ },
+ right of/.style={
+ at={(visualization cs:#1)},
+ anchor=west,
+ every legend inside
+ },
+ left of/.style={
+ at={(visualization cs:#1)},
+ anchor=east,
+ every legend inside
+ },
+ above of/.style={
+ at={(visualization cs:#1)},
+ anchor=south,
+ every legend inside
+ },
+ below of/.style={
+ at={(visualization cs:#1)},
+ anchor=north,
+ every legend inside
+ },
+ above right of/.style={
+ at={(visualization cs:#1)},
+ anchor=south west,
+ every legend inside
+ },
+ above left of/.style={
+ at={(visualization cs:#1)},
+ anchor=south east,
+ every legend inside
+ },
+ below right of/.style={
+ at={(visualization cs:#1)},
+ anchor=north west,
+ every legend inside
+ },
+ below left of/.style={
+ at={(visualization cs:#1)},
+ anchor=north east,
+ every legend inside
+ },
+ %
+ %
+ %
+ % Label text styling
+ %
+ label style/.style={
+ matrix node style={/tikz/data visualization/every label in legend/.append style={#1}}
+ },
+ %
+ % Styling
+ %
+ matrix node style/.style={\tikz@dv@legend/matrix node styling/.append style={#1}},
+}%
+
+
+\tikzdatavisualizationset{
+ new legend entry/.code={
+ \begingroup
+ \pgfkeys{/tikz/data visualization/legend entry options/.cd,#1}
+ \pgfkeysgetvalue{/tikz/data visualization/legend entry options/legend}\tikz@dv@temp@legend
+ \global\let\tikz@dv@temp@legend\tikz@dv@temp@legend
+ \endgroup
+ \tikzdatavisualizationset{new legend/.expanded=\tikz@dv@temp@legend}%
+ \expandafter\tikz@dv@add@legend@entry\expandafter{\tikz@dv@temp@legend}{#1}
+ }
+}%
+
+\def\tikz@dv@add@legend@entry#1#2{
+ \tikz@main@dv.at start survey({
+ \pgfkeysgetvalue{/tikz/data visualization/#1/obj}\pgf@temp
+ \pgf@temp.add entry(\tikz@dv@render@legend@entry{legend=#1,#2})
+ })
+}%
+
+\def\tikz@dv@render@legend@entry#1{
+ \pgfkeys{/tikz/data visualization/.cd,every data set label}
+ \pgfkeys{/tikz/data visualization/legend entry options/.cd,
+ /tikz/data visualization/every label in legend,#1}%
+ \pgfkeysgetvalue{/tikz/data visualization/legend entry options/text}\tikz@dv@temp@lab
+ \pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@dv@temp@style
+ \pgfkeysgetvalue{/tikz/data visualization/legend entry options/setup}\tikz@dv@temp@setup
+ \pgfkeysgetvalue{/tikz/data visualization/legend entry options/visualizer in legend styling}\tikz@dv@temp@visual@styling
+ \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@setup},
+ /utils/exec=\pgf@signalstyle.emit()]
+ \node[/tikz/data visualization/node styling,
+ /utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@style}]
+ {\tikz@dv@pre@height\tikz@dv@temp@lab\tikz@dv@post@height};
+ \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@visual@styling}]
+ \iftikz@lib@dv@text@only
+ \else
+ \pgfkeysvalueof{/tikz/data visualization/legend entry options/visualizer in legend}
+ \fi
+ \endscope
+ \endscope
+}%
+
+\def\tikz@dv@pre@height{\hbox{\vrule height .75em width0pt}}%
+\def\tikz@dv@post@height{\hbox{\vrule depth .25em width0pt}}%
+
+
+
+\pgfkeys{
+ /tikz/data visualization/legend entry options/.cd,
+ %
+ % General options
+ %
+ text/.initial=,
+ node style/.style={/tikz/data visualization/node style={#1}},
+ legend/.initial=main legend,
+ setup/.initial=,
+ visualizer in legend/.initial=,
+ visualizer in legend styling/.initial=,
+ visualizer in legend style/.style={visualizer in legend styling/.append={,#1}},
+ %
+ % Legend visualizers for plots
+ %
+ text right/.style={
+ node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,xshift=.333em},
+ visualizer in legend style={reset cm},
+ },
+ text left/.style={
+ node style={anchor=mid east,inner ysep=1pt,inner xsep=0pt,reset
+ cm,xshift=-.333em,align=right},
+ visualizer in legend style={reset cm,xscale=-1},
+ },
+ text only/.style={
+ node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,text=visualizer color},
+ /utils/exec=\tikz@lib@dv@text@onlytrue
+ },
+ text colored/.style=/tikz/data visualization/text colored,
+}%
+\let\tikz@lib@dv@pin@dir\pgfutil@empty
+\newif\iftikz@lib@dv@text@only
+
+\pgfkeys{
+ /tikz/data visualization/visualizer options/.cd,
+ label in legend/.code={\expandafter\tikz@dv@new@label@in@legend@for@visualizer\expandafter{\tikz@visualizer}{#1}},
+ label in data/.code=\tikzdatavisualizationset{new label visualizer/.expand once=\expandafter{\tikz@visualizer}{auto,#1}},
+ pin in data/.style={label in data={%
+ node style={%
+ /utils/exec={
+ \ifx\tikz@lib@dv@pin@dir\pgfutil@empty
+ \pgf@process{\pgfpointnormalised{%
+ \pgfpointdiff%
+ {\pgfpointanchor{label visualizer coordinate}{center}}%
+ {\pgfpointanchor{label visualizer coordinate'}{center}}}}%
+ \pgf@x=-\pgf@x\relax%
+ \edef\tikz@lib@dv@temp@rot{\noexpand\pgfqpoint{\the\pgf@y}{\the\pgf@x}}%
+ \tikz@addtransform{\pgftransformshift{\pgfpointscale{\tikz@lib@dv@pin@sign\tikz@pin@distance}{\tikz@lib@dv@temp@rot}}}
+ \else%
+ \tikz@addtransform{\pgftransformshift{\pgfpointpolar{\tikz@lib@dv@pin@dir}{\tikz@lib@dv@pin@sign\tikz@pin@distance}}}
+ \fi%
+ },
+ append after command={
+ \bgroup
+ [current point is local=true]
+ (\tikzlastnode) edge [solid, every pin edge] (label visualizer coordinate)
+ \egroup%
+ }},
+ ,#1}},
+ style/.style={/tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={,#1}},
+ label in legend options/.style={/tikz/data visualization/visualizers/\tikz@visualizer/label in legend options/.append style={,#1}},
+ ignore style sheets/.style={/tikz/data visualization/visualizers/\tikz@visualizer/signal/.code=,/utils/exec=\advance\tikzdvvisualizercounter by -1\relax},
+}%
+
+\def\tikz@dv@new@label@in@legend@for@visualizer#1#2{
+ \tikzdatavisualizationset{
+ new legend entry={
+ visualizer in legend style={/tikz/data visualization/visualizers/#1/styling/.try},
+ /tikz/data visualization/every label in legend/.try,
+ /tikz/.cd,
+ every label/.try,
+ /tikz/data visualization/legend entry options/.cd,
+ setup={/data point/set={#1}},
+ /tikz/data visualization/visualizers/#1/label in legend options/.try,
+ #2,
+ }
+ }
+}%
+
+\def\tikz@dv@legend@entry@as@example{
+ \pgfkeysgetvalue{/data point/set}{\tikz@visualizer}
+ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin}
+ \tikz@dv@plot@handler
+ \pgfplotstreamstart
+ \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend line coordinates}{\tikz@dv@temp}
+ \foreach \coordinate in \tikz@dv@temp
+ { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} }
+ \pgfplotstreamend
+ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at end}
+ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin}
+ \tikz@dv@plot@mark@maker
+ \pgfplotstreamstart
+ \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend mark coordinates}{\tikz@dv@temp}
+ \foreach \coordinate in \tikz@dv@temp
+ { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} }
+ \pgfplotstreamend
+ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at end}
+}%
+
+
+\tikzdatavisualizationset{
+ legend entry options/.cd,
+ label in legend line coordinates/.initial=,
+ label in legend rectangle coordinates/.initial={(-1ex,-.5ex),(-1ex,0.968ex),(0ex,0.968ex),(0ex,-.5ex)},
+ label in legend mark coordinates/.initial=,
+ label in legend one mark/.style={
+ label in legend line coordinates={},
+ label in legend mark coordinates={(0,0)},
+ },
+ label in legend three marks/.style={
+ label in legend line coordinates={},
+ label in legend mark coordinates={(-3ex,-.3ex),(-1.5ex,.3ex),(0,0)},
+ },
+ straight label in legend line/.style={
+ label in legend line coordinates={(-2em,0),(-1.5em,0),(-.5em,0),(0,0)},
+ label in legend mark coordinates={(-1.5em,0),(-.5em,0)},
+ },
+ zig zag label in legend line/.style={
+ label in legend line coordinates={(-2em,0),(-1.5em,.3ex),(-.5em,-.3ex),(0,0)},
+ label in legend mark coordinates={(-1.5em,.3ex),(-.5em,-.3ex)},
+ },
+ circular label in legend line/.style={
+ label in legend line coordinates={%
+ ([xshift=-1em]0:.9em and .35ex),%
+ ([xshift=-1em]45:.9em and .35ex),%
+ ([xshift=-1em]90:.9em and .35ex),%
+ ([xshift=-1em]135:.9em and .35ex),%
+ ([xshift=-1em]180:.9em and .35ex),%
+ ([xshift=-1em]225:.9em and .35ex),%
+ ([xshift=-1em]270:.9em and .35ex),%
+ ([xshift=-1em]315:.9em and .35ex)},%
+ label in legend mark coordinates={([xshift=-1em]120:.9em and .35ex),([xshift=-1em]-60:.9em and .35ex)},
+ },
+ gap circular label in legend line/.style={
+ label in legend line coordinates={%
+ ([xshift=-1em,yshift=.2ex]90:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]162:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]234:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]306:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]18:1.4ex and 0.9ex)},
+ label in legend mark coordinates={
+ ([xshift=-1em,yshift=.2ex]90:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]162:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]234:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]306:1.4ex and 0.9ex),%
+ ([xshift=-1em,yshift=.2ex]18:1.4ex and 0.9ex)}
+ },
+ default label in legend path/.style={zig zag label in legend line},
+ default label in legend closed path/.style={circular label in legend line},
+ default label in legend mark/.style={label in legend one mark},
+}%
+
+
+\def\tikz@dv@legend@entry@visualizer@visualizer{
+}%
+
+
+
+%
+% Basic visualizers
+%
+
+\tikzdatavisualizationset{
+ visualize as line/.style={
+ new object={
+ when=after survey,
+ store=/tikz/data visualization/visualizers/#1,
+ class=plot handler visualizer,
+ arg1=#1,
+ arg2={\tikz@dv@plot@handler,\tikz@dv@plot@mark@maker}
+ },
+ new visualizer={#1}{%
+ every path/.style={draw},
+ style={every mark/.append style={color=visualizer color}},
+ mark size=2pt,
+ semithick,
+ color=visualizer color,
+ mark=none,
+ /tikz/data visualization/every visualize as line/.try,
+ }{visualizer in legend=\tikz@dv@legend@entry@as@example},
+ #1={straight line}
+ },
+ visualize as line/.default=line,
+ visualize as smooth line/.style={
+ visualize as line={#1},
+ #1={smooth line}
+ },
+ visualize as smooth line/.default=line,
+ visualize as smooth cycle/.style={
+ visualize as smooth line={#1},
+ #1={smooth cycle}
+ },
+ visualize as smooth cycle/.default=line,
+ visualize as scatter/.style={
+ new object={
+ when=after survey,
+ store=/tikz/data visualization/visualizers/#1,
+ class=plot handler visualizer,
+ arg1=#1,
+ arg2={\tikz@dv@plot@mark@maker}
+ },
+ new visualizer={#1}{%
+ mark=x,
+ mark size=2pt,
+ style={every mark/.append style={color=visualizer color}},
+ /tikz/data visualization/every visualize as scatter/.try,
+ }{visualizer in legend=\tikz@dv@legend@entry@as@example},
+ #1={no lines}
+ },
+ visualize as scatter/.default=scatter
+}%
+
+\def\tikz@dv@plot@mark@maker{
+ \let\tikz@options=\pgfutil@empty%
+ \let\tikz@transform=\pgfutil@empty%
+ \tikzset{solid,shift only,every mark}%
+ \tikz@options%
+ \ifx\tikz@plot@mark\pgfutil@empty%
+ \pgfplothandlerdiscard
+ \else
+ \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}}
+ \fi
+}%
+
+
+
+%
+% Rectangle visualizers
+%
+
+
+\tikzdatavisualizationset{
+ visualize as rectangles/.style={
+ new object={
+ when=before survey,
+ store=/tikz/data visualization/visualizers/#1,
+ class=rectangle visualizer,
+ arg1=#1
+ },
+ /data point/#1/attribute 1/.initial=x,
+ /data point/#1/attribute 2/.initial=y,
+ new visualizer={#1}{%
+ every path/.style={draw},
+ semithick,
+ color=visualizer color,
+ /tikz/data visualization/every visualize as rectangles/.try,
+ }{visualizer in legend=\tikz@dv@legend@entry@as@rectangle},
+ #1={}
+ },
+ visualize as rectangles/.default=rectangles,
+ %
+ %
+ %
+ visualizer options/.cd,
+ attribute 1/.style={/data point/\tikz@visualizer/attribute 1={#1}},
+ attribute 2/.style={/data point/\tikz@visualizer/attribute 2={#1}},
+}%
+
+
+
+\def\tikz@dv@legend@entry@as@rectangle{
+ \pgfkeysgetvalue{/data point/set}{\tikz@visualizer}
+ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin}
+ \pgfplothandlerpolygon
+ \pgfplotstreamstart
+ \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend rectangle coordinates}{\tikz@dv@temp}
+ \foreach \coordinate in \tikz@dv@temp
+ { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} }
+ \pgfplotstreamend
+ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at end}
+}%
+
+
+
+
+%
+% Style sheets
+%
+
+% Style sheet handler
+
+\pgfkeysdef{/handlers/.style sheet}{%
+ \edef\pgf@marshal{
+ \noexpand \pgfoonew \noexpand\tikz@dv@temp=new style attribute(\pgfkeyscurrentpath,#1)
+ \noexpand \tikz@dv@temp.default connects()
+ }
+ \pgf@marshal
+}%
+
+\tikzset{
+ visualizer color/.code=\colorlet{visualizer color}{#1},
+ visualizer color=black
+}%
+
+% Default style sheets
+
+\pgfdvdeclarestylesheet{vary thickness}
+{
+ default style/.style={line width={0.3pt+(#1)*0.2pt}}
+}%
+
+\pgfdvdeclarestylesheet{vary dashing}
+{
+ default style/.style=solid,
+ 1/.style=solid,
+ 2/.style={dash pattern=on 5\pgflinewidth off 2\pgflinewidth},
+ 3/.style={dash pattern=on 1.5\pgflinewidth off 1.5\pgflinewidth},
+ 4/.style={dash pattern=on 5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth},
+ 5/.style={dash pattern=on 10\pgflinewidth off 3\pgflinewidth},
+ 6/.style={dash pattern=on 10\pgflinewidth off 2\pgflinewidth on 2\pgflinewidth off 2\pgflinewidth},
+ 7/.style={dash pattern=on 8\pgflinewidth off 2\pgflinewidth on
+ 1.5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off
+ 1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth}
+}%
+
+\pgfdvdeclarestylesheet{vary thickness and dashing}
+{
+ default style/.style=thin,
+ 1/.style=thin,
+ 2/.style=thick,
+ 3/.style={
+ dash pattern=on 5\pgflinewidth off 2\pgflinewidth,
+ thin
+ },
+ 4/.style={
+ dash pattern=on 5\pgflinewidth off 2\pgflinewidth,
+ thick,
+ },
+ 5/.style={
+ dash pattern=on 1.5\pgflinewidth off 1.5\pgflinewidth,
+ thin
+ },
+ 6/.style={
+ dash pattern=on 1.5\pgflinewidth off 1.5\pgflinewidth,
+ thick
+ },
+ 7/.style={
+ dash pattern=on 5\pgflinewidth off 1.5\pgflinewidth on
+ 1.5\pgflinewidth off 1.5\pgflinewidth,
+ thin
+ },
+ 8/.style={
+ dash pattern=on 5\pgflinewidth off 1.5\pgflinewidth on
+ 1.5\pgflinewidth off 1.5\pgflinewidth,
+ thick
+ },
+ 9/.style={
+ dash pattern=on 10\pgflinewidth off 3\pgflinewidth,
+ thin
+ },
+ 10/.style={
+ dash pattern=on 10\pgflinewidth off 3\pgflinewidth,
+ thick
+ },
+ 11/.style={
+ dash pattern=on 10\pgflinewidth off 2\pgflinewidth on
+ 2\pgflinewidth off 2\pgflinewidth,
+ thin
+ },
+ 12/.style={
+ dash pattern=on 10\pgflinewidth off 2\pgflinewidth on
+ 2\pgflinewidth off 2\pgflinewidth,
+ thick
+ },
+ 13/.style={
+ dash pattern=on 8\pgflinewidth off 2\pgflinewidth on
+ 1.5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off
+ 1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth,
+ thin
+ },
+ 14/.style={
+ dash pattern=on 8\pgflinewidth off 2\pgflinewidth on
+ 1.5\pgflinewidth off 1.5\pgflinewidth on 1.5\pgflinewidth off
+ 1.5\pgflinewidth on 1.5\pgflinewidth off 1.5\pgflinewidth,
+ thick
+ }
+}%
+
+
+\pgfdvdeclarestylesheet{strong colors}
+{
+ default style/.style={visualizer color=black},
+ 1/.style={visualizer color=black},
+ 2/.style={visualizer color=red!80!black},
+ 3/.style={visualizer color=blue!80!black},
+ 4/.style={visualizer color=green!60!black},
+ 5/.style={visualizer color=orange!80!black},
+ 6/.style={visualizer color=black!60}
+}%
+
+
+\pgfdvdeclarestylesheet{cross marks}
+{
+ default style/.style={mark=x,every mark/.append style=thin,mark size=2pt},
+ 1/.style={mark=x,every mark/.append style=thin,mark size=2pt},
+ 2/.style={mark=+,every mark/.append style=thin,mark size=2pt},
+ 3/.style={mark=Mercedes star,every mark/.append style=thin,mark size=2pt},
+ 4/.style={mark=Mercedes star flipped,every mark/.append style=thin,mark size=2pt},
+ 5/.style={mark=star,every mark/.append style=thin,mark size=2pt},
+ 6/.style={mark=10-pointed star,every mark/.append style={line width=.3pt,mark size=1.8pt}}
+}%
+
+
+\pgfdvdeclarestylesheet{* mark}
+{
+ default style/.style={mark=*,every mark/.append style=thin,mark size=1.4pt},
+}%
+
+\pgfdvdeclarestylesheet{dot mark}
+{
+ default style/.style={mark=*,every mark/.append style=thin,mark size=0.6pt},
+}%
+
+
+\pgfdvdeclarestylesheet{o mark}
+{
+ default style/.style={mark=o,every mark/.append style=thin,mark size=1.4pt},
+}%
+
+
+
+% Declare a color series style sheet
+%
+% #1 = name of the style sheet
+% #2 = color model
+% #3 = initial color
+% #4 = step
+%
+% Description:
+%
+% This function declares a style sheet that changes colors according
+% to the value of the attribute. No test is made that the attribute is
+% a number.
+
+\def\tikzdvdeclarestylesheetcolorseries#1#2#3#4{%
+ \definecolorseries{tikzdvcolorseries#1}{#2}{step}[#2]{#3}{#4}%
+ \resetcolorseries{tikzdvcolorseries#1}%
+ \pgfdvdeclarestylesheet{#1}
+ {
+ default style/.style={
+ /utils/exec=\colorlet{tikz@dv@temp}[rgb]{tikzdvcolorseries#1!![##1]},
+ visualizer color=tikz@dv@temp
+ }
+ }%
+}%
+
+\tikzdvdeclarestylesheetcolorseries{vary hue}{hsb}{.4,0.9,0.8}{.213,0,0}%
+\tikzdvdeclarestylesheetcolorseries{shades of blue}{hsb}{.65,1.4,1}{0,-.4,-.0}%
+\tikzdvdeclarestylesheetcolorseries{shades of red}{hsb}{0,1.4,1}{0,-.4,-.0}%
+\tikzdvdeclarestylesheetcolorseries{gray scale}{hsb}{0,0,-.34}{0,0,.34}%
+
+
+
+
+
+%
+% Basic Axes & Coordinate Systems
+%
+
+
+%
+%
+% Basic axis systems
+%
+%
+
+\tikzdatavisualizationset{
+ xy Cartesian/.style={
+ new Cartesian axis=x axis,
+ x axis={attribute=x,unit vector={(1pt,0cm)}},
+ new Cartesian axis=y axis,
+ y axis={attribute=y,unit vector={(0cm,1pt)}}
+ },
+ Xy axes/.style={x axis={#1},y axis={#1}},
+ uv Cartesian/.style={
+ new Cartesian axis=u axis,
+ u axis={attribute=u,unit vector={(1pt,0cm)}},
+ new Cartesian axis=v axis,
+ v axis={attribute=v,unit vector={(0cm,1pt)}}
+ },
+ uv axes/.style={u axis={#1},v axis={#1}},
+}%
+
+\tikzdatavisualizationset{
+ xyz Cartesian cabinet/.style={
+ xy Cartesian,
+ new Cartesian axis=z axis,
+ z axis={attribute=z,unit vector={(-0.353553pt,-0.353553pt)}}
+ },
+ xyz axes/.style={x axis={#1},y axis={#1},z axis={#1}},
+ uvw Cartesian cabinet/.style={
+ uv Cartesian,
+ new Cartesian axis=w axis,
+ w axis={attribute=w,unit vector={(-0.353553pt,-0.353553pt)}}
+ }
+ uvw axes/.style={u axis={#1},v axis={#1},w axis={#1}},
+}%
+
+
+
+%
+% Create a new axis system
+%
+
+\tikzdatavisualizationset{
+ new axis system/.style n args={4}{
+ #1/.style={
+ #2,
+ #1/.cd,
+ #3,
+ /tikz/data visualization/every #1/.try,
+ ##1,
+ /tikz/data visualization/.cd,
+ #4,
+ }
+ }
+}%
+
+
+% The school book axes
+%
+% This coordinate system can be used to create plots that look like
+% plots in a typical school book: There are two axes called "x axis"
+% and "y axis" that meet at the origin, there are arrows at the ends
+% of the axes, pointing in the directions of the positive axes. No
+% scaling is done by default, rather one unit equals one 1cm. This
+% ensures that the even when multiple plots are created, the same
+% scaling will be used each time.
+%
+% To change the scaling, say "all axes={unit length=1mm}" for
+% instance.
+
+\tikzdatavisualizationset{
+ new axis system={school book axes}{%
+ xy Cartesian,
+ x axis={
+ include value=0,
+ scaling=0 at 0 and \pgfkeysvalueof{/tikz/data visualization/school book axes/unit} at 1cm,
+ visualize axis={y axis={goto=0},style=->,padded},
+ visualize ticks={common={y axis={goto=0},direction axis=y axis},
+ major={tick text at low,
+ options at=0 as [{style={draw=none},no tick text}]
+ }},
+ visualize grid={common={direction axis=y axis,padded}},
+ ticks={step=\pgfkeysvalueof{/tikz/data visualization/school book axes/unit}},
+ padding=0.75em
+ },
+ y axis={
+ include value=0,
+ scaling=0 at 0 and \pgfkeysvalueof{/tikz/data visualization/school book axes/unit} at 1cm,
+ visualize axis={x axis={goto=0},style=->,padded},
+ visualize ticks={
+ common={x axis={goto=0},direction axis=x axis},
+ major={tick text at low,options at=0 as [{high=0,low=0,style={draw=none},node style={anchor=north east}}]}
+ },
+ visualize grid={common={direction axis=x axis,padded}},
+ ticks={step=\pgfkeysvalueof{/tikz/data visualization/school book axes/unit}},
+ padding=0.75em
+ }
+ }{%
+ standard labels
+ }{%
+ @make labels
+ },
+ school book axes/.cd,
+ % Possible axis positionings:
+ %
+ % Place labels at the ends of the axes
+ %
+ standard labels/.style={
+ /tikz/data visualization/@make labels/.style={
+ x axis={
+ visualize label={
+ x axis={goto=padded max, anchor at max},
+ y axis={goto=0}
+ }
+ },
+ y axis={
+ visualize label={
+ y axis={goto=padded max, anchor at max},
+ x axis={goto=0}
+ }
+ }
+ }
+ },
+ %
+ % Basic unit
+ %
+ unit/.initial=1,
+}%
+
+
+
+
+% The scientific axes
+%
+% The scientific axes is a 2d plot that has a predetermined width and
+% height. The data is then scaled in such a way that it fits inside
+% this given rectangle.
+
+\tikzdatavisualizationset{
+ new axis system={scientific axes}{%
+ xy Cartesian,
+ every axis/.append style={style={draw=black!50}},
+ every ticks/.append style={style={draw=black!50}},
+ x axis={
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},
+ ticks
+ },
+ y axis={
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height},
+ ticks
+ }
+ }{%
+ standard labels,
+ outer ticks,
+ }{%
+ @make axes,
+ @make labels
+ },
+ scientific axes/.cd,
+ width/.initial=5cm,
+ height/.initial=0.618*\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},% golden ratio...
+ outer ticks/.style={
+ /tikz/data visualization/@make axes/.style={
+ x axis={
+ visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}},
+ visualize ticks={common={y axis={goto=padded max},direction axis=y axis,low=0pt}},
+ visualize axis={y axis={goto=padded min},padded},
+ visualize axis={y axis={goto=padded max},padded},
+ visualize grid={common={direction axis=y axis,padded}},
+ },
+ y axis={
+ visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}},
+ visualize ticks={common={x axis={goto=padded max},direction axis=x axis,low=0pt}},
+ visualize axis={x axis={goto=padded min},padded},
+ visualize axis={x axis={goto=padded max},padded},
+ visualize grid={common={direction axis=x axis,padded}},
+ }
+ }
+ },
+ inner ticks/.style={
+ /tikz/data visualization/@make axes/.style={
+ x axis={
+ visualize ticks={common={y axis={goto=padded min},direction axis=y axis,low=0pt},major={tick text at low}},
+ visualize ticks={common={y axis={goto=padded max},direction axis=y axis,high=0pt}},
+ visualize axis={y axis={goto=padded min},padded},
+ visualize axis={y axis={goto=padded max},padded},
+ visualize grid={common={direction axis=y axis,padded}},
+ },
+ y axis={
+ visualize ticks={common={x axis={goto=padded min},direction axis=x axis,low=0pt},major={tick text at low}},
+ visualize ticks={common={x axis={goto=padded max},direction axis=x axis,high=0pt}},
+ visualize axis={x axis={goto=padded min},padded},
+ visualize axis={x axis={goto=padded max},padded},
+ visualize grid={common={direction axis=x axis,padded}},
+ }
+ }
+ },
+ clean/.style={
+ /tikz/data visualization/@make axes/.style={
+ x axis={
+ visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}},
+ visualize axis={y axis={goto=padded min}},
+ visualize axis={y axis={goto=min}, style={black!25, line cap=rect}},
+ visualize axis={y axis={goto=max}, style={black!25, line cap=rect}},
+ visualize grid={common={direction axis=y axis}},
+ padding=.5em,
+ },
+ y axis={
+ visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}},
+ visualize axis={x axis={goto=padded min}},
+ visualize axis={x axis={goto=min}, style={black!25, line cap=rect}},
+ visualize axis={x axis={goto=max}, style={black!25, line cap=rect}},
+ visualize grid={common={direction axis=x axis}},
+ padding=.5em
+ },
+ }
+ },
+ % Possible axis positionings:
+ %
+ % Place axes labels below and left, where left label is rotated
+ %
+ standard labels/.style={
+ /tikz/data visualization/@make labels/.style={
+ x axis={
+ visualize label={
+ x axis={goto pos=.5},
+ % Vertical position comes from bounding box:
+ node style={
+ at={(0,0 |- data visualization bounding box.south)},
+ below
+ }
+ }
+ },
+ y axis={
+ visualize label={
+ y axis={goto pos=.5},
+ % Horizontal position comes from bounding box:
+ node style={
+ at={(0,0 -| data visualization bounding box.west)},
+ rotate=90,
+ above}
+ }
+ }
+ }
+ },
+ %
+ % Place axes labels below and left, no rotation
+ %
+ upright labels/.style={
+ /tikz/data visualization/@make labels/.style={
+ x axis={
+ visualize label={
+ x axis={goto pos=.5},
+ % Vertical position comes from bounding box:
+ node style={
+ at={(0,0 |- data visualization bounding box.south)},
+ below
+ }
+ }
+ },
+ y axis={
+ visualize label={
+ y axis={goto pos=.5},
+ % Horizontal position comes from bounding box:
+ node style={
+ at={(0,0 -| data visualization bounding box.west)},
+ left
+ }
+ }
+ }
+ }
+ },
+ %
+ % Place axes at the ends of the axes
+ %
+ end labels/.style={
+ /tikz/data visualization/@make labels/.style={
+ x axis={
+ visualize label={
+ y axis={goto=padded min},
+ % Vertical position comes from bounding box:
+ node style={
+ at={(0,0 -| data visualization bounding box.east)},
+ right
+ }
+ }
+ },
+ y axis={
+ visualize label={
+ x axis={goto=padded min},
+ % Horizontal position comes from bounding box:
+ node style={
+ at={(0,0 |- data visualization bounding box.north)},
+ above
+ }
+ }
+ }
+ }
+ }
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.formats.functions.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.formats.functions.code.tex
new file mode 100644
index 0000000000..5a04c51646
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.formats.functions.code.tex
@@ -0,0 +1,16 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarydatavisualization.formats.functions.code.tex}
+
+\usetikzlibrary{datavisualization}%
+\usepgflibrary{datavisualization.formats.functions}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex
new file mode 100644
index 0000000000..5a37b82854
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex
@@ -0,0 +1,565 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarydatavisualization.polar.code.tex}
+
+\usetikzlibrary{datavisualization}%
+\usepgflibrary{datavisualization.polar}%
+
+
+\tikzdatavisualizationset{%
+ new polar axes/.style 2 args={
+ new axis base=#1,
+ #1={attribute=angle},
+ new axis base=#2,
+ #2={attribute=radius},
+ #2/scaling/default=0 at 0 and 1 at 1cm,
+ new object={
+ store=/tikz/data visualization/#1/polar transformer,
+ class=polar transformer,
+ arg1/.expanded=\pgfkeysvalueof{/tikz/data visualization/angle axis/attribute}/scaled,
+ arg2/.expanded=\pgfkeysvalueof{/tikz/data visualization/radius axis/attribute}/scaled,
+ arg3 from key=/tikz/data visualization/#1/unit vector 0 degrees,
+ arg4 from key=/tikz/data visualization/#1/unit vector 90 degrees
+ },
+ /tikz/data visualization/#1/unit vector 0 degrees/.initial=\pgfqpoint{1pt}{0pt},
+ /tikz/data visualization/#1/unit vector 90 degrees/.initial=\pgfqpoint{0pt}{1pt},
+ },
+ new polar axes/.default={angle axis}{radius axis}
+}%
+\def\tikz@lib@dv@polar@a#1{
+ \pgfkeyssetvalue{\tikz@dv@axis/unit vector 0 degrees}{#1}
+}%
+\def\tikz@lib@dv@polar@b#1{
+ \pgfkeyssetvalue{\tikz@dv@axis/unit vector 90 degrees}{#1}
+}%
+
+
+
+%
+% Scientific polar axes
+%
+
+\tikzset{
+ /tikz/data visualization/axis options/.cd,
+ unit vectors/.code 2 args={
+ \tikz@scan@one@point\tikz@lib@dv@polar@a#1
+ \tikz@scan@one@point\tikz@lib@dv@polar@b#2
+ },
+ degrees/.style={\tikz@dv@axis/scaling=0 at 0 and 1 at 1},
+ radians/.style={\tikz@dv@axis/scaling=0 at 0 and 0.03141592653589793 at 1.8},
+}%
+
+
+
+\tikzdatavisualizationset{
+ new axis system={scientific polar axes}{%
+ new polar axes,
+ angle axis={attribute=angle},
+ radius axis={attribute=radius},
+ every axis/.append style={style={draw=black!50}},
+ every ticks/.append style={style={draw=black!50}},
+ }{%
+ 0 to 360,%
+ outer ticks,
+ }{%
+ @make axes,
+ scientific polar axes/@setup axes,
+ /utils/exec={
+ \edef\pgf@marshal{\noexpand\tikzdatavisualizationset{\pgfkeysvalueof{/tikz/data visualization/@which visualize radius axis}/.list={\pgfkeysvalueof{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/@which radius axes at}}}}}
+ \pgf@marshal
+ },
+ @make labels
+ },
+ @which radius axes at/.initial=@inner radius axes at,
+ @which visualize radius axis/.initial=@visualize radius axis,
+ @inner radius axes at/.initial=,
+ @clean radius axes at/.initial=,
+ @visualize radius axis/.style 2 args={
+ radius axis={
+ visualize axis={angle axis={goto=#1},high=padded max,low=0},
+ visualize ticks={
+ common={angle axis={goto=#1}, direction axis=angle axis},
+ major={tick text at #2,
+ options at=0 as [{style={draw=none},no tick text}]
+ }
+ }
+ }
+ },
+ @visualize clean radius axis/.style n args={5}{
+ radius axis={
+ visualize axis={angle
+ axis={goto=#1},high=max,low=0,style={black!25,line cap=rect}},
+ visualize axis={angle
+ axis={goto=#1},high=max,low=0,style={line cap=rect,#4}},
+ visualize ticks={
+ style={#4},
+ common={angle axis={goto=#1}, direction axis=angle axis, #3=0},
+ major={tick text at #2,#5}
+ }
+ }
+ },
+ @visualize zero/.style={@inner visualize zero={#1}},
+ @clean visualize zero/.style={},
+ @inner visualize zero/.style={
+ radius axis={
+ visualize ticks={
+ common={angle axis={goto=0}, direction axis=angle axis},
+ major={tick text at low,low=0,high=0,at=0 as
+ [{style={draw=none},node style={anchor=#1}}]
+ }
+ }
+ }
+ },
+ @degrees/.style={
+ angle axis={degrees, ticks={step=15, tick suffix=$^\circ$, major={
+ options at=360 as [{style={draw=none},no tick text}],
+ options at=-180 as [{style={draw=none},no tick text}]}}}
+ },
+ @rad/.style={
+ angle axis={radians, ticks={
+ step=(pi/12),
+ node style={
+ /pgf/number format/frac,
+ /pgf/number format/frac shift={1}
+ },
+ tick typesetter/.code={%
+ \pgfmathsetmacro{\tikz@lib@dv@pol}{round(####1*3.819718634205488)/12}%
+ \pgfmathapproxequalto{\tikz@lib@dv@pol}{0}%
+ \ifdim\pgfmathresult pt=1.0pt%
+ $0$%
+ \else%
+ \pgfmathapproxequalto{\tikz@lib@dv@pol}{1}%
+ \ifdim\pgfmathresult pt=1.0pt%
+ $\pi$%
+ \else
+ \pgfmathapproxequalto{\tikz@lib@dv@pol}{-1}%
+ \ifdim\pgfmathresult pt=1.0pt%
+ $-\pi$%
+ \else%
+ \pgfmathprintnumber{\tikz@lib@dv@pol}$\pi$%
+ \fi%
+ \fi%
+ \fi%
+ },
+ major={
+ options at=6.2831985e0 as [{style={draw=none},no tick text}],
+ options at=6.2831192e0 as [{style={draw=none},no tick text}],
+ options at=6.2830794e0 as [{style={draw=none},no tick text}],
+ options at=6.2828787e0 as [{style={draw=none},no tick text}],
+ options at=6.2831598e0 as [{style={draw=none},no tick text}],
+ options at=-3.1415991e0 as [{style={draw=none},no tick text}],
+ options at=-3.1415802e0 as [{style={draw=none},no tick text}],
+ options at=-3.1415602e0 as [{style={draw=none},no tick text}],
+ options at=-3.14153961e0 as [{style={draw=none},no tick text}],
+ options at=-3.1414406e0 as [{style={draw=none},no tick text}],
+ }
+ }
+ }
+ },
+ @make labels/.style={},
+}%
+
+\tikzdatavisualizationset{
+ scientific polar axes/.cd,
+ %
+ %
+ %
+ outer ticks/.style={
+ /tikz/data visualization/@make axes/.style={
+ radius axis={
+ min value=0,
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius},
+ padding=0em,
+ ticks={few},
+ visualize grid={common={direction axis=angle axis,low=min,high=max}},
+ },
+ angle axis={
+ visualize axis={radius axis={goto=padded max},low=min,high=max},
+ visualize ticks={common={radius axis={goto=padded max},direction
+ axis=radius axis},common={low=0},major={tick text at high}},
+ visualize grid={common={direction axis=radius axis},low=0,high=padded max},
+ }
+ },
+ /tikz/data visualization/@which radius axes at=@inner radius axes at,
+ /tikz/data visualization/@which visualize radius axis=@visualize radius axis,
+ /tikz/data visualization/@visualize zero/.style={@inner visualize zero={##1}},
+ },
+ inner ticks/.style={
+ /tikz/data visualization/@make axes/.style={
+ radius axis={
+ min value=0,
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius},
+ padding=0em,
+ ticks={few},
+ visualize grid={common={direction axis=angle axis,low=min,high=max}},
+ },
+ angle axis={
+ visualize axis={radius axis={goto=padded max},low=min,high=max},
+ visualize ticks={common={radius axis={goto=padded max},direction
+ axis=radius axis},common={high=0},major={tick text at high}},
+ visualize grid={common={direction axis=radius axis},low=0,high=padded max},
+ }
+ },
+ /tikz/data visualization/@which radius axes at=@inner radius axes at,
+ /tikz/data visualization/@which visualize radius axis=@visualize radius axis,
+ /tikz/data visualization/@visualize zero/.style={@inner visualize zero={##1}},
+ },
+ clean/.style={
+ /tikz/data visualization/@make axes/.style={
+ radius axis={
+ min value=0,
+ length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius},
+ padding=.5em,
+ ticks={few},
+ visualize grid={common={direction axis=angle axis,low=min,high=max}},
+ },
+ angle axis={
+ padding=.5em,
+ visualize axis={radius axis={goto=max}, style={black!25, line cap=rect},low=min,high=max},
+ visualize axis={radius axis={goto=padded max}, style={line cap=rect}, low=min,high=max},
+ visualize ticks={common={radius axis={goto=padded max}, direction axis=radius axis},common={low=0},major={tick text at high}},
+ visualize grid={common={direction axis=radius axis},low=0,high=max},
+ }
+ },
+ /tikz/data visualization/@which radius axes at=@clean radius axes at,
+ /tikz/data visualization/@which visualize radius axis=@visualize clean radius axis,
+ /tikz/data visualization/@visualize zero/.style={@clean visualize zero={##1}},
+ },
+ radius/.initial=3.25cm,
+ %
+ % First quadrant
+ %
+ 0 to pi half/.style={
+ @setup axes/.style={
+ angle axis={min value=0, max value=1.570796326794897},
+ @rad,
+ @visualize zero=north east,
+ @inner radius axes at={{0}{low},{1.570796326794897}{high}},
+ @clean radius axes at={%
+ {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {1.570796326794897}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ 0 to 90/.style={
+ @setup axes/.style={
+ angle axis={min value=0, max value=90},
+ @degrees,
+ @visualize zero=north east,
+ @inner radius axes at={{0}{low},{90}{high}},
+ @clean radius axes at={%
+ {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {90}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ quadrant/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 0 and max at 90, ticks},
+ @visualize zero=north east,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ quadrant clockwise/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 90 and max at 0, ticks},
+ @visualize zero=north east,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ %
+ % Fourth quadrant
+ %
+ -pi half to 0/.style={
+ @setup axes/.style={
+ angle axis={min value=-1.570796326794897, max value=0},
+ @rad,
+ @visualize zero=south east,
+ @inner radius axes at={{-1.570796326794897}{low},{0}{high}},
+ @clean radius axes at={%
+ {-1.570796326794897}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {0}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ -90 to 0/.style={
+ @setup axes/.style={
+ angle axis={min value=-90, max value=0},
+ @degrees,
+ @visualize zero=south east,
+ @inner radius axes at={{-90}{low},{0}{high}},
+ @clean radius axes at={%
+ {-90}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {0}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ fourth quadrant/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at -90 and max at 0, ticks},
+ @visualize zero=south east,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ fourth quadrant clockwise/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 0 and max at -90, ticks},
+ @visualize zero=south east,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{}
+ }
+ }
+ },
+ %
+ % Upper half
+ %
+ 0 to pi/.style={
+ @setup axes/.style={
+ angle axis={min value=0, max value=3.141592653589793},
+ @rad,
+ @visualize zero=north,
+ @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high}},
+ @clean radius axes at={%
+ {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {3.141592653589793}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ 0 to 180/.style={
+ @setup axes/.style={
+ angle axis={min value=0, max value=180},
+ @degrees,
+ @visualize zero=north,
+ @inner radius axes at={{0}{low},{90}{high},{180}{high}},
+ @clean radius axes at={%
+ {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {180}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ upper half/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 0 and max at 180, ticks},
+ @visualize zero=north,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ upper half clockwise/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 180 and max at 0, ticks},
+ @visualize zero=north,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ %
+ % Lower half
+ %
+ lower half/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at -180 and max at 0, ticks},
+ @visualize zero=south,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{yshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ lower half clockwise/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 0 and max at -180, ticks},
+ @visualize zero=south,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{yshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ %
+ % Right half
+ %
+ -pi half to pi half/.style={
+ @setup axes/.style={
+ @rad,
+ angle axis={min value=-1.570796326794897, max value=1.570796326794897},
+ @visualize zero=east,
+ @inner radius axes at={{0}{low},{1.570796326794897}{low},{-1.570796326794897}{high}},
+ @clean radius axes at={%
+ {-1.570796326794897}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {1.570796326794897}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ -90 to 90/.style={
+ @setup axes/.style={
+ angle axis={min value=-90, max value=90},
+ @degrees,
+ @visualize zero=east,
+ @inner radius axes at={{-90}{low},{0}{low},{90}{high}},
+ @clean radius axes at={%
+ {-90}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {90}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ right half/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at -90 and max at 90, ticks},
+ @visualize zero=east,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ right half clockwise/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 90 and max at -90, ticks},
+ @visualize zero=east,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ %
+ % Left half
+ %
+ left half/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 90 and max at 270, ticks},
+ @visualize zero=west,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ left half clockwise/.style={
+ @setup axes/.style={
+ angle axis={scaling=min at 270 and max at 90, ticks},
+ @visualize zero=west,
+ @inner radius axes at={{min}{low},{max}{high}},
+ @clean radius axes at={%
+ {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},%
+ {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data
+ visualization/angle axis/padding max}}{options at=0 as
+ [{style={draw=none}, no tick text}]}
+ }
+ }
+ },
+ %
+ % Full circle
+ %
+ 0 to 2pi/.style={
+ @setup axes/.style={
+ angle axis={min value=0, max value=6.283185307179586},
+ @rad,
+ @visualize zero=north east,
+ @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high},{4.71238898038469}{low}},
+ @clean radius axes at={{0}{low}{high}{}{}}
+ }
+ },
+ -pi to pi/.style={
+ @setup axes/.style={
+ angle axis={min value=-3.141592653589793, max value=3.141592653589793},
+ @rad,
+ @visualize zero=north east,
+ @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high},{-1.57079632679489}{low}},
+ @clean radius axes at={{0}{low}{high}{}{}}
+ }
+ },
+ 0 to 360/.style={
+ @setup axes/.style={
+ angle axis={min value=0, max value=360},
+ @degrees,
+ @visualize zero=north east,
+ @inner radius axes at={{0}{low},{90}{high},{180}{high},{270}{low}},
+ @clean radius axes at={{0}{low}{high}{}{}}
+ }
+ },
+ -180 to 180/.style={
+ @setup axes/.style={
+ angle axis={min value=-180, max value=180},
+ @degrees,
+ @visualize zero=north east,
+ @inner radius axes at={{0}{low},{90}{high},{180}{high},{-90}{low}},
+ @clean radius axes at={{0}{low}{high}{}{}}
+ }
+ },
+}%
+
+
+
+
+%
+% Pie-charts -- still under construction...
+%
+
+\tikzset{
+ /tikz/data visualization/axis options/.cd,
+ percent/.style={\tikz@dv@axis/scaling=0 at 0 and 1 at 3.6},
+ full circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 360},
+ half circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 180},
+ quarter circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 90}
+}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.sparklines.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.sparklines.code.tex
new file mode 100644
index 0000000000..2e2e77ae0b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.sparklines.code.tex
@@ -0,0 +1,37 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarydatavisualization.sparklines.code.tex}
+
+\usetikzlibrary{datavisualization}%
+
+
+
+
+%
+% Sparklines (not yet usable...)
+%
+
+\tikzdatavisualizationset{
+ spark line/.style={
+ xy Cartesian,
+ x axis={
+ unit length={1pt}
+ },
+ y axis={
+ scaling={min at -0.2em and max at 0.8em}
+ },
+ new line plot,
+ every spark line plot/.try
+ }
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex
new file mode 100644
index 0000000000..20a1735807
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex
@@ -0,0 +1,2674 @@
+% Copyright 2019 by Till Tantau
+% Copyright 2019 by Jannis Pohlmann
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarygraphs.code.tex}
+
+
+%
+% Interface keys
+%
+
+\def\tikzgraphsset{\pgfqkeys{/tikz/graphs}}%
+
+\tikzgraphsset{
+ new ->/.code n args={4}{%
+ \path [->,every new ->/.try]
+ (#1\tikzgraphleftanchor)
+ edge[#3] #4
+ (#2\tikzgraphrightanchor);},
+ new --/.code n args={4}{
+ \path [-,every new --/.try]
+ (#1\tikzgraphleftanchor)
+ edge[#3] #4
+ (#2\tikzgraphrightanchor);},
+ new <->/.code n args={4}{
+ \path [<->,every new <->/.try]
+ (#1\tikzgraphleftanchor)
+ edge[#3] #4
+ (#2\tikzgraphrightanchor);},
+ new -!-/.code n args={4}{},
+ new <-/.code n args={4}{%
+ \path [<-,every new <-/.try]
+ (#1\tikzgraphleftanchor)
+ edge[#3] #4
+ (#2\tikzgraphrightanchor);
+ }
+}%
+
+
+\def\tikz@lib@graph@store@anchor#1#2{%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\pgfutil@empty%
+ \let#2\tikz@temp%
+ \else%
+ \def\tikz@temp{.#1}%
+ \let#2\tikz@temp%
+ \fi%
+}%
+
+\tikzgraphsset{
+ default edge kind/.initial=--,
+ --/.style={default edge kind=--},
+ ->/.style={default edge kind=->},
+ <-/.style={default edge kind=<-},
+ <->/.style={default edge kind=<->},
+ -!-/.style={default edge kind=-!-},
+ default edge operator/.initial=matching and star,
+ left anchor/.code=\tikz@lib@graph@store@anchor{#1}{\tikzgraphleftanchor},
+ right anchor/.code=\tikz@lib@graph@store@anchor{#1}{\tikzgraphrightanchor},
+ left anchor=,
+ right anchor=
+}%
+
+
+%
+% Keys for using nodes declared outside a graph inside a graph as if
+% it were declared there
+%
+
+\tikzgraphsset{
+ use existing nodes/.is if=tikz@lib@graph@all
+}%
+
+\tikzset{
+ new set/.code={
+ \expandafter\global\expandafter\let\csname tikz@lg@node@set #1\endcsname\pgfutil@empty%
+ },
+ set/.code={
+ \tikz@fig@mustbenamed%
+ \ifcsname tikz@lg@node@set #1\endcsname\else
+ \tikzerror{Undefined set `#1'}%
+ \fi
+ \expandafter\def\expandafter\tikz@alias\expandafter{\tikz@alias%
+ \expandafter\def\expandafter\pgf@temp\expandafter{\csname tikz@lg@node@set #1\endcsname}%
+ \expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\pgf@temp\expandafter{\expandafter\tikz@lg@do\expandafter{\tikz@fig@name}}%
+ }%
+ },%
+}%
+
+\newif\iftikz@lib@graph@all
+
+
+%
+% Simple versus multi graphs
+%
+\tikzgraphsset{
+ simple/.code={
+ \iftikz@lib@graph@simple%
+ % is already simple, ignore
+ \else
+ \tikz@lib@graph@simpletrue%
+ \pgfkeysalso{operator=\tikz@lib@graph@simple@done}%
+ \fi%
+ },
+ multi/.code={
+ \tikz@lib@graph@simplefalse%
+ }
+}%
+
+\newif\iftikz@lib@graph@simple
+
+\def\tikz@lib@graph@set@simple@edge#1#2#3#4#5{%
+ % #1 = kind (<-, ->, ...)
+ % #2 = from
+ % #3 = to
+ % #4 = options
+ % #5 = edge nodes
+ %
+ % Ok, first, test, whether edge exists:
+ \ifcsname tikz@lg@e@#3@#2\endcsname%
+ \expandafter\global\expandafter\let\csname tikz@lg@e@#3@#2\endcsname\relax% reset
+ \fi%
+ \expandafter\gdef\csname tikz@lg@e@#2@#3\endcsname{\tikz@lib@graph@make@simple@edge{#1}{#2}{#3}{#4}{#5}}%
+}%
+
+\def\tikz@lib@graph@make@simple@edge#1#2#3#4#5{%
+ \pgfqkeys{/tikz/graphs}{new #1={#2}{#3}{#4}{#5}}%
+}%
+
+
+\def\tikz@lib@graph@simple@done{%
+ \tikz@lib@graph@pack@node@list%
+ {%
+ \let\tikz@lg@do\tikz@lib@graph@simple@node%
+ \tikz@lib@graph@node@list
+ }%
+}%
+
+\def\tikz@lib@graph@simple@node#1{%
+ {%
+ \def\tikz@lib@graph@simple@from@node{#1}%
+ \let\tikz@lg@do\tikz@lib@graph@simple@other@node%
+ \tikz@lib@graph@node@list%
+ }%
+}%
+
+\def\tikz@lib@graph@simple@other@node#1{%
+ \ifcsname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname%
+ \csname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname%
+ \expandafter\global\expandafter\let\csname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname\relax%
+ \fi%
+}%
+
+
+%
+% Basic options
+%
+
+\tikzgraphsset{
+ @nodes styling/.style=,
+ nodes/.style={/tikz/graphs/@nodes styling/.append style={,#1}},
+ @edges styling/.initial=,
+ edges/.style={/tikz/graphs/@edges styling/.append={,#1}},
+ edge/.style={edges={#1}},
+ @edges node/.initial=,
+ edge node/.style={/tikz/graphs/@edges node/.append={#1}},
+ edge label/.style={/tikz/graphs/@edges node/.append={node[auto]{#1}}},
+ edge label'/.style={/tikz/graphs/@edges node/.append={node[auto,swap]{#1}}},
+ @operators/.initial=,
+ operator/.style={/tikz/graphs/@operators/.append={#1}},
+ @extra group options/.style=,
+}%
+
+
+\def\tikzgraphinvokeoperator#1{%
+ {%
+ \pgfkeyslet{/tikz/graphs/@operators}\pgfutil@empty%
+ \pgfkeys{/tikz/graphs/.cd,#1}%
+ \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@temp%
+ \global\let\tikz@lib@graph@temp\tikz@lib@graph@temp%
+ }%
+ \tikz@lib@graph@temp%
+ \global\let\tikz@lib@graph@temp\relax%
+}%
+
+
+%
+% The parser
+%
+
+\def\tikz@lib@graph@parser{%
+ \pgfutil@ifnextchar[{\tikz@lib@graph@parser@}{\tikz@lib@graph@parser@[]}%]
+}%
+
+\def\tikz@lib@graph@parser@[#1]{%
+ \setbox\tikz@whichbox=\hbox\bgroup%
+ \unhbox\tikz@whichbox%
+ \hbox\bgroup
+ \bgroup%
+ \pgfinterruptpath%
+ \scope[graphs/.cd,@graph drawing setup/.try,@operators=,every graph/.try,#1]%
+ \begingroup%
+ \iftikz@graph@quick%
+ \expandafter\tikz@lib@graphs@parse@quick@graph%
+ \else%
+ \expandafter\tikz@lib@graphs@normal@main%
+ \fi%
+}%
+
+\long\def\tikz@lib@graphs@normal@main#1{%
+ \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@outer@operators%
+ \let\tikz@lib@graph@options\pgfutil@empty%
+ \let\tikz@lib@graph@node@list\pgfutil@empty%
+ \pgfkeyssetvalue{/tikz/graphs/placement/depth}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/width}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/level}{0}%
+ \tikz@lib@graph@start@hint@group%
+ \tikz@lib@graph@parse@group{#1}%
+ \tikz@lib@graph@end@hint@group
+ \tikz@lib@graph@outer@operators%
+ \let\tikz@lg@do=\tikz@lib@graph@cleanup%
+ \tikz@lib@graph@node@list%
+ \tikz@lib@graph@main@done%
+}%
+
+\def\tikz@lib@graph@main@done{%
+ \endgroup%
+ \endscope%
+ \endpgfinterruptpath%
+ \egroup
+ \egroup%
+ \egroup%
+ \tikz@lib@graph@parser@done%
+}%
+
+
+
+
+
+\def\tikz@lib@graph@start@hint@group{%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/element count}{0}%
+}%
+
+\def\tikz@lib@graph@end@hint@group{%
+ % Get local depth and width outside
+ \xdef\tikz@lib@graph@group@depth{\pgfkeysvalueof{/tikz/graphs/placement/local depth}}
+ \xdef\tikz@lib@graph@group@width{\pgfkeysvalueof{/tikz/graphs/placement/local width}}
+}%
+
+\def\tikz@lib@graph@hint@aftergroup{%
+ \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@h%
+ \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh%
+ \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw%
+ \pgfmathsetmacro\tikz@temp@h{\tikz@lib@graph@group@width+\tikz@temp@h}
+ \pgfmathsetmacro\tikz@temp@lh{\tikz@lib@graph@group@width+\tikz@temp@lh}
+ \pgfmathsetmacro\tikz@temp@lw{max(\tikz@lib@graph@group@depth,\tikz@temp@lw)}
+ \pgfkeyslet{/tikz/graphs/placement/width}\tikz@temp@h%
+ \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh%
+ \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw%
+ %
+ \pgfkeysgetvalue{/tikz/graphs/placement/element count}\tikz@temp%
+ \c@pgf@counta=\tikz@temp\relax%
+ \advance\c@pgf@counta by1\relax%
+ \edef\tikz@temp{\the\c@pgf@counta}%
+ \pgfkeyslet{/tikz/graphs/placement/element count}\tikz@temp%
+}%
+
+\def\tikz@lib@graph@placement@update{%
+ \pgfkeys{/tikz/graphs/placement/logical node depth/.expand once=\tikz@lib@graph@name}
+ \let\tikz@lib@graph@node@depth\pgfmathresult
+ \pgfkeys{/tikz/graphs/placement/logical node width/.expand once=\tikz@lib@graph@name}
+ \let\tikz@lib@graph@node@width\pgfmathresult
+ % This is a single node, so update the lengths accordingly
+ \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@h%
+ \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh%
+ \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw%
+ \pgfmathsetmacro\tikz@temp@h{\tikz@lib@graph@node@width+\tikz@temp@h}
+ \pgfmathsetmacro\tikz@temp@lh{\tikz@lib@graph@node@width+\tikz@temp@lh}
+ \pgfmathsetmacro\tikz@temp@lw{max(\tikz@lib@graph@node@depth,\tikz@temp@lw)}
+ \pgfkeyslet{/tikz/graphs/placement/width}\tikz@temp@h%
+ \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh%
+ \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw%
+ %
+ \pgfkeysgetvalue{/tikz/graphs/placement/element count}\tikz@temp%
+ \c@pgf@counta=\tikz@temp\relax%
+ \advance\c@pgf@counta by1\relax%
+ \edef\tikz@temp{\the\c@pgf@counta}%
+ \pgfkeyslet{/tikz/graphs/placement/element count}\tikz@temp%
+}%
+
+\def\tikz@lib@graph@placement@after@chain@update{%
+ \pgfkeysgetvalue{/tikz/graphs/placement/depth}\tikz@temp@w%
+ \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh%
+ \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw%
+ \pgfmathsetmacro\tikz@temp@w{\tikz@lib@graph@chain@depth+\tikz@temp@w}%
+ \pgfmathsetmacro\tikz@temp@lw{\tikz@lib@graph@chain@depth+\tikz@temp@lw}%
+ \pgfmathsetmacro\tikz@temp@lh{max(\tikz@lib@graph@chain@width,\tikz@temp@lh)}%
+ \pgfkeyslet{/tikz/graphs/placement/depth}\tikz@temp@w%
+ \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh%
+ \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw%
+ %
+ \pgfkeysgetvalue{/tikz/graphs/placement/chain count}\tikz@temp%
+ \c@pgf@counta=\tikz@temp\relax%
+ \advance\c@pgf@counta by1\relax%
+ \edef\tikz@temp{\the\c@pgf@counta}%
+ \pgfkeyslet{/tikz/graphs/placement/chain count}\tikz@temp%
+}%
+
+
+%
+% Parse a group
+%
+
+\long\def\tikz@lib@graph@parse@group#1{
+ \let\tikz@lib@graph@group@qa\pgfutil@empty%
+ \let\tikz@lib@graph@group@q\pgfutil@empty%
+ \let\tikz@lib@graph@group@c\pgfutil@empty%
+ \let\tikz@lib@graph@group@cont\pgfutil@empty%
+ \let\tikz@lib@graph@group@conta\pgfutil@empty%
+ \tikz@lib@graph@group@check#1\par\pgf@stop@eogroup%
+}%
+
+
+
+%
+% Start of a group
+%
+\def\tikz@lib@graph@group@check{%
+ \pgfutil@ifnextchar[\tikz@lib@graph@group@opt{\tikz@lib@graph@group@opt[]}%]
+}%
+
+\def\tikz@lib@graph@group@opt[#1]{%
+ \let\tikz@lib@graph@parse@extras\pgfutil@empty%
+ \tikzgraphsset{
+ @operators=,
+ every group/.try,
+ @extra group options,
+ @extra group options/.style=,%
+ #1}%
+ \expandafter\tikz@lib@graph@par\tikz@lib@graph@parse@extras%
+}%
+
+\tikzgraphsset{
+ parse/.code={\expandafter\def\expandafter\tikz@lib@graph@parse@extras\expandafter{\tikz@lib@graph@parse@extras#1}},
+}%
+
+
+
+%
+% Remove \par
+%
+
+\def\tikz@lib@graph@par{%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@par@@}{\tikz@lib@graph@par@}%
+}%
+\long\def\tikz@lib@graph@par@#1\par{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \expandafter\tikz@lib@graph@quotes\tikz@lib@graph@group@c#1"}{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@c\expandafter{\tikz@lib@graph@group@c#1}%
+ \tikz@lib@graph@par%
+ }%
+}%
+\long\def\tikz@lib@graph@par@@#1{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@c\expandafter{\tikz@lib@graph@group@c{#1}}%
+ \tikz@lib@graph@par
+}%
+
+
+
+%
+% Replace ..."..."... by ..."{...}"...
+%
+\def\tikz@lib@graph@quotes{%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@quotes@@}{\tikz@lib@graph@quotes@}%
+}%
+\def\tikz@lib@graph@quotes@#1"{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \tikz@lib@graph@passon{#1}%
+ }{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q#1"}%
+ \tikz@lib@graph@quotes@cont%
+ }%
+}%
+
+\def\tikz@lib@graph@quotes@cont#1"#2"{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \tikz@lib@graph@passon{{#1}"#2}}{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q{#1}"#2"}%
+ \tikz@lib@graph@quotes@cont}%
+}%
+
+\def\tikz@lib@graph@quotes@@#1{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q{#1}}%
+ \tikz@lib@graph@quotes%
+}%
+
+
+
+%
+% Replace ..."..."... by ..."{...}"... (active version)
+%
+{%
+ \catcode`\"=13\relax
+
+ \gdef\tikz@lib@graph@passon#1{\expandafter\tikz@lib@graph@quotesactive\tikz@lib@graph@group@q#1"}%
+
+ \gdef\tikz@lib@graph@quotesactive{%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@quotesactive@@}{\tikz@lib@graph@quotesactive@}%
+ }%
+ \gdef\tikz@lib@graph@quotesactive@#1"{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@qa#1[%
+ }{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa#1"}%
+ \tikz@lib@graph@quotesactive@cont%
+ }%
+ }%
+
+ \gdef\tikz@lib@graph@quotesactive@cont#1"#2"{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@qa{#1}"#2[}{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa{#1}"#2"}%
+ \tikz@lib@graph@quotesactive@cont}%
+ }%
+
+ \gdef\tikz@lib@graph@quotesactive@@#1{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa{#1}}%
+ \tikz@lib@graph@quotesactive%
+ }%
+}%
+
+
+
+
+%
+% Replace ...[...]... by ...[{...}]...
+%
+\def\tikz@lib@graph@encloser{%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@encloser@@}{\tikz@lib@graph@encloser@}%
+}%
+\def\tikz@lib@graph@encloser@#1[{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \expandafter\tikz@lib@graph@semi\tikz@lib@graph@group@cont#1;%
+ }{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@cont\expandafter{\tikz@lib@graph@group@cont#1[}%]
+ \tikz@lib@graph@encloser@cont%
+ }%
+}%
+
+\def\tikz@lib@graph@encloser@cont#1]#2[{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \expandafter\tikz@lib@graph@semi\tikz@lib@graph@group@cont{#1}]#2;}{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@cont\expandafter{\tikz@lib@graph@group@cont{#1}]#2[}%
+ \tikz@lib@graph@encloser@cont}%
+}%
+
+\def\tikz@lib@graph@encloser@@#1{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@cont\expandafter{\tikz@lib@graph@group@cont{#1}}%
+ \tikz@lib@graph@encloser%
+}%
+
+
+
+
+%
+% Replace ; by ,
+%
+
+\def\tikz@lib@graph@semi{%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@semi@@}{\tikz@lib@graph@semi@}%
+}%
+\def\tikz@lib@graph@semi@#1;{%
+ \pgfutil@ifnextchar\pgf@stop@eogroup{%
+ \expandafter\tikz@lib@graph@main@parser\tikz@lib@graph@group@conta#1,}{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@conta\expandafter{\tikz@lib@graph@group@conta#1,}%
+ \tikz@lib@graph@semi%
+ }%
+}%
+\def\tikz@lib@graph@semi@@#1{%
+ \expandafter\def\expandafter\tikz@lib@graph@group@conta\expandafter{\tikz@lib@graph@group@conta{#1}}%
+ \tikz@lib@graph@semi%
+}%
+
+
+%
+% Main parse
+%
+
+\def\tikz@lib@graph@main@parser{%
+ \begingroup%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}%
+ \let\tikz@lib@graph@stored@actions\pgfutil@empty%
+ \let\tikz@lib@graph@node@list\pgfutil@empty% reset
+ \tikz@lib@graph@main@parser@start%
+}%
+\def\tikz@lib@graph@main@parser@start{%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@protect@group}{\tikz@lib@graph@main@parser@cont}%
+}%
+
+\def\tikz@lib@graph@protect@group#1{% skip space
+ \pgfutil@ifnextchar\relax{\tikz@lib@graph@main@parser@cont{{#1}}}{\tikz@lib@graph@main@parser@cont{{#1}}}%
+}%
+
+\def\tikz@lib@graph@main@parser@cont{\tikz@lib@graph@check@quotes\tikz@lib@graph@main@parser@cont@normal}%
+\def\tikz@lib@graph@main@parser@cont@normal#1,{%
+ \tikz@lib@graph@parse@one#1-\pgf@stop@eodashes%
+}%
+
+\def\tikz@lib@graph@parse@one{%
+ \pgfutil@ifnextchar\bgroup\tikz@lib@graph@scope\tikz@lib@graph@node%
+}%
+
+
+
+% Special quoted nodes
+
+\def\tikz@lib@graph@check@quotes#1{%
+ \let\tikz@lib@graph@cont@quote#1%
+ \pgfutil@ifnextchar"{\begingroup\pgfkeys@temptoks{}\pgfutil@empty\tikz@lib@graph@quote@parser}{\tikz@lib@graph@check@quotes@active}%
+}%
+{%
+ \catcode`\"=13\relax
+ \gdef\tikz@lib@graph@check@quotes@active{%
+ \pgfutil@ifnextchar"{\begingroup\pgfkeys@temptoks{}\pgfutil@empty\tikz@lib@graph@quote@parser@active}{\tikz@lib@graph@cont@quote}%
+ }%
+ \gdef\tikz@lib@graph@quote@parser@active"#1"{%
+ \pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks #1}%
+ \pgfutil@ifnextchar"{\pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks "}\tikz@lib@graph@quote@parser@active}{\tikz@lib@graph@quote@parser@done}%
+ }%
+}%
+
+\def\tikz@lib@graph@quote@parser"#1"{%
+ \pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks #1}%
+ \pgfutil@ifnextchar"{\pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks "}\tikz@lib@graph@quote@parser}{\tikz@lib@graph@quote@parser@done}%
+}%
+
+\def\tikz@lib@graph@quote@parser@done{%
+ {\expandafter\scantokens\expandafter{%
+ \expandafter\expandafter\expandafter\tikzlibgraphactivations\expandafter\expandafter\expandafter\tikzlibgraphdoedef\expandafter{\the\pgfkeys@temptoks}%
+ }}%
+ {\expandafter\scantokens\expandafter{\expandafter\tikzlibgraphactivationsbrace\expandafter\xdef\expandafter\tikzlibgraphreplaced\expandafter<\tikzlibgraphreplaced>\catcode`\}=2\relax}}%
+ \edef\tikzlibgraphreplaced{\expandafter\detokenize\expandafter{\tikzlibgraphreplaced}}
+ \pgfutil@ifnextchar/\tikz@lib@graph@quotes@slash\tikz@lib@graph@quotes@no@slash%
+}%
+\def\tikz@lib@graph@quotes@no@slash{%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \tikz@smuggle\expandafter\expandafter\expandafter{\expandafter\tikzlibgraphreplaced\expandafter/\expandafter{\the\pgfkeys@temptoks}}%
+ \expandafter\endgroup\expandafter\tikz@lib@graph@cont@quote\tikz@smuggle%
+}%
+\def\tikz@lib@graph@quotes@slash/{%
+ \pgfutil@ifnextchar/% Ah, double slash...
+ {\tikz@lib@graph@quotes@no@slash/}{\expandafter\endgroup\expandafter\tikz@lib@graph@cont@quote\tikzlibgraphreplaced/}%
+}%
+\def\tikzlibgraphdoedef{\xdef\tikzlibgraphreplaced}%
+
+\def\tikz@lib@prepare@active#1#2#3{%
+ {%
+ \catcode`#1=13\relax%
+ \scantokens{\gdef\tikzlibgraphactivator{\def#2{@#3@}}}%
+ }%
+ \pgfutil@g@addto@macro\tikzlibgraphactivations{\catcode`#1=13\relax}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\tikzlibgraphactivations\expandafter{\tikzlibgraphactivator}%
+}%
+
+\let\tikzlibgraphactivations\pgfutil@empty
+
+%
+% Remove \outer from \+ for plain TeX
+%
+
+\outer\def\tikz@lib@outer@test{\tabalign}%
+\ifx\+\tikz@lib@outer@test
+ \def\+{\tabalign}
+\fi
+
+\tikz@lib@prepare@active{\$}{$}{DOLLAR SIGN}% $
+\tikz@lib@prepare@active{\&}{&}{AMPERSAND}%
+\tikz@lib@prepare@active{\^}{^}{CIRCUMFLEX ACCENT}%
+\tikz@lib@prepare@active{\~}{~}{TILDE}%
+\tikz@lib@prepare@active{\_}{_}{LOW LINE}%
+\tikz@lib@prepare@active{\|}{|}{VERTICAL LINE}%
+\tikz@lib@prepare@active{\[}{[}{LEFT SQUARE BRACKET}%
+\tikz@lib@prepare@active{\]}{]}{RIGHT SQUARE BRACKET}%
+\tikz@lib@prepare@active{\(}{(}{LEFT PARENTHESIS}%
+\tikz@lib@prepare@active{\)}{)}{RIGHT PARENTHESIS}%
+\tikz@lib@prepare@active{\/}{/}{SOLIDUS}%
+\tikz@lib@prepare@active{\.}{.}{FULL STOP}%
+\tikz@lib@prepare@active{\-}{-}{HYPHEN MINUS}%
+\tikz@lib@prepare@active{\,}{,}{COMMA}%
+\tikz@lib@prepare@active{\+}{+}{PLUS SIGN}%
+\tikz@lib@prepare@active{\*}{*}{ASTERISK}%
+\tikz@lib@prepare@active{\'}{'}{APOSTROPHE}%
+\tikz@lib@prepare@active{\!}{!}{EXCLAMATION MARK}%
+\tikz@lib@prepare@active{\"}{"}{QUOTATION MARK}%
+\tikz@lib@prepare@active{\:}{:}{COLON}%
+\tikz@lib@prepare@active{\;}{;}{SEMINCOLON}%
+\tikz@lib@prepare@active{\<}{<}{LESS THAN SIGN}%
+\tikz@lib@prepare@active{\=}{=}{EQUALS SIGN}%
+\tikz@lib@prepare@active{\>}{>}{GREATER THAN SIGN}%
+\tikz@lib@prepare@active{\?}{?}{QUESTION MARK}%
+%\tikz@lib@prepare@active{\@}{@}{COMMERCIAL AT}%
+\tikz@lib@prepare@active{\`}{`}{GRAVE ACCENT}%
+{\catcode`\%=11\catcode`\#=11
+\tikz@lib@prepare@active{\%}{%}{PERCENT SIGN}
+\tikz@lib@prepare@active{\#}{#}{NUMBER SIGN}
+}
+
+\pgfutil@g@addto@macro\tikzlibgraphactivations{\catcode`\\=13\relax}%
+{%
+ \catcode`\|=0\relax
+ \catcode`\\=13\relax
+ |pgfutil@g@addto@macro|tikzlibgraphactivations{|def\{@REVERSE SOLIDUS@}}%
+}%
+{%
+ \gdef\tikzlibgraphscommercialat{@COMMERCIAL AT@}%
+ \let\g=\pgfutil@g@addto@macro
+ \catcode`\@=13\relax
+ \g\tikzlibgraphactivations{\catcode`\@=13\relax\let@=\tikzlibgraphscommercialat}%
+}%
+
+\def\tikzlibgraphactivationsbrace{%
+ \catcode`\{=13\relax%
+ \catcode`\}=13\relax%
+ \catcode`\<=1\relax%
+ \catcode`\>=2\relax%
+}%
+{%
+ \catcode`\{=13\relax%
+ \catcode`\}=13\relax%
+ \catcode`\<=1\relax%
+ \catcode`\>=2\relax%
+ \pgfutil@g@addto@macro\tikzlibgraphactivationsbrace<\def{<@LEFT CURLY BRACE@>> %}
+ \pgfutil@g@addto@macro\tikzlibgraphactivationsbrace<\def}<@RIGHT CURLY BRACE@>> %{
+>%
+
+% A normal node
+
+% First, check for special quote syntax:
+
+\def\tikz@lib@graph@node{\tikz@lib@graph@check@quotes\tikz@lib@graph@node@normal}%
+
+\def\tikz@lib@graph@node@normal{%
+ \pgfutil@ifnextchar({\tikz@lib@graph@node@dressed}{\tikz@lib@graph@node@naked}%
+}%
+
+\def\tikz@lib@graph@node@dressed(#1){%
+ % Add extra braces around nodes to protect dashes
+ \tikz@lib@graph@node@naked{(#1)}%
+}%
+
+\def\tikz@lib@graph@node@naked#1-{%
+ % Detect trailing <
+ \tikz@lib@graph@@node#1<\pgf@stop%
+}%
+
+\def\tikz@lib@graph@@node#1<#2\pgf@stop%
+{
+ %
+ % #1 will be a node (not a group)
+ %
+ % Syntax: node name [options]
+ %
+ % Grab node name
+ \tikz@lib@graph@grab@name#1\pgf@stop%
+ \tikz@lib@graph@stored@actions%
+ \pgfutil@ifnextchar\pgf@stop@eodashes{%
+ \tikz@lib@graph@graph@done%
+ }{%
+ %
+ % Now, get arrow kind
+ %
+ \def\pgf@test{#2}%
+ \ifx\pgf@test\pgfutil@empty%
+ \expandafter\tikz@lib@graph@no@back@arrow%
+ \else%
+ \expandafter\tikz@lib@graph@back@arrow%
+ \fi%
+ }%
+}%
+
+\def\tikz@lib@graph@no@back@arrow{%
+ \pgfutil@ifnextchar>\tikz@lib@graph@forward@arrow{%
+ \pgfutil@ifnextchar-\tikz@lib@graph@undirected@arrow{%
+ \pgfutil@ifnextchar!\tikz@lib@graph@no@arrow{%
+ \tikzerror{One of the arrow types <-, --, ->, -!- or <-> expected}%
+ \tikz@lib@graph@undirected@arrow%
+ }%
+ }%
+ }%
+}%
+
+\def\tikz@lib@graph@undirected@arrow-{%
+ \def\tikz@lib@graph@arrow@type{--}%
+ \tikz@lib@graph@after@arrow%
+}%
+
+\def\tikz@lib@graph@forward@arrow>{%
+ \def\tikz@lib@graph@arrow@type{->}%
+ \tikz@lib@graph@after@arrow%
+}%
+
+\def\tikz@lib@graph@bi@arrow>{%
+ \def\tikz@lib@graph@arrow@type{<->}%
+ \tikz@lib@graph@after@arrow%
+}%
+
+\def\tikz@lib@graph@no@arrow!-{%
+ \def\tikz@lib@graph@arrow@type{-!-}%
+ \tikz@lib@graph@after@arrow%
+}%
+
+\def\tikz@lib@graph@back@arrow{%
+ \pgfutil@ifnextchar>{\tikz@lib@graph@bi@arrow}{%
+ \def\tikz@lib@graph@arrow@type{<-}%
+ \tikz@lib@graph@after@arrow%
+ }%
+}%
+
+\def\tikz@lib@graph@after@arrow{%
+ \pgfutil@ifnextchar[{\tikz@lib@graph@after@arrow@opt}{\tikz@lib@graph@after@arrow@opt[]}%]
+}%
+
+\def\tikz@lib@graph@after@arrow@opt[#1]{%
+ %
+ % Ok, first recolor
+ %
+ \tikzgraphinvokeoperator{recolor source by=source''}
+ \tikzgraphinvokeoperator{recolor target by=target'}
+ % Save action for next node
+ \expandafter\def\expandafter\tikz@lib@graph@stored@actions\expandafter{%
+ \expandafter\tikz@lib@graph@joiner\expandafter{\tikz@lib@graph@arrow@type}{#1}}%
+ %
+ \tikzgdeventgroupcallback{descendants}%
+ \tikz@lib@graph@parse@one%
+}%
+
+\def\tikz@lib@graph@joiner#1#2{%
+ \tikzgraphinvokeoperator{recolor source by=source'}
+ \tikzgraphinvokeoperator{recolor source'' by=source}
+ {%
+ \tikz@enable@edge@quotes%
+ \pgfkeyssetvalue{/tikz/graphs/default edge kind}{#1}%
+ \pgfkeys{/tikz/graphs/.cd,@operators=,%
+ /tikz/graphs/.unknown/.code=\tikz@lib@graph@unknown@edge@option{##1},#2}%
+ \pgfkeysgetvalue{/tikz/graphs/@operators}\pgf@temp%
+ \ifx\pgf@temp\pgfutil@empty%
+ \edef\pgf@temp{\noexpand\pgfkeys{/tikz/graphs/.cd,\pgfkeysvalueof{/tikz/graphs/default edge operator}}}%
+ \pgf@temp%
+ \pgfkeysgetvalue{/tikz/graphs/@operators}\pgf@temp%
+ \fi%
+ \pgf@temp%
+ }%
+ \tikzgraphinvokeoperator{not source',not target'}
+}%
+
+\def\tikz@lib@graph@unknown@edge@option#1{%
+ \def\tikz@temp{/tikz/graphs/@edges styling/.append=}
+ \expandafter\expandafter\expandafter\pgfkeys%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@temp\expandafter{\expandafter,\pgfkeyscurrentname={#1}}}
+}%
+
+\def\tikz@lib@graph@graph@done\pgf@stop@eodashes{%
+ % Get local depth and width outside
+ \xdef\tikz@lib@graph@chain@depth{\pgfkeysvalueof{/tikz/graphs/placement/local depth}}
+ \xdef\tikz@lib@graph@chain@width{\pgfkeysvalueof{/tikz/graphs/placement/local width}}
+ % Get node list outside...
+ \expandafter%
+ \endgroup%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@node@list%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}%
+ % Compute new local depth and width of group...
+ \tikz@lib@graph@placement@after@chain@update
+ %
+ \pgfutil@ifnextchar\pgf@stop@eogroup%
+ \tikz@lib@graph@graph@group@done%
+ \tikz@lib@graph@main@parser%
+}%
+
+\def\tikz@lib@graph@graph@group@done\pgf@stop@eogroup{%
+ \pgfkeysvalueof{/tikz/graphs/@operators}%
+}%
+
+
+
+%
+% Handle node
+%
+\def\tikz@lib@graph@grab@name{%
+ \pgfutil@ifnextchar\foreach\tikz@lib@graph@do@foreach\tikz@lib@graph@parse@node@text%
+}%
+
+\def\tikz@lib@graph@do@foreach\foreach#1in{%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@do@foreach@normal{#1}}{\def\tikz@temp{#1}\tikz@lib@graph@do@foreach@macro}%
+}%
+\def\tikz@lib@graph@do@foreach@macro#1{%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@do@foreach@normal\expandafter\tikz@temp\expandafter{#1}%
+}%
+
+\def\tikz@lib@graph@do@foreach@normal#1#2#3\pgf@stop{%
+ % Ok, we do a parse on a foreach loop.
+ \begingroup
+ \let\tikz@lib@graph@node@list@saved\pgfutil@empty%
+ \xdef\tikz@lib@graph@saved@placement{%
+ {\pgfkeysvalueof{/tikz/graphs/placement/local depth}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/local width}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/chain count}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/element count}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/width}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/depth}}%
+ }%
+ \foreach #1 in {#2}%
+ {%
+ \let\tikz@lib@graph@node@list\tikz@lib@graph@node@list@saved%
+ \expandafter\tikz@lib@graph@setup@placement\tikz@lib@graph@saved@placement%
+ \tikz@lib@graph@parse@group{#3}%
+ \xdef\tikz@lib@graph@saved@placement{%
+ {\pgfkeysvalueof{/tikz/graphs/placement/local depth}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/local width}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/chain count}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/element count}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/width}}%
+ {\pgfkeysvalueof{/tikz/graphs/placement/depth}}%
+ }%
+ % TODO: Need to also save hints!
+ \global\let\tikz@lib@graph@node@list@saved\tikz@lib@graph@node@list%
+ }%
+ \expandafter%
+ \endgroup%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@node@list%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list@saved}%
+ \expandafter\tikz@lib@graph@setup@placement\tikz@lib@graph@saved@placement%
+}%
+
+\def\tikz@lib@graph@setup@placement#1#2#3#4#5#6{%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{#1}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local width}{#2}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{#3}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/element count}{#4}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/width}{#5}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/depth}{#6}%
+}%
+
+\def\tikz@lib@graph@parse@node@text#1\pgf@stop{%
+ %
+ % Ok, first test whether #1 contains "//"
+ %
+ \pgfutil@in@{//}{#1 }
+ \ifpgfutil@in@%
+ % Ok, a layout node:
+ \tikz@lib@parse@layout@node#1\pgf@stop%
+ \else%
+ \tikz@lib@graph@fake@nodefalse
+ \let\tikz@lib@graph@node@parsed\tikz@lib@graph@node@opt@normal%
+ \def\tikz@lib@graph@empty@node@parsed{\tikzgdeventcallback{node}{}}%
+ \tikz@lib@parse@normal@node#1[\pgf@stop%
+ \fi%
+}%
+
+\newif\iftikzgraphsautonumbernodes
+\newcount\tikz@lib@auto@number
+
+\def\tikz@lib@do@autonumber{%
+ \ifx\tikz@lib@graph@name@only\pgfutil@empty%
+ \else%
+ \edef\tikz@lib@graph@name@only{\tikz@lib@graph@name@only\tikz@lib@auto@sep\the\tikz@lib@auto@number}%
+ \global\advance\tikz@lib@auto@number by1\relax%
+ \fi%
+}%
+
+%
+% Parse the normal part of a node (name and, possibly, text after slash)
+%
+
+\def\tikz@lib@parse@normal@node#1[{
+ %
+ % Test whether #1 contains "/" or "__"
+ %
+ \pgfutil@in@{/}{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@parse@node@with@slash#1\pgf@stop%
+ \else
+ \pgfutil@in@{__}{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@parse@node@with@doubleunder#1\pgf@stop%
+ \else
+ \edef\pgf@marshal{\noexpand\pgfkeys@spdef\noexpand\tikz@lib@graph@name@only{#1}}%
+ \pgf@marshal%
+ \let\tikz@lib@graph@node@text\tikz@lib@graph@name@only%
+ \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}%
+ \fi%
+ \fi%
+ \tikz@lib@graph@handle@node@cont%
+}%
+
+\def\tikz@lib@parse@node@with@slash#1/{
+ \pgfkeys@spdef\tikz@lib@graph@name@only{#1}%
+ \ifx\tikz@lib@graph@name@only\pgfutil@empty%
+ \global\advance\tikz@fig@count by1\relax
+ \edef\tikz@lib@graph@name@only{tikz@f@\the\tikz@fig@count}%
+ \fi%
+ \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}%
+ \pgfutil@ifnextchar"\tikz@lg@slash@quote{\pgfutil@ifnextchar\tikz@active@quotes@token\tikz@lg@slash@quote@active\tikz@lg@slash@cont}
+}%
+\def\tikz@lg@slash@quote"#1"#2\pgf@stop{%
+ \iftikz@handle@active@nodes%
+ \def\tikz@lib@graph@node@text{\scantokens{#1}}%
+ \else
+ \def\tikz@lib@graph@node@text{#1}%
+ \fi%
+}%
+{\catcode`\"=13\relax
+ \gdef\tikz@lg@slash@quote@active"#1"#2\pgf@stop{%
+ \iftikz@handle@active@nodes%
+ \def\tikz@lib@graph@node@text{\scantokens{#1}}%
+ \else
+ \def\tikz@lib@graph@node@text{#1}%
+ \fi%
+ }%
+}%
+\def\tikz@lg@slash@cont#1\pgf@stop{%
+ \iftikz@handle@active@nodes%
+ \def\tikz@lib@graph@node@text{\scantokens{#1}}%
+ \else
+ \def\tikz@lib@graph@node@text{#1}%
+ \fi%
+}%
+
+\def\tikz@lib@parse@node@with@doubleunder#1__{\tikz@lib@parse@node@with@slash{#1}/}%
+
+\def\tikz@lg@find@fresh@name{%
+ \edef\tikz@lib@graph@name@only{\tikz@lib@graph@name@only'}%
+ \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}%
+ \tikz@lg@if@local@node{\tikz@lib@graph@name}{\tikz@lg@find@fresh@name}{}%
+}%
+
+
+%
+% We have now parsed everything up to the opening "[". We continue
+%
+
+\def\tikz@lib@graph@handle@node@cont{%
+ \iftikzgraphsautonumbernodes%
+ \tikz@lib@do@autonumber%
+ \fi%
+ \iftikz@lib@graph@fresh@node%
+ \tikz@lg@if@local@node{\tikz@lib@graph@name}{\tikz@lg@find@fresh@name}{}%
+ \fi%
+ \let\tikzgraphnodeas\tikzgraphnodeas@default%
+ \pgfutil@ifnextchar\pgf@stop{%
+ \ifx\tikz@lib@graph@name@only\pgfutil@empty%
+ \expandafter\tikz@lib@graph@node@empty@done%
+ \else
+ \expandafter\tikz@lib@graph@node@opt\expandafter[\expandafter]\expandafter[%
+ \fi%
+ }{\tikz@lib@graph@node@opt[}%
+}%
+
+\def\tikzgraphnodeas@default{%
+ \tikz@lib@graph@typesetter%
+}%
+
+\let\tikz@lib@graph@empty@node@parsed\relax%
+
+\def\tikz@lib@graph@node@opt[#1]#2[\pgf@stop{%
+ \tikz@lib@graph@node@parsed{#1}%
+}%
+
+\def\tikz@lib@graph@node@empty@done\pgf@stop{\tikz@lib@graph@empty@node@parsed}%
+
+%
+% Parse a layout node
+%
+
+\def\tikz@lib@parse@layout@node#1//{%
+ \pgf@lib@graph@empty@layout@nodefalse%
+ \let\tikz@lib@graph@node@parsed\tikz@lib@layout@node@parsed%
+ \let\tikz@lib@graph@empty@node@parsed\tikz@lib@graph@empty@layout@node@parsed
+ \tikz@lib@parse@normal@node#1[\pgf@stop%
+}%
+
+\newif\ifpgf@lib@graph@empty@layout@node
+
+\def\tikz@lib@layout@node@parsed{%
+ \tikz@lib@layout@parse@rest%
+}%
+
+\def\tikz@lib@graph@empty@layout@node@parsed{%
+ \pgf@lib@graph@empty@layout@nodetrue
+ \tikz@lib@layout@parse@rest{}%
+}%
+
+\def\tikz@lib@layout@parse@rest#1{%
+ \def\tikz@lib@layout@node@options{#1}%
+ \pgfutil@ifnextchar[{\tikz@lib@layout@node@opt}{\tikz@lib@layout@node@opt[]}%}
+}%
+
+\def\tikz@lib@layout@node@parsed#1{%
+ \def\tikz@lib@layout@node@options{#1}%
+ \pgfutil@ifnextchar[{\tikz@lib@layout@node@opt}{\tikz@lib@layout@node@opt[]}%}
+}%
+
+\def\tikz@lib@layout@node@opt[#1]{%
+ \def\tikz@lib@layout@options{#1}%
+ \pgfutil@ifnextchar\bgroup{\tikz@lib@layout@start}{\tikzerror{Opening brace at beginning of sublayout expected}}%
+}%
+
+
+%
+% Typeset a normal node
+%
+
+\def\tikz@lib@graph@node@opt@normal#1{%
+ \expandafter\tikz@lib@graph@test@use@list\tikz@lib@graph@name@only\pgf@stop
+ \iftikz@lib@graph@use@list%
+ % Ok, make a list of the nodes stored in #1:
+ \let\tikz@lg@temp\pgfutil@empty%
+ \foreach \tikz@lg@node@name in \tikz@lib@graph@use@list {\expandafter\tikz@lib@graph@handle@use\expandafter{\tikz@lg@node@name}}
+ % Ok, now add the nodes to the node list
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@node@list%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\tikz@lib@graph@node@list\tikz@lg@temp}%
+ % Then color and initialize them:
+ \let\tikz@lg@do\tikz@lib@graph@do@use%
+ \tikz@lg@temp%
+ \else%
+ \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}%
+ \expandafter\ifx\csname tikz@lib@graph@def@\tikz@lib@graph@name@only\endcsname\relax%
+ \pgfkeysgetvalue{/tikz/graphs/placement/level}\tikz@temp%
+ \c@pgf@counta=\tikz@temp\relax%
+ \advance\c@pgf@counta by1\relax%
+ \edef\tikz@temp{\the\c@pgf@counta}%
+ \pgfkeyslet{/tikz/graphs/placement/level}\tikz@temp%
+ \tikzgraphsset{
+ level/.try=\pgfkeysvalueof{/tikz/graphs/placement/level},
+ level \pgfkeysvalueof{/tikz/graphs/placement/level}/.try
+ }
+ {%
+ \edef\tikz@lib@graph@node@list{\noexpand\tikz@lg@do{\tikz@lib@graph@name}}%
+ \global\tikz@lib@graph@node@createdfalse%
+ \pgfkeyslet{/tikz/graphs/@operators}\pgfutil@empty%
+ \tikz@lib@activate@source@target@edge@syntax%
+ \tikz@lg@if@local@node{\tikz@lib@graph@name}%
+ {\tikz@lg@local@node@handle{#1}}%
+ {%
+ \tikz@lg@init@color{\tikz@lib@graph@name}{\tikz@lgc@all@true\tikz@lgc@source@true\tikz@lgc@target@true}%
+ \iftikz@lib@graph@all%
+ \tikzgraphsset{#1}\pgfkeysvalueof{/tikz/graphs/@operators}%
+ \else%
+ \pgfkeys{/tikz/graphs/placement/place}%
+ \let\tikzgraphnodetext\tikz@lib@graph@node@text%
+ \let\tikzgraphnodename\tikz@lib@graph@name@only%
+ \let\tikzgraphnodepath\tikz@lib@graph@path%
+ \let\tikzgraphnodefullname\tikz@lib@graph@name%
+ \iftikz@lib@graph@fake@node%
+ {% run options in protected mode...
+ \pgfkeys{
+ /tikz/graphs/.cd,%
+ .unknown/.code=,
+ /tikz/graphs/@nodes styling,%
+ #1}%
+ \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@op@save%
+ \global\let\tikz@lib@graph@op@save\tikz@lib@graph@op@save%
+ }%
+ \else%
+ \node [%
+ name=\tikz@lib@graph@name,%
+ execute at end node={%
+ \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@op@save%
+ \global\let\tikz@lib@graph@op@save\tikz@lib@graph@op@save%
+ },%
+ graphs/redirect unknown to tikz,
+ /tikz/graphs/.cd,%
+ /tikz/graphs/@nodes styling,%
+ #1]%
+ {%
+ \tikzgraphnodeas%
+ };%
+ \fi%
+ \tikz@lib@graph@op@save\global\let\tikz@lib@graph@op@save\relax%%
+ \global\tikz@lib@graph@node@createdtrue%
+ \fi
+ }%
+ }%
+ \iftikz@lib@graph@node@created\tikz@lib@graph@placement@update\fi%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@node@list%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\tikz@lib@graph@node@list\expandafter\tikz@lg@do\expandafter{\tikz@lib@graph@name}}%
+ \iftikz@lib@graph@trie\tikzgraphsset{name=\tikz@lib@graph@name@only}\fi%
+ \else
+ % The name of the node is a graph name
+ \tikz@lib@graph@handle@graph{#1}%
+ \fi
+ \fi%
+}%
+
+\newif\iftikz@lib@graph@fake@node
+
+\newif\iftikz@lib@graph@use@list
+\def\tikz@lib@graph@test@use@list{%
+ \pgfutil@ifnextchar({\tikz@lib@graph@use@list@grap}{\tikz@lib@graph@test@use@list@done}%)
+}%
+
+\def\tikz@lib@graph@test@use@list@done#1\pgf@stop{\tikz@lib@graph@use@listfalse}%
+\def\tikz@lib@graph@use@list@grap(#1)\pgf@stop{\def\tikz@lib@graph@use@list{#1}\tikz@lib@graph@use@listtrue}%
+
+
+%
+% Typeset a layout node
+%
+
+\def\tikz@lib@layout@start#1#2\pgf@stop{%
+ \tikz@lib@ensure@gd@loaded%
+ % Parameters are:
+ %
+ % Node name is \tikz@lib@graph@name@only
+ % Node text is \tikz@lib@graph@node@text
+ % Node options are \tikz@lib@layout@node@options
+ % Layout options are \tikz@lib@layout@options
+ % Layout is #1
+ % Rest is #2 (should be empty or just whitespace)
+ \tikz@lib@graph@fake@nodefalse%
+ \ifpgf@lib@graph@empty@layout@node%
+ \else%
+ \ifx\tikz@lib@graph@name\pgfutil@empty%
+ \tikzerror{Internal error: Node has no name, but it should!}%
+ \else
+ \tikz@lib@graph@fake@nodetrue%
+ \expandafter\tikz@lib@graph@node@opt@normal\expandafter{\tikz@lib@layout@node@options}%
+ \fi%
+ \fi%
+ \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}%
+ %
+ % Prepare tikz node options
+ %
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@layout@node@options\expandafter\expandafter\expandafter{\expandafter\tikz@lib@layout@startup@node@options\tikz@lib@layout@node@options,}%
+ \begingroup
+ % Create a subgraph node, if name is given.
+ \iftikz@lib@graph@fake@node%
+ \expandafter\expandafter\expandafter%
+ \expandafter\expandafter\expandafter\expandafter\tikz@lib@make@subgraph@node%
+ \expandafter\expandafter\expandafter%
+ \expandafter\expandafter\expandafter\expandafter{%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@name%
+ \expandafter\expandafter\expandafter}%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\tikz@lib@graph@node@text\expandafter}\expandafter{\tikz@lib@layout@node@options}
+ \fi%
+ %
+ % Here comes the scope:
+ %
+ \expandafter\expandafter\expandafter\scope\expandafter\expandafter\expandafter[\expandafter\tikz@lib@layout@node@options@prefix\tikz@lib@layout@options]
+ \tikzgdeventgroupcallback{array}%
+ \let\tikz@lib@graph@node@list\pgfutil@empty%
+ \tikz@lib@graph@start@hint@group%
+ \tikz@lib@graph@parse@group{#1}%
+ \tikz@lib@graph@end@hint@group%
+ \def\tikz@lg@old@col{\tikz@lgc@source@true}%
+ \let\tikz@lg@new@col\pgfutil@empty%
+ \let\tikz@lg@do\tikz@lg@change@color%
+ \tikz@lib@graph@node@list%
+ \def\tikz@lg@old@col{\tikz@lgc@target@true}%
+ \tikz@lib@graph@node@list%
+ \expandafter%
+ \endscope\expandafter%
+ \endgroup%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@node@list%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}%
+ \tikz@lib@graph@hint@aftergroup%
+}%
+\def\tikz@lib@make@subgraph@node#1#2#3{%
+ \pgfgdsubgraphnode{#1}{#3}{\pgfgdsubgraphnodecontents{#2}}%
+}%
+\def\tikz@lib@layout@startup@node@options{%
+ /utils/exec=\tikzlibignorecomparisonsINTERNAL,
+ /tikz/graphs/.cd,%
+ redirect unknown to tikz,%
+ anchor=base,%
+ /tikz/every subgraph node/.try,%
+}%
+\def\tikzlibignorecomparisonsINTERNAL{%
+ \pgfkeys{/handlers/first char syntax=true}
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string>}{\pgfutil@gobble}%
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string<}{\pgfutil@gobble}%
+}%
+\def\tikz@lib@layout@node@options@prefix{graphs/.cd,}%
+
+\ifx\tikz@lib@ensure@gd@loaded\pgfutil@undefined%
+\def\tikz@lib@ensure@gd@loaded{\tikzerror{You must say \string\usetikzlibrary{graphdrawing} to use the (sub)layout syntax}}%
+\fi
+
+\def\tikz@lg@local@node@handle#1{%
+ %
+ % Handle late options and operators
+ \tikzgraphsset{source,target,.unknown/.code=,#1}%
+ \tikzgdlatenodeoptionacallback{\tikz@pp@name\tikz@lib@graph@name}%
+ \node also[graphs/redirect unknown to tikz,/tikz/graphs/.cd,#1](\tikz@lib@graph@name);%
+ \pgfkeysvalueof{/tikz/graphs/@operators}%
+}%
+
+\tikzgraphsset{redirect unknown to tikz/.style={
+ /tikz/graphs/.unknown/.code={%
+ \let\tikz@key\pgfkeyscurrentname%
+ \pgfkeys{tikz/.cd,\tikz@key={##1},/tikz/graphs/.cd}%
+ }}
+}%
+
+\def\tikz@lib@activate@source@target@edge@syntax{%
+ \pgfkeys{/handlers/first char syntax=true}
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string>}{\tikz@lg@parse@more}%
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string<}{\tikz@lg@parse@less}%
+}%
+
+\def\tikz@lg@parse@less#1{\tikz@lg@parse@less@#1\pgf@stop}%
+\def\tikz@lg@parse@less@<{\pgfutil@ifnextchar"{\tikz@lg@parse@quote{source}}{\tikz@lg@parse@noquote{source}}}%
+\def\tikz@lg@parse@more#1{\tikz@lg@parse@more@#1\pgf@stop}%
+\def\tikz@lg@parse@more@>{\pgfutil@ifnextchar"{\tikz@lg@parse@quote{target}}{\tikz@lg@parse@noquote{target}}}%
+
+\def\tikz@lg@parse@noquote#1#2\pgf@stop{{\tikzgraphsset{#1 edge style={#2}}}}%
+\def\tikz@lg@parse@quote#1#2\pgf@stop{%
+ {\tikzgraphsset{/tikz/node quotes mean={#1 edge node={node [every edge quotes,##2]{##1}}},/utils/exec=\tikz@enable@node@quotes,#2}}%
+}%
+
+\tikzgraphsset{
+ clear >/.style=target edge clear,
+ clear </.style=source edge clear
+}%
+
+
+% Positioning
+
+\def\tikz@lib@graph@x{0}%
+\def\tikz@lib@graph@y{0}%
+
+\tikzgraphsset{
+ x/.code=\def\tikz@lib@graph@x{#1}\tikz@lib@graphs@check@at,
+ y/.code=\def\tikz@lib@graph@y{#1}\tikz@lib@graphs@check@at
+}%
+\def\tikz@lib@graphs@check@at{%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@temp%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\expandafter\expandafter(%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@x\expandafter}%
+ \expandafter,\expandafter{\tikz@lib@graph@y})}%
+ \pgfqkeys{/tikz}{at/.expand once=\tikz@temp}%
+}%
+
+
+\newif\iftikz@lib@graph@trie
+\tikzgraphsset{
+ trie/.is if=tikz@lib@graph@trie,
+ put node text on incoming
+ edges/.style={nodes={/utils/exec=\tikz@lg@make@edge@node{target}{#1}}},
+ put node text on outgoing
+ edges/.style={nodes={/utils/exec=\tikz@lg@make@edge@node{source}{#1}}},
+ edge quotes/.style={/tikz/every edge quotes/.style={#1}},
+ edge quotes center/.style={edge quotes={anchor=center}},
+ edge quotes mid/.style={edge quotes={anchor=mid}}
+}%
+
+\def\tikz@lg@make@edge@node#1#2{%
+ \def\pgf@marshal{node[#2]}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgf@marshal\expandafter{\tikzgraphnodetext}}%
+ \pgfkeysalso{#1 edge node/.expand once=\pgf@marshal,as=}%
+}%
+
+\newif\iftikz@lib@graph@fresh@node
+\tikzgraphsset{fresh nodes/.is if=tikz@lib@graph@fresh@node}%
+
+\tikzgraphsset{number nodes/.code=%
+ \pgfmathsetcount\tikz@lib@auto@number{#1}%
+ \tikzgraphsautonumbernodestrue,%
+ number nodes/.default=1,%
+ number nodes sep/.code=\def\tikz@lib@auto@sep{#1}
+}%
+\def\tikz@lib@auto@sep{\space}%
+
+\newif\iftikz@lib@graph@node@created
+
+\def\tikz@lib@graph@handle@use#1{%
+ % Is #1 the name of a node set?
+ \expandafter\let\expandafter\pgf@temp\csname tikz@lg@node@set #1\endcsname
+ \ifx\pgf@temp\relax
+ \pgfutil@g@addto@macro\tikz@lg@temp{\tikz@lg@do{#1}}
+ \else%
+ \expandafter\pgfutil@g@addto@macro\expandafter\tikz@lg@temp\expandafter{\pgf@temp}
+ \fi
+}%
+
+\def\tikz@lib@graph@do@use#1{%
+ \tikz@lg@init@color{#1}{\tikz@lgc@all@true\tikz@lgc@source@true\tikz@lgc@target@true}%
+}%
+
+\tikzgraphsset{
+ typeset/.store in=\tikz@lib@graph@typesetter,
+ math nodes/.style={/tikz/graphs/typeset=$\tikzgraphnodetext$},
+ empty nodes/.style={/tikz/graphs/typeset=},
+ typeset=\tikzgraphnodetext
+}%
+
+
+%
+% Handle scope
+%
+\def\tikz@lib@graph@scope#1{
+ \begingroup%
+ \tikzgdeventgroupcallback{array}%
+ \let\tikz@lib@graph@node@list\pgfutil@empty%
+ \tikz@lib@graph@start@hint@group%
+ \tikz@lib@graph@parse@group{#1}%
+ \tikz@lib@graph@end@hint@group%
+ \expandafter%
+ \endgroup%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@node@list%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}%
+ \tikz@lib@graph@hint@aftergroup%
+ \tikz@lib@graph@stored@actions%
+ \pgfutil@ifnextchar-{\tikz@lib@graph@scope@minus}{%
+ \pgfutil@ifnextchar<{\tikz@lib@graph@scope@less}{%
+ \tikzerror{One of the arrow types <-, --, ->, -!-, or <-> expected}%
+ }%
+ }%
+}%
+
+\def\tikz@lib@graph@scope@minus-{
+ \pgfutil@ifnextchar>\tikz@lib@graph@forward@arrow{%
+ \pgfutil@ifnextchar-\tikz@lib@graph@undirected@arrow{%
+ \pgfutil@ifnextchar!\tikz@lib@graph@no@arrow{%
+ \pgfutil@ifnextchar\pgf@stop@eodashes\tikz@lib@graph@graph@done{%
+ \tikzerror{One of the arrow types <-, --, ->, -!-, or <-> expected}%
+ \tikz@lib@graph@undirected@arrow%
+ }%
+ }%
+ }%
+ }%
+}%
+
+\def\tikz@lib@graph@scope@less<-{\tikz@lib@graph@back@arrow}%
+
+
+
+
+%
+% Predefining graphs
+%
+
+\tikzgraphsset{
+ declare/.code 2 args={\expandafter\def\csname tikz@lib@graph@def@#1\endcsname{\tikz@lib@graph@do@graph{#2}}}%
+}%
+
+\def\tikz@lib@graph@handle@graph#1{%
+ \begingroup%
+ \let\tikz@lib@graph@node@list\pgfutil@empty%
+ \tikzgraphsset{@extra group options/.style={#1}}%
+ \tikz@lib@graph@start@hint@group%
+ \csname tikz@lib@graph@def@\tikz@lib@graph@name@only\endcsname%
+ \tikz@lib@graph@end@hint@group%
+ \expandafter%
+ \endgroup%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@node@list%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}%
+ \tikz@lib@graph@hint@aftergroup%
+}%
+
+\def\tikz@lib@graph@do@graph#1{%
+ \tikz@lib@graph@parse@group{#1}%
+}%
+
+\let\tikz@lib@graph@path\pgfutil@empty
+
+\tikzgraphsset{
+ name separator/.store in=\tikz@lib@graph@name@separator,
+ name separator=\space,
+ name/.code={%
+ \edef\tikz@lib@graph@path{\tikz@lib@graph@path#1\tikz@lib@graph@name@separator}%
+ }%
+}%
+
+
+%
+% Colors
+%
+\def\tikz@lg@newif{\csname newif\endcsname}%
+\tikzgraphsset{
+ as/.code=\def\tikzgraphnodeas{#1},%
+ color class/.style={%
+ /utils/exec=\expandafter\tikz@lg@newif\csname iftikz@lgc@#1@\endcsname,
+ #1/.style={operator={%
+ \edef\tikz@lg@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}%
+ \let\tikz@lg@do\tikz@lg@colorize%
+ \tikz@lib@graph@node@list%
+ }},
+ not #1/.style={operator={%
+ \edef\tikz@lg@old@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}%
+ \let\tikz@lg@new@col\pgfutil@empty%
+ \let\tikz@lg@do\tikz@lg@change@color%
+ \tikz@lib@graph@node@list%
+ }},
+ recolor #1 by/.style={operator={%
+ \edef\tikz@lg@old@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}%
+ \edef\tikz@lg@new@col{\expandafter\noexpand\csname tikz@lgc@##1@true\endcsname}%
+ \let\tikz@lg@do\tikz@lg@change@color%
+ \tikz@lib@graph@node@list%
+ }},
+ !#1/.style=not #1,
+ },
+ color class=source,
+ color class=source',
+ color class=source'',
+ color class=target,
+ color class=target',
+ color class=all
+}%
+
+\def\tikz@lg@init@color#1#2{%
+ \expandafter\gdef\csname tikz@lgc@#1\endcsname{#2}%
+}%
+
+\def\tikz@lib@graph@cleanup#1{%
+ \expandafter\global\expandafter\let\csname tikz@lgc@#1\endcsname\relax%
+ \ifcsname tikz@lgca@@#1\endcsname\expandafter\global\expandafter\let\csname tikz@lgca@@#1\endcsname\relax\fi%
+ \ifcsname tikz@lgcb@@#1\endcsname\expandafter\global\expandafter\let\csname tikz@lgcb@@#1\endcsname\relax\fi%
+}%
+
+\def\tikz@lg@colorize#1{%
+ \expandafter\let\expandafter\pgf@temp\csname tikz@lgc@#1\endcsname%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@temp%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\tikz@lg@col\pgf@temp}%
+ \expandafter\global\expandafter\let\csname tikz@lgc@#1\endcsname\pgf@temp%
+}%
+
+\def\tikz@lg@change@color#1{%
+ \def\tikz@lg@temp@save{#1}%
+ \let\tikz@lg@collect\pgfutil@empty%
+ \expandafter\let\expandafter\pgf@temp\csname tikz@lgc@#1\endcsname%
+ \expandafter\tikz@lg@change@check\pgf@temp\pgf@stop%
+}%
+\def\tikz@lg@change@check#1{%
+ \ifx#1\pgf@stop%
+ \tikz@lg@change@write@back%
+ \else%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\tikz@lg@old@col%
+ \expandafter\tikz@lg@change@add\expandafter{\tikz@lg@new@col}% Found!
+ \else%
+ \tikz@lg@change@add{#1}%
+ \fi%
+ \expandafter\tikz@lg@change@check
+ \fi%
+}%
+\def\tikz@lg@change@add#1{%
+ \expandafter\def\expandafter\tikz@lg@collect\expandafter{\tikz@lg@collect#1}%
+}%
+
+\def\tikz@lg@change@write@back{%
+ \expandafter\global\expandafter\let\csname tikz@lgc@\tikz@lg@temp@save\endcsname\tikz@lg@collect%
+}%
+
+
+
+\def\tikz@lg@if@has@color#1#2#3#4{%
+ {%
+ \csname tikz@lgc@#1\endcsname%
+ \expandafter\let\expandafter\pgf@temp\csname iftikz@lgc@#2@\endcsname%
+ \ifx\pgf@temp\relax%
+ \tikz@lib@reset@temp%
+ \fi%
+ \pgf@temp%
+ \global\tikz@color@testtrue%
+ \else%
+ \global\tikz@color@testfalse%
+ \fi%
+ }%
+ \iftikz@color@test#3\else#4\fi%
+}%
+\newif\iftikz@color@test
+
+\def\tikz@lg@if@local@node#1#2#3{\expandafter\ifx\csname tikz@lgc@#1\endcsname\relax#3\else#2\fi}%
+
+\def\tikz@lib@reset@temp{\let\pgf@temp\iffalse}%
+
+%
+% Handle connection annotations
+%
+\def\tikz@lib@annotate@#1#2#3#4{%
+ \expandafter\ifx\csname tikz@lgc#1@@#2\endcsname\relax%
+ \expandafter\gdef\csname tikz@lgc#1@@#2\endcsname{{#3}{#4}}%
+ \else%
+ \expandafter\expandafter\expandafter\tikz@lib@annotate@read\csname tikz@lgc#1@@#2\endcsname{#3}{#4}%
+ \expandafter\global\expandafter\let\csname tikz@lgc#1@@#2\endcsname\pgf@temp%
+ \fi%
+}%
+\def\tikz@lib@annotate@read#1#2#3#4{\def\pgf@temp{{#1,#3}{#2#4}}}%
+
+\tikzgraphsset{
+ source edge style/.code=\tikz@lib@annotate@{a}{\tikz@lib@graph@name}{#1}{},
+ source edge node/.code=\tikz@lib@annotate@{a}{\tikz@lib@graph@name}{}{#1},
+ source edge clear/.code={
+ \expandafter\global\expandafter\let\csname tikz@lgca@@\tikz@lib@graph@name\endcsname\relax%
+ },
+ target edge style/.code=\tikz@lib@annotate@{b}{\tikz@lib@graph@name}{#1}{},
+ target edge node/.code=\tikz@lib@annotate@{b}{\tikz@lib@graph@name}{}{#1},
+ target edge clear/.code={%
+ \expandafter\global\expandafter\let\csname tikz@lgcb@@\tikz@lib@graph@name\endcsname\relax%
+ }
+}%
+
+
+
+% Packing a node list: Replace the node list by a new node list where
+% each node is mentioned at most once.
+
+\def\tikz@lib@graph@pack@node@list{%
+ {%
+ \let\tikz@lg@packed\pgfutil@empty%
+ \let\tikz@lg@do\tikz@lg@packer%
+ \tikz@lib@graph@node@list%
+ \expandafter
+ }\expandafter%
+ \def\expandafter\tikz@lib@graph@node@list\expandafter{\tikz@lg@packed}%
+}%
+
+\def\tikz@lg@packer#1{%
+ \expandafter\ifx\csname tikz@lg@p@#1\endcsname\pgf@stop%
+ \else%
+ \expandafter\let\csname tikz@lg@p@#1\endcsname\pgf@stop%
+ \expandafter\def\expandafter\tikz@lg@packed\expandafter{\tikz@lg@packed\tikz@lg@do{#1}}
+ \fi
+}%
+
+%
+% Color functions
+%
+
+% Do something for all nodes having a certain color
+%
+% #1 = the color name
+% #2 = a macro
+%
+% Description:
+%
+% For each node having color #1, the macro #2 will be called. This
+% macro should take a single parameter, which will be set
+% to the node's name.
+
+\def\tikzgraphforeachcolorednode#1#2{%
+ \tikz@lib@graph@pack@node@list%
+ \expandafter\def\expandafter\iftikz@lib@graph@color@picker\expandafter{\csname iftikz@lgc@#1@\endcsname}%
+ \let\tikz@lib@graph@action#2%
+ \let\tikz@lg@do\tikz@lg@pick%
+ \tikz@lib@graph@node@list%
+}%
+\def\tikz@lg@pick#1{
+ {%
+ \csname tikz@lgc@#1\endcsname%
+ \iftikz@lib@graph@color@picker
+ \global\tikz@color@testtrue%
+ \else%
+ \global\tikz@color@testfalse%
+ \fi%
+ }%
+ \iftikz@color@test\tikz@lib@graph@action{#1}\fi%
+}%
+
+
+
+% Prepare a color
+%
+% #1 is the color name
+% #2 is a counter
+% #3 is a prefix
+%
+% Description:
+%
+% You can call this function inside a connector. It will do the
+% following: First, its counts how many nodes exist that have color
+% #1. This number is stored in the counter passed as #2. Furthermore,
+% let <name> be the name of the <i>-th vertex that has color #1. Then, a
+% macro called \#3<i> will store <name>. For instance, if #1 is "red"
+% and the third red node is called foo and if #3 is "bar", then a
+% macro called "\bar3" is set to "foo" as if you had said
+% "\expandafter\def\csname bar3\endcsname{foo}".
+%
+% The bottom line of all this is that after a preparation you can
+% easily iterate over nodes having a certain color. If you wish to
+% iterate over a single color, it will be quicker and easier to call
+% \tikzgraphforeachcolorednode, but if you need to iterate over two
+% colors simultaneously, it will be better to first prepare the color.
+
+\def\tikzgraphpreparecolor#1#2#3{%
+ \let\tikz@lib@graph@count#2%
+ \tikz@lib@graph@count0\relax
+ \def\tikz@lib@graph@prefix{#3}%
+ \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@prepare%
+}%
+
+\def\tikz@lib@graph@prepare#1{%
+ \advance\tikz@lib@graph@count by1\relax%
+ \expandafter\def\csname\tikz@lib@graph@prefix\the\tikz@lib@graph@count\endcsname{#1}%
+}%
+
+
+
+
+%
+% The bipartite connector
+%
+
+\tikzgraphsset{
+ complete bipartite/.style 2 args={operator={
+ \def\tikz@lg@shoreb{#2}%
+ \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@bipartite@outer
+ }},
+ complete bipartite/.default={target'}{source'},
+ induced complete bipartite/.style 2 args={
+ induced independent set={#1},
+ induced independent set={#2},
+ complete bipartite={#1}{#2}
+ },
+ induced complete bipartite/.default={target'}{source'},
+}%
+
+\def\tikz@lib@graph@bipartite@outer#1{%
+ \def\tikz@lib@graph@from{#1}%
+ {%
+ \tikzgraphforeachcolorednode{\tikz@lg@shoreb}\tikz@lib@graph@bipartite@inner%
+ }%
+}%
+
+\def\tikz@lib@graph@bipartite@inner#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\tikz@lib@graph@from\else%
+ \tikz@lib@graph@default@new@edge{\tikz@lib@graph@from}{#1}%
+ \fi%
+}%
+
+\def\tikz@lib@graph@default@new@edge#1#2{%
+ \pgfkeysgetvalue{/tikz/graphs/@edges styling}\pgf@temp
+ \pgfkeysgetvalue{/tikz/graphs/@edges node}\pgf@temp@b
+ \let\tikz@lib@add@temp\pgfutil@empty%
+ \tikz@lib@graph@add@edge@annotations{a}{#1}
+ \tikz@lib@graph@add@edge@annotations{b}{#2}
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@temp%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@temp\tikz@lib@add@temp}%
+ \expandafter\expandafter\expandafter\tikz@lib@graph@default@new@edge@%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{\pgf@temp@b}{#1}{#2}%
+}%
+\def\tikz@lib@graph@default@new@edge@#1#2#3#4{%
+ \iftikz@lib@graph@simple%
+ \edef\tikz@temp{{\pgfkeysvalueof{/tikz/graphs/default edge kind}}{#3}{#4}}
+ \expandafter\tikz@lib@graph@set@simple@edge\tikz@temp{#1}{#2}%
+ \else%
+ \pgfkeys{/tikz/graphs/.cd,new \pgfkeysvalueof{/tikz/graphs/default edge kind}={#3}{#4}{#1}{#2}}%
+ \fi%
+}%
+\def\tikz@lib@graph@add@edge@annotations#1#2{%
+ \ifcsname tikz@lgc#1@@#2\endcsname%
+ \expandafter\let\expandafter\tikz@lg@temp@\csname tikz@lgc#1@@#2\endcsname%
+ \ifx\tikz@lg@temp@\relax\else
+ \expandafter\tikz@lib@graph@add@edge@annotations@\tikz@lg@temp@%
+ \let\tikz@lib@add@temp\tikz@lib@final@edge@style
+ \fi%
+ \fi%
+}%
+\def\tikz@lib@graph@add@edge@annotations@#1#2{
+ \expandafter\def\expandafter\pgf@temp\expandafter{\pgf@temp,#1}%
+ \expandafter\def\expandafter\pgf@temp@b\expandafter{\pgf@temp@b#2}%
+}%
+\def\tikz@lib@final@edge@style{,after source and target edge/.try}%
+
+%
+% The clique connector
+%
+
+\tikzgraphsset{
+ clique/.style={operator={
+ \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}%
+ \tikz@lg@clique@loop%
+ }},
+ clique/.default=all
+}%
+
+\def\tikz@lg@clique@loop{%
+ \ifnum\c@pgf@counta=0\relax%
+ \else
+ \c@pgf@countb=\c@pgf@counta\relax%
+ \tikz@lg@clique@loop@inner%
+ \advance\c@pgf@counta by-1\relax%
+ \expandafter\tikz@lg@clique@loop%
+ \fi%
+}%
+
+\def\tikz@lg@clique@loop@inner{%
+ \advance\c@pgf@countb by-1\relax%
+ \ifnum\c@pgf@countb>0\relax%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\csname tikz@lg\the\c@pgf@counta\endcsname}%
+ \expandafter\tikz@lg@clique@loop@inner%
+ \fi%
+}%
+
+
+%
+% The independent set connector
+%
+
+\tikzgraphsset{
+ induced independent set/.style={operator={
+ \pgfkeysgetvalue{/tikz/graphs/default edge kind}\tikz@lg@default%
+ \pgfkeyssetvalue{/tikz/graphs/default edge kind}{-!-}%
+ \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}%
+ \tikz@lg@indep@loop%
+ \pgfkeyslet{/tikz/graphs/default edge kind}\tikz@lg@default%
+ }},
+ induced independent set/.default=all
+}%
+
+\def\tikz@lg@indep@loop{%
+ \ifnum\c@pgf@counta=0\relax%
+ \else
+ \c@pgf@countb=\c@pgf@counta\relax%
+ \tikz@lg@indep@loop@inner%
+ \advance\c@pgf@counta by-1\relax%
+ \expandafter\tikz@lg@indep@loop%
+ \fi%
+}%
+
+\def\tikz@lg@indep@loop@inner{%
+ \advance\c@pgf@countb by-1\relax%
+ \ifnum\c@pgf@countb>0\relax%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@counta\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}%
+ \expandafter\tikz@lg@indep@loop@inner%
+ \fi%
+}%
+
+
+%
+% The path connector
+%
+
+\tikzgraphsset{
+ path/.style={operator={%
+ \let\tikz@lg@prev\relax%
+ \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@path@do%
+ }},
+ path/.default=all,
+ induced path/.style={induced independent set={#1},path={#1}},
+ induced path/.default=all,
+}%
+
+\def\tikz@lib@graph@path@do#1{%
+ \ifx\tikz@lg@prev\relax%
+ \else%
+ \tikz@lib@graph@default@new@edge{\tikz@lg@prev}{#1}%
+ \fi
+ \def\tikz@lg@prev{#1}%
+}%
+
+
+%
+% The cycle connector
+%
+
+\tikzgraphsset{
+ cycle/.style={operator={%
+ \let\tikz@lg@prev\relax%
+ \let\tikz@lg@first\relax%
+ \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@cycle@do%
+ \ifx\tikz@lg@first\relax%
+ \else%
+ \tikz@lib@graph@default@new@edge{\tikz@lg@prev}{\tikz@lg@first}%
+ \fi%
+ }},
+ cycle/.default=all,
+ induced cycle/.style={induced independent set={#1},cycle={#1}},
+ induced cycle/.default=all,
+}%
+
+\def\tikz@lib@graph@cycle@do#1{%
+ \ifx\tikz@lg@prev\relax%
+ \def\tikz@lg@prev{#1}%
+ \let\tikz@lg@first\tikz@lg@prev%
+ \else%
+ \tikz@lib@graph@default@new@edge{\tikz@lg@prev}{#1}%
+ \def\tikz@lg@prev{#1}%
+ \fi%
+}%
+
+
+
+
+%
+% The matching and star connector
+%
+
+\tikzgraphsset{
+ matching and star/.style 2 args={operator=%
+ {%
+ \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}
+ \c@pgf@countb=0\relax%
+ \let\tikz@lg@prev\relax
+ \tikzgraphforeachcolorednode{#2}\tikz@lib@graph@flow@do%
+ \tikz@lib@graph@flow@rest%
+ }%
+ },
+ matching and star/.default={target'}{source'}
+}%
+
+\def\tikz@lib@graph@flow@do#1{%
+ \advance\c@pgf@countb by1\relax%
+ \ifnum\c@pgf@countb>\c@pgf@counta\relax%
+ \c@pgf@countb=\c@pgf@counta\relax%
+ \fi%
+ \ifnum\c@pgf@countb>0\relax%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}%
+ \fi%
+ \def\tikz@lg@prev{#1}%
+}%
+
+\def\tikz@lib@graph@flow@rest{%
+ \ifnum\c@pgf@countb<\c@pgf@counta\relax%
+ \ifnum\c@pgf@countb>0\relax%
+ \advance\c@pgf@countb by1\relax%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\tikz@lg@prev}%
+ \expandafter\tikz@lib@graph@flow@rest%
+ \fi%
+ \fi%
+}%
+
+
+
+%
+% The matching connector
+%
+
+\tikzgraphsset{
+ matching/.style 2 args={operator=
+ {%
+ \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}
+ \c@pgf@countb=0\relax%
+ \tikzgraphforeachcolorednode{#2}\tikz@lib@graph@matching@do%
+ }%
+ },
+ matching/.default={target'}{source'}
+}%
+
+\def\tikz@lib@graph@matching@do#1{%
+ \advance\c@pgf@countb by1\relax%
+ \ifnum\c@pgf@countb>\c@pgf@counta\relax%
+ \else%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}%
+ \fi%
+}%
+
+
+
+
+
+%
+% The butterfly connector
+%
+
+\tikzgraphsset{
+ butterfly/.style={operator=
+ {}{%
+ \pgfkeys{/tikz/graphs/butterfly/.cd,#1}%
+ \ifnum\pgfkeysvalueof{/tikz/graphs/butterfly/level}=0\relax%
+ \tikzgraphinvokeoperator{matching and star={\pgfkeysvalueof{/tikz/graphs/butterfly/from}}{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}}%
+ \else%
+ {%
+ \tikzgraphpreparecolor{\pgfkeysvalueof{/tikz/graphs/butterfly/from}}\c@pgf@counta{tikz@lg}
+ \c@pgf@countb=0\relax%
+ \tikzgraphforeachcolorednode{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}\tikz@lib@graph@butterfly@do%
+ }%
+ \iftikz@butterfly@prime\else\tikzgraphinvokeoperator{matching and star={\pgfkeysvalueof{/tikz/graphs/butterfly/from}}{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}}\fi%
+ \fi%
+ }%
+ },
+ butterfly/.default=,
+ butterfly/level/.initial=1,
+ butterfly/from/.initial=target',
+ butterfly/to/.initial=source',
+ butterfly'/.style={operator={}{\tikz@butterfly@primetrue\pgfkeysalso{butterfly={#1}}}},
+ butterfly'/.default=,
+}%
+
+\newif\iftikz@butterfly@prime
+
+\def\tikz@lib@graph@butterfly@do#1{%
+ \advance\c@pgf@countb by1\relax%
+ % Compute other side...
+ \c@pgf@countc=\pgfkeysvalueof{/tikz/graphs/butterfly/level}\relax%
+ {%
+ % Computer countb mod (2level)
+ \count0=\c@pgf@countc\relax%
+ \multiply\count0 by2\relax%
+ \count1=\c@pgf@countb\relax%
+ \advance\count1 by-1\relax%
+ \count2=\count1\relax%
+ \count3=\count1\relax%
+ \divide\count1 by\count0\relax%
+ \multiply\count1 by\count0\relax%
+ \advance\count2 by-\count1\relax%
+ % count0 = 2*level
+ % count2 = countb mod (2level) (starting with 0)
+ % count1 = countb - count2 (starting with 0)
+ \ifnum\count2<\c@pgf@countc\relax%
+ \advance\count3 by \c@pgf@countc\relax%
+ \else%
+ \advance\count3 by -\c@pgf@countc\relax%
+ \fi%
+ \expandafter%
+ }%
+ \expandafter\c@pgf@countc\the\count3\relax%
+ \advance\c@pgf@countc by1\relax%
+ \ifnum\c@pgf@countc>\c@pgf@counta\relax%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \fi%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countc\endcsname}{#1}%
+}%
+
+
+
+
+%
+% The no edges connector
+%
+\tikzgraphsset{no edges/.style={operator=\relax}}%
+
+
+
+
+%
+% The grid connector
+%
+\tikzgraphsset{
+ grid/.style={operator={
+ \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}%
+ \c@pgf@countb=0\relax%
+ \tikzgraphpreparewrapafter%
+ \tikz@lg@grid@loop%
+ }%
+ },
+ grid/.default=all
+}%
+
+\def\tikzgraphpreparewrapafter{%
+ \pgfkeysgetvalue{/tikz/graphs/wrap after}\tikz@temp%
+ \ifnum\tikz@temp=0\relax%
+ \pgfmathparse{sqrt(\tikzgraphVnum)}%
+ \pgfmathint{\pgfmathresult}%
+ \edef\tikzgraphwrapafter{\pgfmathresult}%
+ \else%
+ \edef\tikzgraphwrapafter{\tikz@temp}
+ \fi%
+}%
+
+\def\tikz@lg@grid@loop{%
+ \ifnum\c@pgf@counta=0\relax%
+ \else%
+ \advance\c@pgf@countb by 1\relax%
+ \pgfmathmod{\c@pgf@countb-1}{\tikzgraphwrapafter}%
+ \pgfmathint{\pgfmathresult}%
+ \ifnum\pgfmathresult>0%
+ \pgfmathsubtract{\c@pgf@countb}{1}%
+ \pgfmathint{\pgfmathresult}%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\csname tikz@lg\pgfmathresult\endcsname}%
+ \fi%
+ \pgfmathparse{\c@pgf@countb <= \tikzgraphwrapafter}%
+ \ifnum\pgfmathresult=0%
+ \pgfmathsubtract{\c@pgf@countb}{\tikzgraphwrapafter}%
+ \pgfmathint{\pgfmathresult}%
+ \tikz@lib@graph@default@new@edge{\csname tikz@lg\pgfmathresult\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}%
+ \fi%
+ \advance\c@pgf@counta by-1\relax%
+ \expandafter\tikz@lg@grid@loop%
+ \fi%
+}%
+
+
+
+
+% Positioning
+%
+% It is not the job of the graph library to compute good positions for
+% nodes in a graph. However, some basic support is provided for simple
+% cases.
+%
+% The idea is at follows: Graphs are specified hierarchically. For
+% instance, consider the following graph specification:
+%
+% graph { a, b, c -> d -> {e -> f -> g, h} -> i, j -> k }
+%
+% Here, we have the *group* {e->f->g,h} inside the larger graph
+% specification. Each group consists of sequence of *chains* like
+% e->f->g or j->k.
+%
+% In order to facilitate the automatic positioning of nodes, the graph
+% library will provide you with information about the position of
+% nodes inside their groups and chains.
+%
+% As a chain is being parsed, a counter stored in
+% /tikz/graphs/placement/element count is available that is advanced for
+% each element in the chain.
+%
+% Additionally, a counter stored in placement/width is
+% available. This "logical" width is defined recursively as follows: The
+% width of a single node is computed by calling the key
+% placement/logical node width, which should return a real or logical
+% width of the node passed as a parameter in the macro \pgfmathresult. The
+% width of a chain is the sum of the widths of its elements. The
+% width of a group is the maximum of the widths of its elements.
+%
+%
+% Symmetrically, as a group is being constructed, a counter stored in
+% placement/chain count is available that is advanced for each chain
+% in the group. The number placement/depth is the defined
+% recursively as follows: For a single node, the depth is
+% computed by the key placement/logical node depth. The depth
+% of a group is the sum of the depths of its elements. The depth of a
+% chain is the maximum of the depth of its elements.
+%
+%
+% The above keys get updated automatically. You should setup the key
+% placement/compute position such that it uses the above keys to
+% compute a good position for a new node based on the above
+% keys. Typically, this key should execute node={shift=(...)} to setup
+% the necessary shift for a new node.
+%
+% The key placement/compute position should not be called
+% directly. Instead, the key placement/place should be used. This key
+% has two effects: First, it calls placement/compute position. Second,
+% it resets the length and normal counters. It will setup a completely
+% new counting of lengths and counters inside the current scope.
+%
+% The placmenet/place key is executed automatically whenever a new
+% node is automatically created. Furthermore, placement strategies
+% will call this key.
+
+\tikzgraphsset{
+ placement/.cd,
+ compute position/.code=\tikz@lib@graph@linear@pos,
+ place/.code={%
+ \pgfkeys{/tikz/graphs/placement/compute position}%
+ \aftergroup\tikz@lib@graph@reset@locals%
+ \pgfkeyssetvalue{/tikz/graphs/placement/element count}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/depth}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/width}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}%
+ \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}%
+ },
+ element count/.initial=0,
+ chain count/.initial=0,
+ depth/.initial=0,
+ width/.initial=0,
+ level/.initial=0,
+ logical node depth/.code=\def\pgfmathresult{1},
+ logical node width/.code=\def\pgfmathresult{1},
+}%
+
+\def\tikz@lib@graph@reset@locals{%
+ \gdef\tikz@lib@graph@group@depth{0}%
+ \gdef\tikz@lib@graph@group@width{0}%
+}%
+
+
+% Arrange nodes evenly
+%
+% This strategy works as follows: You specify a "chain shift vector"
+% and a "group shift vector". Then each new element on a chain is
+% shifted by the chain shift vector relative to the previous element
+% on the chain. Similarly for each new element of a group.
+
+\tikzgraphsset{
+ Cartesian placement/.style={
+ placement/place,
+ placement/compute position/.code=\tikz@lib@graph@linear@pos%
+ },
+ chain shift/.initial={(1,0)},
+ group shift/.initial={(0,-1)},
+ grow right/.style={
+ placement/place,
+ chain shift={(#1,0)},
+ @auto anchor horizontal=center,
+ placement/logical node width/.code=\def\pgfmathresult{1}
+ },
+ grow right/.default=1,
+ grow left/.style={
+ placement/place,
+ chain shift={(-#1,0)},
+ @auto anchor horizontal=center,
+ placement/logical node width/.code=\def\pgfmathresult{1}
+ },
+ grow left/.default=1,
+ grow up/.style={
+ placement/place,
+ chain shift={(0,#1)},
+ @auto anchor horizontal=center,
+ placement/logical node width/.code=\def\pgfmathresult{1}
+ },
+ grow up/.default=1,
+ grow down/.style={
+ placement/place,
+ chain shift={(0,-#1)},
+ @auto anchor vertical=center,
+ placement/logical node width/.code=\def\pgfmathresult{1}
+ },
+ grow down/.default=1,
+ branch right/.style={
+ placement/place,
+ group shift={(#1,0)},
+ @auto anchor horizontal=center,
+ placement/logical node depth/.code=\def\pgfmathresult{1}
+ },
+ branch right/.default=1,
+ branch left/.style={
+ placement/place,
+ group shift={(-#1,0)},
+ @auto anchor horizontal=center,
+ placement/logical node depth/.code=\def\pgfmathresult{1}
+ },
+ branch left/.default=1,
+ branch up/.style={
+ placement/place,
+ group shift={(0,#1)},
+ @auto anchor vertical=center,
+ placement/logical node depth/.code=\def\pgfmathresult{1}
+ },
+ branch up/.default=1,
+ branch down/.style={
+ placement/place,
+ group shift={(0,-#1)},
+ @auto anchor vertical=center,
+ placement/logical node depth/.code=\def\pgfmathresult{1}
+ },
+ branch down/.default=1,
+ %
+ % Sep shifts
+ %
+ grow right sep/.style={
+ Cartesian placement,
+ chain shift={(1pt,0)},
+ @auto anchor horizontal=west,
+ placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1}
+ },
+ grow right sep/.default=1em,
+ grow left sep/.style={
+ Cartesian placement,
+ chain shift={(-1pt,0)},
+ @auto anchor horizontal=east,
+ placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1}
+ },
+ grow left sep/.default=1em,
+ grow up sep/.style={
+ Cartesian placement,
+ chain shift={(0,1pt)},
+ @auto anchor vertical=south,
+ placement/logical node width/.code=\tikz@lib@graph@depth@sep{##1}{#1}
+ },
+ grow up sep/.default=1em,
+ grow down sep/.style={
+ Cartesian placement,
+ chain shift={(0,-1pt)},
+ @auto anchor vertical=north,
+ placement/logical node width/.code=\tikz@lib@graph@depth@sep{##1}{#1}
+ },
+ grow down sep/.default=1em,
+ grow right sep/.style={
+ Cartesian placement,
+ chain shift={(1pt,0)},
+ @auto anchor horizontal=west,
+ placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1}
+ },
+ %
+ branch right sep/.style={
+ Cartesian placement,
+ group shift={(1pt,0)},
+ @auto anchor horizontal=west,
+ placement/logical node depth/.code=\tikz@lib@graph@width@sep{##1}{#1}
+ },
+ branch right sep/.default=1em,
+ branch left sep/.style={
+ Cartesian placement,
+ group shift={(-1pt,0)},
+ @auto anchor horizontal=east,
+ placement/logical node depth/.code=\tikz@lib@graph@width@sep{##1}{#1}
+ },
+ branch left sep/.default=1em,
+ branch up sep/.style={
+ Cartesian placement,
+ group shift={(0,1pt)},
+ @auto anchor vertical=south,
+ placement/logical node depth/.code=\tikz@lib@graph@depth@sep{##1}{#1}
+ },
+ branch up sep/.default=1em,
+ branch down sep/.style={
+ Cartesian placement,
+ group shift={(0,-1pt)},
+ @auto anchor vertical=north,
+ placement/logical node depth/.code=\tikz@lib@graph@depth@sep{##1}{#1}
+ },
+ branch down sep/.default=1em,
+ %
+ @auto anchor horizontal/.style={
+ nodes={anchor=\csname tikz@lib@graph@auto@\tikz@lib@graph@auto@h @\tikz@lib@graph@auto@v\endcsname},
+ /utils/exec=\def\tikz@lib@graph@auto@h{#1}
+ },
+ @auto anchor vertical/.style={
+ nodes={anchor=\csname tikz@lib@graph@auto@\tikz@lib@graph@auto@h @\tikz@lib@graph@auto@v\endcsname},
+ /utils/exec=\def\tikz@lib@graph@auto@v{#1}
+ },
+ %
+ %
+ no placement/.style={
+ placement/place,
+ placement/compute position/.code=%
+ }
+}%
+
+\def\tikz@lib@graph@auto@h{center}%
+\def\tikz@lib@graph@auto@v{center}%
+
+\def\tikz@lib@graph@auto@center@center{center}%
+\def\tikz@lib@graph@auto@west@center{west}%
+\def\tikz@lib@graph@auto@east@center{east}%
+\def\tikz@lib@graph@auto@center@north{north}%
+\def\tikz@lib@graph@auto@west@north{north west}%
+\def\tikz@lib@graph@auto@east@north{north east}%
+\def\tikz@lib@graph@auto@center@south{south}%
+\def\tikz@lib@graph@auto@west@south{south west}%
+\def\tikz@lib@graph@auto@east@south{south east}%
+
+\def\tikz@lib@graph@linear@pos{%
+ \pgfkeysgetvalue{/tikz/graphs/chain shift}\tikz@temp
+ \expandafter\tikz@scan@one@point\expandafter\pgf@process\tikz@temp
+ \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/width}}{}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgfkeysgetvalue{/tikz/graphs/group shift}\tikz@temp
+ \expandafter\tikz@scan@one@point\expandafter\pgf@process\tikz@temp
+ \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/depth}}{}}%
+ \advance\pgf@xa by\pgf@x%
+ \advance\pgf@ya by\pgf@y%
+ \edef\tikz@lib@graph@shift{(\the\pgf@xa,\the\pgf@ya)}
+ \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}}
+}%
+
+
+\def\tikz@lib@graph@width@sep#1#2{%
+ \pgf@process{\pgfpointdiff{\pgfpointanchor{#1}{west}}{\pgfpointanchor{#1}{east}}}%
+ \pgfmathparse{#2+\the\pgf@x}%
+}%
+
+\def\tikz@lib@graph@depth@sep#1#2{%
+ \pgf@process{\pgfpointdiff{\pgfpointanchor{#1}{south}}{\pgfpointanchor{#1}{north}}}%
+ \pgfmathparse{#2+\the\pgf@y}%
+}%
+
+
+% Circular arrangements
+%
+% This strategy works a bit like the arrange evenly strategy, but in
+% polar coordinates. Both for the chains and the groups you specify a
+% polar shift, which must be in the form "(delta degree:delta
+% distance)". For each element in a chain, the delta degree is added
+% to the chain degree, likewise for each element the delta distance is
+% added. Similarly for groups.
+%
+% There is an initial degree and radius, stored in the key "phase" and
+% "radius".
+
+\tikzgraphsset{,
+ circular placement/.style={
+ placement/place,
+ placement/compute position/.code=\tikz@lib@graph@circular@pos,%
+ placement/logical node depth/.code=\def\pgfmathresult{1},
+ placement/logical node width/.code=\def\pgfmathresult{1},
+ },
+ clockwise/.style={
+ circular placement,
+ group polar shift={(-360/#1:0)}
+ },
+ clockwise/.default=\tikzgraphVnum,
+ counterclockwise/.style={
+ circular placement,
+ group polar shift={(360/#1:0)}
+ },
+ counterclockwise/.default=\tikzgraphVnum,
+ chain polar shift/.initial={(0:1cm)},
+ group polar shift/.initial={(60:0)},
+ radius/.initial=1cm,
+ phase/.initial=90,
+}%
+
+\def\tikz@lib@graph@circular@pos{%
+ \pgfkeysgetvalue{/tikz/graphs/chain polar shift}\tikz@temp
+ \expandafter\tikz@lib@graph@decompose@polar\tikz@temp%
+ \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/width}}{}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgfkeysgetvalue{/tikz/graphs/group polar shift}\tikz@temp
+ \expandafter\tikz@lib@graph@decompose@polar\tikz@temp%
+ \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/depth}}{}}%
+ \advance\pgf@xa by\pgf@x%
+ \advance\pgf@ya by\pgf@y%
+ \pgfmathparse{\pgfkeysvalueof{/tikz/graphs/radius}}%
+ \advance\pgf@ya by\pgfmathresult pt%
+ \pgfmathsetmacro\tikz@temp{\the\pgf@xa+\pgfkeysvalueof{/tikz/graphs/phase}}%
+ \edef\tikz@lib@graph@shift{(\tikz@temp:\the\pgf@ya)}
+ \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}}
+}%
+
+
+\def\tikz@lib@graph@decompose@polar(#1:#2){%
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgfmathsetlength\pgf@y{#2}%
+}%
+
+
+% Grid arrangements
+%
+\tikzgraphsset{
+ grid placement/.style={
+ placement/place,
+ placement/compute position/.code=\tikz@lib@graph@grid@pos,%
+ },
+}%
+
+
+\def\tikz@lib@graph@grid@pos{%
+ %
+ % Make sure to set \tikzgraphwrapafter before we compute
+ % the positions of nodes in the grid
+ %
+ \tikzgraphpreparewrapafter%
+ %
+ % find out the coordinate in the grid
+ %
+ \pgfkeysgetvalue{/tikz/graphs/placement/depth}\tikz@temp@depth%
+ \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@width%
+ \pgfmathsetmacro{\tikz@temp}{max(\tikz@temp@depth, \tikz@temp@width)}%
+ \pgfmathsetmacro{\tikz@temp@col}{mod(\tikz@temp,\tikzgraphwrapafter)}%
+ \pgfmathsetmacro{\tikz@temp@row}{div(\tikz@temp,\tikzgraphwrapafter)}%
+ %
+ % multiply row by the group shift and col by the chain shift
+ %
+ \pgfkeysgetvalue{/tikz/graphs/group shift}\tikz@temp%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@lib@graph@grid@pos@a\tikz@temp%
+ \pgfkeysgetvalue{/tikz/graphs/chain shift}\tikz@temp%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@lib@graph@grid@pos@b\tikz@temp%
+ %
+ % apply the shift
+ %
+ \edef\tikz@lib@graph@shift{(\the\pgf@xa,\the\pgf@ya)}
+ \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}}
+}%
+
+\def\tikz@lib@graph@grid@pos@a#1{\pgf@process{\pgfpointscale{\tikz@temp@row}{#1}}\pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax}%
+\def\tikz@lib@graph@grid@pos@b#1{\pgf@process{\pgfpointscale{\tikz@temp@col}{#1}}%
+ \advance\pgf@xa by\pgf@x\relax
+ \advance\pgf@ya by\pgf@y\relax}%
+
+\tikzgraphsset{
+ % Grids:
+ wrap after/.initial=0,
+ % Node sets:
+ V/.code={%
+ \def\tikzgraphV{#1}%
+ \c@pgf@counta=0\foreach \tikz@dummy in {#1} {\global\advance\c@pgf@counta by1\relax}%
+ \edef\tikzgraphVnum{\the\c@pgf@counta}
+ },
+ V={1},
+ n/.style={V={1,...,#1},name shore V/.style={name=V}},
+ W/.code={%
+ \def\tikzgraphW{#1}%
+ \c@pgf@counta=0\foreach \tikz@dummy in {#1} {\global\advance\c@pgf@counta by1\relax}%
+ \edef\tikzgraphWnum{\the\c@pgf@counta}
+ },
+ W={1},
+ m/.style={W={1,...,#1},name shore W/.style={name=W}},
+ % Shores:
+ name shore V/.style=,
+ name shore W/.style=,
+}%
+
+
+
+%
+% Quick graphs
+%
+% Parsing the graph syntax can take a lot of time for large
+% graphs. This is mainly due to the transformation of commas and
+% semicolons and all the internal bookkeeping.
+%
+% For large graphs, the quick graph syntax offers a greatly reduced
+% syntax that will be processed much more quickly. This syntax is
+% compatible with the normal graph syntax in the sense that all
+% specifications written in the reduced syntax are also legal in the
+% normal syntax, but not the other way round.
+%
+% The following rules apply:
+%
+% 1) A quick graph consists of a sequence of either nodes, edges sequences, or
+% groups. These are separated by commas or semicolons.
+%
+% 2) Every node is of the form
+%
+% "node name"/"node text"[options]
+%
+% Here, the quotation marks are mandatory. The part '/"node text"' may
+% be missing, in which case the node name is used as the node
+% text. The options may also be missing. The node name may not contain
+% any "funny" characters (unlike in the normal graph command).
+%
+% 3) Every edge is of the form
+%
+% <node spec> <connector> <node spec> <connector> <node spec> ... <connector> <node spec>;
+%
+% Here, the <node spec> are node specifications as described above,
+% the <connector> is one of the four connectors "->", "<-", "--", and
+% "<->", followed by optional options in square
+% brackets. The semicolon may be replaced by a comma.
+%
+% 4) Every group is of the form
+%
+% { [options] lines };
+%
+% The options are compulsory, the lines must be a sequence of nodes,
+% edges, and groups as described above. The semicolon can, again, be
+% replaced by a comma.
+%
+%
+% Things that are allowed in the normal syntax, but not in the quick
+% syntax, include:
+%
+% - Connecting a node and a group as in a->{b,c}.
+% - Node names without quotation marks.
+% - Using subgraphs (graph macros).
+% - Using graph sets.
+% - Using graph color classes.
+% - Using anonymous nodes.
+% - Using the "fresh nodes" option.
+% - Using sublayouts.
+% - Using the -!- edge connector.
+% - Using the "simple" option.
+% - Using edge annotations.
+%
+% Example:
+%
+% \graph [quick] {
+% "a"/"$a$"[red] -> "b"[blue] -> "c";
+% "b" -> "d";
+% "c" ->[thick] "e";
+% { [same layer] "c", "d" };
+% };
+%
+%
+
+\tikzgraphsset{quick/.is if=tikz@graph@quick}%
+\newif\iftikz@graph@quick
+
+\def\tikz@lib@graphs@parse@quick@graph{
+ % Ok, we are before the initial brace. We open a group and start
+ % setting up some bookkeeping
+ \begingroup%
+ \global\tikz@qnode@count0\relax%
+ \let\tikzgraphnodepath\pgfutil@empty%
+ \tikz@q@outertrue%
+ \afterassignment\tikz@lib@graphs@quick@main\let\pgf@temp=%
+}%
+
+\newcount\tikz@qnode@count
+\newif\iftikz@q@outer
+
+\def\tikz@lib@graphs@quick@main{%
+ \afterassignment\tikz@lib@graphs@quick@handle\let\pgf@let@token=%
+}%
+\def\tikz@lib@graphs@quick@handle{%
+ \ifx\pgf@let@token"%
+ \expandafter\tikz@lib@graphs@quick@first@node%
+ \else%
+ \expandafter\tikz@lib@graphs@quick@other%
+ \fi%
+}%
+\def\tikz@lib@graphs@quick@other{%
+ \let\tikz@next\tikz@lib@graphs@quick@error%
+ \ifx\pgf@let@token\egroup%
+ \let\tikz@next\tikz@lib@graphs@quick@end@group%
+ \else%
+ \ifx\pgf@let@token\bgroup%
+ \let\tikz@next\tikz@lib@graphs@quick@start@group%
+ \else%
+ \ifx\pgf@let@token\par%
+ \let\tikz@next\tikz@lib@graphs@quick@main%
+ \fi%
+ \fi
+ \fi%
+ \tikz@next%
+}%
+
+\def\tikz@lib@graphs@quick@error#1{\tikzerror{Unexpected token '\string#1' in quick graph syntax}\tikz@lib@graphs@quick@main}%
+\def\tikz@lib@graphs@quick@start@group{%
+ \pgfutil@ifnextchar[\tikz@lib@graphs@quick@start@group@{\tikzerror{Group
+ in quick graph syntax must start with options.}}
+}%
+
+\def\tikz@lib@graphs@quick@start@group@[#1]{%
+ \begingroup%
+ \tikz@q@outerfalse%
+ \tikzgraphsset{#1}%
+ \tikz@lib@graphs@quick@main%
+}%
+\def\tikz@lib@graphs@quick@end@group{%
+ \iftikz@q@outer%
+ \endgroup%
+ % Ok, cleanup!
+ \pgfutil@loop%
+ \ifnum\tikz@qnode@count>0\relax%
+ \expandafter\global\expandafter\let\csname tikz@gr@q@@\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\endcsname\relax%
+ \expandafter\global\expandafter\let\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\relax%
+ \global\advance\tikz@qnode@count by-1\relax%
+ \pgfutil@repeat%
+ \expandafter\tikz@lib@graph@main@done%
+ \else%
+ \endgroup%
+ \expandafter\tikz@lib@graphs@end@group@%
+ \fi%
+}%
+\def\tikz@lib@graphs@end@group@{%
+ \pgfutil@ifnextchar;{\expandafter\tikz@lib@graphs@quick@main\pgfutil@gobble}{%
+ \pgfutil@ifnextchar,{\expandafter\tikz@lib@graphs@quick@main\pgfutil@gobble}{%
+ \tikzerror{Graph groups in quick syntax must be followed by a semicolon or a comma.}%
+ }%
+ }%
+}%
+
+
+\def\tikz@lib@graphs@quick@first@node{%
+ \let\tikz@quick@prev@node\relax%
+ \tikz@lib@graphs@quick@node%
+}%
+
+\def\tikz@lib@graphs@quick@node#1"{%
+ \def\tikzgraphnodename{#1}%
+ \let\tikzgraphnodetext\tikzgraphnodename%
+ \iftikzgraphsautonumbernodes
+ \edef\tikzgraphnodename{\tikzgraphnodename\tikz@lib@auto@sep\the\tikz@lib@auto@number}%
+ \global\advance\tikz@lib@auto@number by1\relax%
+ \fi
+ \pgfutil@ifnextchar/\tikz@lib@graphs@quick@text\tikz@lib@graphs@quick@opt%
+}%
+\def\tikz@lib@graphs@quick@text/"#1"{%
+ \def\tikzgraphnodetext{#1}%
+ \tikz@lib@graphs@quick@opt%
+}%
+\def\tikz@lib@graphs@quick@opt{%
+ \pgfutil@ifnextchar[\tikz@lib@graphs@quick@withopt{\tikz@lib@graphs@quick@withopt[]}%]
+}%
+\def\tikz@lib@graphs@quick@withopt[#1]{%
+ % Test, whether node already exists
+ \expandafter\ifx\csname tikz@gr@q@@\tikzgraphnodename\endcsname\relax%
+ % New node
+ \global\advance\tikz@qnode@count by1\relax%
+ \expandafter\global\expandafter\let\csname tikz@gr@q@@\tikzgraphnodename\endcsname\pgfutil@empty% not relax
+ \expandafter\global\expandafter\let\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\tikzgraphnodename% back pointer
+ \let\tikzgraphnodefullname\tikzgraphnodename%
+ \let\tikzgraphnodeas\tikzgraphnodeas@default%
+ \node [%
+ name=\tikzgraphnodename,%
+ graphs/redirect unknown to tikz,
+ /tikz/graphs/.cd,%
+ /tikz/graphs/@nodes styling,%
+ #1]%
+ {%
+ \tikzgraphnodeas%
+ };%
+ \else%
+ %
+ % Handle late options and operators
+ \tikzgdlatenodeoptionacallback{\tikzgraphnodename}%
+ \node also[graphs/redirect unknown to tikz,/tikz/graphs/.cd,#1](\tikzgraphnodename);%
+ \fi%
+ % Connect, if necessary
+ \tikz@lig@graph@quikc@make@edge@if@necessary%
+ \tikz@lib@graphs@quick@scan@after@node%
+}%
+
+\def\tikz@lig@graph@quikc@make@edge@if@necessary{%
+ \ifx\tikz@quick@prev@node\relax%
+ \else%
+ \tikz@lib@graphs@quick@make@edge%
+ \fi%
+}%
+
+\def\tikz@lib@graphs@quick@scan@after@node{%
+ \pgfutil@ifnextchar,\tikz@lib@graphs@quick@comma{%
+ \pgfutil@ifnextchar;\tikz@lib@graphs@quick@semi{%
+ \pgfutil@ifnextchar\egroup{\tikz@lib@graphs@quick@semi;}{%
+ \pgfutil@ifnextchar\par{\expandafter\tikz@lib@graphs@quick@scan@after@node\tikz@lib@graphs@quick@gobble@par}%
+ \tikz@lib@graphs@quick@connector}}}%
+}%
+\long\def\tikz@lib@graphs@quick@gobble@par#1{}%
+
+\def\tikz@lib@graphs@quick@comma,{\tikz@lib@graphs@quick@main}%
+\def\tikz@lib@graphs@quick@semi;{\tikz@lib@graphs@quick@main}%
+\def\tikz@lib@graphs@quick@connector#1#2{%
+ \def\tikz@lib@graphs@quick@edge@kind{#1#2}%
+ \pgfutil@ifnextchar>\tikz@lib@graphs@back@edge{%
+ \pgfutil@ifnextchar[\tikz@lib@graphs@quick@connector@handle@opt{\tikz@lib@graphs@quick@connector@handle@opt[]}%]
+ }%
+}%
+\def\tikz@lib@graphs@back@edge#1{%
+ \expandafter\def\expandafter\tikz@lib@graphs@quick@edge@kind\expandafter{\tikz@lib@graphs@quick@edge@kind#1}%
+ \pgfutil@ifnextchar[\tikz@lib@graphs@quick@connector@handle@opt{\tikz@lib@graphs@quick@connector@handle@opt[]}%]
+}%
+\def\tikz@lib@graphs@quick@connector@handle@opt[#1]{%
+ \def\tikz@lib@graphs@quick@edge@options{#1}%
+ \let\tikz@quick@prev@node\tikzgraphnodename%
+ \tikz@lib@graphs@quick@scan@after@connector%
+}%
+\def\tikz@lib@graphs@quick@scan@after@connector{%
+ \pgfutil@ifnextchar\par{\expandafter\tikz@lib@graphs@quick@scan@after@connector\tikz@lib@graphs@quick@gobble@par}{%
+ \pgfutil@ifnextchar"{\expandafter\tikz@lib@graphs@quick@node\pgfutil@gobble}{%
+ \tikzerror{Quotation marks expected after edge connector}%
+ }%
+ }%
+}%
+
+\def\tikz@lib@graphs@quick@make@edge{%
+ {
+ \expandafter\tikz@lib@graphs@quick@make@edge@styling\expandafter{\tikz@lib@graphs@quick@edge@options}%
+ \expandafter\expandafter\expandafter\tikz@lib@graphs@quick@make@edge@for%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@quick@prev@node\expandafter}\expandafter{\tikzgraphnodename}%
+ }
+}%
+
+\def\tikz@lib@graphs@quick@make@edge@styling#1{%
+ \tikz@enable@edge@quotes%
+ \tikzgraphsset{.unknown/.code=\tikz@lib@graph@unknown@edge@option{##1},#1}%
+}%
+
+\def\tikz@lib@graphs@quick@make@edge@for#1#2{%
+ \pgfkeysgetvalue{/tikz/graphs/@edges styling}\pgf@tempa
+ \pgfkeysgetvalue{/tikz/graphs/@edges node}\pgf@temp@b
+ \expandafter\expandafter\expandafter\tikz@lib@graphs@quick@make@edge@for@with%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@tempa\expandafter}\expandafter{\pgf@temp@b}{#1}{#2}%
+}%
+
+\def\tikz@lib@graphs@quick@make@edge@for@with#1#2#3#4{%
+ \tikzgraphsset{new \tikz@lib@graphs@quick@edge@kind={#3}{#4}{#1}{#2}}%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex
new file mode 100644
index 0000000000..4cac3e51eb
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex
@@ -0,0 +1,109 @@
+% Copyright 2019 by Till Tantau
+% Copyright 2019 by Jannis Pohlmann
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarygraphs.standard.code.tex}
+
+\usetikzlibrary{graphs}%
+
+%
+% Basic graphs
+%
+
+
+\tikzgraphsset{
+ %
+ % An independent set $V$ of nodes.
+ %
+ declare={subgraph I_n}%
+ {
+ \foreach \tikz@lib@graph@node@num in \tikzgraphV
+ { \tikz@lib@graph@node@num }
+ },
+ %
+ % An two-shore independent set $V$ with shores V and W.
+ %
+ declare={subgraph I_nm}%
+ {
+ subgraph I_n [name shore V] -- [no edges]
+ subgraph I_n [name shore W, V/.expand once=\tikzgraphW]
+ },
+ %
+ % The complete clique on $V$.
+ %
+ declare={subgraph K_n}%
+ {
+ [clique]
+ subgraph I_n
+ },
+ %
+ % A complete bipartite graph with shores V and W.
+ %
+ declare={subgraph K_nm}%
+ {
+ [color class=shore V,
+ color class=shore W,
+ complete bipartite={shore V}{shore W}]
+ subgraph I_n [name shore V, shore V] -- [no edges]
+ subgraph I_n [name shore W, V/.expand once=\tikzgraphW, shore W]
+ },
+ %
+ % A cycle with n nodes.
+ %
+ declare={subgraph C_n}%
+ {
+ [cycle]
+ subgraph I_n
+ },
+ %
+ % A path with n nodes.
+ %
+ declare={subgraph P_n}%
+ {
+ [path]
+ subgraph I_n
+ },
+ %
+ % A grid with n nodes.
+ %
+ declare={subgraph Grid_n}%
+ {
+ [grid]
+ subgraph I_n
+ },
+ %
+ % A random graph according to the G_{n,p} model: For each pair of
+ % vertices there is an edge between them with probability p.
+ %
+ p/.initial=0.5,
+ declare={subgraph G_np}%
+ {
+ [/utils/exec={
+ \pgfmathsetmacro\tikz@lib@lg@p{\pgfkeysvalueof{/tikz/graphs/p}}
+ \let\tikz@lib@gnp@edges\pgfutil@empty%
+ \foreach \tikz@lib@graph@node@a [count=\tikz@lib@g@count@a] in \tikzgraphV
+ \foreach \tikz@lib@graph@node@b [count=\tikz@lib@g@count@b] in \tikzgraphV
+ {
+ \ifnum\tikz@lib@g@count@a<\tikz@lib@g@count@b\relax
+ \pgfmathparse{rnd}
+ \ifdim\pgfmathresult pt<\tikz@lib@lg@p pt%
+ \ifx\tikz@lib@gnp@edges\pgfutil@empty
+ \xdef\tikz@lib@gnp@edges{\tikz@lib@graph@node@a--\tikz@lib@graph@node@b}%
+ \else
+ \xdef\tikz@lib@gnp@edges{\tikz@lib@gnp@edges,\tikz@lib@graph@node@a--\tikz@lib@graph@node@b}%
+ \fi
+ \fi
+ \fi
+ }
+ }]
+ \foreach \tikz@lg@temp in \tikz@lib@gnp@edges {
+ [parse/.expand once=\tikz@lg@temp]
+ }
+ },
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzexternalshared.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzexternalshared.code.tex
new file mode 100644
index 0000000000..2ff5aa2d38
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzexternalshared.code.tex
@@ -0,0 +1,1714 @@
+% Copyright 2008-2020 by Christian Feuersaenger
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% ******************************
+% This here is the shared implementation of TeX-dialect specific files
+% tikzlibraryexternal.code.tex
+% ******************************
+%
+%
+% This file provides a high-level automatic export feature for tikz pictures.
+% It allows to export EACH SINGLE FIGURE into a separate PDF.
+%
+% The simplest way is to use the 'convert with system call' option; it simply converts every figure using the write18 method. If that is not possible, a list of figure file names is generated and you need to generate these figures manually (or with a script).
+%
+%
+% It replaces \tikzpicture/ \endtikzpicture and \tikz and invokes \beginpgfgraphicnamed ... \endpgfgraphicnamed
+% commands if necessary.
+
+% handle with extreme care and only in small, local groups:
+\toksdef\t@tikzexternal@tmpa=0
+\toksdef\t@tikzexternal@tmpb=1
+
+\newif\iftikzexternal@nestedflag
+\newif\iftikzexternal@verboseuptodate
+\newif\iftikzexternal@verboseio
+\newif\iftikzexternal@genfigurelist
+\newif\iftikzexternal@onlynamed
+\newif\iftikzexternal@file@isuptodate
+\newif\iftikzexternal@force@remake
+\newif\iftikzexternal@optimize
+\newif\iftikzexternal@export@enabled
+\tikzexternal@export@enabledtrue
+
+% must be numeric!
+\gdef\c@tikzexternal@version{2}
+
+% This 'if' can be used as part of the public user interface.
+%
+% It is set by the 'remake next' key.
+%
+% It disables any up-to-date checks for the *next* picture, forcing a
+% remake of it.
+%
+% It applies only to *one* picture.
+\newif\iftikzexternalremakenext
+\newif\iftikzexternal@verbose@optimize
+\tikzexternal@verbose@optimizetrue
+
+% A global boolean which can be used to skip single figures.
+\newif\iftikzexternalexportnext
+\tikzexternalexportnexttrue
+
+% Invokes '#1' if the external lib is currently externalizing
+% something and '#2' if not.
+%
+% This command must be called *after* \tikzexternalize.
+\def\tikzifexternalizing#1#2{%
+ \ifpgf@external@grabshipout #1\else #2\fi
+}%
+% Invokes '#1' if the external lib is currently externalizing the NEXT FOLLOWING
+% tikzpicture. It invokes '#2' if that is not the case.
+\def\tikzifexternalizingnext#1#2{%
+ \ifpgf@external@grabshipout
+ \tikzexternalgetnextfilename\tikzexternal@temp
+ \tikzifexternaljobnamematches\tikzexternal@temp{#1}{#2}%
+ \else
+ #2%
+ \fi
+}%
+% Invokes '#1' if the external lib is currently externalizing the
+% current picture. It invokes '#2' if that is not the case.
+%
+% If the command is invoked outside of a picture, '#2' will be
+% invoked.
+\def\tikzifexternalizingcurrent#1#2{%
+ \ifpgf@external@grabshipout
+ \tikzexternalgetcurrentfilename\tikzexternal@temp
+ \ifx\tikzexternal@temp\pgfutil@empty
+ #2%
+ \else
+ \tikzifexternaljobnamematches\tikzexternal@temp{#1}{#2}%
+ \fi
+ \else
+ #2%
+ \fi
+}%
+
+% Invokes '#2' if \jobname equals '#1' and '#3' if not.
+% I suppose that '#1' is a macro containing the file name.
+%
+\def\tikzifexternaljobnamematches#1#2#3{%
+ \edef\pgf@tempa{\expandafter\string\csname#1\endcsname}%
+ \edef\pgf@tempb{\expandafter\string\csname\pgfactualjobname\endcsname}%
+ \ifx\pgf@tempa\pgf@tempb #2\else#3 \fi%
+}%
+
+
+\pgfutil@IfUndefined{pdfshellescape}{%
+ % let's hope that \usepackage{pdftexcmds} has been used...
+ \pgfutil@IfUndefined{pdf@shellescape}{%
+ \def\tikzexternalcheckshellescape{0}%
+ }{%
+ \let\tikzexternalcheckshellescape=\pdf@shellescape
+ }%
+}{%
+ \let\tikzexternalcheckshellescape=\pdfshellescape
+}%
+\ifnum\tikzexternalcheckshellescape=1
+ \def\tikzexternalcheckshellescape{\pgfkeysvalueof{/tikz/external/shell escape}\space}%
+\else
+ \def\tikzexternalcheckshellescape{}%
+\fi
+
+\newif\iftikzexternal@auto@detect@jobname
+
+\pgfqkeys{/tikz/external}{
+ figure list/.is if=tikzexternal@genfigurelist,
+ aux in dpth/.style={/pgf/images/aux in dpth={#1}},%
+ disable dependency files/.code={%
+ \let\tikzexternalfiledependsonfile@ACTIVE=\tikzexternalfiledependsonfile
+ },
+ % 'mode' applies only if \jobname==real job name.
+ mode/.is choice,
+ mode/only graphics/.code = {%
+ \def\tikzexternal@opmode{0}%
+ \pgfkeysalso{/pgf/images/aux in dpth=true}%
+ },
+ mode/no graphics/.code = {\def\tikzexternal@opmode{1}},
+ % an alias for 'no graphics:'
+ mode/only pictures/.code = {\def\tikzexternal@opmode{1}},
+ mode/graphics if exists/.code= {%
+ \def\tikzexternal@opmode{2}%
+ \pgfkeysalso{/pgf/images/aux in dpth=true}%
+ },
+ mode/list only/.code = {\def\tikzexternal@opmode{3}\tikzexternal@genfigurelisttrue},
+ mode/convert with system call/.code={%
+ \def\tikzexternal@opmode{4}%
+ \pgfkeysalso{/tikz/external/figure list=false,/pgf/images/aux in dpth=true}%
+ },
+ mode/list and make/.code = {%
+ \def\tikzexternal@opmode{5}%
+ \pgfkeysalso{/tikz/external/figure list=true,/pgf/images/aux in dpth=true}%
+ },
+ mode=convert with system call,
+ force remake/.is if=tikzexternal@force@remake,
+ force remake/.default=true,
+ %
+ % DEPRECATED: this here will work out-of-the box (provided that
+ % 'aux in dpth' is active):
+ failed ref warnings for/.initial={\ref,\cite,\pageref},
+ export next/.is if=tikzexternalexportnext,
+ export/.is if=tikzexternal@export@enabled,
+ remake next/.is if=tikzexternalremakenext,
+ remake next/.default=true,
+ verbose IO/.is if=tikzexternal@verboseio,
+ verbose IO/.default=true,
+ verbose IO=true,
+ verbose optimize/.is if=tikzexternal@verbose@optimize,
+ verbose up to date/.is if=tikzexternal@verboseuptodate,
+ verbose/.style={
+ verbose IO=#1,
+ verbose optimize=#1,
+ verbose up to date=#1,
+ },
+ shell escape/.initial=-shell-escape,
+ read main aux/.is if=pgfexternalreadmainaux,
+ image discarded text/.initial={%
+ [[ \textsc{Image Discarded Due To} \texttt{`/tikz/external/%
+ \ifcase\tikzexternal@opmode\relax
+ mode=only graphics%
+ \or
+ mode=no graphics%
+ \or
+ mode=graphics if exists%
+ \or
+ mode=list only%
+ \or
+ mode=convert with system call%
+ \or
+ mode=list and make%
+ \fi
+ '}~]]%
+ \pgfutil@ifundefined{tikzexternal@warning@at@end}{%
+ \pgfutil@ifundefined{AtEndDocument}{}{%
+ \AtEndDocument{%
+ \message{! Package tikz Warning: Some images are not up-to-date and need to be generated. }%
+ }%
+ }%
+ \gdef\tikzexternal@warning@at@end{1}%
+ }{}%
+ },
+ optimize/.is choice,
+ optimize/true/.code={%
+ \tikzexternal@optimizetrue
+ \iftikzexternal@optimize
+ \ifpgf@external@grabshipout
+ % we have already started the externalization! Install
+ % optimization commands to activate the new one:
+ \tikzexternal@optimize@REPLACE
+ \fi
+ \fi
+ },
+ optimize/false/.code={%
+ \tikzexternal@optimizefalse%
+ \tikzexternal@optimize@RESTORE
+ },%
+ optimize=true,
+ optimize away text/.code={[ \textsc{\string#1\ optimized away because it does not contribute to exported PDF}]},
+ optimize/install/.code={},%
+ optimize/restore/.code={},%
+ % Expects two arguments, the command name and (optionally) a count
+ % of expected arguments.
+ % Example:
+ % 'optimize command away=\includegraphics'
+ % 'optimize command away={\mycommand}{3}'
+ %
+ % It accepts commands which have '[]' arguments and whose first
+ % argument always begins with '{'.
+ %
+ % #1: the command name
+ % #2: either empty or a number of EXPECTED arguments. It will be checked
+ % for one optional argument in square brackets as well.
+ optimize command away/.code 2 args={%
+ \expandafter\global\expandafter\let\csname\string#1@ORIG\endcsname=#1%
+ \pgfkeysalso{%
+ /tikz/external/optimize/install/.append code={%
+ \def#1{\tikzexternal@optimize@away@cmd{#1}{#2}}%
+ },
+ /tikz/external/optimize/restore/.append code={%
+ \expandafter\let\expandafter#1\csname\string#1@ORIG\endcsname
+ }
+ }%
+ \iftikzexternal@optimize
+ \ifpgf@external@grabshipout
+ % we have already started the externalization! Install
+ % optimization commands to activate the new one:
+ \tikzexternal@optimize@REPLACE
+ \fi
+ \fi
+ },
+ optimize command away=\includegraphics,
+ optimize command away=\pgfincludeexternalgraphics,
+ % EXPERIMENTAL (UNTESTED):
+ optimize latex env away/.code={%
+ \expandafter\let\expandafter\pgf@tempa\csname #1\endcsname
+ \expandafter\global\expandafter\let\csname #1@ORIG\endcsname=\pgf@tempa%
+ \pgfkeysalso{%
+ /tikz/external/optimize/install/.append code={%
+ \pgfutil@namedef{#1}{\tikzexternal@optimize@away@latex@env{#1}}%
+ },
+ /tikz/external/optimize/restore/.append code={%
+ \pgfutil@namelet{#1}{#1@ORIG}%
+ }%
+ }%
+ },
+ only named/.is if=tikzexternal@onlynamed,
+ only named/.default=true,
+ figure name/.initial=\tikzexternal@realjob-figure,
+ reset counter/.code={%
+ \expandafter\gdef\csname c@tikzext@no@#1\endcsname{0}%
+ },%
+ prefix/.code={\tikzsetexternalprefix{#1}},
+ up to date check/.is choice,
+ up to date check/simple/.code={\def\tikzexternal@uptodate@mode{0}},
+ % md5 relies on \pdfmdfivesum of pdftex. It uses 'diff' as fallback if we do not have that command.
+ up to date check/md5/.code={\def\tikzexternal@uptodate@mode{1}},
+ up to date check/diff/.code={\def\tikzexternal@uptodate@mode{2}},
+ up to date check=md5,
+}
+
+\expandafter\def\csname tikzexternal@driver@pgfsys-luatex.def\endcsname{%
+ \pgfkeyssetvalue{/tikz/external/system call}{%
+ lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"%
+ }%
+}%
+\expandafter\def\csname tikzexternal@driver@pgfsys-pdftex.def\endcsname{%
+ \pgfutil@IfUndefined{directlua}{%
+ \pgfkeyssetvalue{/tikz/external/system call}{%
+ pdflatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"%
+ }%
+ }{%
+ \pgfkeyssetvalue{/tikz/external/system call}{%
+ lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"%
+ }%
+ }%
+}%
+%--------------------------------------------------
+% \expandafter\def\csname tikzexternal@driver@pgfsys-dvipdfm.def\endcsname{%
+% \pgfkeyssetvalue{/tikz/external/system call}{%
+% latex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"%
+% && dvipdfm "\image".dvi %
+% }%
+% }%
+%--------------------------------------------------
+\expandafter\def\csname tikzexternal@driver@pgfsys-xetex.def\endcsname{%
+ \pgfkeyssetvalue{/tikz/external/system call}{%
+ xelatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"%
+ }%
+}%
+\expandafter\def\csname tikzexternal@driver@pgfsys-dvips.def\endcsname{%
+ \pgfkeyssetvalue{/tikz/external/system call}{%
+ latex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource" %
+ && dvips -o "\image".ps "\image".dvi %
+ }%
+}%
+
+% Auto-select a suitable default value fo 'system call':
+\pgfutil@ifundefined{tikzexternal@driver@\pgfsysdriver}{%
+ % fallback. We do not know the driver here.
+ \csname tikzexternal@driver@pgfsys-pdftex.def\endcsname
+}{%
+ \csname tikzexternal@driver@\pgfsysdriver\endcsname
+}%
+
+
+\def\tikzsetfigurename#1{\pgfkeyssetvalue{/tikz/external/figure name}{#1}}%
+\def\tikzappendtofigurename#1{\pgfkeys{/tikz/external/figure name/.add={}{#1}}}
+
+% This method sets the file name prefix used for every import/export.
+%
+% It is invoked by the '/tikz/external/prefix' key.
+\def\tikzsetexternalprefix#1{\def\tikzexternal@filenameprefix{#1}}
+\tikzsetexternalprefix{}
+
+% This method initialises automatic externalization.
+%
+% The command does need any argument, but it has two optional ones:
+%
+% 1. \tikzexternalize[<options>]
+%
+% 2. \tikzexternalize{<real job's name>}
+%
+% 3. \tikzexternalize[<options>]{<real job's name>}
+%
+% The <real job's name> is the job's file name, without the suffix
+% .tex .
+% If the <real job's name> is omitted, it will be deduced
+% automatically.
+%
+% The effect is:
+% 1. automatically surround EVERY tikzpicture by \beginpgfgraphicnamed % sections.
+% 2. in case that the job's real name and the current \jobname differ,
+% it will process ONLY the matching tikzpicture.
+\def\tikzexternalize{%
+ \pgfutil@ifnextchar[{%
+ \tikzexternalize@opt
+ }{%
+ \tikzexternalize@opt[]%
+ }%
+}%
+\def\tikzexternalize@opt[#1]{%
+ \pgfutil@ifnextchar\bgroup{%
+ \tikzexternal@auto@detect@jobnamefalse
+ \tikzexternalize@opt@withname[#1]%
+ }{%
+ \tikzexternal@auto@detect@jobnametrue
+ \pgfutil@ifundefined{tikzexternalrealjob}{%
+ % ok, \tikzexternalrealjob is not known.
+ % Assume we are currently *not* externalizing.
+ \let\tikzexternalrealjob=\jobname
+ }{}%
+ \def\pgf@tempa{\tikzexternalize@opt@withname[#1]}%
+ \expandafter\pgf@tempa\expandafter{\tikzexternalrealjob}%
+ }%
+}%
+\def\tikzexternalize@opt@withname[#1]#2{%
+ \gdef\tikzexternalrealjob{#2}%
+ \if1\tikzexternalize@hasbeencalled
+ \else
+ \pgfqkeys{/tikz/external}{#1}%
+ \def\tikzexternal@realjob{#2}%
+ \tikzexternalauxlock@init
+ \pgfrealjobname{#2}%
+ \def\tikzexternalize@hasbeencalled{1}%
+ \tikzexternalenable
+ \def\tikzexternal@determineimgextension##1:##2\relax{\gdef\tikzexternalimgextension{##1}}%
+ \xdef\pgf@tempa{\pgfsys@imagesuffixlist}%
+ \expandafter\tikzexternal@determineimgextension\pgf@tempa:\relax
+ \pgfutil@ifundefined{includegraphics}{%
+ \let\tikzexternal@orig@includegraphics=\relax
+ }{%
+ \let\tikzexternal@orig@includegraphics=\includegraphics
+ }%
+ \let\tikzexternalfiledependsonfile=\tikzexternalfiledependsonfile@ACTIVE
+ \let\tikzpicturedependsonfile=\tikzpicturedependsonfile@ACTIVE
+ \fi
+}
+\def\tikzexternalize@hasbeencalled{0}%
+
+\def\tikzifexternalizehasbeencalled#1#2{%
+ \if1\tikzexternalize@hasbeencalled
+ #1%
+ \else
+ #2%
+ \fi
+}%
+
+% If mode=`convert with system call', the boolean \ifpgfexternalreadmainaux
+% will be set depending on the current lock file.
+%
+% The idea is as follows: Suppose
+% pdflatex -shell-escape mainjob.tex
+% is running.
+%
+% While it runs,
+% a) it modifies its mainjob.aux file,
+% b) it issues pdflatex -jobname mainjob-figure0 mainjob.tex .
+%
+% The call (b) will try to read mainjob.aux in order to resolve \ref
+% commands. This may fail since the aux
+% file is not complete; it may be subject to output buffering. To
+% avoid such failure, a locking mechanism is established.
+%
+% The locking mechanisms causes (a) to write a lock command into
+% mainjob.auxlock
+% just before (b) is called. Then, (b) will check it. After (b) has
+% completed, the lock will be reset.
+%
+% Thus: mode=convert with system call does NOT support \ref commands
+% inside of images. You will need to call the externalization command
+% manually. In this case, it should work.
+%
+% The lock file allows to detect automatically whether an image is created by
+% 'convert with system call' or if the user issued the required command manually.
+%
+% @PRECONDITION : this command must be invoked AFTER
+% \tikzexternal@realjob has been defined but BEFORE \pgfrealjobname is
+% called.
+%
+% @POSTCONDITION : If \ifpgfexternalreadmainaux=\iffalse, we won't do
+% anything. Otherwise, it will be changed depending for 'mode=convert
+% with system call' if necessary.
+\def\tikzexternalauxlock@init{%
+ \if4\tikzexternal@opmode
+ % mode=convert with system call
+ \ifpgfexternalreadmainaux
+ % ohoh. This case needs care because the main.aux might
+ % not be ready at this time!
+ % check.
+ %
+ \edef\pgf@tempa{\expandafter\string\csname\tikzexternal@realjob\endcsname}%
+ \edef\pgf@tempb{\expandafter\string\csname\jobname\endcsname}%
+ \ifx\pgf@tempa\pgf@tempb
+ % we are *not* externalizing. Set lock into its
+ % initial "unlocked" state.
+ \tikzexternalauxlock@setlock{0}%
+ \else
+ % we are externalizing. Query the lock's value:
+ \tikzexternalauxlock@getlockvalue
+ \if1\tikzexternallocked
+ \pgfexternalreadmainauxfalse
+ % the main .aux file won't be read right now.
+ \else
+ \pgfexternalreadmainauxtrue
+ \fi
+ \fi
+ \else
+ % NO-OP. We won't read the main aux file anyway.
+ \def\tikzexternalauxlock@setlock##1{}%
+ \fi
+ \fi
+}
+% defines \tikzexternallocked to be either 0 or 1, depending on the
+% lock file.
+\def\tikzexternalauxlock@getlockvalue{%
+ \openin\r@pgf@reada=\tikzexternal@realjob.auxlock
+ \ifeof\r@pgf@reada
+ % no lock file. Unlock.
+ \def\tikzexternallocked{0}%
+ \else
+ % read first line...
+ \read\r@pgf@reada to\pgf@tempa
+ % ... and execute it.
+ \pgf@tempa
+ % it should contain a definition of \tikzexternallocked. If
+ % not, lock it anyway.
+ \pgfutil@ifundefined
+ {tikzexternallocked}
+ {\def\tikzexternallocked{1}}%
+ {}%
+ \fi
+ \closein\r@pgf@reada
+}%
+\def\tikzexternalauxlock@setlock#1{%
+ \immediate\openout\w@pgf@writea=\tikzexternal@realjob.auxlock
+ \immediate\write\w@pgf@writea{\noexpand\def\noexpand\tikzexternallocked{#1}}%
+ \immediate\closeout\w@pgf@writea
+}
+
+
+% this is a hook into pgfcoreexternal.code.tex:
+\def\pgf@external@grab@refundefinedtrue@code{%
+ \gdef\noexpand\tikzexternal@systemcall@reschedule@to@end@document{1}%
+}%
+
+% Expands to the default image extension (it is set by
+% \tikzexternalize).
+%
+% This image extension may not resemble the correct one; you may need
+% to overwrite this macro *after* \tikzexternalize in this case.
+%
+% The default setting uses the first registered image extension.
+\def\tikzexternalimgextension{}%
+
+% can be used to (temporarily) disable the externalization.
+\def\tikzexternaldisable{%
+ \tikzexternaldisable@nofading
+ \pgfutil@ifundefined{tikzexternal@orig@tikzfadingfrompicture}
+ {}% NOP
+ {%
+ \let\tikzfadingfrompicture=\tikzexternal@orig@tikzfadingfrompicture
+ \let\endtikzfadingfrompicture=\tikzexternal@orig@endtikzfadingfrompicture
+ \let\tikzfading=\tikzexternal@orig@tikzfading
+ }%
+}%
+\def\tikzexternaldisable@nofading{%
+ \let\tikz=\tikzexternal@origtikz
+ \tikzexternal@TEXDIALECT@restore@picture
+ \iftikzexternal@optimize
+ \ifpgf@external@grabshipout
+ \tikzexternal@optimize@RESTORE
+ \fi
+ \fi
+}
+% re-enables externalization after a \tikzexternalizedisable.
+\def\tikzexternalenable{%
+ \if\tikzexternalize@hasbeencalled1%
+ \let\tikz=\tikzexternal@tikz@replacement
+ \tikzexternal@TEXDIALECT@installreplacement@picture
+ \pgfutil@ifundefined{tikzfadingfrompicture}%
+ {}% no special handling for 'fading lib'
+ {%
+ % oh, ok -- patch fading lib!
+ \pgfutil@ifundefined{tikzexternal@orig@tikzfadingfrompicture}{%
+ \let\tikzexternal@orig@tikzfadingfrompicture=\tikzfadingfrompicture
+ \let\tikzexternal@orig@endtikzfadingfrompicture=\endtikzfadingfrompicture
+ \let\tikzexternal@orig@tikzfading=\tikzfading
+ }{}%
+ \def\tikzfadingfrompicture{%
+ \begingroup
+ \tikzexternaldisable@nofading
+ \tikzexternal@orig@tikzfadingfrompicture}%
+ \def\endtikzfadingfrompicture{%
+ \tikzexternal@orig@endtikzfadingfrompicture
+ \endgroup}%
+ \def\tikzfading[##1]{%
+ \begingroup
+ \tikzexternaldisable@nofading
+ \tikzexternal@orig@tikzfading[##1]%
+ \endgroup}%
+ }%
+ \iftikzexternal@optimize
+ \ifpgf@external@grabshipout
+ \tikzexternal@optimize@REPLACE
+ \fi
+ \fi
+ \fi
+}%
+
+% Sets the filename for the next tikzpicture or \tikz shortcommand.
+%
+% It will *only* be used for the next picture.
+%
+% If you don't call \tikzsetnextfilename for a picture, a file name
+% will be assembled automatically.
+%
+% Please note that the global file prefix will be prepended anyway.
+\def\tikzsetnextfilename#1{\gdef\tikzexternal@nextfile{#1}}
+\tikzsetnextfilename{}
+
+
+% These are few TeX dialect-specific commands which need to be overridden when used with
+% something different than plain TeX:
+%
+% 1. this command collects a complete image into a macro, up to (but not including) the
+% final TeX-dialect specific end-image command.
+% This is really difficult for LaTeX because \end{tikzpicture} either involves dirty
+% catcode-hacks to parse the braces or an ugly loop which loops until it
+% finds \end followed by {tikzpicture}.
+%
+% #1: a macro which will be called with the collected environment contents.
+% all following tokens: the environment contents.
+\long\gdef\tikzexternal@TEXDIALECT@collectpicture#1#2\endtikzpicture{#1{#2}}
+%
+% 2. the following commands should expand to the TeX-dialect specific begin and end image command, i.e.
+% \tikzpicture / \endtikzpicture
+% or
+% \begin{tikzpicture} / \end{tikzpicture}
+% or
+% \starttikzpicture / \stoptikzpicture
+\def\tikzexternal@TEXDIALECT@begpicture{\tikzpicture}
+\def\tikzexternal@TEXDIALECT@endpicture{\endtikzpicture}%
+%
+% 3. This installs the replacement macros:
+\def\tikzexternal@TEXDIALECT@installreplacement@picture{%
+ \let\tikzpicture=\tikzexternal@tikzpicture@replacement
+}%
+\def\tikzexternal@TEXDIALECT@restore@picture{%
+ \let\tikzpicture=\tikzexternal@origpicture
+}%
+
+
+
+
+\let\tikzexternal@origtikz=\tikz
+\let\tikzexternal@origpicture=\tikzpicture
+\let\tikzexternal@origendpicture=\endtikzpicture
+\let\tikzexternal@curfilename=\relax
+
+% Replacement for '\tikzpicture'.
+%
+% There are two different states in which this method is applied:
+% - normal typesetting. Then, the 'mode' key controls its behavior.
+% - externalize mode (i.e. jobname != real job name). Then, it will
+% externalize the picture selected by 'jobname' (and only this picture).
+\def\tikzexternal@tikzpicture@replacement{%
+ \leavevmode
+ \global\tikzexternal@file@isuptodatetrue% may be set to false during checks.
+ \tikzexternal@getnextfilename\tikzexternal@curfilename
+ \ifx\tikzexternal@curfilename\pgfutil@empty
+ \ifpgf@external@grabshipout
+ % This picture won't be externalized.
+ % But maybe we can optimize it away:
+ \iftikzexternal@optimize
+ % -> it won't be shipped out anyway, so save typesetting time!
+ \let\tikzexternal@next=\tikzexternal@skipfigure
+ \else
+ % include this graphics into the output (even if
+ % it will be discarded anyway).
+ \let\tikzexternal@next=\tikzexternal@normalpicture@nographics
+ \fi
+ \else
+ \let\tikzexternal@next=\tikzexternal@normalpicture@nographics
+ \fi
+ \else
+ \ifpgf@external@grabshipout
+ \tikzifexternaljobnamematches\tikzexternal@curfilename{%
+ % ok, this here IS the picture for which
+ % pdflatex --jobname <my name>
+ % has been invoked.
+ \let\tikzexternal@next=\tikzexternal@externalizefig
+ }{%
+ \iftikzexternal@optimize
+ % No, another picture should be exported. Simply skip this one
+ % -> it won't be shipped out anyway, so save typesetting time!
+ \let\tikzexternal@next=\tikzexternal@skipfigure
+ \else
+ % include this graphics into the output (even it
+ % it will be discarded anyway).
+ \let\tikzexternal@next=\tikzexternal@normalpicture@nographics
+ \fi
+ }%
+ \else
+ \ifcase\tikzexternal@opmode\relax
+ % 'mode=only graphics'
+ \let\tikzexternal@next=\tikzexternal@forcegraphics
+ \or
+ % 'mode=no graphics'
+ \let\tikzexternal@next=\tikzexternal@normalpicture@nographics
+ \or
+ % 'mode=graphics if exists'
+ \let\tikzexternal@next=\tikzexternal@externalizefig
+ \or
+ % 'mode=list only'
+ \let\tikzexternal@next=\tikzexternal@listmodepicture
+ \or
+ % 'mode=convert with system call'
+ \let\tikzexternal@next=\tikzexternal@externalizefig@systemcall
+ \or
+ % 'mode=list and make'
+ \let\tikzexternal@next=\tikzexternal@list@and@makefile@mode@picture
+ \fi
+ \fi
+ \fi
+ \tikzexternal@next
+}%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Replacement for \tikz short command:
+\def\tikzexternal@tikz@replacement{%
+ \pgfutil@ifnextchar[{\tikzexternal@tikz@replacement@opt}{\tikzexternal@tikz@replacement@opt[]}%
+}%
+\def\tikzexternal@tikz@replacement@opt[#1]{%
+ \pgfutil@ifnextchar\bgroup{\tikzexternal@tikz@replacement@opt@{#1}}{\tikzexternal@tikz@replacement@opt@@{#1}}%
+}
+\long\def\tikzexternal@tikz@replacement@opt@#1#2{%
+ \tikzexternal@tikz@replacement@opt@process{#1}{#2}%
+}%
+\def\tikzexternal@tikz@replacement@opt@@#1{%
+ \def\tikz@next{\tikzexternal@tikz@replacement@collectnormalsemicolon{#1}}%
+ \ifnum\the\catcode`\;=\active\relax%
+ \def\tikz@next{\tikzexternal@tikz@replacement@collectactivesemicolon{#1}}%
+ \fi%
+ \tikz@next}
+\long\def\tikzexternal@tikz@replacement@collectnormalsemicolon#1#2;{%
+ \tikzexternal@tikz@replacement@opt@process{#1}{#2;}%
+}%
+{
+ \catcode`\;=\active
+ \long\gdef\tikzexternal@tikz@replacement@collectactivesemicolon#1#2;{%
+ \tikzexternal@tikz@replacement@opt@process{#1}{#2;}%
+ }
+}
+\long\def\tikzexternal@tikz@replacement@opt@process#1#2{%
+ \begingroup
+ \t@tikzexternal@tmpa=\expandafter{\tikzexternal@TEXDIALECT@begpicture[#1]#2}%
+ \t@tikzexternal@tmpb=\expandafter{\tikzexternal@TEXDIALECT@endpicture}%
+ \xdef\pgf@tempa{\the\t@tikzexternal@tmpa\the\t@tikzexternal@tmpb}%
+ \endgroup
+ \pgf@tempa
+}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def\tikzexternal@getnextfilename@advancecount{%
+ \begingroup
+ \c@pgf@counta=\csname c@tikzext@no@\tikzexternal@figurename\endcsname\relax
+ \advance\c@pgf@counta by1
+ \expandafter\xdef\csname c@tikzext@no@\tikzexternal@figurename\endcsname{\the\c@pgf@counta}%
+ \endgroup
+}%
+
+% Returns the file name which will be used for the next tikzpicture (based on the currently available information only, of course).
+\def\tikzexternalgetnextfilename#1{%
+ \begingroup
+ \let\tikzexternal@getnextfilename@advancecount\relax% NOP
+ \let\tikzexternal@getnextfilename@resetglobals=\relax% NOP
+ \def\tikzexternal@protocol@to@file##1{}% NOP
+ \tikzexternal@getnextfilename#1%
+ \pgfmath@smuggleone#1%
+ \endgroup
+}%
+
+% Returns the file name of the current picture.
+%
+% It returns the empty string in case the command is invoked outside
+% of a picture.
+% #1 the macro which will contain the file name.
+% @see \tikzexternalgetnextfilename
+\def\tikzexternalgetcurrentfilename#1{%
+ \ifx\tikzexternal@curfilename\relax
+ % we are outside of a picture.
+ \let#1=\pgfutil@empty
+ \else
+ % we are inside of a picture.
+ \let#1=\tikzexternal@curfilename
+ \fi
+}
+
+% Fills #1 with a filename for the current picture.
+%
+% The filename will be generated automatically by appending '-figure<number>' to the real jobname.
+%
+% This method deals with
+% - \tikzsetnextfilename
+% - \tikzexternalexportnextfalse
+%
+% It returns #1={} if the current figure shall NOT be exported.
+%
+% Please note that both, \tikzsetnextfilename and \tikzexternalexportnextfalse
+% affect only ONE picture. They will be reset afterwards.
+\def\tikzexternal@getnextfilename#1{%
+ \let#1=\pgfutil@empty
+ % determine next file name:
+ \iftikzexternal@export@enabled
+ \iftikzexternalexportnext
+ \begingroup
+ \t@tikzexternal@tmpa=\expandafter{\tikzexternal@filenameprefix}%
+ \ifx\tikzexternal@nextfile\pgfutil@empty
+ \iftikzexternal@onlynamed
+ \xdef\pgf@tempa{}%
+ \else
+ \pgfkeysgetvalue{/tikz/external/figure name}\tikzexternal@figurename
+ \pgfutil@ifundefined{c@tikzext@no@\tikzexternal@figurename}{%
+ % initialise on first usage:
+ \expandafter\gdef\csname c@tikzext@no@\tikzexternal@figurename\endcsname{0}%
+ }{}%
+ \t@tikzexternal@tmpb=\expandafter{\tikzexternal@figurename}%
+ \xdef\pgf@tempa{\the\t@tikzexternal@tmpa\the\t@tikzexternal@tmpb\csname c@tikzext@no@\tikzexternal@figurename\endcsname}%
+ % advance the counter for 'figure name':
+ \tikzexternal@getnextfilename@advancecount
+ \fi
+ \else
+ \t@tikzexternal@tmpb=\expandafter{\tikzexternal@nextfile}%
+ \xdef\pgf@tempa{\the\t@tikzexternal@tmpa\the\t@tikzexternal@tmpb}%
+ \fi
+ \endgroup
+ \let#1=\pgf@tempa
+ \fi
+ \fi
+ %
+ \tikzexternal@getnextfilename@resetglobals%
+ %
+ \tikzexternal@protocol@to@file#1%
+}%
+
+\def\tikzexternal@getnextfilename@resetglobals{%
+ % Reset global flags:
+ \global\let\tikzexternal@nextfile=\pgfutil@empty
+ \global\tikzexternalexportnexttrue
+}%
+
+% #1: the image file name which should be protocolled. (can be a
+% macro)
+\def\tikzexternal@protocol@to@file#1{%
+ \ifpgf@external@grabshipout%
+ \else
+ \iftikzexternal@genfigurelist
+ \edef\tikzexternal@temp{#1}%
+ \ifx\tikzexternal@temp\pgfutil@empty
+ \else
+ \pgfutil@ifundefined{tikzexternal@listmode@openedfile}{%
+ \message{Opening '\tikzexternal@realjob.figlist' for writing.}%
+ \begingroup
+ \globaldefs=1
+ % this gets round '\outer\newwrite' in plain TeX:
+ \csname newwrite\endcsname\tikzexternal@outfile
+ \endgroup
+ \immediate\openout\tikzexternal@outfile=\tikzexternal@realjob.figlist\relax
+ \gdef\tikzexternal@listmode@openedfile{1}%
+ \if\tikzexternal@opmode5% mode='list and make'
+ \tikzexternal@list@and@make@prepare
+ \fi
+ }{}%
+ \iftikzexternal@verboseio
+ \pgf@typeout{Writing '#1' to '\tikzexternal@realjob.figlist'.}%
+ \fi
+ \immediate\write\tikzexternal@outfile{#1}%
+ \if\tikzexternal@opmode5% mode='list and make'
+ \tikzexternal@list@and@make@gentarget{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+}%
+
+\def\tikzexternal@list@and@make@gentarget#1{%
+ \tikzexternal@assemble@systemcall{#1}{\pgf@tempa}%
+ \def\tikzexternal@tempb{\pgfutilstrreplace{^^J}{^^J\tikzexternal@TABchar}}%
+ \expandafter\tikzexternal@tempb\expandafter{\pgf@tempa}%
+ \let\pgf@tempa=\pgfretval
+ \iftikzexternal@verboseio
+ \pgf@typeout{Writing '#1' to '\tikzexternal@realjob.makefile'.}%
+ \fi
+ \global\tikzexternal@file@isuptodatetrue% only check for force remake:
+ \tikzexternal@checkforceremake%
+ \immediate\write\tikzexternal@outmakefile{#1\tikzexternalimgextension: \iftikzexternal@file@isuptodate\else FORCEREMAKE\fi}%
+ \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar\pgf@tempa}%
+ \immediate\write\tikzexternal@outmakefile{}%
+}
+
+\def\tikzexternal@list@and@make@prepare{%
+ \iftikzexternal@verboseio
+ \pgf@typeout{Opening '\tikzexternal@realjob.makefile' for writing.}%
+ \fi
+ \begingroup
+ % this makes \tikzexternal@outmakefile global:
+ \globaldefs=1
+ % this gets round '\outer\newwrite' in plain TeX:
+ \csname newwrite\endcsname\tikzexternal@outmakefile
+ \endgroup
+ \immediate\openout\tikzexternal@outmakefile=\tikzexternal@realjob.makefile\relax
+ \immediate\write\tikzexternal@outmakefile{ALL_FIGURE_NAMES=\tikzexternal@DOLLARchar(shell cat \tikzexternal@realjob.figlist)}%
+ \immediate\write\tikzexternal@outmakefile{ALL_FIGURES=\tikzexternal@DOLLARchar(ALL_FIGURE_NAMES:\tikzexternal@PERCENTchar=\tikzexternal@PERCENTchar\tikzexternalimgextension)}%
+ \immediate\write\tikzexternal@outmakefile{}%
+ \immediate\write\tikzexternal@outmakefile{allimages: \tikzexternal@DOLLARchar(ALL_FIGURES)}%
+ \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar @echo All images exist now. Use make -B to re-generate them.}%
+ \immediate\write\tikzexternal@outmakefile{}%
+ \immediate\write\tikzexternal@outmakefile{FORCEREMAKE:}%
+ \immediate\write\tikzexternal@outmakefile{}%
+ %
+ % support for .dep files and auto-dependencies:
+ \immediate\write\tikzexternal@outmakefile{-include $(ALL_FIGURE_NAMES:\tikzexternal@PERCENTchar=\tikzexternal@PERCENTchar.\tikzexternaldepext)}%
+ \immediate\write\tikzexternal@outmakefile{}%
+ \tikzexternalmakefiledefaultdeprule
+ \immediate\write\tikzexternal@outmakefile{}%
+ \tikzexternal@outmakefile@pendingcommands
+ \pgfutil@ifundefined{AtEndDocument}{}{%
+ \AtEndDocument{\pgf@typeout{===== mode=`list and make': Use 'make -f \tikzexternal@realjob.makefile' to generate all images. Then, re-run (pdf)latex \tikzexternal@realjob. =====}}%
+ }%
+}%
+\def\tikzexternaldepext{dep}
+
+\def\tikzexternalmakefiledefaultdeprule{%
+ \immediate\write\tikzexternal@outmakefile{\tikzexternal@PERCENTchar.\tikzexternaldepext:}%
+ \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar mkdir -p \tikzexternal@normal@dq $(dir $@)\tikzexternal@normal@dq}%
+ \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar touch \tikzexternal@normal@dq $@\tikzexternal@normal@dq\space \tikzexternal@HASHchar\space will be filled later.}%
+}%
+
+% Invokes '#1' if a makefile is to be written and '#2' if not.
+\def\tikzexternalifwritesmakefile#1#2{%
+ \if5\tikzexternal@opmode #1\else #2\fi
+}%
+\def\tikzexternal@outmakefile@pendingcommands{}%
+
+% Will write something to the make file. If the makefile is not yet
+% opened, #1 will be written as soon as it *is* opened.
+\def\tikzexternalwritetomakefile#1{%
+ \if\tikzexternal@opmode5% mode='list and make'
+ \pgfutil@ifundefined{tikzexternal@outmakefile}{%
+ \expandafter\gdef\expandafter\tikzexternal@outmakefile@pendingcommands\expandafter{%
+ \tikzexternal@outmakefile@pendingcommands
+ \immediate\write\tikzexternal@outmakefile{#1}%
+ }%
+ }{%
+ \immediate\write\tikzexternal@outmakefile{#1}%
+ }%
+ \fi
+}%
+
+\def\tikzexternal@dep@file@name{}
+
+% Adds a dependency for the externalized picture file name `#1',
+% namely another file `#2'.
+%
+% #1: the fully qualified path name (without image extension) of the
+% external graphics for which we are adding a dependency.
+% #2: a file name. If this file gets changed, #1 shall be remade.
+%
+% This command will be activated as soon as \tikzexternalize has been
+% called.
+\def\tikzexternalfiledependsonfile@ACTIVE#1#2{%
+ \begingroup
+ \def\tikzpicturedependsonfile@name{#1}%
+ \ifx\tikzpicturedependsonfile@name\pgfutil@empty
+ % could be auto-generated: empty file name means "picture
+ % won't be externalized". Skip it.
+ \else
+ % if we encounter any dependencies while we externalize a
+ % picture, we have to write these things into the image's .dep
+ % file.
+ \tikzifexternalizingcurrent
+ {\tikzexternalfiledependsonfile@append@to@dep@file{#1}{#2}}%
+ {\tikzexternalfiledependsonfile@append@to@makefile{#1}{#2}}%
+ \fi
+ \endgroup
+}%
+\def\tikzexternalfiledependsonfile#1#2{}% NO-OP until \tikzexternalize has been called.
+
+% sub-routine of \tikzexternalfiledependsonfile which appends stuff to
+% the pictures .dep file.
+%
+% The file #1.dep is generated during the externalization of #1. If
+% you change and/or overwrite it in any other context, its information
+% might get lost (because #1 won't be regenerated).
+%
+% Consequently, this here has to be called if and only if #1 is about
+% to be externalized.
+\def\tikzexternalfiledependsonfile@append@to@dep@file#1#2{%
+ % write every dependency which is defined *INSIDE* of the current
+ % picture into the .dep file of the current picture:
+ \tikzexternalgetcurrentfilename\tikzpicturedependsonfile@name
+ \edef\tikzpicturedependsonfile@name{\tikzpicturedependsonfile@name.\tikzexternaldepext}%
+ %\edef\tikzpicturedependsonfile@name{#1.\tikzexternaldepext}%
+ \ifx\tikzexternal@dep@file@name\tikzpicturedependsonfile@name
+ % file is open and ready.
+ \else
+ % create new output file.
+ \pgfutil@ifundefined{tikzexternal@dep@file}{%
+ \begingroup
+ % this makes \tikzexternal@dep@file global:
+ \globaldefs=1
+ % this gets round '\outer\newwrite' in plain TeX:
+ \csname newwrite\endcsname\tikzexternal@dep@file
+ \endgroup
+ }{}%
+ \ifx\tikzexternal@dep@file@name\pgfutil@empty
+ \else
+ % it is already open. Close it.
+ \immediate\closeout\tikzexternal@dep@file
+ \fi
+ \global\let\tikzexternal@dep@file@name=\tikzpicturedependsonfile@name
+ \immediate\openout\tikzexternal@dep@file=\tikzexternal@dep@file@name\relax
+ \fi
+ \immediate\write\tikzexternal@dep@file{#1\tikzexternalimgextension: #2}%
+}
+
+% sub-routine of \tikzexternalfiledependsonfile which appends stuff to
+% the makefile of the current \jobname .
+%
+% This is used for dependencies which are recomputed by every run of
+% tex; we must not write them into #1.dep (for reasons explained in
+% the documentation of
+% \tikzexternalfiledependsonfile@append@to@dep@file)
+\def\tikzexternalfiledependsonfile@append@to@makefile#1#2{%
+ \edef\tikzexternal@temp{#1\tikzexternalimgextension: #2}%
+ \expandafter\tikzexternalwritetomakefile\expandafter{\tikzexternal@temp}%
+}
+
+% Adds a dependency for the NEXT picture which is about to be
+% externalized. If we are currently inside of a picture, the
+% dependency is added for this current picture.
+%
+% #1: a file name. If this file gets changed, the tikzpicture's
+% externalized graphics shall be remade.
+%
+% This command will be activated as soon as \tikzexternalize has been
+% called.
+\def\tikzpicturedependsonfile@ACTIVE#1{%
+ \begingroup
+ \tikzexternalgetcurrentfilename\tikzpicturedependsonfile@name
+ \ifx\tikzpicturedependsonfile@name\pgfutil@empty
+ \tikzexternalgetnextfilename\tikzpicturedependsonfile@name
+ \fi
+ \expandafter\tikzexternalfiledependsonfile\expandafter{\tikzpicturedependsonfile@name}{#1}%
+ \endgroup
+}%
+\def\tikzpicturedependsonfile#1{}% NO-OP until \tikzexternalize has been called.
+
+
+% This command is invoked
+% if and only if ( (grab mode && --jobname matches) || 'mode=graphics if exists' )
+%
+% It converts the current tikzpicture into an image in grab mode
+% or processes the 'graphics if exist' mode.
+\def\tikzexternal@externalizefig{%
+ \ifpgf@external@grabshipout%
+ % In this case, we already KNOW that the filename matches.
+ \expandafter\tikzexternal@externalizefig@GRAB%
+ \else
+ \expandafter\tikzexternal@externalizefig@mode@graphics@if@exists
+ \fi%
+}
+\def\tikzexternal@externalizefig@mode@graphics@if@exists{%
+ % check if there is already a file.
+ % In that case, use it. If not, typeset the picture normally.
+ \gdef\pgf@filename{}%
+ \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}%
+ \pgf@tempa
+ \ifx\pgf@filename\pgfutil@empty%
+ % Note: since we have no 'GRAB' mode, we do not have to deal with optimization.
+ % there is no graphics.
+ \expandafter\tikzexternal@normalpicture@nographics
+ \else
+ \expandafter\tikzexternal@forcegraphics
+ \fi
+}%
+
+
+% Used by the optimization code.
+% It will be called if GRAB mode is on.
+% See the 'optimize command away' key.
+\def\tikzexternal@optimize@away@cmd#1#2{%
+ \pgfutil@ifnextchar[{%
+ \tikzexternal@optimize@away@cmd@{#1}{#2}%
+ }{%
+ \tikzexternal@optimize@away@cmd@{#1}{#2}[]%
+ }%
+}%
+\def\tikzexternal@optimize@away@cmd@#1#2[#3]{%
+ \def\tikz@temp{#2}%
+ \ifx\tikz@temp\pgfutil@empty
+ \def\tikz@temp{\tikzexternal@optimize@away@cmd@auto{#1}{#3}}%
+ \else
+ \ifcase#2\relax
+ \def\tikzexternal@optimize@away@cmd@manual{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2##3{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}{##3}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2##3##4{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}{##3}{##4}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2##3##4##5{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}{##3}{##4}{##5}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2##3##4##5##6{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}{##3}{##4}{##5}{##6}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2##3##4##5##6##7{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2##3##4##5##6##7##8{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}}%
+ }%
+ \or
+ \def\tikzexternal@optimize@away@cmd@manual##1##2##3##4##5##6##7##8##9{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#3}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}}%
+ }%
+ \fi
+ \def\tikz@temp{\tikzexternal@optimize@away@cmd@manual}%
+ \fi
+ \tikz@temp
+}%
+\def\tikzexternal@optimize@away@cmd@auto#1#2{%
+ \pgfutil@ifnextchar\bgroup{%
+ \tikzexternal@optimize@away@cmd@auto@{#1}{#2}%
+ }{%
+ \tikzexternal@optimize@away@cmd@auto@{#1}{#2}{<no argument in curly braces>}% give empty argument.
+ }
+}%
+
+\def\tikzexternal@optimize@away@cmd@auto@#1#2#3{%
+ \tikzexternal@optimize@away@cmd@@@{#1}{#2}{{#3}}% <-- provide braces
+}%
+\def\tikzexternal@optimize@away@cmd@@@#1#2#3{%
+ \begingroup
+ \toks0={#1[#2]#3}%
+ \iftikzexternal@verbose@optimize
+ \pgf@typeout{The command '\the\toks0' has been optimized away. Use '/tikz/external/optimize=false' to disable this.}%
+ \fi
+ \endgroup
+ \begingroup
+ \pgfkeysvalueof{/tikz/external/optimize away text/.@cmd}#1\pgfeov%
+ \endgroup
+}%
+
+\def\tikzexternal@optimize@away@latex@env#1{%
+ \def\tikzexternal@optimize@away@latex@env@{#1}%
+ \begingroup
+ \def\tikzexternal@laTeX@collect@until@end@tikzpicturetikzpicturestring{#1}%
+ \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@optimize@away@latex@env@close
+}%
+\long\def\tikzexternal@optimize@away@latex@env@close#1{%
+ \iftikzexternal@verbose@optimize
+ \pgf@typeout{The complete contents of \string\begin{tikzexternal@optimize@away@latex@env@} up to the next \end{tikzexternal@optimize@away@latex@env@} has been optimized away because it does not contribute to the exported PDF. Use '/tikz/external/optimize=false' to disable this.}%
+ \fi
+ \endgroup
+ % we still need to invoke \end{<name>} in latex because \begin{<name>}
+ % starts a local group - that must be closed properly. Make sure then \end<name> does nothing:
+ \expandafter\let\csname end\tikzexternal@optimize@away@latex@env@\endcsname=\relax
+ \expandafter\end\expandafter{\tikzexternal@optimize@away@latex@env@}%
+}%
+
+\def\tikzexternal@optimize@REPLACE{%
+ \pgfkeysvalueof{/tikz/external/optimize/install/.@cmd}\pgfeov
+}%
+
+\def\tikzexternal@optimize@RESTORE{%
+ \pgfkeysvalueof{/tikz/external/optimize/restore/.@cmd}\pgfeov
+}%
+
+% Closes one 'tikzpicture' environment. This is only used for LaTeX,
+% because the '\end{tikzpicture}' command would raise an exception otherwise.
+% It does *not* call \endtikzpicture.
+\def\tikzexternal@closeenvironments{%
+ \let\endtikzpicture=\relax
+ \tikzexternal@TEXDIALECT@endpicture
+ \let\endtikzpicture=\tikzexternal@origendpicture
+ \let\tikzexternal@curfilename=\relax
+}
+
+% Throws a tikzpicture away - without further notice.
+% Used if we are currently converting *another* picture. No need to waste time
+% with expensive pictures if they are not shipped out anyway.
+%
+% See the 'optimize' key to disable this.
+\def\tikzexternal@skipfigure{%
+ \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@skipfigure@@
+}
+\long\def\tikzexternal@skipfigure@@#1{%
+ \iftikzexternal@verbose@optimize
+ \pgf@typeout{A tikzpicture has been optimized away. Use '/tikz/external/optimize=false' to disable this.}%
+ \fi
+ \tikzexternal@closeenvironments
+ \pgfkeysvalueof{/tikz/external/optimize away text/.@cmd}tikzpicture\pgfeov%
+}
+
+% Processes tikzpicture normally; without any externalization.
+%
+% We need to do further work here to deal with NESTED tikzpicture environments
+% because all of them shall also be typeset normally.
+%
+% Idea:
+% 1. restore the original \tikzpicture macro
+% 2. install the replacement \tikzpicture in \end{tikzpicture}.
+% and keep track of nesting.
+%
+% FIXME: could it be possible that nested tikzpictures use other code anyway?
+\def\tikzexternal@normalpicture@nographics{%
+ \tikzexternal@nestedflagfalse
+ \let\tikzpicture=\tikzexternal@normalpicture@begreplace
+ \let\endtikzpicture=\tikzexternal@normalpicture@endreplace
+ \tikzpicture
+}
+\def\tikzexternal@normalpicture@begreplace{%
+ \begingroup
+ \tikzexternal@nestedflagtrue
+ \tikzexternal@origpicture
+}
+\def\tikzexternal@normalpicture@endreplace{%
+ \tikzexternal@origendpicture
+ \endgroup
+ \iftikzexternal@nestedflag
+ \else
+ \let\tikzpicture=\tikzexternal@tikzpicture@replacement
+ \let\endtikzpicture=\tikzexternal@origendpicture
+ \fi
+}%
+
+% Assumes there is an image on disk and reads it. The tikzpicture is thrown away.
+\def\tikzexternal@forcegraphics{%
+ \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@forcegraphics@@
+}
+\long\def\tikzexternal@forcegraphics@@#1{\tikzexternal@forcegraphics@@@}%
+\def\tikzexternal@forcegraphics@@@{%
+ \if5\tikzexternal@opmode
+ \let\tikz@refundefinedtrue@@=\G@refundefinedtrue
+ \gdef\G@refundefinedtrue{%
+ \tikz@refundefinedtrue@@
+ \tikzexternal@forceremake@undefined@reference@handler
+ }%
+ \fi
+ \expandafter\pgfincludeexternalgraphics\expandafter{\tikzexternal@curfilename}%
+ \if5\tikzexternal@opmode
+ \global\let\G@refundefinedtrue=\tikz@refundefinedtrue@@
+ \fi
+ \tikzexternal@closeenvironments
+}
+
+\def\tikzexternal@forceremake@undefined@reference@handler{%
+ \pgf@typeout{===== 'mode=list and make': encountered undefined reference in current picture. Adding dependency to FORCEREMAKE. Rerun make to update the picture.' ========^^J}%
+ \tikzpicturedependsonfile{FORCEREMAKE}%
+}%
+
+% Simply replaces the complete picture by some placeholder text.
+% It is used by 'mode=list only' to reduce runtime.
+\def\tikzexternal@listmodepicture{%
+ \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@listmodepicture@@
+}
+\long\def\tikzexternal@listmodepicture@@#1{\tikzexternal@listmodepicture@@@}
+\def\tikzexternal@listmodepicture@@@{%
+ \pgfkeysvalueof{/tikz/external/image discarded text}%
+ \tikzexternal@closeenvironments
+}
+
+% check if there is already a file.
+% In that case, use it. If not, skip it.
+\def\tikzexternal@list@and@makefile@mode@picture{%
+ \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@list@and@makefile@mode@picture@
+}%
+\long\def\tikzexternal@list@and@makefile@mode@picture@#1{%
+ %
+ \tikzexternal@check@uptodate@mode{#1}%
+ %
+ \gdef\pgf@filename{}%
+ \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}%
+ \pgf@tempa
+ \ifx\pgf@filename\pgfutil@empty%
+ % Note: since we have no 'GRAB' mode, we do not have to deal with optimization.
+ % there is no graphics.
+ \expandafter\tikzexternal@listmodepicture@@@
+ \else
+ \expandafter\tikzexternal@forcegraphics@@@
+ \fi
+}%
+
+\def\tikzexternal@externalizefig@before@grab{%
+ \pgfutil@IfUndefined{TP@holdbox}{%
+ }{%
+ % \usepackage[absolute]{textpos}
+ % populates this box -- and would inject unwanted material into our images. Reset it:
+ \global\setbox\TP@holdbox\vbox{}%
+ }%
+}%
+
+\def\tikzexternal@externalizefig@GRAB{%
+ \ifpgf@external@grabshipout
+ \iftikzexternal@optimize
+ \tikzexternal@optimize@RESTORE
+ \fi
+ \tikzexternal@externalizefig@before@grab
+ \fi
+ \def\tikzpicture{%
+ \def\tikzpicture{% make sure that nested \tikzpicture are processed normally.
+ \begingroup
+ \def\endtikzpicture{%
+ \tikzexternal@origendpicture
+ \endgroup
+ }%
+ \tikzexternal@origpicture
+ }%
+ \pgf@external@grab{\tikzexternal@curfilename}%
+ \tikzexternal@origpicture
+ }%
+ \def\endtikzpicture{%
+ \tikzexternal@origendpicture
+ \pgf@externalend
+ %
+ \tikzexternal@ensure@nonempty@floats
+ %
+ \let\tikzpicture=\tikzexternal@tikzpicture@replacement
+ \let\endtikzpicture=\tikzexternal@origendpicture
+ \iftikzexternal@optimize
+ \ifpgf@external@grabshipout
+ \tikzexternal@optimize@REPLACE
+ \fi
+ \fi
+ }%
+ \tikzpicture
+}%
+
+% If a sequence of floats containing JUST tikzpictures is
+% externalized, this results in EMPTY floats. Empty floats, in turn,
+% can confuse latex; it thinks it did something wrong.
+%
+% Solution: Avoid empty floats by writing junk into it.
+%
+% Note that this method is only invoked if \ifpgf@external@grabshipout
+% is true and if the text is OUTSIDE of the original shipout routine.
+% In other words: this text is being thrown away.
+%
+% see
+% http://tex.stackexchange.com/questions/54625/why-is-fixltx2e-incompatible-with-tikzexternalize
+\def\tikzexternal@ensure@nonempty@floats{%
+ tikzexternal: picture has been externalized. This text is required to avoid empty floats.
+}%
+
+% 1. Discards the current picture in this document.
+% 2. Checks whether an image exists already. If that is the case: acquire it.
+% 3. If no image exists: call '/tikz/external/system call'. This will
+% process \tikzexternal@externalizefig.
+% 4. Assert that finally an image exists and use it.
+\def\tikzexternal@externalizefig@systemcall{%
+ \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@externalizefig@systemcall@@
+}
+
+{
+\catcode`\"=12
+\catcode`\'=12
+\catcode`\;=12
+\catcode`\&=12
+\catcode`\-=12
+\xdef\tikzexternal@normal@dq{"}
+\xdef\tikzexternal@normal@sq{'}
+\xdef\tikzexternal@normal@semic{;}
+\xdef\tikzexternal@normal@and{&}
+\xdef\tikzexternal@normal@dash{-}
+\catcode`\"=13
+\catcode`\'=13
+\catcode`\;=13
+\catcode`\&=13
+\catcode`\-=13
+\gdef\tikzexternal@activate@normal@dq{\let"=\tikzexternal@normal@dq}
+\gdef\tikzexternal@activate@normal@sq{\let'=\tikzexternal@normal@sq}
+\gdef\tikzexternal@activate@normal@semic{\let;=\tikzexternal@normal@semic}
+\gdef\tikzexternal@activate@normal@and{\let&=\tikzexternal@normal@and}
+\gdef\tikzexternal@activate@normal@dash{\let-=\tikzexternal@normal@dash}
+\catcode`\|=0
+\catcode`\\=12
+|xdef|tikzexternal@normal@backslash{\}%
+}
+{
+\catcode`\^^I=12
+\catcode`\$=12
+\catcode`\%=12
+\catcode`\#=12
+\gdef\tikzexternal@HASHchar{#}
+\gdef\tikzexternal@TABchar{^^I}\gdef\tikzexternal@PERCENTchar{%}\xdef\tikzexternal@DOLLARchar{$}}
+
+% Creates the '/tikz/external/system call' command as string and
+% returns it into the (global!) macro #2.
+% #1: the image file name (as returned by
+% \tikzexternalgetnextfilename)
+% #2: the global return value macro
+%
+\def\tikzexternal@assemble@systemcall#1#2{%
+ \begingroup
+ \def\image{#1}%
+ \iftikzexternal@auto@detect@jobname
+ \edef\texsource{\string\def\string\tikzexternalrealjob{\tikzexternal@realjob}\string\input{\tikzexternal@realjob}}%
+ \else
+ \let\texsource=\tikzexternal@realjob
+ \fi
+ \ifnum\the\catcode`\"=13 \tikzexternal@activate@normal@dq\fi
+ \ifnum\the\catcode`\'=13 \tikzexternal@activate@normal@sq\fi
+ \ifnum\the\catcode`\;=13 \tikzexternal@activate@normal@semic\fi
+ \ifnum\the\catcode`\-=13 \tikzexternal@activate@normal@dash\fi
+ \let\\=\tikzexternal@normal@backslash
+ \xdef#2{\pgfkeysvalueof{/tikz/external/system call}}%
+ \endgroup
+}%
+\long\def\tikzexternal@externalizefig@systemcall@@#1{%
+ \tikzexternal@externalizefig@systemcall@uptodatecheck{#1}%
+ \tikzexternal@assemble@systemcall{\tikzexternal@curfilename}{\pgf@tempa}%
+ \global\let\tikzexternal@cursyscall=\pgf@tempa
+ \gdef\tikzexternal@typeset@picture@on@failure{1}%
+ \iftikzexternal@file@isuptodate
+ \iftikzexternal@verboseio
+ \pgf@typeout{===== Image '\tikzexternal@curfilename' is up-to-date. ======}%
+ \fi
+ \let\pgf@filename=\tikzexternal@curfilename
+ \else
+ \begingroup
+ % no such image. Generate it!
+ %
+ \tikzexternalauxlock@setlock1%
+ \tikzexternal@externalizefig@systemcall@call{\tikzexternal@cursyscall}%
+ \tikzexternalauxlock@setlock0%
+ \expandafter\tikzexternal@externalizefig@systemcall@assertsuccess\expandafter{\tikzexternal@cursyscall}%
+ \pgfmath@smuggleone\pgf@filename
+ \endgroup
+ \fi
+ \ifx\pgf@filename\pgfutil@empty
+ \if1\tikzexternal@typeset@picture@on@failure
+ % error recovery: something did not work! Try to load it
+ % anyway. Perhaps it was just that shell-escape wasn't
+ % enabled.
+ \begingroup
+ \toks0={%
+ \tikzexternaldisable
+ }%
+ % FIXME : THIS WILL FAIL IF THERE IS '##' INSIDE OF '#1'!
+ % for example something like /.style={#1} in the picture environment *will* fail.
+ \toks1={%
+ \tikzpicture
+ #1%
+ }%
+ \toks2={%
+ \tikzexternal@TEXDIALECT@endpicture
+ \tikzexternalenable
+ }%
+ \xdef\tikzexternal@externalizefig@systemcall@next{%
+ \the\toks0
+ % try reading them again as if they were in the input file.
+ \noexpand\scantokens{\the\toks1 }%
+ \the\toks2
+ }%
+ \endgroup
+ \else
+ % Ah -- this picture failed, but the failure has already
+ % been handled somehow. Do not typeset it again!
+ %
+ % A use-case is that the picture has been rescheduled for
+ % \end{document}.
+ \gdef\tikzexternal@externalizefig@systemcall@next{\tikzexternal@closeenvironments}%
+ \fi
+ \else
+ % ok, take the image!
+ \gdef\tikzexternal@systemcall@reschedule@to@end@document{0}%
+ \expandafter\pgfincludeexternalgraphics\expandafter{\tikzexternal@curfilename}%
+ \if1\tikzexternal@systemcall@reschedule@to@end@document
+ \pgfutil@IfUndefined{AtVeryEndDocument}{%
+ }{%
+ \pgf@typeout{===== The previous system call resulted in undefined references inside of the output file. Rescheduling it for \string\end{document}. ========}%
+ \expandafter\tikzexternal@externalizefig@systemcall@reschedule\expandafter{\tikzexternal@cursyscall}%
+ }%
+ \fi
+ \gdef\tikzexternal@externalizefig@systemcall@next{\tikzexternal@closeenvironments}%
+ \fi
+ \tikzexternal@externalizefig@systemcall@next
+}%
+
+\def\tikzexternal@externalizefig@systemcall@call#1{%
+ \iftikzexternal@verboseio
+ \pgf@typeout{===== 'mode=convert with system call': Invoking '#1' ========}%
+ \fi
+ \pgfutil@shellescape{#1}%
+}%
+
+% Sets \iftikzexternal@file@isuptodate to false if one of the "force
+% remake" things is active.
+\def\tikzexternal@checkforceremake{%
+ \iftikzexternal@force@remake
+ \global\tikzexternal@file@isuptodatefalse
+ \else
+ \iftikzexternalremakenext
+ \global\tikzexternal@file@isuptodatefalse
+ \global\tikzexternalremakenextfalse
+ \fi
+ \fi
+}
+
+\pgfutil@IfUndefined{pdfmdfivesum}{%
+}{%
+ % predefine to this value. This does only make sense for pdftex.
+ % note that the latex library for 'external' loads \usepackage{pdftexcmds} which \let's this to \pdf@mdfivesum:
+ \let\tikzexternal@mdfivesum=\pdfmdfivesum
+}%
+
+\long\def\tikzexternal@computemdfivesum#1{%
+ \t@tikzexternal@tmpb={#1}%
+ \edef\tikzexternal@temp{\the\t@tikzexternal@tmpb}%
+ % \meaning results in a string of catcode 12 - which is expandable.
+ \edef\pgfretval{\tikzexternal@mdfivesum{\meaning\tikzexternal@temp}}%
+}
+\long\def\tikzexternal@computemdfivesum@diff@fallback#1{%
+ \t@tikzexternal@tmpb={#1}%
+ \edef\tikzexternal@temp{\the\t@tikzexternal@tmpb}%
+ % \meaning results in a string of catcode 12 - which is expandable.
+ \edef\pgfretval{\meaning\tikzexternal@temp}%
+}
+
+% Will be set dynamically, depending on 'up to date check'.
+%
+% It expands to code such that \tikzexternallastkey contains the
+% serialized version of '#1'.
+%
+% It is used as argument for \write{..}
+%
+% #1 the hash key to serialize.
+% \def\tikzexternal@hashfct@serialize
+\long\def\tikzexternal@hashfct@serialize@std#1{%
+ \noexpand\def\noexpand\tikzexternallastkey{#1}%
+}%
+
+% serializes using temporary token registers. Necessary if #1 contains
+% executable code.
+\long\def\tikzexternal@hashfct@serialize@tok#1{%
+ \noexpand\begingroup
+ % in order to allow '#' inside of the body, we have to use token registers:
+ \noexpand\toks0={#1}%
+ \noexpand\xdef\noexpand\tikzexternallastkey{\noexpand\the\noexpand\toks0 }%
+ \noexpand\endgroup
+}%
+
+\def\tikzexternal@check@uptodate@ext{.md5}
+
+\def\tikzexternal@check@uptodate@mode@warn@fallback{%
+ \message{Package tikz Warning: The key 'up to date check=md5' is impossible, there is no macro to compute MD5. Falling back to 'up to date check=diff'.}%
+ %
+ % warn only once:
+ \global\let\tikzexternal@check@uptodate@mode@warn@fallback=\relax
+}%
+
+% assigns the boolean \iftikzexternal@file@isuptodate
+\long\def\tikzexternal@check@uptodate@mode#1{%
+ \if1\tikzexternal@uptodate@mode
+ % up to date check=md5:
+ % check if we CAN compute MD5 sums:
+ \pgfutil@IfUndefined{tikzexternal@mdfivesum}{%
+ % we cannot compute md5 sums - fallback to diff.
+ \tikzexternal@check@uptodate@mode@warn@fallback
+ \def\tikzexternal@uptodate@mode{2}%
+ }{}%
+ \fi
+ %
+ \ifcase\tikzexternal@uptodate@mode
+ % up to date check=simple
+ % nothing to do -- file existence is checked anyway.
+ \let\tikzexternal@hashfct=\pgfutil@empty
+ \let\tikzexternal@hashfct@serialize=\pgfutil@empty
+ \or
+ % up to date check=md5
+ \let\tikzexternal@hashfct=\tikzexternal@computemdfivesum
+ \let\tikzexternal@hashfct@serialize=\tikzexternal@hashfct@serialize@std
+ \or
+ \let\tikzexternal@hashfct=\tikzexternal@computemdfivesum@diff@fallback
+ \let\tikzexternal@hashfct@serialize=\tikzexternal@hashfct@serialize@tok
+ \fi
+ \ifx\tikzexternal@hashfct\pgfutil@empty
+ \else
+ \tikzpicturedependsonfile{\tikzexternal@curfilename\tikzexternal@check@uptodate@ext}%
+ \tikzexternal@hashfct{#1}%
+ \let\tikzexternal@lastkey@new=\pgfretval
+ \begingroup
+ % no '@' token in this macro: avoid messing up the catcodes in input files:
+ \global\let\tikzexternallastkey=\pgfutil@empty
+ \openin\r@pgf@reada=\tikzexternal@curfilename\tikzexternal@check@uptodate@ext\relax %
+ \ifeof\r@pgf@reada
+ \else
+ % read first line...
+ \endlinechar=-1 % older versions did not have a '%' at the end-of-line. Avoid spurious spaces.
+ \read\r@pgf@reada to\pgf@tempa
+ % ... and execute it.
+ \pgf@tempa
+ % it should contain a definition of \tikzexternallastkey.
+ \fi
+ \closein\r@pgf@reada
+ %
+ \let\tikzexternal@lastkey=\tikzexternallastkey
+ \pgfmath@smuggleone\tikzexternal@lastkey
+ \endgroup
+ % normalize catcodes. Unfortunately, they cannot be expected to be the same.
+ % \meaning will use catcode 12 for each token:
+ \edef\tikzexternal@lastkey@normalized{\meaning\tikzexternal@lastkey}%
+ \edef\tikzexternal@lastkey@new@normalized{\meaning\tikzexternal@lastkey@new}%
+ \iftikzexternal@verboseuptodate
+ \pgf@typeout{Up-to-date check of \tikzexternal@curfilename: new \tikzexternal@lastkey@new@normalized; old \tikzexternal@lastkey@normalized.^^J}%
+ \fi
+ \ifx\tikzexternal@lastkey@normalized\tikzexternal@lastkey@new@normalized
+ \tikzexternal@file@isuptodatetrue
+ \else
+ \tikzexternal@file@isuptodatefalse
+ \immediate\openout\w@pgf@writea=\tikzexternal@curfilename\tikzexternal@check@uptodate@ext\relax%
+ \immediate\write\w@pgf@writea{\tikzexternal@hashfct@serialize{\tikzexternal@lastkey@new}\tikzexternal@PERCENTchar}%
+ \immediate\closeout\w@pgf@writea
+ \fi
+ \fi
+}
+
+% Checks whether the current picture needs to be externalized.
+%
+% This is the case if
+% a) there is no external image yet,
+% b) the picture has been invalidated manually.
+%
+% It returns \iftikzexternal@file@isuptodate accordingly.
+% #1: the picture-content
+\long\def\tikzexternal@externalizefig@systemcall@uptodatecheck#1{%
+ \tikzexternal@check@uptodate@mode{#1}%
+ \tikzexternal@checkforceremake
+ \iftikzexternal@file@isuptodate
+ % check if there is already a file.
+ % In that case, use it. If that is not the case, generate it and include it afterwards.
+ \gdef\pgf@filename{}%
+ \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}%
+ \pgf@tempa
+ \ifx\pgf@filename\pgfutil@empty%
+ \global\tikzexternal@file@isuptodatefalse
+ \fi
+ \fi
+}%
+
+% \pgf@filename will be empty if the assertion failed.
+\def\tikzexternal@externalizefig@systemcall@assertsuccess#1{%
+ % check if there is a file now and raise an error message if not.
+ \gdef\pgf@filename{}%
+ \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}%
+ \pgf@tempa
+ \ifx\pgf@filename\pgfutil@empty%
+ \tikzexternal@externalizefig@systemcall@handleexception{#1}%
+ \fi
+}%
+\def\tikzexternal@externalizefig@systemcall@handleexception@msg#1{%
+ \tikzerror{Sorry, the system call '#1' did NOT result in a usable output file '\tikzexternal@curfilename' (expected one of \pgfsys@imagesuffixlist). Please verify that you have enabled system calls. For pdflatex, this is 'pdflatex -shell-escape'. Sometimes it is also named 'write 18' or something like that. Or maybe the command simply failed? Error messages can be found in '\tikzexternal@curfilename.log'. If you continue now, I'll try to typeset the picture}{}%
+}
+\def\tikzexternal@externalizefig@systemcall@handleexception@retry@later#1{%
+ \gdef\tikzexternal@systemcall@reschedule@to@end@document{0}%
+ \expandafter\pgfexternalreaddpth\expandafter{\tikzexternal@curfilename}%
+ \if1\tikzexternal@systemcall@reschedule@to@end@document
+ \pgfutil@IfUndefined{AtVeryEndDocument}{%
+ \tikzexternal@externalizefig@systemcall@handleexception@msg{#1}%
+ }{%
+ \pgf@typeout{===== The last system call resulted in an EMPTY output file. Maybe it is part of \string\ref. Rescheduling it for \string\end{document}. ========}%
+ \gdef\tikzexternal@typeset@picture@on@failure{0}%
+ \tikzexternal@externalizefig@systemcall@reschedule{#1}%
+ }%
+ \else
+ \tikzexternal@externalizefig@systemcall@handleexception@msg{#1}%
+ \fi
+}
+
+% reschedules the externalization of the current file to
+% \AtVeryEndDocument.
+%
+% This hook allows to execute code AFTER the main .aux file is
+% finished; it will even re-read the main aux file.
+\def\tikzexternal@externalizefig@systemcall@reschedule#1{%
+ \t@tikzexternal@tmpb={%
+ \global\let\tikzexternal@externalizefig@systemcall@handleexception=\tikzexternal@externalizefig@systemcall@handleexception@msg%
+ % ... no auxlocks!
+ \tikzexternal@externalizefig@systemcall@call{#1}%
+ \tikzexternal@externalizefig@systemcall@assertsuccess{#1}%
+ }%
+ \xdef\pgfutil@tempa{%
+ \noexpand\def\noexpand\tikzexternal@curfilename{\tikzexternal@curfilename}%
+ \the\t@tikzexternal@tmpb
+ }%
+ \expandafter\AtVeryEndDocument\expandafter{\pgfutil@tempa}%
+ \gdef\tikzexternal@has@rescheduled@something{1}%
+}%
+\let\tikzexternal@externalizefig@systemcall@handleexception=\tikzexternal@externalizefig@systemcall@handleexception@retry@later%
+
+\def\tikzexternal@has@rescheduled@something{0}%
+\pgfutil@IfUndefined{AtVeryEndDocument}{}{%
+ \AtVeryEndDocument{%
+ \if1\tikzexternal@has@rescheduled@something
+ \pgf@typeout{===== tikzexternal: \string\end{document} reached. Working on rescheduled images to resolve references... ========}%
+ \fi
+ }%
+}
+
+% Overwrite error message of pgf.
+% This happens if the generated image was empty, i.e. if there was no \shipout.
+\def\pgfexternal@error@no@shipout{%
+ \begingroup
+ \begingroup
+ % overwrite .dpth file in order to flag the file as "need to be scheduled
+ % for \AtVeryEndDocument" :
+ \immediate\openout\pgf@plotwrite=\pgfactualjobname.dpth
+ \let\w@pgfexternal@auxout=\pgf@plotwrite
+ \pgfexternalstorecommand@isexporting{\gdef\noexpand\tikzexternal@systemcall@reschedule@to@end@document{1}}%
+ \immediate\closeout\pgf@plotwrite
+ \endgroup
+ \tikzexternal@assemble@systemcall{\pgfactualjobname}{\pgf@tempa}%
+ \toks0=\expandafter{\pgf@tempa}%
+ \tikzerror{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname', but it seems there is no such image in the document!?
+ \if\tikzexternal@opmode4 ^^J
+\space\space You are currently using 'mode=convert with system call'. This problem can happen if the image (or one of the images preceding it) was declared inside of a \string\label{} (i.e. in the .aux file): 'convert with system call' has no access to the main aux file.^^J
+\space\space Possible solutions in this case:^^J
+\space\space (a) Try using 'mode=list and make',^^J
+\space\space (b) Issue the externalization command '\the\toks0' *manually* (also check the preceding externalized images, perhaps the file name sequence is not correct).^^J
+\space\space Repeat: the resulting image was EMPTY, your attention is required
+\else
+ \if\tikzexternal@opmode5 ^^J
+\space\space You are currently using 'mode=list and make'. Possible solutions:^^J
+\space\space (a) Try to delete `\tikzexternal@realjob.makefile'. Perhaps it is not up-to-date.^^J
+\space\space (b) Perhaps pictures are declared inside of \string\label{} and the .aux file is not up-to-date. Re-run latex, perhaps re-generate the graphics as well.^^J
+\space\space Repeat: the resulting image was EMPTY, your attention is required
+ \fi
+\fi}%
+ \endgroup
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex
new file mode 100644
index 0000000000..f39eaee866
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex
@@ -0,0 +1,108 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrary3d.code.tex}
+
+
+
+% New coordinate systems:
+
+\tikzdeclarecoordinatesystem{xyz cylindrical}
+{%
+ \pgfset{/tikz/cs/.cd,angle=0,radius=0,z=0,#1}%
+ \pgfpointcylindrical{\tikz@cs@angle}{\tikz@cs@xradius}{\tikz@cs@z}%
+}%
+
+\tikzdeclarecoordinatesystem{xyz spherical}
+{%
+ \pgfset{/tikz/cs/.cd,angle=0,radius=0,latitude=0,longitude=0,#1}%
+ \pgfpointspherical{\tikz@cs@angle}{\tikz@cs@latitude}{\tikz@cs@xradius}%
+}%
+
+\pgfset{/tikz/cs/longitude/.store in=\tikz@cs@angle}%
+\pgfset{/tikz/cs/latitude/.store in=\tikz@cs@latitude}%
+
+
+% Options for transforming into a plane:
+
+\tikzoption{plane origin}{\def\tikz@plane@origin{\tikz@scan@one@point\pgfutil@firstofone#1}}%
+\tikzoption{plane x}{\def\tikz@plane@x{\tikz@scan@one@point\pgfutil@firstofone#1}}%
+\tikzoption{plane y}{\def\tikz@plane@y{\tikz@scan@one@point\pgfutil@firstofone#1}}%
+
+\let\tikz@plane@origin=\pgfpointorigin
+\def\tikz@plane@x{\pgfpointxy{1}{0}}%
+\def\tikz@plane@y{\pgfpointxy{0}{1}}%
+
+\tikzoption{canvas is plane}[]{
+ \tikz@canvas@is@plane
+}%
+\tikzoption{canvas is xy plane at z}[]{%
+ \def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
+ \def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
+ \def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
+ \tikz@canvas@is@plane
+}%
+\tikzoption{canvas is yx plane at z}[]{%
+ \def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
+ \def\tikz@plane@x{\pgfpointxyz{0}{1}{#1}}%
+ \def\tikz@plane@y{\pgfpointxyz{1}{0}{#1}}%
+ \tikz@canvas@is@plane
+}%
+\tikzoption{canvas is xz plane at y}[]{%
+ \def\tikz@plane@origin{\pgfpointxyz{0}{#1}{0}}%
+ \def\tikz@plane@x{\pgfpointxyz{1}{#1}{0}}%
+ \def\tikz@plane@y{\pgfpointxyz{0}{#1}{1}}%
+ \tikz@canvas@is@plane
+}%
+\tikzoption{canvas is zx plane at y}[]{%
+ \def\tikz@plane@origin{\pgfpointxyz{0}{#1}{0}}%
+ \def\tikz@plane@x{\pgfpointxyz{0}{#1}{1}}%
+ \def\tikz@plane@y{\pgfpointxyz{1}{#1}{0}}%
+ \tikz@canvas@is@plane
+}%
+\tikzoption{canvas is yz plane at x}[]{%
+ \def\tikz@plane@origin{\pgfpointxyz{#1}{0}{0}}%
+ \def\tikz@plane@x{\pgfpointxyz{#1}{1}{0}}%
+ \def\tikz@plane@y{\pgfpointxyz{#1}{0}{1}}%
+ \tikz@canvas@is@plane
+}%
+\tikzoption{canvas is zy plane at x}[]{%
+ \def\tikz@plane@origin{\pgfpointxyz{#1}{0}{0}}%
+ \def\tikz@plane@x{\pgfpointxyz{#1}{0}{1}}%
+ \def\tikz@plane@y{\pgfpointxyz{#1}{1}{0}}%
+ \tikz@canvas@is@plane
+}%
+
+
+
+% Transformation code
+
+\def\tikz@canvas@is@plane{
+ \pgf@process{\tikz@plane@x}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\tikz@plane@y}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{\tikz@plane@origin}%
+ \edef\pgf@marshal{\noexpand\tikz@addtransform{%
+ \noexpand\pgftransformtriangle
+ {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}
+ \noexpand\pgftransformscale{0.035146}%
+ \noexpand\pgfsetxvec{\noexpand\pgfpoint{1cm}{0cm}}%
+ \noexpand\pgfsetyvec{\noexpand\pgfpoint{0cm}{1cm}}%
+ \noexpand\pgfsetzvec{\noexpand\pgfpoint{0cm}{0cm}}%
+ }}%
+ \pgf@marshal%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex
new file mode 100644
index 0000000000..2d6abbd2e9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex
@@ -0,0 +1,100 @@
+% Copyright 2019 by Till Tantau
+% Copyright 2019 by Kroum Tzanev
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryangles.code.tex}
+
+
+\tikzset{
+ pics/angle/.style = {
+ setup code = \tikz@lib@angle@parse#1\pgf@stop,
+ code = {},
+ background code = \tikz@lib@angle@background#1\pgf@stop,
+ foreground code = \tikz@lib@angle@foreground#1\pgf@stop,
+ },
+ pics/right angle/.style = {
+ setup code = \tikz@lib@angle@parse#1\pgf@stop,
+ code = {},
+ background code = \tikz@lib@rightangle@background#1\pgf@stop,
+ foreground code = \tikz@lib@rightangle@foreground#1\pgf@stop,
+ },
+ pics/angle/.default=A--B--C,
+ angle eccentricity/.initial=.6,
+ angle radius/.initial=5mm,
+}%
+
+\def\tikz@lib@angle@background#1--#2--#3\pgf@stop{%
+ \path [name prefix ..] [pic actions, draw=none] (#2.center)
+ -- ++(\tikz@start@angle@temp:\tikz@lib@angle@rad pt)
+ arc [start angle=\tikz@start@angle@temp, end
+ angle=\tikz@end@angle@temp, radius=\tikz@lib@angle@rad pt] -- cycle;
+}%
+
+\def\tikz@lib@angle@foreground#1--#2--#3\pgf@stop{%
+ \path [name prefix ..] [pic actions, fill=none, shade=none]
+ ([shift={(\tikz@start@angle@temp:\tikz@lib@angle@rad pt)}]#2.center)
+ arc [start angle=\tikz@start@angle@temp, end
+ angle=\tikz@end@angle@temp, radius=\tikz@lib@angle@rad pt];
+ \ifx\tikzpictext\relax\else%
+ \def\pgf@temp{\node()[name prefix
+ ..,at={([shift={({.5*\tikz@start@angle@temp+.5*\tikz@end@angle@temp}:\pgfkeysvalueof{/tikz/angle
+ eccentricity}*\tikz@lib@angle@rad pt)}]#2.center)}]}
+ \expandafter\pgf@temp\expandafter[\tikzpictextoptions]{\tikzpictext};%
+ \fi
+}%
+
+\def\tikz@lib@rightangle@background#1--#2--#3\pgf@stop{%
+ \path [name prefix ..] [pic actions, draw=none] (#2.center)
+ -- ++(\tikz@start@angle@temp:\tikz@lib@angle@rad pt)
+ -- ++(\tikz@end@angle@temp:\tikz@lib@angle@rad pt)
+ -- ++(\tikz@start@angle@temp:-\tikz@lib@angle@rad pt)
+ -- cycle;
+}%
+
+\def\tikz@lib@rightangle@foreground#1--#2--#3\pgf@stop{%
+ \path [name prefix ..] [pic actions, fill=none, shade=none]
+ ([shift={(\tikz@start@angle@temp:\tikz@lib@angle@rad pt)}]#2.center)
+ -- ++(\tikz@end@angle@temp:\tikz@lib@angle@rad pt)
+ -- ++(\tikz@start@angle@temp:-\tikz@lib@angle@rad pt);
+ \ifx\tikzpictext\relax\else%
+ \def\pgf@temp{\node()[name prefix
+ ..,at={([shift={({.5*\tikz@start@angle@temp+.5*\tikz@end@angle@temp}:\pgfkeysvalueof{/tikz/angle
+ eccentricity}*1.4142136*\tikz@lib@angle@rad pt)}]#2.center)}]}
+ \expandafter\pgf@temp\expandafter[\tikzpictextoptions]{\tikzpictext};%
+ \fi
+}%
+
+\def\tikz@lib@angle@parse#1--#2--#3\pgf@stop{%
+ % Compute radius:
+ \pgfmathsetmacro\tikz@lib@angle@rad{\pgfkeysvalueof{/tikz/angle radius}}
+ \ifdim\tikz@lib@angle@rad pt>0pt\else\def\tikz@lib@angle@rad{12}\fi%
+ % Compute first coordinate:
+ \pgf@process{\pgfpointanchor{#2}{center}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointanchor{#1}{center}}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{\pgfpointanchor{#3}{center}}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \advance\pgf@xc by-\pgf@xa%
+ \advance\pgf@yc by-\pgf@ya%
+ \pgfmathsetmacro{\tikz@start@angle@temp}{atan2(\the\pgf@yb,\the\pgf@xb)}
+ \pgfmathsetmacro{\tikz@end@angle@temp}{atan2(\the\pgf@yc,\the\pgf@xc)}
+ \ifdim\tikz@end@angle@temp pt<\tikz@start@angle@temp pt%
+ \pgfmathsetmacro{\tikz@start@angle@temp}{\tikz@start@angle@temp-360}%
+ \fi%
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryanimations.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryanimations.code.tex
new file mode 100644
index 0000000000..7b3fc12bf1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryanimations.code.tex
@@ -0,0 +1,904 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryanimations.code.tex}
+
+\usepgfmodule{animations}%
+
+
+
+% Scope syntax extension:
+
+\def\tikz@collect@scope@anims#1{%
+ \let\tikz@scope@anims\pgfutil@empty%
+ \let\tikz@collect@command#1%
+ \tikz@collect@scope@anims@parse%
+}%
+\def\tikz@collect@scope@anims@parse{%
+ \pgfutil@ifnextchar[{\tikz@collect@scope@anims@opt}{%
+ \pgfutil@ifnextchar:{\tikz@collect@scope@anims@go}{%
+ \tikz@collect@scope@anims@done}}%]
+}%
+\def\tikz@collect@scope@anims@done{%
+ \expandafter\tikz@collect@command\expandafter[\tikz@scope@anims]%
+}%
+\def\tikz@collect@scope@anims@opt[{%]
+ \expandafter\tikz@collect@command\expandafter[\tikz@scope@anims%]
+}%
+\def\tikz@collect@scope@anims@go:#1=#2{%
+ \expandafter\def\expandafter\tikz@scope@anims\expandafter{\tikz@scope@anims animate={myself:={:{#1}={#2}}},}%
+ \tikz@collect@scope@anims@parse%
+}%
+
+
+
+
+%
+% The main keys:
+%
+
+\def\tikzanimateset{\pgfqkeys{/tikz/animate}}%
+\tikzanimateset{
+ .code={
+ \pgfkeys{/handlers/first char syntax=true}
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string"}{\tikz@animation@value}%
+ \def\tikz@anim@t{0}%
+ \def\tikz@anim@t@base{0}%
+ \def\tikz@anim@t@current{0}%
+ \tikzanimateset{#1}
+ },
+ scope/.code=\tikz@anim@scope{#1}{}{},
+ sync/.code=\tikz@anim@sync@scope{#1}{}{},
+ entry/.code=\tikz@anim@make@entry,
+ object/.code=\tikz@anim@set@object{#1},
+ attribute/.code=\tikz@anim@set@attr{#1},
+ id/.code=\tikz@anim@set@id{#1},
+ time/.code=\tikz@anim@set@time{#1},
+ value/.code=\tikz@anim@add{\tikz@anim@value{#1}},%
+ remember/.code=\pgfmathadd@{\tikz@anim@t}{\tikz@anim@t@base}\global\let#1\pgfmathresult,
+ resume/.code=\tikz@anim@resume{#1},
+ fork/.code={\tikz@anim@parse@time{#1}\pgfmathadd@\tikz@anim@t\tikz@anim@t@base\let\tikz@anim@t@base\pgfmathresult\def\tikz@anim@t{0}},
+ fork/.default = 0later,
+ base/.style={scope={/utils/exec=\let\tikz@animation@time\tikz@anim@base@text,#1,entry}},
+}%
+
+\tikzset{
+ make snapshot of/.code=\edef\tikz@temp{#1}\ifx\tikz@temp\pgfutil@empty\else\pgfsnapshot{#1}\fi,
+ make snapshot after/.code=\edef\tikz@temp{#1}\ifx\tikz@temp\pgfutil@empty\else\pgfsnapshotafter{#1}\fi,
+ make snapshot if necessary/.code=\ifpgfsysanimationsupported\else\pgfsnapshot{#1}\fi,
+ make snapshot if necessary/.default=0s,
+}%
+
+\def\tikz@anim@scope#1#2#3{%
+ {#2\tikzanimateset{#1}#3}%
+}%
+\def\tikz@anim@sync@scope#1#2#3{%
+ {%
+ #2%
+ \tikzanimateset{#1}%
+ #3%
+ \pgfmathadd@{\tikz@anim@t}{\tikz@anim@t@base}%
+ \expandafter%
+ }\expandafter\pgfmathsubtract@\expandafter{\pgfmathresult}{\tikz@anim@t@base}%
+ \tikz@anim@set@time{\pgfmathresult}%
+}%
+
+\def\tikz@anim@set@time#1{%
+ \tikz@anim@parse@time{#1}%
+ \let\tikz@anim@t@current\tikz@anim@t%
+ \pgfmathadd@\tikz@anim@t\tikz@anim@t@base%
+ \let\tikz@animation@time\pgfmathresult%
+}%
+
+\def\tikz@anim@value#1{%
+ \def\tikz@anim@result{#1}
+ \ifx\tikz@anim@result\pgf@special@current@text%
+ \else%
+ \ifx\tikz@animation@parser\relax%
+ \else%
+ \tikz@animation@parser{#1}%
+ \fi%
+ \fi%
+}%
+
+
+\def\tikz@anim@resume#1{%
+ \pgfparsetime{#1}%
+ \pgfmathsubtract@{\pgftimeresult}{\tikz@anim@t@base}%
+ \tikz@anim@set@time{\pgfmathresult}%
+}%
+
+
+% The object--attribute entries are of the following forms:
+%
+% objects:attributes
+% objects:attributes_id
+%
+
+\def\tikz@animation@syntax@check#1#2{%
+ \def\tikz@animation@rest{#1}%
+ \expandafter\pgfutil@in@\expandafter:\expandafter{\tikz@key}%
+ \ifpgfutil@in@%
+ \expandafter\tikz@anim@parse@colon\tikz@key\pgf@stop%
+ \else%
+ #2%
+ \fi%
+}%
+
+\def\tikz@anim@parse@colon#1:#2\pgf@stop{%
+ \expandafter\tikz@anim@sync@scope\expandafter{\tikz@animation@rest}{%
+ \tikz@anim@set@object{#1}%
+ \pgfutil@in@_{#2}%
+ \ifpgfutil@in@%
+ \tikz@anim@parse@under#2\pgf@stop%
+ \else%
+ \tikz@anim@parse@under#2_\pgf@stop%
+ \fi%
+ }{\tikz@anim@make@entry}%
+}%
+
+\def\tikz@anim@parse@under#1_#2\pgf@stop{%
+ \tikz@anim@set@attr{#1}%
+ \tikz@anim@set@id{#2}%
+}%
+
+\def\tikz@anim@set@attr#1{%
+ \pgfkeys@spdef\tikz@anim@a{#1}%
+ \ifx\tikz@anim@a\pgfutil@empty%
+ \else%
+ \let\tikz@anim@tl@attributes\tikz@anim@a%
+ \fi%
+}%
+
+\def\tikz@anim@set@id#1{%
+ \pgfkeys@spdef\tikz@anim@a{#1}%
+ \ifx\tikz@anim@a\pgfutil@empty%
+ \else%
+ \let\tikz@anim@tl@id\tikz@anim@a%
+ \fi%
+}%
+
+\def\tikz@anim@set@object#1{%
+ \pgfkeys@spdef\tikz@anim@a{#1}%
+ \ifx\tikz@anim@a\pgfutil@empty%
+ \else%
+ \let\tikz@anim@tl@objects\tikz@anim@a%
+ \fi%
+}%
+
+
+%
+% Parsing of values
+%
+
+\def\tikz@animation@value#1{%
+ \tikz@animation@value@parser#1\pgf@stop%
+}%
+
+\def\tikz@animation@value@parser"#1"{%
+ \def\tikz@animation@value@head{#1}%
+ \pgfutil@ifnextchar\pgf@stop{\tikz@animation@value@rest=}{%
+ \pgfutil@ifnextchar b\tikz@animation@value@rest@base\tikz@animation@value@rest%
+ }%
+}%
+\def\tikz@animation@value@rest=#1\pgf@stop{%
+ \tikz@anim@sync@scope{#1}{\expandafter\tikz@anim@add\expandafter{\expandafter\tikz@anim@value\expandafter{\tikz@animation@value@head}}}{\tikz@anim@make@entry}%
+}%
+
+\def\tikz@animation@value@rest@base base{%
+ \tikz@anim@sync@scope{}{\let\tikz@animation@time\tikz@anim@base@text\expandafter\tikz@anim@add\expandafter{\expandafter\tikz@anim@value\expandafter{\tikz@animation@value@head}}}{\tikz@anim@make@entry}%
+ \pgfutil@ifnextchar\pgf@stop{\tikz@animation@value@rest=}{\tikz@animation@value@rest}%
+}%
+
+
+
+
+%
+% The parsers
+%
+
+\def\tikz@anim@simple@parse#1{} % nothing to do, \def\tikz@anim@result{#1} is already done
+
+\def\tikz@anim@slant@parse#1{\pgfmathsetmacro\tikz@anim@result{atan(#1)}}%
+
+\def\tikz@anim@dashpattern@parse#1{%
+ \pgfmathsetmacro\tikz@anim@dash@phase{\tikz@dashphase}%
+ \def\tikz@dashpattern{}%
+ \expandafter\tikz@scandashon\pgfutil@gobble#1o\@nil%
+ \edef\tikz@anim@result{{\tikz@dashpattern}{\tikz@anim@dash@phase pt}}%
+}%
+\def\tikz@anim@dashoffset@parse#1{%
+ \pgfmathparse{#1}%
+ \edef\tikz@anim@result{{\tikz@dashpattern}{\pgfmathresult pt}}%
+}%
+\def\tikz@anim@dash@parse#1{%
+ \tikz@anim@dash@parse@#1\pgf@stop%
+}%
+\def\tikz@anim@dash@parse@#1phase#2\pgf@stop{%
+ \pgfmathsetmacro\tikz@anim@dash@phase{#2}%
+ \def\tikz@dashpattern{}%
+ \expandafter\tikz@scandashon\pgfutil@gobble#1o\@nil%
+ \edef\tikz@anim@result{{\tikz@dashpattern}{\tikz@anim@dash@phase pt}}%
+}%
+
+\def\tikz@anim@xshift@parse#1{\pgfmathparse{#1}\edef\tikz@anim@result{\noexpand\pgfqpoint{\pgfmathresult pt}{0pt}}}%
+\def\tikz@anim@yshift@parse#1{\pgfmathparse{#1}\edef\tikz@anim@result{\noexpand\pgfqpoint{0pt}{\pgfmathresult pt}}}%
+
+\def\tikz@anim@xscale@parse#1{\pgfmathparse{#1}\edef\tikz@anim@result{\pgfmathresult,1}}%
+\def\tikz@anim@yscale@parse#1{\pgfmathparse{#1}\edef\tikz@anim@result{1,\pgfmathresult}}%
+
+\def\tikz@anim@shift@parse#1{\tikz@scan@one@point\tikz@anim@do@shift#1}%
+\def\tikz@anim@do@shift#1{\def\tikz@anim@result{#1}}%
+
+\def\tikz@anim@position@parse#1{%
+ \begingroup%
+ \let\tikz@transform=\relax%
+ \pgf@xc-\pgf@pt@x%
+ \pgf@yc-\pgf@pt@y%
+ \pgfsettransform\tikz@anim@saved@transform%
+ \tikz@scan@one@point\tikz@anim@do@position#1}%
+\def\tikz@anim@do@position#1{%
+ \pgf@process{\pgfpointtransformed{#1}}%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \xdef\tikz@anim@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \endgroup%
+ \let\tikz@anim@result\tikz@anim@temp%
+}%
+
+\def\tikz@anim@view@parse#1{\tikz@anim@view@parse@#1\pgf@stop}%
+\def\tikz@anim@view@parse@{%
+ \pgfutil@ifnextchar({\tikz@scan@one@point\tikz@anim@view@parse@a}{\tikz@anim@view@node}%
+}%
+\def\tikz@anim@view@parse@a#1{%
+ \def\tikz@anim@result{{#1}}%
+ \pgfutil@ifnextchar r{\tikz@anim@view@parsed@rec}{\tikz@scan@one@point\tikz@anim@view@parse@b}%
+}%
+\def\tikz@anim@view@parsed@rec rectangle{\tikz@scan@one@point\tikz@anim@view@parse@b}%
+\def\tikz@anim@view@parse@b#1{%
+ \expandafter\def\expandafter\tikz@anim@result\expandafter{\tikz@anim@result{#1}}%
+ \pgfutil@ifnextchar\pgf@stop\pgfutil@gobble{\tikzerror{Wrong view syntax}}%
+}%
+\def\tikz@anim@view@node#1\pgf@stop{%
+ \expandafter\ifx\csname pgf@sh@ns@#1\endcsname\relax%
+ \tikzerror{Undefined node '#1'}%
+ \else%
+ % Compute a bounding box for the node:
+ {%
+ \pgf@process{\pgfpointanchor{#1}{west}}%
+ \pgf@xa\pgf@x \pgf@ya\pgf@y
+ \pgf@xb\pgf@x \pgf@yb\pgf@y
+ \pgf@process{\pgfpointanchor{#1}{north}}%
+ \ifdim\pgf@x<\pgf@xa \pgf@xa=\pgf@x\fi%
+ \ifdim\pgf@x>\pgf@xb \pgf@xb=\pgf@x\fi%
+ \ifdim\pgf@y<\pgf@ya \pgf@ya=\pgf@y\fi%
+ \ifdim\pgf@y>\pgf@yb \pgf@yb=\pgf@y\fi%
+ \pgf@process{\pgfpointanchor{#1}{south}}%
+ \ifdim\pgf@x<\pgf@xa \pgf@xa=\pgf@x\fi%
+ \ifdim\pgf@x>\pgf@xb \pgf@xb=\pgf@x\fi%
+ \ifdim\pgf@y<\pgf@ya \pgf@ya=\pgf@y\fi%
+ \ifdim\pgf@y>\pgf@yb \pgf@yb=\pgf@y\fi%
+ \pgf@process{\pgfpointanchor{#1}{east}}%
+ \ifdim\pgf@x<\pgf@xa \pgf@xa=\pgf@x\fi%
+ \ifdim\pgf@x>\pgf@xb \pgf@xb=\pgf@x\fi%
+ \ifdim\pgf@y<\pgf@ya \pgf@ya=\pgf@y\fi%
+ \ifdim\pgf@y>\pgf@yb \pgf@yb=\pgf@y\fi%
+ \xdef\tikz@anim@result{{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}}
+ }%
+ \fi%
+}%
+
+\def\tikz@anim@path@parse#1{%
+ {%
+ \setbox0=\hbox{{% protext against side effects
+ \pgfinterruptpath%
+ \expandafter\tikz@scan@next@command#1\pgf@stop%
+ \pgfsyssoftpath@getcurrentpath\tikz@anim@result%
+ \pgfprocessround{\tikz@anim@result}{\tikz@anim@result}%
+ \global\let\tikz@anim@result\tikz@anim@result%
+ \endpgfinterruptpath%
+ }}%
+ }%
+}%
+
+% The special along parser
+
+
+\def\tikz@anim@along#1#2{%
+ % Parse the path...
+ {%
+ \setbox0=\hbox{{% protect against side effects
+ \pgfinterruptpath%
+ \pgf@relevantforpicturesizefalse%
+ \iftikz@anim@is@position%
+ \let\tikz@transform=\relax%
+ \pgf@x-\pgf@pt@x%
+ \pgf@y-\pgf@pt@y%
+ \edef\tikz@anim@along@shift{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
+ \pgfsettransformentries#1%
+ \else%
+ \pgftransformreset%
+ \fi
+ \tikz@scan@next@command#2\pgf@stop%
+ \pgfsyssoftpath@getcurrentpath\tikz@anim@parsed@path%
+ \pgfprocessround{\tikz@anim@parsed@path}{\tikz@anim@parsed@path}%
+ \iftikz@anim@is@position%
+ \tikz@anim@shift@path%
+ \global\let\tikz@anim@parsed@path\tikz@anim@patched@path%
+ \else%
+ \global\let\tikz@anim@parsed@path\tikz@anim@parsed@path%
+ \fi%
+ \endpgfinterruptpath%
+ }}%
+ }%
+ \pgfanimationset{along softpath/.expand once=\tikz@anim@parsed@path}%
+}%
+
+\def\tikz@anim@shift@path{%
+ \let\tikz@anim@patched@path\pgfutil@empty%
+ \tikz@anim@along@shift%
+ \expandafter\tikz@anim@shift@path@\tikz@anim@parsed@path\pgf@stop%
+}%
+\def\tikz@anim@shift@path@{%
+ \pgfutil@ifnextchar\pgf@stop\pgfutil@gobble{%
+ \pgfutil@ifnextchar\bgroup\tikz@anim@shift@path@sub\tikz@anim@shift@path@copy}%
+}%
+\def\tikz@anim@shift@path@copy#1{%
+ \expandafter\def\expandafter\tikz@anim@patched@path\expandafter{\tikz@anim@patched@path#1}%
+ \tikz@anim@shift@path@%
+}%
+\def\tikz@anim@shift@path@sub#1#2{%
+ \pgf@x#1%
+ \pgf@y#2%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \edef\tikz@temp{{\the\pgf@x}{\the\pgf@y}}%
+ \expandafter\tikz@anim@shift@path@copy\expandafter{\tikz@temp}%
+}%
+
+
+
+\def\tikz@anim@parse@origin#1{%
+ \tikz@scan@one@point\tikz@anim@parse@origin@#1\relax%
+}%
+\def\tikz@anim@parse@origin@#1{\tikz@anim@add{\pgfanimationset{origin={#1}}}}%
+
+
+% Internals
+
+\def\tikz@anim@tl@objects{}%
+\def\tikz@anim@tl@attributes{}%
+\def\tikz@anim@tl@id{default}%
+
+\let\tikz@anim@tl@exec@options\pgfutil@empty
+\let\tikz@anim@tl@early@options\pgfutil@empty
+
+\def\tikz@anim@add@early#1{\expandafter\def\expandafter\tikz@anim@tl@early@options\expandafter{\tikz@anim@tl@early@options#1}}%
+\def\tikz@anim@add@once@early#1{%
+ \global\advance\tikz@anim@once@count by1\relax%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@anim@tl@early@options%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@anim@tl@early@options\expandafter\tikz@anim@exec@once\expandafter{\the\tikz@anim@once@count}{#1}}%
+}%
+\def\tikz@anim@add#1{\expandafter\def\expandafter\tikz@anim@tl@exec@options\expandafter{\tikz@anim@tl@exec@options#1}}%
+\def\tikz@anim@add@once#1{%
+ \global\advance\tikz@anim@once@count by1\relax%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@anim@tl@exec@options%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@anim@tl@exec@options\expandafter\tikz@anim@exec@once\expandafter{\the\tikz@anim@once@count}{#1}}%
+}%
+\newcount\tikz@anim@once@count%
+\def\tikz@anim@exec@once#1#2{%
+ \expandafter\ifx\csname tikz@anim@once@#1\endcsname\pgf@stop%
+ \else%
+ \expandafter\let\csname tikz@anim@once@#1\endcsname\pgf@stop%
+ #2%
+ \fi%
+}%
+
+\newif\iftikz@anim@do@entry
+
+\def\tikz@anim@make@entry{%
+ \tikz@anim@do@entrytrue%
+ \ifx\tikz@anim@tl@objects\pgfutil@empty\tikz@anim@do@entryfalse\fi%
+ \ifx\tikz@anim@tl@attributes\pgfutil@empty\tikz@anim@do@entryfalse\fi%
+ \ifx\tikz@anim@tl@exec@options\pgfutil@empty\ifx\tikz@anim@tl@early@options\pgfutil@empty\tikz@anim@do@entryfalse\fi\fi%
+ \iftikz@anim@do@entry%
+ \foreach\tikz@anim@tl@object in\tikz@anim@tl@objects{%
+ \expandafter\tikzanimationattributesset\expandafter{\tikz@anim@tl@attributes}%
+ }%
+ \fi%
+}%
+
+\def\tikzanimationattributesset#1{\pgfqkeys{/tikz/animate/attributes}{#1}}%
+
+\tikzanimationattributesset{
+ .unknown/.code={
+ \let\tikz@anim@attribute@name\pgfkeyscurrentname
+ \expandafter\let\expandafter\pgf@temp\csname tikz@anim@def@pgf@attr@\tikz@anim@attribute@name\endcsname%
+ \ifx\pgf@temp\relax%
+ \tikzerror{Unknown animation attribute '\tikz@anim@attribute@name'}%
+ \else%
+ \expandafter\tikz@timeline@config\expandafter\tikz@anim@tl@object\expandafter\tikz@anim@attribute@name\expandafter\tikz@anim@tl@id\expandafter{\tikz@anim@configs}%
+ \edef\pgf@marshal{\noexpand\tikz@timeline@entry{\tikz@anim@tl@object}{\tikz@anim@attribute@name}{\tikz@anim@tl@id}}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgf@marshal\expandafter{\tikz@anim@tl@early@options}}%
+ \expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\tikz@anim@entry\expandafter\expandafter\expandafter{\expandafter\tikz@anim@tl@exec@options\expandafter\def\expandafter\tikz@animation@time\expandafter{\tikz@animation@time}}}%
+ \fi%
+ }
+}%
+\let\tikz@anim@configs\pgfutil@empty
+
+\def\tikz@anim@entry#1{%
+ % Reset splines and value:
+ \let\tikz@anim@result\pgfutil@empty%
+ \pgf@anim@reset@linear%
+ #1%
+ \ifx\tikz@anim@result\pgfutil@empty%
+ \else%
+ \ifx\tikz@animation@time\pgfutil@empty%
+ \else%
+ \ifx\tikz@animation@time\tikz@anim@base@text%
+ \expandafter\pgf@anim@base\expandafter{\tikz@anim@result}%
+ \else%
+ \expandafter\expandafter\expandafter\pgf@anim@entry%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@animation@time\expandafter}\expandafter{\tikz@anim@result}%
+ \fi%
+ \fi%
+ \fi%
+}%
+\let\tikz@animation@time\pgfutil@empty%
+\def\tikz@anim@base@text{base}%
+
+\tikzanimateset{
+ .unknown/.code={%
+ \let\tikz@key\pgfkeyscurrentname%
+ \tikz@animation@syntax@check{#1}{\tikz@anim@options{#1}}%
+ }
+}%
+
+
+\def\tikz@anim@options#1{
+ \let\tikz@anim@key\pgfkeyscurrentname%
+ \pgfqkeys{/tikz/animate/options}{\tikz@anim@key/.try={#1}}%
+ \ifpgfkeyssuccess%
+ \else%
+ \def\tikz@anim@unparsed@value{#1}%
+ \expandafter\tikz@anim@time@test\tikz@anim@key\pgf@stop%
+ \fi%
+}%
+
+\tikzanimateset{
+ options/.cd,
+ name/.code=\tikz@anim@add{\pgfanimationset{name={#1}}},
+ forever/.code=\tikz@anim@add{\pgfanimationset{freeze at end}},
+ freeze/.code=\tikz@anim@add{\pgfanimationset{freeze at end}},
+ restart/.code=\tikz@anim@add{\pgfanimationset{restart={#1}}},
+ repeats/.code=\tikz@anim@add{\pgfanimationset{repeats={#1}}},
+ repeats/.default=,
+ repeat/.code=\tikz@anim@add{\pgfanimationset{repeats={#1}}},
+ repeat/.default=,
+ begin/.code=\tikz@anim@add@once{\pgfanimationset{begin={#1}}},
+ end/.code=\tikz@anim@add@once{\pgfanimationset{end={#1}}},
+ begin on/.code=\tikz@anim@event{begin}{#1},
+ end on/.code=\tikz@anim@event{begin}{#1},
+ begin snapshot/.code=\tikz@anim@add{\pgfanimationset{begin snapshot={#1}}},
+ origin/.code=\tikz@anim@parse@origin{#1},
+ transform/.code=\tikz@anim@add{\pgfanimationset{transform={\let\tikz@transform\relax\tikzset{#1}}}},
+ along/.code=\tikz@anim@handle@along#1\pgf@stop,
+ entry control/.code=\tikz@anim@add{\pgfanimationset{entry control={#1}}},
+ exit control/.code=\tikz@anim@add{\pgfanimationset{exit control={#1}}},
+ stay/.code=\tikz@anim@add{\pgfanimationset{stay}},
+ jump/.code=\tikz@anim@add{\pgfanimationset{jump}},
+ ease/.style={
+ entry control={1-(#1)}{1},
+ exit control={#1}{0}
+ },
+ ease/.default=0.5,
+ ease in/.style={
+ entry control={1-(#1)}{1},
+ },
+ ease in/.default=0.5,
+ ease out/.style={
+ exit control={#1}{0},
+ },
+ ease out/.default=0.5,
+ arrows/.code=\tikz@anim@add@early{\pgfanimationset{arrows={#1}}},
+ shorten >/.code=\tikz@anim@add@early{\pgfanimationset{shorten >={#1}}},
+ shorten </.code=\tikz@anim@add@early{\pgfanimationset{snorten <={#1}}},
+}%
+\newif\iftikz@anim@along
+
+\def\tikz@anim@t{0}%
+
+\def\tikz@anim@handle@along#1{%
+ \pgfutil@ifnextchar s{\tikz@anim@handle@sloped{#1}}{\tikz@anim@handle@upright{#1}}%
+}%
+\def\tikz@anim@handle@sloped#1sloped{%
+ \pgfgettransform\tikz@anim@trans@pre%
+ \expandafter\tikz@anim@add@once%
+ \expandafter{%
+ \expandafter\tikz@anim@along\expandafter{\tikz@anim@trans@pre}{#1}%
+ \pgfsysanimkeycanvastransform{%
+ \pgf@xc\pgf@pt@x%
+ \pgf@yc\pgf@pt@y%
+ \pgftransformreset%
+ \pgf@pt@x\pgf@xc%
+ \pgf@pt@y\pgf@yc%
+ {\pgflowlevelsynccm}%
+ }{\pgftransforminvert\pgflowlevelsynccm}%
+ \pgfanimationset{rotate along=true}%
+ }%
+ \def\tikz@anim@configs{\tikz@anim@alongtrue}%
+ \tikz@anim@handle@in%
+}%
+\def\tikz@anim@handle@upright#1upright{%
+ \pgfgettransform\tikz@anim@trans@pre%
+ \expandafter\tikz@anim@add@once%
+ \expandafter{%
+ \expandafter\tikz@anim@along\expandafter{\tikz@anim@trans@pre}{#1}%
+ \pgfsysanimkeycanvastransform{}{}%
+ }%
+ \def\tikz@anim@configs{\tikz@anim@alongtrue}%
+ \tikz@anim@handle@in%
+}%
+\def\tikz@anim@handle@in{%
+ \pgfutil@ifnextchar i{\tikz@anim@handle@in@yes}{\tikz@anim@handle@in@no}%
+}%
+\def\tikz@anim@handle@in@no\pgf@stop{}%
+\def\tikz@anim@handle@in@yes in#1\pgf@stop{%
+ \tikzanimateset{scope={time=0,value=0,entry,time=#1,value=1,entry}}%
+}%
+
+
+
+\def\tikz@anim@event#1#2{%
+ {%
+ % evaluate #2 once to determine the id now
+ \let\pgf@anim@id\pgfutil@empty%
+ \pgfqkeys{/pgf/animation/events}{#2}%
+ \expandafter}%
+ \expandafter\def\expandafter\tikz@anim@temp@id\expandafter{\pgf@anim@id}%
+ \ifx\tikz@anim@temp@id\pgfutil@empty%
+ \def\tikz@temp{#1 on={of id=\tikz@anim@current@id,#2}}%
+ \else
+ \expandafter\tikz@anim@event@setter\expandafter{\tikz@anim@temp@id}{#1}{#2}%
+ \fi%
+ \expandafter\tikz@anim@add@once\expandafter{\expandafter\pgfanimationset\expandafter{\tikz@temp}}%
+}%
+\def\tikz@anim@event@setter#1#2#3{%
+ \def\tikz@temp{#2 on={#3,of id=#1}}%
+}%
+
+\def\tikz@anim@time@test#1#2\pgf@stop{%
+ \edef\tikz@temp{\meaning#1}%
+ \expandafter\ifx\csname tikz@anim@test@\tikz@temp\endcsname\relax%
+ \tikzerror{I do not know the timing key '#1#2' to which you passed '\tikz@anim@unparsed@value'}%
+ \else%
+ \expandafter\tikz@anim@sync@scope\expandafter{\tikz@anim@unparsed@value}{\tikz@anim@set@time{#1#2}}{\tikz@anim@make@entry}%
+ \fi%
+}%
+
+\def\tikz@anim@parse@time#1{%
+ \pgfutil@in@{later\pgf@stop}{#1\pgf@stop}%
+ \ifpgfutil@in@%
+ \tikz@anim@parse@later#1\pgf@stop%
+ \else%
+ \pgfparsetime{#1}\let\tikz@anim@t\pgftimeresult%
+ \fi%
+}%
+\def\tikz@anim@parse@later#1later\pgf@stop{%
+ \pgfparsetime{#1+\tikz@anim@t@current}\let\tikz@anim@t\pgftimeresult%
+}%
+
+\expandafter\let\csname tikz@anim@test@the character 0\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 1\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 2\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 3\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 4\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 5\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 6\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 7\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 8\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character 9\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character -\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character +\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character .\endcsname\pgfutil@empty
+\expandafter\let\csname tikz@anim@test@the character (\endcsname\pgfutil@empty
+
+
+
+
+
+% Configure an animation attribute
+%
+% #1 = tikz attribute name
+% #2 = configuration
+%
+% Description:
+%
+% Sets up internals for the tikz attribute.
+
+\def\tikzanimationdefineattribute#1#2{%
+ \expandafter\def\csname tikz@anim@def@pgf@attr@#1\endcsname{#1}%
+ \expandafter\let\csname tikz@anim@def@no@node@#1\endcsname\pgfutil@empty
+ \expandafter\let\csname tikz@anim@def@is@node@#1\endcsname\pgfutil@empty
+ \expandafter\let\csname tikz@anim@def@code@#1\endcsname\pgfutil@empty
+ \expandafter\let\csname tikz@anim@def@parser@#1\endcsname\tikz@anim@simple@parse
+ \def\tikz@anim@attr{#1}%
+ \pgfkeys{/tikz/animate/@attrdef/.cd,#2}%
+}%
+
+\pgfkeys{/tikz/animate/@attrdef/.cd,
+ pgf attribute name/.code=\expandafter\def\csname tikz@anim@def@pgf@attr@\tikz@anim@attr\endcsname{#1},
+ pgf attribute name scope/.code=\expandafter\def\csname tikz@anim@def@pgf@attr@@scope@\tikz@anim@attr\endcsname{#1},
+ pgf attribute name node/.code=\expandafter\def\csname tikz@anim@def@pgf@attr@@node@\tikz@anim@attr\endcsname{#1},
+ scope type/.code=\expandafter\def\csname tikz@anim@def@no@node@\tikz@anim@attr\endcsname{#1},
+ node type/.code=\expandafter\def\csname tikz@anim@def@is@node@\tikz@anim@attr\endcsname{#1},
+ code/.code=\expandafter\def\csname tikz@anim@def@code@\tikz@anim@attr\endcsname{#1},
+ setup/.code=\expandafter\def\csname tikz@anim@def@setup@\tikz@anim@attr\endcsname{#1},
+ parser/.code=\expandafter\def\csname tikz@anim@def@parser@\tikz@anim@attr\endcsname{#1},
+}%
+
+
+% Configure an animation attribute list
+%
+% #1 = tikz attribute list name
+% #2 = list of tikz attributes
+%
+% Description:
+%
+% Sets up internals for the tikz attribute.
+
+\def\tikzanimationdefineattributelist#1#2{%
+ \tikzanimationattributesset{#1/.style={#2}}%
+}%
+
+
+
+
+% Definition of the tikz attributes
+
+
+\tikzanimationdefineattributelist{color}{@color,text}%
+\tikzanimationdefineattribute{@color}{pgf attribute name=color,node type=.background}%
+\tikzanimationdefineattribute{dash pattern}{pgf attribute name=dash,parser=dashpattern, node type=.background}%
+\tikzanimationdefineattribute{dash phase}{pgf attribute name=dash,parser=dashoffset, node type=.background}%
+\tikzanimationdefineattribute{dash}{parser=dash, node type=.background}%
+\tikzanimationdefineattribute{draw opacity}{pgf attribute name=stroke opacity}%
+\tikzanimationdefineattribute{draw}{pgf attribute name=stroke, node type=.background}%
+\tikzanimationdefineattribute{fill opacity}{}%
+\tikzanimationdefineattribute{fill}{node type=.background}%
+\tikzanimationdefineattribute{line width}{node type=.background}%
+\tikzanimationdefineattribute{path}{pgf attribute name=softpath, scope type=.path, node type=.background.path, parser=path}%
+\tikzanimationdefineattribute{opacity}{}%
+\tikzanimationdefineattribute{position}{%
+ pgf attribute name=\iftikz@anim@along motion\else translate\fi,
+ parser=\iftikz@anim@along simple\else position\fi,
+ setup=\tikz@anim@position@setup,
+}%
+\tikzanimationdefineattribute{rotate}{}%
+\tikzanimationdefineattribute{scale}{}%
+\tikzanimationdefineattribute{shift}{
+ pgf attribute name=\iftikz@anim@along motion\else translate\fi,
+ parser=\iftikz@anim@along simple\else shift\fi
+}%
+\tikzanimationdefineattribute{stage}{}%
+\tikzanimationdefineattribute{text opacity}{pgf attribute name=fill opacity, node type=.text, pgf attribute name scope=none}%
+\tikzanimationdefineattribute{text}{pgf attribute name=color, node type=.text, pgf attribute name scope=none}%
+\tikzanimationdefineattribute{view}{scope type=.view, parser=view}%
+\tikzanimationdefineattribute{visible}{}%
+\tikzanimationdefineattribute{xshift}{pgf attribute name=translate, parser=xshift}%
+\tikzanimationdefineattribute{xscale}{pgf attribute name=scale, parser=xscale}%
+\tikzanimationdefineattribute{xskew}{}%
+\tikzanimationdefineattribute{xslant}{pgf attribute name=xskew, parser=slant}%
+\tikzanimationdefineattribute{yshift}{pgf attribute name=translate, parser=yshift}%
+\tikzanimationdefineattribute{yskew}{}%
+\tikzanimationdefineattribute{yslant}{pgf attribute name=yskew, parser=slant}%
+\tikzanimationdefineattribute{yscale}{pgf attribute name=scale, parser=yscale}%
+
+
+\def\tikz@anim@position@setup{%
+ \pgfgettransform\tikz@anim@saved@transform%
+ \expandafter\def\expandafter\tikz@temp\expandafter{%
+ \expandafter\def\expandafter\tikz@anim@saved@transform\expandafter{\tikz@anim@saved@transform}%
+ \pgfsysanimkeycanvastransform{}{}%
+ \tikz@anim@is@positiontrue%
+ }%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@anim@initial@options%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@temp\tikz@anim@initial@options}%
+}%
+\newif\iftikz@anim@is@position
+
+
+% The TikZ animation callbacks
+%
+% Description:
+%
+% The callbacks called by tikz.code.tex whenever an object is
+% created. These callbacks will add the accumulated animation code.
+
+\def\tikz@anim@id@hook{%
+ \expandafter\ifx\csname tikz@anim@att@\tikz@id@name\endcsname\relax%
+ % No named animation:
+ % Now, check for auto animation:
+ \expandafter\ifx\csname tikz@anim@att@\tikz@auto@id\endcsname\relax%
+ \else%
+ % Auto animation%
+ \ifx\tikz@id@name\pgfutil@empty% Id set?
+ % No, so set it
+ \def\tikz@id@name{@auto}%
+ \fi%
+ \pgfidrefnextuse\tikz@anim@current@id\tikz@id@name%
+ \csname tikz@anim@att@\tikz@auto@id\endcsname%
+ \expandafter\global\expandafter\let\csname tikz@anim@att@\tikz@auto@id\endcsname\relax%
+ \fi%
+ \else%
+ % Named animation:
+ \pgfidrefnextuse\tikz@anim@current@id\tikz@id@name%
+ \csname tikz@anim@att@\tikz@id@name\endcsname%
+ \csname tikz@anim@att@\tikz@auto@id\endcsname% and unnamed animation
+ \expandafter\global\expandafter\let\csname tikz@anim@att@\tikz@id@name\endcsname\relax%
+ \expandafter\global\expandafter\let\csname tikz@anim@att@\tikz@auto@id\endcsname\relax%
+ \fi%
+}%
+
+% Add hook:
+\expandafter\def\expandafter\tikz@id@hook\expandafter{\tikz@id@hook\tikz@anim@id@hook}%
+
+
+
+% Attaches an animation to a named object (named in tikz)
+%
+% #1 = name of the object. If equal to the special text "myself", the
+% next created object is meant.
+% #2 = Animation code. When this code is executed, the following
+% things will be setup:
+%
+% \iftikz@is@node will be set to true or false
+% depending on whether the name references a node.
+%
+% \tikz@id@name will be set to the name of the object,
+% typically #1, except when #1 was ".", in this case another
+% name may have been used by the user, which will be used
+% instead.
+%
+% Description:
+%
+% After the call, the next time an object named #1 is created in TikZ
+% (using name=#1), the code #2 will be executed inside a scope to
+% create an animation of the object.
+
+\def\tikzanimationattachto#1#2{%
+ {%
+ \def\tikz@anim@name{#1}%
+ \ifx\tikz@anim@name\pgfutil@empty%
+ \tikzerror{Trying to attach an animation to an unnamed object. This should not happen.}%
+ \else%
+ \expandafter\ifx\csname tikz@anim@att@\tikz@anim@name\endcsname\relax%
+ \expandafter\gdef\csname tikz@anim@att@\tikz@anim@name\endcsname{#2}%
+ \else%
+ \expandafter\let\expandafter\tikz@temp\csname tikz@anim@att@\tikz@anim@name\endcsname%
+ \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@temp#2}%
+ \expandafter\global\expandafter\let\csname tikz@anim@att@\tikz@anim@name\endcsname\tikz@temp%
+ \fi%
+ \fi%
+ }%
+}%
+\def\tikz@auto@id{myself}%
+\expandafter\let\csname tikz@anim@att@\tikz@auto@id\endcsname\relax%
+
+
+% Add config code to a timeline
+%
+% #1 = The object (may be "myself")
+% #2 = The attribute (see pgfanimateattribute)
+% #3 = Timeline sequence identifier
+% #4 = code
+%
+% Description:
+%
+% This commands adds the code to the timeline configuration, which is
+% code that gets executed before the rest of entries of the timeline
+% are executed.
+
+\def\tikz@timeline@config#1#2#3#4{%
+ \expandafter\def\expandafter\tikz@temp\expandafter{\csname tikz@a@conf@#1@#2@#3\endcsname}%
+ \expandafter\ifx\tikz@temp\relax%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\tikz@temp\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\global\expandafter\let\tikz@temp\relax}%
+ \fi%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\tikz@temp\expandafter\expandafter\expandafter{\tikz@temp#4}%
+}%
+
+
+
+% Add a timeline entry
+%
+% #1 = The object (may be "myself")
+% #2 = The attribute (see pgfanimateattribute)
+% #3 = Timeline sequence identifier
+% #4 = early code
+% #5 = later code
+%
+% Description:
+%
+% This command stores an option with a timeline of an object. For each
+% object--attribute--identifier tuple a timeline can be created, for
+% which the values of #4 and #5 are collected. Later on, \pgfanimateattribute
+% will be called for the pgf attribute associated with tikz attribute,
+% the type associated with it and initial code, followed by the
+% accumulated values of #4 and then the accumulated values of #5.
+
+\def\tikz@timeline@entry#1#2#3#4#5{%
+ % First, does the object have an animation already attached?
+ \expandafter\ifx\csname tikz@a@tlo@#1\endcsname\relax%
+ % No, first entry!
+ % Create call:
+ \edef\pgf@marshal{\noexpand\tikzanimationattachto{#1}{\expandafter\noexpand\csname tikz@a@tlo@#1\endcsname}}%
+ \pgf@marshal%
+ \expandafter\gdef\csname tikz@a@tlo@#1\endcsname{\tikz@anim@cleanup{#1}}%
+ \fi%
+ % Second, does the timeline exist?
+ \expandafter\ifx\csname tikz@a@tlc@#1@#2@#3\endcsname\relax%
+ % No, first entry!
+ \def\tikz@anim@initial@early@options{#4}%
+ \def\tikz@anim@initial@options{#5}%
+ \csname tikz@anim@def@setup@#2\endcsname%
+ % Create timeline...
+ \expandafter\global\expandafter\let\csname tikz@a@tlc@#1@#2@#3\endcsname\tikz@anim@initial@options%
+ \expandafter\global\expandafter\let\csname tikz@a@tld@#1@#2@#3\endcsname\tikz@anim@initial@early@options%
+ % ...and add to calls
+ \expandafter\let\expandafter\pgf@temp\csname tikz@a@tlo@#1\endcsname%
+ \expandafter\def\expandafter\pgf@temp@name\expandafter{\tikz@anim@create{#1}{#2}{#3}}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@temp\expandafter\expandafter\expandafter{\expandafter\pgf@temp\pgf@temp@name}%
+ \expandafter\global\expandafter\let\csname tikz@a@tlo@#1\endcsname\pgf@temp%
+ \else%
+ % Add to timeline:
+ \expandafter\let\expandafter\pgf@temp\csname tikz@a@tld@#1@#2@#3\endcsname%
+ \expandafter\def\expandafter\pgf@temp\expandafter{\pgf@temp#4}%
+ \expandafter\global\expandafter\let\csname tikz@a@tld@#1@#2@#3\endcsname\pgf@temp%
+ \expandafter\let\expandafter\pgf@temp\csname tikz@a@tlc@#1@#2@#3\endcsname%
+ \expandafter\def\expandafter\pgf@temp\expandafter{\pgf@temp#5}%
+ \expandafter\global\expandafter\let\csname tikz@a@tlc@#1@#2@#3\endcsname\pgf@temp%
+ \fi%
+}%
+
+
+\def\tikz@anim@cleanup#1{%
+ \expandafter\global\expandafter\let\csname tikz@a@tlo@#1\endcsname\relax%
+}%
+
+\def\tikz@anim@create#1#2#3{%
+ \csname tikz@a@conf@#1@#2@#3\endcsname%
+ \iftikz@is@node%
+ \expandafter\let\expandafter\tikz@temp\csname tikz@anim@def@pgf@attr@@node@#2\endcsname%
+ \else%
+ \expandafter\let\expandafter\tikz@temp\csname tikz@anim@def@pgf@attr@@scope@#2\endcsname%
+ \fi%
+ \ifx\tikz@temp\relax%
+ \expandafter\let\expandafter\tikz@temp\csname tikz@anim@def@pgf@attr@#2\endcsname%
+ \fi%
+ \expandafter\pgfanimateattributecode\expandafter{\tikz@temp}{%
+ \iftikz@is@node%
+ \edef\tikz@anim@whom{\tikz@id@name\csname tikz@anim@def@is@node@#2\endcsname}%
+ \else%
+ \edef\tikz@anim@whom{\tikz@id@name\csname tikz@anim@def@no@node@#2\endcsname}%
+ \fi%
+ \pgfanimationset{whom=\tikz@anim@whom}%
+ \expandafter\let\expandafter\tikz@animation@parser\csname tikz@anim@\csname tikz@anim@def@parser@#2\endcsname @parse\endcsname%
+ \csname tikz@anim@def@code@#2\endcsname%
+ \csname tikz@a@tld@#1@#2@#3\endcsname%
+ \csname tikz@a@tlc@#1@#2@#3\endcsname%
+ }%
+ \expandafter\global\expandafter\let\csname tikz@a@tlc@#1@#2@#3\endcsname\relax%
+ \expandafter\global\expandafter\let\csname tikz@a@tld@#1@#2@#3\endcsname\relax%
+}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryarrows.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryarrows.code.tex
new file mode 100644
index 0000000000..b3f1728e44
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryarrows.code.tex
@@ -0,0 +1,14 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryarrows.code.tex}
+
+\usepgflibrary{arrows}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryautomata.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryautomata.code.tex
new file mode 100644
index 0000000000..690e0fd63a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryautomata.code.tex
@@ -0,0 +1,105 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryautomata.code.tex}
+
+\usetikzlibrary{shapes.multipart}%
+
+% Styles for states:
+
+\tikzset{every state/.style= {}}%
+
+\tikzset{state without output/.style= {circle,draw,minimum size=2.5em,every state}}%
+\tikzset{state with output/.style= {circle split,draw,minimum size=2.5em,every state}}%
+
+\tikzset{accepting by arrow/.style= {after node path=
+{
+ {
+ [to path=
+ {
+ [->,double=none,every accepting by arrow]
+ --
+ ([shift=(\tikz@accepting@angle:\tikz@accepting@distance)]\tikztostart.\tikz@accepting@angle)
+ node [shape=rectangle,anchor=\tikz@accepting@anchor] {\tikz@accepting@text}
+ }]
+ edge ()
+ }
+}}}%
+\tikzset{every accepting by arrow/.style={}}%
+\tikzset{accepting by double/.style= {double,outer sep=.5\pgflinewidth+.3pt}} % .3pt is half double width distance
+
+\tikzset{initial by arrow/.style= {after node path=
+{
+ {
+ [to path=
+ {
+ [->,double=none,every initial by arrow]
+ ([shift=(\tikz@initial@angle:\tikz@initial@distance)]\tikztostart.\tikz@initial@angle)
+ node [shape=rectangle,anchor=\tikz@initial@anchor] {\tikz@initial@text}
+ -- (\tikztostart)}]
+ edge ()
+ }
+}}}%
+\tikzset{every initial by arrow/.style={}}%
+
+\tikzset{initial by diamond/.style={shape=diamond}}%
+
+
+\tikzoption{initial text}{\tikzaddafternodepathoption{\def\tikz@initial@text{#1}}}%
+\tikzoption{accepting text}{\tikzaddafternodepathoption{\def\tikz@accepting@text{#1}}}%
+
+\tikzoption{initial where}{\tikzaddafternodepathoption{\csname tikz@initial@compute@#1\endcsname}}%
+\tikzoption{accepting where}{\tikzaddafternodepathoption{\csname tikz@accepting@compute@#1\endcsname}}%
+
+\tikzoption{initial distance}{\tikzaddafternodepathoption{\def\tikz@initial@distance{#1}}}%
+\tikzoption{accepting distance}{\tikzaddafternodepathoption{\def\tikz@accepting@distance{#1}}}%
+
+\def\tikz@initial@text{start}%
+\def\tikz@accepting@text{}%
+
+\def\tikz@initial@distance{3ex}%
+\def\tikz@accepting@distance{3ex}%
+
+\def\tikz@initial@compute@above{\def\tikz@initial@angle{90}\def\tikz@initial@anchor{south}}%
+\def\tikz@initial@compute@below{\def\tikz@initial@angle{270}\def\tikz@initial@anchor{north}}%
+\def\tikz@initial@compute@left{\def\tikz@initial@angle{180}\def\tikz@initial@anchor{east}}%
+\def\tikz@initial@compute@right{\def\tikz@initial@angle{0}\def\tikz@initial@anchor{west}}%
+
+\def\tikz@initial@angle{180}%
+\def\tikz@initial@anchor{east}%
+
+\def\tikz@accepting@compute@above{\def\tikz@accepting@angle{90}\def\tikz@accepting@anchor{south}}%
+\def\tikz@accepting@compute@below{\def\tikz@accepting@angle{270}\def\tikz@accepting@anchor{north}}%
+\def\tikz@accepting@compute@left{\def\tikz@accepting@angle{180}\def\tikz@accepting@anchor{east}}%
+\def\tikz@accepting@compute@right{\def\tikz@accepting@angle{0}\def\tikz@accepting@anchor{west}}%
+
+\def\tikz@accepting@angle{0}%
+\def\tikz@accepting@anchor{west}%
+
+
+\tikzset{initial above/.style= {initial by arrow,initial where=above}}%
+\tikzset{initial below/.style= {initial by arrow,initial where=below}}%
+\tikzset{initial left/.style= {initial by arrow,initial where=left}}%
+\tikzset{initial right/.style= {initial by arrow,initial where=right}}%
+
+\tikzset{accepting above/.style= {accepting by arrow,accepting where=above}}%
+\tikzset{accepting below/.style= {accepting by arrow,accepting where=below}}%
+\tikzset{accepting left/.style= {accepting by arrow,accepting where=left}}%
+\tikzset{accepting right/.style= {accepting by arrow,accepting where=right}}%
+
+
+% Defaults:
+
+\tikzset{state/.style= {state without output}}%
+\tikzset{accepting/.style= {accepting by double}}%
+\tikzset{initial/.style= {initial by arrow}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex
new file mode 100644
index 0000000000..e24439f75f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex
@@ -0,0 +1,17 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarybabel.code.tex}
+
+\tikzset{
+ handle active characters in code,
+ handle active characters in nodes,
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
new file mode 100644
index 0000000000..1a42a4b40e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
@@ -0,0 +1,148 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarybackgrounds.code.tex}
+
+
+% Layers
+
+\pgfdeclarelayer{background}%
+\pgfsetlayers{background,main}%
+
+
+% Switch command
+\tikzset{on background layer/.style={
+ execute at begin scope={%
+ \pgfonlayer{background}%
+ \let\tikz@options=\pgfutil@empty%
+ \tikzset{every on background layer/.try,#1}%
+ \tikz@options},
+ execute at end scope={\endpgfonlayer}
+ }
+}%
+
+
+% Main style
+
+\tikzset{background rectangle/.style= {draw}}%
+\tikzset{background top/.style= {draw}}%
+\tikzset{background bottom/.style= {draw}}%
+\tikzset{background left/.style= {draw}}%
+\tikzset{background right/.style= {draw}}%
+\tikzset{background grid/.style= {help lines,draw}}%
+
+\tikzoption{inner frame sep}{\def\tikz@framexsep{#1}\def\tikz@frameysep{#1}}%
+\tikzoption{inner frame xsep}{\def\tikz@framexsep{#1}}%
+\tikzoption{inner frame ysep}{\def\tikz@frameysep{#1}}%
+\def\tikz@framexsep{1ex}%
+\def\tikz@frameysep{1ex}%
+
+\tikzoption{outer frame sep}{\def\tikz@outerframexsep{#1}\def\tikz@outerframeysep{#1}}%
+\tikzoption{outer frame xsep}{\def\tikz@outerframexsep{#1}}%
+\tikzoption{outer frame ysep}{\def\tikz@outerframeysep{#1}}%
+\def\tikz@outerframexsep{0ex}%
+\def\tikz@outerframeysep{0ex}%
+
+
+% Looseness
+
+\tikzset{loose background/.style= {inner frame sep=2ex}}%
+\tikzset{tight background/.style= {inner frame sep=0ex}}%
+
+
+
+% Showing background styles
+
+\tikzset{framed/.style= {style=show background rectangle}}%
+\tikzset{gridded/.style= {style=show background grid}}%
+
+\tikzset{show background rectangle/.style={execute at end picture=\tikz@background@framed}}%
+\tikzset{show background top/.style= {execute at end picture=\tikz@background@top}}%
+\tikzset{show background bottom/.style= {execute at end picture=\tikz@background@bottom}}%
+\tikzset{show background left/.style= {execute at end picture=\tikz@background@left}}%
+\tikzset{show background right/.style= {execute at end picture=\tikz@background@right}}%
+\tikzset{show background grid/.style= {execute at end picture=\tikz@background@grid}}%
+
+
+% Implementation
+
+\def\tikz@background@save{%
+ \pgftransformreset%
+ \ifx\tikz@bg@minx\@undefined%
+ \pgf@xb=\pgf@picminx%
+ \pgf@yb=\pgf@picminy%
+ \pgf@xc=\pgf@picmaxx%
+ \pgf@yc=\pgf@picmaxy%
+ \pgfmathsetlength{\pgf@x}{\tikz@framexsep}%
+ \pgfmathsetlength{\pgf@y}{\tikz@frameysep}%
+ \advance\pgf@xb by-\pgf@x%
+ \advance\pgf@yb by-\pgf@y%
+ \advance\pgf@xc by\pgf@x%
+ \advance\pgf@yc by\pgf@y%
+ \edef\tikz@bg@minx{\the\pgf@xb}%
+ \edef\tikz@bg@miny{\the\pgf@yb}%
+ \edef\tikz@bg@maxx{\the\pgf@xc}%
+ \edef\tikz@bg@maxy{\the\pgf@yc}%
+ \pgfmathsetlength{\pgf@x}{\tikz@outerframexsep}%
+ \pgfmathsetlength{\pgf@y}{\tikz@outerframeysep}%
+ \advance\pgf@xb by-\pgf@x%
+ \advance\pgf@yb by-\pgf@y%
+ \advance\pgf@xc by\pgf@x%
+ \advance\pgf@yc by\pgf@y%
+ \edef\tikz@bg@outerminx{\the\pgf@xb}%
+ \edef\tikz@bg@outerminy{\the\pgf@yb}%
+ \edef\tikz@bg@outermaxx{\the\pgf@xc}%
+ \edef\tikz@bg@outermaxy{\the\pgf@yc}%
+ \fi%
+}%
+
+\def\tikz@background@framed{%
+ \tikz@background@save%
+ \pgfonlayer{background}
+ \path[style=background rectangle] (\tikz@bg@minx,\tikz@bg@miny) rectangle (\tikz@bg@maxx,\tikz@bg@maxy);
+ \endpgfonlayer
+}%
+
+\def\tikz@background@top{%
+ \tikz@background@save%
+ \pgfonlayer{background}
+ \path[style=background top] (\tikz@bg@outerminx,\tikz@bg@maxy) -- (\tikz@bg@outermaxx,\tikz@bg@maxy);
+ \endpgfonlayer
+}%
+
+\def\tikz@background@bottom{%
+ \tikz@background@save%
+ \pgfonlayer{background}
+ \path[style=background bottom] (\tikz@bg@outerminx,\tikz@bg@miny) -- (\tikz@bg@outermaxx,\tikz@bg@miny);
+ \endpgfonlayer
+}%
+
+\def\tikz@background@left{%
+ \tikz@background@save%
+ \pgfonlayer{background}
+ \path[style=background left] (\tikz@bg@minx,\tikz@bg@outerminy) -- (\tikz@bg@minx,\tikz@bg@outermaxy);
+ \endpgfonlayer
+}%
+
+\def\tikz@background@right{%
+ \tikz@background@save%
+ \pgfonlayer{background}
+ \path[style=background right] (\tikz@bg@maxx,\tikz@bg@outerminy) -- (\tikz@bg@maxx,\tikz@bg@outermaxy);
+ \endpgfonlayer
+}%
+
+\def\tikz@background@grid{%
+ \tikz@background@save%
+ \pgfonlayer{background}
+ \path[style=background grid] (\tikz@bg@minx,\tikz@bg@miny) grid (\tikz@bg@maxx,\tikz@bg@maxy);
+ \endpgfonlayer
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex
new file mode 100644
index 0000000000..169995bcde
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex
@@ -0,0 +1,15 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarybending.code.tex}
+
+\usepgfmodule{bending}%
+\tikzset{arrows=[flex]}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex
new file mode 100644
index 0000000000..373ea7752d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex
@@ -0,0 +1,618 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarycalc.code.tex}
+
+%
+%
+% Part I: The let path command
+%
+%
+
+
+%
+% Syntax: let \p{name1} = (coord), \p{name2} = (coord), ... in ...
+%
+% Currently (this may get more fancy in the future), the (coord)s are
+% evaluated one by one. If the first evaluates to, say, (10pt,20pt),
+% the macro \p{name1} is set to "10pt,20pt" (without parentheses), the
+% macro \x{name1} is set to "10pt" and the macro \y{name1} is set to
+% "20pt".
+%
+% If you use a number for {name}, you need no parentheses, so you
+% could write:
+%
+% \draw let
+% \p1 = (1,1),
+% \p2 = ($ 2.5*(3,2) $)
+% in
+% (\x1,\x2) -- (\y1,\y2);
+
+\def\tikz@let@command et{%
+ \let\p=\tikz@cc@dop%
+ \let\x=\tikz@cc@dox%
+ \let\y=\tikz@cc@doy%
+ \let\n=\tikz@cc@don%
+ \pgfutil@ifnextchar i{\tikz@cc@stop@let}{\tikz@cc@handle@line}%
+}%
+\def\tikz@cc@handle@line{%
+ \pgfutil@ifnextchar\p{%
+ \tikz@cc@handle@coor%
+ }{%
+ \pgfutil@ifnextchar\n{%
+ \tikz@cc@handle@num%
+ }{%
+ \pgfutil@ifnextchar i{%
+ \tikz@cc@stop@let
+ }{%
+ \tikzerror{``\string\p'' or ``\string\n'' expected}%
+ }%
+ }%
+ }%
+}%
+\def\tikz@cc@handle@num\n#1#2=#3{%
+ \pgfmathparse{#3}%
+ \expandafter\edef\csname tikz@cc@n@#1\endcsname{\pgfmathresult\ifpgfmathunitsdeclared pt\fi}
+ \pgfutil@ifnextchar,{\tikz@cc@handle@nextline}{\tikz@cc@stop@let}%
+}%
+\def\tikz@cc@handle@coor\p#1#2={%
+ \def\tikz@cc@coord@name{#1}%
+ \tikz@scan@one@point\tikz@cc@dolet%
+}%
+\def\tikz@cc@dolet#1{%
+ \pgf@process{#1}%
+ \expandafter\edef\csname tikz@cc@p@\tikz@cc@coord@name\endcsname{\the\pgf@x,\the\pgf@y}%
+ \expandafter\edef\csname tikz@cc@x@\tikz@cc@coord@name\endcsname{\the\pgf@x}%
+ \expandafter\edef\csname tikz@cc@y@\tikz@cc@coord@name\endcsname{\the\pgf@y}%
+ \pgfutil@ifnextchar,{\tikz@cc@handle@nextline}{\tikz@cc@stop@let}%
+}%
+\def\tikz@cc@handle@nextline,{%
+ \tikz@cc@handle@line%
+}%
+\def\tikz@cc@stop@let in{%
+ \tikz@scan@next@command%
+}%
+
+\def\tikz@cc@dop#1{\csname tikz@cc@p@#1\endcsname}%
+\def\tikz@cc@dox#1{\csname tikz@cc@x@#1\endcsname}%
+\def\tikz@cc@doy#1{\csname tikz@cc@y@#1\endcsname}%
+\def\tikz@cc@don#1{\csname tikz@cc@n@#1\endcsname}%
+
+
+
+%
+%
+% Part II: The ($...$) parser
+%
+%
+
+\def\tikz@parse@calculator#1(${%$
+ \def\tikz@cc@command{#1}%
+ \begingroup%
+ %
+ % Parse main computation. It's a series of optional factors in front
+ % of coordinates.
+ %
+ \pgf@xa=0pt% We accumulate the result in here.
+ \pgf@ya=0pt%
+ \tikz@cc@parse+%
+}%
+
+\def\tikz@cc@parse{%
+ \pgfutil@ifnextchar${%$
+ % Ok, we found the end...
+ \tikz@cc@end%
+ }
+ {\pgfutil@ifnextchar+{%
+ % Ok, we found a coordinate...
+ \tikz@cc@add%
+ }{%
+ \pgfutil@ifnextchar-{%
+ \tikz@cc@sub%
+ }{%
+ \tikzerror{+ or - expected}%
+ \tikz@cc@end$%$
+ }%
+ }%
+ }%
+}%
+
+%
+% The end is reached with $
+%
+\def\tikz@cc@end$#1){%$
+ \xdef\tikz@marshal{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \endgroup%
+ \expandafter\tikz@cc@command\expandafter{\tikz@marshal}%
+}%
+
+
+%
+% Another coordinate with +/-, possibly with a factor
+%
+\def\tikz@cc@add+{%
+ \def\tikz@cc@factor{1}%
+ \tikz@cc@factororcoordinate%
+}%
+\def\tikz@cc@sub-{%
+ \def\tikz@cc@factor{-1}%
+ \tikz@cc@factororcoordinate%
+}%
+
+%
+% Check for a factor: If we see a (, its a coordinate...
+%
+\def\tikz@cc@factororcoordinate{%
+ \pgfutil@ifnextchar({%)
+ % Ok, found coordinate
+ \tikz@cc@coordinate%
+ }{%
+ \tikz@cc@parse@factor%
+ }%
+}%
+
+%
+% ... otherwise it's a factor. It ends at ...*(
+%
+\def\tikz@cc@parse@factor#1*({%
+ \pgfmathparse{#1*\tikz@cc@factor}%
+ \let\tikz@cc@factor=\pgfmathresult%
+ \tikz@cc@coordinate(%)
+}%
+
+\def\tikz@cc@coordinate{%
+ \tikz@scan@absolute\tikz@cc@after@coordinate%
+}%
+\def\tikz@cc@after@coordinate#1{%
+ \pgf@process{#1}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \tikz@cc@mid@checks%
+}%
+
+
+%
+% A coordinate can be followed by !...!(...)
+%
+
+\def\tikz@cc@mid@checks{%
+ \ifnum\the\catcode`\!=\active\relax
+ \expandafter\tikz@cc@mid@checks@active
+ \else
+ \expandafter\tikz@cc@mid@checks@nonactive
+ \fi
+}%
+
+\def\tikz@cc@mid@checks@nonactive{%
+ \pgfutil@ifnextchar!{%
+ \tikz@cc@mid@nonactive%
+ }{%
+ \advance\pgf@xa by\tikz@cc@factor\pgf@xb
+ \advance\pgf@ya by\tikz@cc@factor\pgf@yb
+ \tikz@cc@parse%
+ }%
+}%
+
+\def\tikz@cc@mid@nonactive!{%
+ \pgfutil@ifnextchar({%
+ \tikz@scan@one@point\tikz@cc@project%
+ }{%
+ \tikz@cc@mid@num@nonactive%
+ }%
+}%
+
+\begingroup
+ \catcode`\!=\active
+ \gdef\tikz@cc@mid@checks@active{%
+ \pgfutil@ifnextchar!{%
+ \tikz@cc@mid@active%
+ }{%
+ \advance\pgf@xa by\tikz@cc@factor\pgf@xb
+ \advance\pgf@ya by\tikz@cc@factor\pgf@yb
+ \tikz@cc@parse%
+ }%
+ }%
+
+ \gdef\tikz@cc@mid@active!{%
+ \pgfutil@ifnextchar({%
+ \tikz@scan@one@point\tikz@cc@project%
+ }{%
+ \tikz@cc@mid@num@active%
+ }%
+ }%
+\endgroup
+
+%
+% Partway case: (coord a)!number!(coord b)
+%
+% Returns the position that is at <number> fraction on the way from a
+% to b. This, (a)!0!(b) is (a), (a)!.5!(b) is the middle and (a)!1!(b)
+% is (b)
+%
+
+\def\tikz@cc@mid@num@nonactive#1!{\tikz@cc@mid@num{#1}}%
+
+\begingroup
+ \catcode`\!=\active
+ \gdef\tikz@cc@mid@num@active#1!{\tikz@cc@mid@num{#1}}%
+\endgroup
+
+\def\tikz@cc@mid@num#1{%
+ \pgfmathparse{#1}%
+ \ifpgfmathunitsdeclared%
+ \let\tikz@cc@mid@unit=\pgfmathresult%
+ \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@unit%
+ \else%
+ \let\tikz@cc@mid@factor=\pgfmathresult%
+ \pgfmathparse{1-\tikz@cc@mid@factor}%
+ \let\tikz@cc@mid@factor@one=\pgfmathresult%
+ \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@num%
+ \fi%
+}%
+
+\def\tikz@cc@after@num#1{%
+ \pgf@process{#1}%
+ \pgf@xb=\tikz@cc@mid@factor@one\pgf@xb%
+ \pgf@yb=\tikz@cc@mid@factor@one\pgf@yb%
+ \advance\pgf@xb by\tikz@cc@mid@factor\pgf@x%
+ \advance\pgf@yb by\tikz@cc@mid@factor\pgf@y%
+ \tikz@cc@mid@checks%
+}%
+
+
+
+%
+% Distance case: (coord a)!dimension!(coord b)
+%
+% Returns the position that is at <dimension> removed from (coord a)
+% in the direction of (coord b).
+%
+
+\def\tikz@cc@after@unit#1{%
+ \pgf@process{#1}%
+ \advance\pgf@x by-\pgf@xb%
+ \advance\pgf@y by-\pgf@yb%
+ \pgf@process{\pgfpointnormalised{}}%
+ \advance\pgf@xb by\tikz@cc@mid@unit\pgf@x%
+ \advance\pgf@yb by\tikz@cc@mid@unit\pgf@y%
+ \tikz@cc@mid@checks%
+}%
+
+%
+% Projection case: (a)!(p)!(b)
+%
+% Projection of p on line from a to b
+%
+\def\tikz@cc@project#1{%
+ \pgf@process{#1}%
+ % Save in c
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \begingroup
+ \ifnum\the\catcode`\!=\active
+ \def\tikz@next{%
+ \endgroup
+ \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project
+ \tikz@cc@scan@ex@active}%
+ \else
+ \def\tikz@next{%
+ \endgroup
+ \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project
+ \tikz@cc@scan@ex@nonactive}%
+ \fi
+ \tikz@next%
+}%
+
+\def\tikz@cc@scan@ex@nonactive!{}%
+
+\begingroup
+ \catcode`\!=\active
+ \gdef\tikz@cc@scan@ex@active!{}%
+\endgroup
+
+\def\tikz@cc@after@project#1{%
+ \pgf@process{#1}%
+ % Ok, now we need to project (xc,yc) on the line (xb,xc) to (x,y)
+ \advance\pgf@x by-\pgf@xb%
+ \advance\pgf@y by-\pgf@yb%
+ \advance\pgf@xc by-\pgf@xb%
+ \advance\pgf@yc by-\pgf@yb%
+ \pgf@process{\pgfpointnormalised{}}%
+ % Scalar product
+ \pgf@xc=\pgf@sys@tonumber{\pgf@xc}\pgf@x%
+ \advance\pgf@xc by\pgf@sys@tonumber{\pgf@yc}\pgf@y%
+ % and add
+ \advance\pgf@xb by\pgf@sys@tonumber{\pgf@xc}\pgf@x%
+ \advance\pgf@yb by\pgf@sys@tonumber{\pgf@xc}\pgf@y%
+ \tikz@cc@mid@checks%
+}%
+
+%
+% Rotational scanner: radius:(x)
+%
+
+\def\tikz@cc@scan@rot#1{%
+ \pgfutil@ifnextchar({%)
+ \tikz@scan@one@point#1% normal
+ }%
+ {%
+ \def\tikz@cc@scan@rot@cmd{#1}%
+ \ifnum\the\catcode`\:=\active\relax
+ \expandafter\tikz@cc@scan@one@rot@active%
+ \else
+ \expandafter\tikz@cc@scan@one@rot@nonactive%
+ \fi
+ }%
+}%
+
+\def\tikz@cc@scan@one@rot@nonactive#1:{%
+ \def\tikz@cc@scan@rot@angle{#1}%
+ \tikz@scan@one@point\tikz@cc@handle@rot%
+}%
+
+\begingroup
+ \catcode`\:=\active
+ \gdef\tikz@cc@scan@one@rot@active#1:{%
+ \def\tikz@cc@scan@rot@angle{#1}%
+ \tikz@scan@one@point\tikz@cc@handle@rot%
+ }%
+\endgroup
+
+\def\tikz@cc@handle@rot#1{%
+ \pgf@process{#1}%
+ % Ok, now we need to rotate x/y around xb/xb by ...rot@angle
+ {%
+ \pgftransformreset%
+ % Save them...
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgftransformshift{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgftransformrotate{\tikz@cc@scan@rot@angle}%
+ \pgftransformshift{\pgfqpoint{-\pgf@xb}{-\pgf@yb}}%
+ \pgfpointtransformed{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \expandafter
+ }%
+ \edef\tikz@marshal{\noexpand\tikz@cc@scan@rot@cmd{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \tikz@marshal%
+}%
+
+
+
+
+%
+%
+% Part III: Calculation coordinate systems
+%
+%
+
+% Tangent cs: Keys are a node and a point. Depending on the type of
+% node, the appropriate tangent computation should be done.
+
+\tikzdeclarecoordinatesystem{tangent}
+{%
+ \tikzset{cs/.cd,#1}%
+ \expandafter\ifx\csname tikz@tangent@\tikz@cs@type\endcsname\relax%
+ \tikzerror{I do not know how to compute the tangent to
+ a \tikz@cs@type}%
+ \pgfpointorigin%
+ \else%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@lib@do@tangent\tikz@cs@point%
+ \fi%
+}%
+
+\tikzset{cs/node/.code=\tikz@cs@unpack{\tikz@cs@node}{\tikz@cs@type}{#1}}%
+\tikzset{cs/point/.store in=\tikz@cs@point}%
+
+\def\tikz@lib@do@tangent{\csname tikz@tangent@\tikz@cs@type\endcsname}%
+
+\def\tikz@tangent@coordinate#1{%
+ \pgfpointanchor{\tikz@cs@node}{center}%
+}%
+
+\def\tikz@tangent@circle#1{%
+ {%
+ % Step 1: Compute the transformed position of the input:
+ \pgf@process{\pgfpointtransformed{#1}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ %
+ % Step 2: Compute vector from center of circle to transformed #1
+ %
+ \pgf@process{\pgfpointtransformed{\pgfpointanchor{\tikz@cs@node}{center}}}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ %
+ % Step 2: Reset transformations, they distract...
+ %
+ \pgftransformreset%
+ %
+ % Step 3: Transform to the center of the circle.
+ %
+ \pgftransformshift{\pgfpointanchor{\tikz@cs@node}{center}}%
+ %
+ % Step 4: Compute the radius
+ %
+ \pgf@process{\pgfpointanchor{\tikz@cs@node}{east}}%
+ \pgf@xc=\pgf@x%
+ %
+ % Now, (xa,ya) is a point. Compute the tangent from this point to
+ % a circle around the origin of radius xc.
+ %
+ % acos(radius/veclen(xa,ya)) is the angle of the tangent.
+ \pgfmathparse{veclen(\the\pgf@xa,\the\pgf@ya)}
+ \pgfmathparse{acos(\the\pgf@xc/\pgfmathresult)}
+ \ifnum\pgfkeysvalueof{/tikz/cs/solution}>1\relax%
+ \pgfmathparse{0-\pgfmathresult}%
+ \fi%
+ \let\tikz@lib@temp=\pgfmathresult%
+ %
+ % Now \pgfmathparse contains the desired angle. Use this to
+ % compute the correct position on the circle...
+ %
+ % But, first, rotate to the point.
+ \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}%
+ % Finally, rotate...
+ \pgf@process{\pgfpointtransformed{\pgfpointpolar{\tikz@lib@temp}{\the\pgf@xc}}}%
+ %
+ % Ok, undo transformations...
+ }%
+ % \pgf@x, \pgf@y have been smuggled outside by \pgf@process
+ {%
+ \pgftransforminvert%
+ \pgf@process{\pgfpointtransformed{}}%
+ }%
+}%
+
+
+% Implementation of intersections
+
+
+\def\tikz@intersect@circle@and@circle{%
+ {%
+ \pgftransformreset% transformations only confuse us, here...
+ %
+ % Compute origin and radius of first circle
+ %
+ \pgf@process{\pgfpointanchor{\tikz@cs@node@a}{center}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointanchor{\tikz@cs@node@a}{east}}%
+ \advance\pgf@x by-\pgf@xa%
+ \pgf@xc=\pgf@x% ok, pgf@xc is first radius, (xa,ya) is center
+ %
+ % Compute origin and radius of second circle
+ %
+ \pgf@process{\pgfpointanchor{\tikz@cs@node@b}{center}}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{\pgfpointanchor{\tikz@cs@node@b}{east}}%
+ \advance\pgf@x by-\pgf@xb%
+ \pgf@yc=\pgf@x% \pgf@yc is second radius, (xb,yb) is center
+ %
+ \pgf@process{%
+ \pgfpointintersectionofcircles{\pgfqpoint{\pgf@xa}{\pgf@ya}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgf@xc}{\pgf@yc}{\pgfkeysvalueof{/tikz/cs/solution}}%
+ }%
+ }%
+ % \pgf@x, \pgf@y have been smuggled outside by \pgf@process,
+ % reinstall transformations...
+ {%
+ \pgftransforminvert%
+ \pgf@process{\pgfpointtransformed{}}%
+ }%
+}%
+
+
+\def\tikz@intersect@line@and@circle{%
+ {%
+ %
+ % Step 1: Get line
+ %
+ \expandafter\tikz@scan@one@point\expandafter\tikz@parse@line\tikz@cs@line@a%
+ \pgf@process{\pgfpointtransformed{}}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ %
+ % Step 2: Subtract center of circle
+ %
+ \pgf@process{\pgfpointtransformed{\pgfpointanchor{\tikz@cs@node@b}{center}}}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \advance\pgf@xb by-\pgf@x%
+ \advance\pgf@yb by-\pgf@y%
+ %
+ % Step 3: Reset transformations, they distract...
+ %
+ \pgftransformreset%
+ %
+ % Step 4: Transform to the center of the circle.
+ %
+ \pgftransformshift{\pgfpointanchor{\tikz@cs@node@b}{center}}%
+ %
+ % Step 5: Compute the radius
+ %
+ \pgf@process{\pgfpointanchor{\tikz@cs@node@b}{east}}%
+ \edef\tikz@lib@saved@radius{\pgf@sys@tonumber{\pgf@x}}%
+ %
+ % Step 6: Compute projection of origin on line (xa,ya) -- (xb,yb),
+ % store in (xa,ya)
+ \pgf@x=\pgf@xb%
+ \pgf@y=\pgf@yb%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \pgf@process{\pgfpointnormalised{}}%
+ % Scalar product
+ \pgf@xc=\pgf@sys@tonumber{\pgf@xa}\pgf@x%
+ \advance\pgf@xc by\pgf@sys@tonumber{\pgf@ya}\pgf@y%
+ \pgf@xc=-\pgf@xc%
+ % and add
+ \advance\pgf@xa by\pgf@sys@tonumber{\pgf@xc}\pgf@x%
+ \advance\pgf@ya by\pgf@sys@tonumber{\pgf@xc}\pgf@y%
+ %
+ % Now, we have a triangle with a right angle at (xa,ya). The
+ % second point of the triangle is the origin. The third point is
+ % sought.
+ % Save x/y
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ % Square radius
+ \pgf@xb=\tikz@lib@saved@radius pt%
+ %
+ % First, make numbers smaller, in case they are too large
+ %
+ \c@pgf@counta=1\relax%
+ \loop%
+ \ifdim\pgf@xb>50pt%
+ \multiply\c@pgf@counta by2\relax%
+ \divide\pgf@xa by2\relax%
+ \divide\pgf@ya by2\relax%
+ \divide\pgf@xb by2\relax%
+ \repeat%
+ \pgf@xb=\pgf@sys@tonumber{\pgf@xb}\pgf@xb%
+ % Subtract xa^2 + ya^2
+ \pgf@yb=\pgf@sys@tonumber{\pgf@xa}\pgf@xa%
+ \advance\pgf@xb by-\pgf@yb%
+ \pgf@yb=\pgf@sys@tonumber{\pgf@ya}\pgf@ya%
+ \advance\pgf@xb by-\pgf@yb%
+ % Square root
+ \ifdim\pgf@xb<0pt%
+ \pgf@xb=0pt%
+ \fi%
+ \pgfmathsqrt@{\pgf@sys@tonumber{\pgf@xb}}%
+ \pgfmathmultiply@{\pgfmathresult}{\the\c@pgf@counta}%
+ \multiply\pgf@xa by\c@pgf@counta\relax%
+ \multiply\pgf@ya by\c@pgf@counta\relax%
+ \ifnum\pgfkeysvalueof{/tikz/cs/solution}>1\relax%
+ \pgfmathsubtract{0}{\pgfmathresult}%
+ \fi%
+ % Ok, now add things...
+ \advance\pgf@xa by \pgfmathresult\pgf@xc%
+ \advance\pgf@ya by \pgfmathresult\pgf@yc%
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
+ % Ok, undo transformations...
+ }%
+ % \pgf@x, \pgf@y have been smuggled outside by \pgf@process
+ {%
+ \pgftransforminvert%
+ \pgf@process{\pgfpointtransformed{}}%
+ }%
+}%
+
+\def\tikz@intersect@circle@and@line{%
+ % Swap
+ {%
+ \let\tikz@cs@node@b=\tikz@cs@node@a%
+ \let\tikz@cs@line@a=\tikz@cs@line@b%
+ \tikz@intersect@line@and@circle%
+ }%
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex
new file mode 100644
index 0000000000..98cdffe154
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex
@@ -0,0 +1,444 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarycalendar.code.tex}
+
+
+\pgfutil@usemodule{pgfcalendar}
+
+
+%
+% General options (these options affect all calendars typeset unsind \calendar):
+%
+% Start, end, and code executed for each current date
+%
+
+\tikzoption{dates}{\tikz@lib@cal@parse#1\relax}
+\def\tikz@lib@cal@parse#1to#2\relax{%
+ \def\tikz@lib@cal@start{#1}
+ \def\tikz@lib@cal@end{#2}%
+}
+\tikzoption{execute at begin day scope}{\expandafter\def\expandafter\tikz@atbegin@day\expandafter{\tikz@atbegin@day#1}}
+\tikzoption{execute at end day scope}{%
+ \def\pgf@temp{#1}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@atend@day%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@temp\tikz@atend@day}}
+\tikzoption{execute before day scope}{\expandafter\def\expandafter\tikz@before@day\expandafter{\tikz@before@day#1}}
+\tikzoption{execute after day scope}{\expandafter\def\expandafter\tikz@after@day\expandafter{\tikz@after@day#1}}
+
+\let\tikz@atbegin@day=\pgfutil@empty
+\let\tikz@atend@day=\pgfutil@empty
+\let\tikz@before@day=\pgfutil@empty
+\let\tikz@after@day=\pgfutil@empty
+
+
+
+%
+% Options affecting some calendars:
+%
+
+%
+% Shifts and skips
+%
+
+% Shift between days
+
+\tikzoption{day xshift}{\def\tikz@lib@cal@xshift{#1}}
+\tikzoption{day yshift}{\def\tikz@lib@cal@yshift{#1}}
+
+\def\tikz@lib@cal@yshift{3ex}
+\def\tikz@lib@cal@xshift{3.5ex}
+
+
+% Shift between months
+
+\tikzoption{month xshift}{\def\tikz@lib@cal@month@xshift{#1}}
+\tikzoption{month yshift}{\def\tikz@lib@cal@month@yshift{#1}}
+
+\def\tikz@lib@cal@month@yshift{9ex}
+\def\tikz@lib@cal@month@xshift{9ex}
+
+
+
+
+% Templates for typesetting days, month, years
+
+\tikzoption{day code}{\def\tikzdaycode{#1}}
+\tikzoption{day text}{\def\tikzdaytext{#1}}
+\tikzoption{days}{\tikzset{every day/.append style={#1}}}
+\tikzset{every day/.style={anchor=base east}}
+
+\tikzoption{month code}{\def\tikzmonthcode{#1}}
+\tikzoption{month text}{\def\tikzmonthtext{#1}}
+\tikzset{every month/.style={}}
+
+\tikzoption{year code}{\def\tikzyearcode{#1}}
+\tikzoption{year text}{\def\tikzyeartext{#1}}
+\tikzset{every year/.style={}}
+
+\def\tikzdaycode{\node[name=\pgfcalendarsuggestedname,every day]{\tikzdaytext};}
+\def\tikzmonthcode{\node[every month]{\tikzmonthtext};}
+\def\tikzyearcode{\node[every year]{\tikzyeartext};}
+
+\def\tikzdaytext{\%d-}
+\def\tikzmonthtext{\%mt}
+\def\tikzyeartext{\%y0}
+
+
+% Internal option for storing the "width" of a calendar as a number of
+% days
+
+\tikzoption{tikz@lib@cal@width}{\def\tikz@lib@cal@width{#1}}
+
+\def\tikz@lib@cal@width{1}
+
+%
+% Days on a line
+%
+
+\tikzset{day list downward/.style={%
+ execute before day scope={
+ \ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}
+ {%
+ % On first of month, except when first date in calendar.
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
+ \pgftransformyshift{-\pgf@y}
+ }%
+ }{}%
+ },
+ execute after day scope={\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}\pgftransformyshift{-\pgf@y}},
+ tikz@lib@cal@width=1
+}}
+\tikzset{day list upward/.style={%
+ execute before day scope={
+ \ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}
+ {%
+ % On first of month, except when first date in calendar.
+ \pgftransformyshift{\tikz@lib@cal@month@yshift}%
+ }%
+ }{}%
+ },
+ execute after day scope={\pgftransformyshift\tikz@lib@cal@yshift},
+ tikz@lib@cal@width=1
+}}
+\tikzset{day list right/.style={%
+ execute before day scope={
+ \ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}
+ {%
+ % On first of month, except when first date in calendar.
+ \pgftransformxshift{\tikz@lib@cal@month@xshift}%
+ }%
+ }{}%
+ },
+ execute after day scope={\pgftransformxshift\tikz@lib@cal@xshift},
+ tikz@lib@cal@width=30% not quite right, but close enough in most cases...
+}}
+
+\tikzset{day list left/.style={%
+ execute before day scope={
+ \ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}
+ {%
+ % On first of month, except when first date in calendar.
+ \pgfmathsetlength{\pgf@x}{\tikz@lib@cal@month@xshift}
+ \pgftransformxshift{-\pgf@x}%
+ }%
+ }{}%
+ },
+ execute after day scope={
+ \pgfmathsetlength{\pgf@x}{\tikz@lib@cal@xshift}
+ \pgftransformxshift{-\pgf@x}%
+ },
+ tikz@lib@cal@width=30% not quite right, but close enough in most cases...
+}}
+
+
+
+%
+% Week list
+%
+
+\tikzset{week list/.style={%
+ execute before day scope={%
+ \ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}
+ {%
+ % On first of month, except when first date in calendar.
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
+ \pgftransformyshift{-\pgf@y}
+ }%
+ }{}%
+ },
+ execute at begin day scope={%
+ \pgfmathsetlength\pgf@x{\tikz@lib@cal@xshift}%
+ \pgf@x=\pgfcalendarcurrentweekday\pgf@x%
+ \pgftransformxshift{\pgf@x}%
+ },
+ execute after day scope={%
+ \ifdate{Sunday}{%
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
+ \pgftransformyshift{-\pgf@y}
+ }{}%
+ },
+ tikz@lib@cal@width=7
+}}
+
+
+
+%
+% Month list
+%
+
+\tikzset{month list/.style={%
+ execute before day scope={%
+ \ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}
+ {%
+ % On first of month, except when first date in calendar.
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
+ \pgftransformyshift{-\pgf@y}
+ }%
+ }{}%
+ \ifdate{day of month=1}
+ {%
+ \edef\tikz@lib@cal@month@list@start{\pgfcalendarcurrentweekday}%
+ }{}%
+ \ifdate{equals=\pgfcalendarbeginiso}%
+ {%
+ % Computer day of week for start of month
+ {%
+ \c@pgf@counta=\pgfcalendarcurrentjulian%
+ \advance\c@pgf@counta by-\pgfcalendarcurrentday%
+ \advance\c@pgf@counta by1\relax%
+ \pgfcalendarjuliantoweekday{\c@pgf@counta}{\c@pgf@countb}%
+ \xdef\pgf@temp{\the\c@pgf@countb}%
+ }%
+ \let\tikz@lib@cal@month@list@start=\pgf@temp%
+ }{}%
+ },
+ execute at begin day scope={%
+ \pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
+ \pgf@xb=\pgfcalendarcurrentday\pgf@xa%
+ \advance\pgf@xb by\tikz@lib@cal@month@list@start\pgf@xa%
+ \advance\pgf@xb by-\pgf@xa\relax%
+ \pgftransformxshift{\pgf@xb}%
+ },
+ tikz@lib@cal@width=37
+}}
+
+
+
+
+%
+% Month labels
+%
+
+\tikzset{month label left/.style={%
+ execute before day scope={\ifdate{day of month=1}{\tikzmonthcode}{}},
+ every month/.append style={anchor=base east,xshift=-3.5ex}
+}}
+
+\tikzset{month label left vertical/.style={%
+ execute before day scope={\ifdate{day of month=1}{\tikzmonthcode}{}},
+ every month/.append style={anchor=base east,xshift=-4.5ex,yshift=2.25ex,rotate=90}
+}}
+
+\tikzset{month label right/.style={%
+execute before day scope={\ifdate{day of month=1}{%
+ {%
+ \pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
+ \pgftransformxshift{\tikz@lib@cal@width\pgf@xa}%
+ \pgftransformxshift{-\pgf@xa}%
+ \tikzmonthcode%
+ }}{}},
+ every month/.append style={anchor=base west,xshift=1ex}
+}}
+
+\tikzset{month label right vertical/.style={%
+ execute before day scope={\ifdate{day of month=1}{%
+ {%
+ \pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
+ \pgftransformxshift{\tikz@lib@cal@width\pgf@xa}%
+ \pgftransformxshift{-\pgf@xa}%
+ \tikzmonthcode%
+ }}{}},
+ every month/.append style={anchor=base west,xshift=2ex,yshift=2.25ex,rotate=-90}
+}}
+
+\tikzset{month label above centered/.style={%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ {
+ \pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
+ \pgf@xb=\tikz@lib@cal@width\pgf@xa%
+ \advance\pgf@xb by-\pgf@xa%
+ \pgf@xb=.5\pgf@xb%
+ \pgftransformxshift{\pgf@xb}%
+ \pgftransformxshift{-1.5ex}%
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
+ \pgftransformyshift{1.25\pgf@y}
+ \tikzmonthcode%
+ }
+ }{}},
+ every month/.append style={anchor=base}
+}}
+
+\tikzset{month label above left/.style={%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ {
+ \pgftransformxshift{-3.25ex}%
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
+ \pgftransformyshift{1.25\pgf@y}
+ \tikzmonthcode%
+ }
+ }{}},
+ every month/.append style={anchor=base west}
+}}
+
+
+
+\tikzset{month label above right/.style={%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ {
+ \pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
+ \pgf@xb=\tikz@lib@cal@width\pgf@xa%
+ \advance\pgf@xb by-\pgf@xa%
+ \pgftransformxshift{\pgf@xb}%
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
+ \pgftransformyshift{1.25\pgf@y}
+ \tikzmonthcode%
+ }
+ }{}},
+ every month/.append style={anchor=base east}
+}}
+
+\tikzset{month label below centered/.style={%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ {
+ \pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
+ \pgf@xb=\tikz@lib@cal@width\pgf@xa%
+ \advance\pgf@xb by-\pgf@xa%
+ \pgf@xb=.5\pgf@xb%
+ \pgftransformxshift{\pgf@xb}%
+ \pgftransformxshift{-1.5ex}%
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
+ \pgftransformyshift{-1.25\pgf@y}
+ \tikzmonthcode%
+ }
+ }{}},
+ every month/.append style={anchor=base}
+}}
+
+\tikzset{month label below left/.style={%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ {
+ \pgftransformxshift{-3.25ex}%
+ \pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
+ \pgftransformyshift{-1.25\pgf@y}
+ \tikzmonthcode%
+ }
+ }{}},
+ every month/.append style={anchor=base west}
+}}
+
+
+
+%
+% Code of the actual \calendar command (tikz.code.tex contains \let\calendar=\tikz@lib@cal@calendar):
+%
+
+\def\tikz@lib@cal@calendar{%
+ \begingroup%
+ \let\tikz@lib@cal@ifs=\pgfutil@empty%
+ \tikz@resetexpandcount
+ \tikzset{name=,at={(0,0)}}%
+ \let\%=\pgfcalendarshorthand%
+ \tikzset{every calendar/.try}%
+ \tikz@lib@cal@scanner%
+}
+
+\def\tikz@lib@cal@scanner{%
+ \afterassignment\tikz@lib@cal@handle\let\pgf@let@token=%
+}
+
+\def\tikz@lib@cal@handle{%
+ \pgfutil@switch\pgfutil@ifx\pgf@let@token{%
+ {;}{\let\pgfutil@next\tikz@lib@cal@stop}%
+ {(}{\let\pgfutil@next\tikz@lib@cal@name}%)
+ {a}{\let\pgfutil@next\tikz@lib@cal@at}%
+ {[}{\let\pgfutil@next\tikz@lib@cal@option}%]
+ {i}{\let\pgfutil@next\tikz@lib@cal@if}%
+ }{\tikz@resetexpandcount\pgfutil@next}{\tikz@lib@cal@expand}%
+}
+\def\tikz@lib@cal@expand{%
+ \advance\tikz@expandcount by -1
+ \ifnum\tikz@expandcount<0\relax%
+ \tikzerror{Giving up on this calendar}%
+ \let\pgfutil@next=\tikz@lib@cal@end%
+ \else%
+ \let\pgfutil@next=\tikz@lib@cal@@expand
+ \fi%
+ \pgfutil@next}
+
+\def\tikz@lib@cal@@expand{\expandafter\tikz@lib@cal@scanner\pgf@let@token}
+
+
+\def\tikz@lib@cal@name#1){%
+ \tikzset{name=#1}%
+ \tikz@lib@cal@scanner%
+}
+\def\tikz@lib@cal@at t#1(#2){%
+ \tikzset{at={(#2)}}%
+ \tikz@lib@cal@scanner%
+}
+\def\tikz@lib@cal@option#1]{%
+ \tikzset{#1}%
+ \tikz@lib@cal@scanner%
+}
+\def\tikz@lib@cal@if f#1(#2){%
+ \pgfutil@ifnextchar[{\tikz@lib@cal@if@opt{#2}}{\tikz@lib@cal@if@code{#2}}}%}
+
+\def\tikz@lib@cal@if@opt#1[#2]{\tikz@lib@cal@if@code{#1}{\tikzset{#2}}}
+\def\tikz@lib@cal@if@code#1#2{%
+ \pgfutil@ifnextchar e{\tikz@lib@cal@if@else{#1}{#2}}{\tikz@lib@cal@if@else{#1}{#2}else{}}}
+
+\def\tikz@lib@cal@if@else#1#2else{%
+ \pgfutil@ifnextchar[{\tikz@lib@cal@if@else@opt{#1}{#2}}{\tikz@lib@cal@if@else@code{#1}{#2}}}%}
+\def\tikz@lib@cal@if@else@opt#1#2[#3]{\tikz@lib@cal@if@else@code{#1}{#2}{\tikzset{#3}}}
+\def\tikz@lib@cal@if@else@code#1#2#3{%
+ \expandafter\def\expandafter\tikz@lib@cal@ifs\expandafter{\tikz@lib@cal@ifs\ifdate{#1}{#2}{#3}}%
+ \tikz@lib@cal@scanner%
+}
+\def\tikz@lib@cal@stop{%
+ \pgftransformshift{\tikz@node@at}%
+ \expandafter\pgfcalendar\expandafter{\tikz@fig@name}{\tikz@lib@cal@start}{\tikz@lib@cal@end}%
+ {%
+ \tikz@before@day%
+ \scope%
+ \tikz@atbegin@day%
+ \tikz@lib@cal@ifs%
+ \tikzdaycode%
+ \tikz@atend@day%
+ \endscope%
+ \tikz@after@day%
+ }%
+ \endgroup%
+}
+
+\tikzoption{if}{%
+ \let\tikz@lib@cal@scanner@orig=\tikz@lib@cal@scanner%
+ \let\tikz@lib@cal@scanner=\relax%
+ \tikz@lib@cal@if f#1\relax%
+ \let\tikz@lib@cal@scanner=\tikz@lib@cal@scanner@orig}
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex
new file mode 100644
index 0000000000..1d85b27c45
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex
@@ -0,0 +1,214 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarychains.code.tex}
+
+\usetikzlibrary{positioning}%
+
+\tikzset{start chain/.default=,
+ start chain/.code={%
+ \tikz@lib@chain@parse{#1}%
+ \ifx\tikz@lib@chain@name\pgfutil@empty%
+ \def\tikz@lib@chain@name{chain}%
+ \fi%
+ \ifx\tikz@lib@chain@direction\relax%
+ \let\tikz@lib@chain@direction=\tikz@lib@chain@default@direction%
+ \fi%
+ \expandafter\ifx\csname tikz@lib@chain@active@\tikz@lib@chain@name\endcsname\relax%
+ \expandafter\let\csname tikz@lib@chain@active@\tikz@lib@chain@name\endcsname=\pgfutil@empty% does not matter
+ \expandafter\global\expandafter\let\csname tikz@lib@chain@exists@\tikz@lib@chain@name\endcsname=\pgfutil@empty% does not matter
+ % Setup chain parameters
+ \expandafter\gdef\csname tikz@lib@chain@count@\tikz@lib@chain@name\endcsname{0}%
+ \expandafter\global\expandafter\let\csname tikz@lib@chain@dir@\tikz@lib@chain@name\endcsname\tikz@lib@chain@direction%
+ \let\tikz@lib@current@chain=\tikz@lib@chain@name%
+ \let\chainin=\tikz@lib@chainin%
+ \else%
+ \tikzerror{Chain ``\tikz@lib@chain@name'' is already active}%
+ \fi%
+ },
+ continue chain/.default=,
+ continue chain/.code={%
+ \tikz@lib@chain@parse{#1}%
+ \ifx\tikz@lib@chain@name\pgfutil@empty%
+ \let\tikz@lib@chain@name\tikz@lib@current@chain%
+ \fi%
+ \expandafter\ifx\csname tikz@lib@chain@exists@\tikz@lib@chain@name\endcsname\relax%
+ \tikzerror{Unknown chain ``#1''}%
+ \else%
+ \let\tikz@lib@current@chain=\tikz@lib@chain@name%
+ \expandafter\let\csname tikz@lib@chain@active@\tikz@lib@chain@name\endcsname=\pgfutil@empty% does not matter
+ \ifx\tikz@lib@chain@direction\relax%
+ % Just restart...
+ \else%
+ % Setup chain parameters
+ \expandafter\global\expandafter\let\csname tikz@lib@chain@dir@\tikz@lib@chain@name\endcsname\tikz@lib@chain@direction%
+ \fi%
+ \fi%
+ },
+ join/.code=\tikz@lib@parse@join{#1},
+ join/.default={}%
+}%
+
+\def\tikz@lib@chain@parse#1{%
+ \pgfutil@in@{going }{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@chain@going#1\pgf@stop%
+ \else%
+ \pgfutil@in@{placed }{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@chain@positioning#1\pgf@stop%
+ \else%
+ \def\tikz@lib@chain@name{#1}%
+ \let\tikz@lib@chain@direction\relax%
+ \fi%
+ \fi%
+}%
+
+\def\tikz@lib@chain@going#1going #2\pgf@stop{%
+ \def\tikz@lib@chain@name{#1}%
+ \ifx\tikz@lib@chain@name\pgfutil@empty%
+ \else%
+ \tikz@lib@chain@strip#1\pgf@stop%%
+ \fi%
+ \tikz@lib@chain@is@goingtrue%
+ \def\tikz@lib@chain@direction{%
+ \ifx\tikzchainprevious\pgfutil@empty%
+ \else%
+ \tikz@lib@chain@place{#2}%
+ \fi%
+ }%
+}%
+
+\def\tikz@lib@chain@positioning#1placed #2\pgf@stop{%
+ \def\tikz@lib@chain@name{#1}%
+ \ifx\tikz@lib@chain@name\pgfutil@empty%
+ \else%
+ \tikz@lib@chain@strip#1\pgf@stop%%
+ \fi%
+ \tikz@lib@chain@is@goingfalse%
+ \def\tikz@lib@chain@direction{\tikz@lib@chain@place{#2}}%
+}%
+\newif\iftikz@lib@chain@is@going
+
+
+\tikzset{/tikz/chain default direction/.code=%
+ {%
+ \tikz@lib@chain@parse{#1}%
+ \let\tikz@lib@chain@default@direction=\tikz@lib@chain@direction%
+ },%
+ /tikz/chain default direction=going right
+}%
+
+\def\tikz@lib@current@chain{chain}%
+
+\pgfutil@g@addto@macro\tikz@node@reset@hook{\let\tikz@lib@chain@caller=\relax}%
+\pgfutil@g@addto@macro\tikz@node@begin@hook{\tikz@lib@chain@caller}%
+
+\tikzset{
+ on chain/.default=,
+ on chain/.code=\tikz@lib@on@chain{#1}%
+}%
+\def\tikz@lib@on@chain#1{%
+ \tikz@lib@chain@parse{#1}%
+ \ifx\tikz@lib@chain@name\pgfutil@empty%
+ \let\tikz@lib@chain@name\tikz@lib@current@chain%
+ \fi%
+ \expandafter\ifx\csname tikz@lib@chain@exists@\tikz@lib@chain@name\endcsname\relax%
+ \tikzerror{Unknown chain ``\tikz@lib@chain@name''}%
+ \else%
+ \c@pgf@counta\csname tikz@lib@chain@count@\tikz@lib@chain@name\endcsname\relax%
+ \ifnum\c@pgf@counta=0\relax%
+ \global\let\tikzchainprevious=\pgfutil@empty%
+ \else
+ \xdef\tikzchainprevious{\tikz@lib@chain@name-\the\c@pgf@counta}%
+ \fi%
+ \advance\c@pgf@counta by1\relax%
+ \xdef\tikzchaincount{\the\c@pgf@counta}%
+ \ifx\tikz@lib@chain@direction\relax%
+ \csname tikz@lib@chain@dir@\tikz@lib@chain@name\endcsname% use default
+ \else%
+ \tikz@lib@chain@direction%
+ \fi%
+ \edef\tikz@lib@chain@caller{\noexpand\tikz@lib@chain@last@found{\tikz@lib@chain@name}}%
+ \fi%
+}%
+\def\tikz@lib@chain@last@found#1{%
+ % Increase the count and set name, if necessary.
+ \c@pgf@counta\csname tikz@lib@chain@count@#1\endcsname\relax%
+ \advance\c@pgf@counta by1\relax%
+ \xdef\tikzchaincurrent{#1-\the\c@pgf@counta}%
+ \expandafter\xdef\csname tikz@lib@chain@count@#1\endcsname{\the\c@pgf@counta}%
+ \ifnum\c@pgf@counta=1\relax%
+ \tikzset{alias/.expanded={#1-begin}} % Define pseudostart
+ \fi%
+ \tikzset{alias/.expanded={#1-end}} % Define pseudostart
+ \tikzset{alias/.expanded={#1-\the\c@pgf@counta}} % Define pseudostart
+ \tikz@lib@chain@direction%
+ \tikzset{every on chain/.try}%
+}%
+
+
+\def\tikz@lib@chain@place#1{%
+ \pgfutil@in@{=}{#1}%
+ \ifpgfutil@in@%
+ \tikzset{#1}%
+ \else%
+ \tikzset{#1=of \tikzchainprevious}%
+ \fi%
+}%
+
+\def\tikz@lib@chain@strip#1 \pgf@stop{%
+ \def\tikz@lib@chain@name{#1}%
+}%
+
+\def\tikz@lib@parse@join#1{%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\pgfutil@empty%
+ \tikz@lib@parse@join@by by \pgf@stop%
+ \else%
+ \pgfutil@in@{with }{#1}%
+ \ifpgfutil@in@%
+ \pgfutil@in@{by }{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@parse@join@with@by#1\pgf@stop%
+ \else%
+ \tikz@lib@parse@join@with@by#1 by \pgf@stop%
+ \fi%
+ \else%
+ \tikz@lib@parse@join@by#1\pgf@stop%
+ \fi%
+ \fi%
+}%
+\def\tikz@lib@parse@join@with@by with #1 by #2\pgf@stop{%
+ \tikzset{after node path={(#1)edge[every join,#2](\tikzchaincurrent)}}%
+}%
+\def\tikz@lib@parse@join@by by #1\pgf@stop{%
+ \tikzset{after node path={\ifx\tikzchainprevious\pgfutil@empty\else (\tikzchainprevious)edge[every join,#1](\tikzchaincurrent)\fi}}%
+}%
+\tikzset{every join/.style=}%
+
+
+\def\tikz@lib@chainin#1(#2){\pgfutil@ifnextchar[{\tikz@lib@chainin@{#2}}{\tikz@lib@chainin@{#2}[]}}%]%
+\def\tikz@lib@chainin@#1[#2]{\path[late options={name=#1,on chain,every chain in/.try,#2}]}%
+
+
+%
+% Branches
+%
+
+\tikzset{start branch/.code={%
+ % save last node on current chain:
+ \let\tikz@lib@save@current\tikz@lib@current@chain%
+ \pgfkeysalso{/tikz/start chain/.expand once=\tikz@lib@current@chain/#1}%
+ \path[late options={name=\tikz@lib@save@current-end,on chain}];%
+ }%
+}%
+\tikzset{continue branch/.style={continue chain/.expand once=\tikz@lib@current@chain/#1}}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex
new file mode 100644
index 0000000000..bfe8863efc
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex
@@ -0,0 +1,194 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+% Define the basic decoration stuff for tikz. Load more libraries to
+% "actually use" decorations
+
+\tikzset{decorate/.is if=tikz@decoratepath,
+ /pgf/decoration/name/.store in=\tikz@decoration@name,
+ /pgf/decoration/.unknown/.code=%
+ \pgfifdecoration{\pgfkeyscurrentname}{\edef\tikz@decoration@name{\pgfkeyscurrentname}}
+ {\pgfifmetadecoration{\pgfkeyscurrentname}{\edef\tikz@decoration@name{\pgfkeyscurrentname}}
+ % Fully expand `\pgfkeyscurrentname' before being used in first-arg of
+ % `/errors/unknown key'.
+ {\pgfkeys{/errors/unknown
+ key/.expanded={/pgf/decoration/\pgfkeyscurrentname}{\pgfutil@unexpanded{#1}}}}},%
+ /pgf/decoration/raise/.code={\def\tikz@dec@shift{\pgftransformyshift{#1}}\tikz@dec@trans},
+ /pgf/decoration/mirror/.code={%
+ \csname if#1\endcsname
+ \def\tikz@dec@mirror{\pgftransformyscale{-1}}%
+ \else%
+ \let\tikz@dec@mirror=\relax%
+ \fi%
+ \tikz@dec@trans%
+ },
+ /pgf/decoration/mirror/.default=true,
+ /pgf/decoration/transform/.code={%
+ {%
+ \pgftransformreset%
+ \def\tikz@transform{}%
+ \pgfkeysalso{/tikz/.cd, #1}%
+ \expandafter\gdef\expandafter\tikz@g@temptransform\expandafter{\tikz@transform}%
+ }%
+ \let\tikz@dec@user@transform=\tikz@g@temptransform%
+ \tikz@dec@trans%
+ },%
+ /pgf/decoration/pre/.initial=lineto,
+ /pgf/decoration/post/.initial=lineto,
+ /pgf/decoration/pre length/.initial=0pt,
+ /pgf/decoration/post length/.initial=0pt,
+}%
+
+\let\tikz@decoration@name=\tikz@nonetext
+
+\def\tikz@dec@trans{\pgfsetdecorationsegmenttransformation{\tikz@dec@user@transform\tikz@dec@mirror\tikz@dec@shift}}%
+\let\tikz@dec@user@transform=\relax
+\let\tikz@dec@shift=\relax
+\let\tikz@dec@mirror=\relax
+
+\pgfdeclaremetadecoration{tikz@internal}{pre}{%
+ \state{pre}[width=\pgfkeysvalueof{/pgf/decoration/pre length}, next state=main]
+ {
+ \tikz@dec@trans
+ \decoration{\pgfkeysvalueof{/pgf/decoration/pre}}
+ }%
+ \state{main}[width=\pgfmetadecoratedremainingdistance-\pgfkeysvalueof{/pgf/decoration/post length}, next state=final]
+ {
+ \tikz@dec@trans
+ \decoration{\tikz@decoration@name}
+ }%
+ \state{final}
+ {
+ \tikz@dec@trans
+ \decoration{\pgfkeysvalueof{/pgf/decoration/post}}
+ }%
+}%
+
+
+\newif\iftikz@metadecoration
+
+\def\tikz@lib@dec@addtomacro#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}%
+
+\def\tikz@lib@decoration[#1]{%
+ \begingroup%
+ % Just to be on the save side...
+ %
+ % Now, let's parse the options:
+ \tikzset{#1}%
+ %
+ \ifx\tikz@decoration@name\tikz@nonetext%
+ % Ok, let's forget about this decoration stuff...
+ \else
+ \expandafter\tikz@lib@do@dec%
+ \fi%
+ % Now, we expect a brace.
+ \pgfutil@ifnextchar\bgroup{%
+ \begingroup%
+ \tikz@auto@end@pathfalse%
+ \aftergroup\tikz@enddecoration%
+ \afterassignment\tikz@scan@next@command%
+ \let\tikz@lib@next% gobble \bgroup%
+ }%
+ {%
+ \tikzerror{A decoration must begin with a brace}%
+ \tikz@enddecoration%
+ }%
+}%
+\def\tikz@lib@do@dec{%
+ % Ok, now what?
+ \pgfifmetadecoration{\tikz@decoration@name}%
+ {\expandafter\pgfmetadecoration\expandafter{\tikz@decoration@name}}%
+ {%
+ \pgfifdecoration{\tikz@decoration@name}%
+ {\tikz@lib@dec@startdecoration}%
+ {\tikzerror{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps you
+ misspelled it?}}%
+ }%
+ \ifx\pgfdecorateexistingpath\pgfutil@empty%
+ \pgfpathmoveto{\pgfqpoint{\the\tikz@lastxsaved}{\the\tikz@lastysaved}}%
+ \fi%
+}%
+\newbox\tikz@lib@dec@box
+\def\tikz@enddecoration{%
+ \global\setbox\tikz@lib@dec@box=\box\tikz@tempbox%
+ \ifx\tikz@decoration@name\tikz@nonetext%
+ % ignore this.
+ \else
+ % Ok, now what?
+ \iftikz@metadecoration%
+ \endpgfmetadecoration%
+ \else%
+ \tikz@lib@dec@stopdecoration%
+ \fi%
+ \fi
+ \endgroup%
+ \setbox\tikz@tempbox=\box\tikz@lib@dec@box%
+}%
+
+
+\def\tikz@lib@dec@decorate@path{%
+ \ifx\tikz@decoration@name\tikz@nonetext%
+ \else%
+ \pgfgetpath\tikz@lib@dec@currentpath%
+ \pgfsetpath\pgfutil@empty%
+ \pgfifmetadecoration{\tikz@decoration@name}
+ {
+ \expandafter\pgfmetadecoration\expandafter{\tikz@decoration@name}%
+ \pgfsetpath\tikz@lib@dec@currentpath%
+ \endpgfmetadecoration%
+ }
+ {
+ \pgfifdecoration{\tikz@decoration@name}
+ {
+ \tikz@lib@dec@startdecoration%
+ \pgfsetpath\tikz@lib@dec@currentpath%
+ \tikz@lib@dec@stopdecoration%
+ }
+ {
+ \tikzerror{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps
+ you misspelled it?}
+ }
+ }
+ \fi%
+}%
+
+\def\tikz@lib@dec@zpttext{0pt}%
+
+\newif\iftikz@lib@dec@temp
+\def\tikz@lib@dec@startdecoration{%
+ \pgfkeysgetvalue{/pgf/decoration/pre length}{\tikz@lib@pre}%
+ \pgfkeysgetvalue{/pgf/decoration/post length}{\tikz@lib@post}%
+ \tikz@lib@dec@tempfalse%
+ \ifx\tikz@lib@pre\tikz@lib@dec@zpttext%
+ \ifx\tikz@lib@post\tikz@lib@dec@zpttext%
+ \else%
+ \tikz@lib@dec@temptrue%
+ \fi%
+ \else%
+ \tikz@lib@dec@temptrue%
+ \fi%
+ \iftikz@lib@dec@temp%
+ \pgfmetadecoration{tikz@internal}%
+ \else%
+ \expandafter\pgfdecoration\expandafter{\expandafter{\tikz@decoration@name}{\pgfdecoratedpathlength}{}{}}%
+ \fi%
+}%
+
+\def\tikz@lib@dec@stopdecoration{%
+ \iftikz@lib@dec@temp%
+ \endpgfmetadecoration%
+ \else%
+ \endpgfdecoration%
+ \fi%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.footprints.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.footprints.code.tex
new file mode 100644
index 0000000000..10bc743f24
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.footprints.code.tex
@@ -0,0 +1,13 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{decorations}%
+\usepgflibrary{decorations.footprints}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.fractals.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.fractals.code.tex
new file mode 100644
index 0000000000..4ef2342784
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.fractals.code.tex
@@ -0,0 +1,13 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{decorations}%
+\usepgflibrary{decorations.fractals}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.markings.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.markings.code.tex
new file mode 100644
index 0000000000..04f3e571b1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.markings.code.tex
@@ -0,0 +1,31 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{decorations}%
+\usepgflibrary{decorations.markings}%
+
+% Upgrade \arrow command
+\def\pgf@lib@dec@doarrowhead{%
+ \pgfutil@ifnextchar[{\tikz@lib@dec@doarrowhead}{\tikz@lib@dec@doarrowhead[]}%]
+}%
+\def\tikz@lib@dec@doarrowhead[#1]#2{%
+ \scope[#1]
+ \pgf@lib@dec@arrowhead{1}{#2}%
+ \endscope
+}%
+\def\pgf@lib@dec@doarrowheadrev{%
+ \pgfutil@ifnextchar[{\tikz@lib@dec@doarrowheadrev}{\tikz@lib@dec@doarrowheadrev[]}%]
+}%
+\def\tikz@lib@dec@doarrowheadrev[#1]#2{%
+ \scope[#1]
+ \pgf@lib@dec@arrowhead{-1}{#2}%
+ \endscope
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathmorphing.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathmorphing.code.tex
new file mode 100644
index 0000000000..5bc38b1dc8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathmorphing.code.tex
@@ -0,0 +1,13 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{decorations}%
+\usepgflibrary{decorations.pathmorphing}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathreplacing.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathreplacing.code.tex
new file mode 100644
index 0000000000..4f52ff9a1e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathreplacing.code.tex
@@ -0,0 +1,36 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{decorations}%
+\usepgflibrary{decorations.pathreplacing}%
+
+
+\def\tikz@lib@dec@installinputsegmentpoints{%
+ \pgf@process{\pgf@decorate@inputsegment@first}%
+ \edef\tikzinputsegmentfirst{\the\pgf@x,\the\pgf@y}%
+ %
+ \pgf@process{\pgf@decorate@inputsegment@last}%
+ \edef\tikzinputsegmentlast{\the\pgf@x,\the\pgf@y}%
+ %
+ \pgf@process{\pgf@decorate@inputsegment@supporta}%
+ \edef\tikzinputsegmentsupporta{\the\pgf@x,\the\pgf@y}%
+ %
+ \pgf@process{\pgf@decorate@inputsegment@supportb}%
+ \edef\tikzinputsegmentsupportb{\the\pgf@x,\the\pgf@y}%
+}%
+
+\pgfkeys{
+ /pgf/decoration/.cd,
+ moveto code/.code=\def\pgfdecoratedinputsegmentmovetocode{\tikz@lib@dec@installinputsegmentpoints#1},
+ lineto code/.code=\def\pgfdecoratedinputsegmentlinetocode{\tikz@lib@dec@installinputsegmentpoints#1},
+ curveto code/.code=\def\pgfdecoratedinputsegmentcurvetocode{\tikz@lib@dec@installinputsegmentpoints#1},
+ closepath code/.code=\def\pgfdecoratedinputsegmentclosepathcode{\tikz@lib@dec@installinputsegmentpoints#1}
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.shapes.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.shapes.code.tex
new file mode 100644
index 0000000000..3074a03905
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.shapes.code.tex
@@ -0,0 +1,13 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{decorations}%
+\usepgflibrary{decorations.shapes}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex
new file mode 100644
index 0000000000..030135d8f5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex
@@ -0,0 +1,704 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{decorations}%
+\usepgflibrary{decorations.text}%
+
+
+% Code for the `text effects along path' decoration
+
+% Some text constants
+% To do: merge these with existing text constants
+\def\tikz@lib@dec@te@space@text{space}%
+\def\tikz@lib@dec@align@left@text{left}%
+\def\tikz@lib@dec@align@right@text{right}%
+\def\tikz@lib@dec@align@center@text{center}%
+\def\tikz@lib@dec@te@none@text{none}%
+
+% Some ifs
+\newif\iftikz@lib@dec@te@pathfromtext%
+\newif\iftikz@lib@dec@te@segmentfromwidth%
+\newif\iftikz@lib@dec@te@scaletexttopath%
+\newif\iftikz@lib@dec@te@fittexttopath%
+\newif\iftikz@lib@dec@te@wordsep%
+\newif\iftikz@lib@dec@te@finalletter%
+
+
+% Utility macros
+% To do: integrate with existing pgf macros
+\def\tikz@lib@dec@te@addto@macro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}%
+
+\def\tikz@lib@dec@te@namelet#1#2{%
+ \expandafter\expandafter\expandafter\let\expandafter\expandafter\csname\expandafter#1\expandafter\endcsname\expandafter=\csname#2\endcsname%
+}%
+
+\def\tikz@lib@dec@te@advancecountmacro#1#2{%
+ \pgfutil@tempcnta=#1\relax%
+ \advance\pgfutil@tempcnta by#2\relax%
+ \edef#1{\the\pgfutil@tempcnta}%
+}%
+
+\def\tikz@lib@dec@te@advancedimenmacro#1#2{%
+ \pgf@x=#1\relax%
+ \advance\pgf@x by#2\relax%
+ \edef#1{\the\pgf@x}%
+}%
+
+% Macros for defining and updating text parameters
+\def\tikz@lib@dec@te@start@parameters#1{%
+ \expandafter\let\csname tikz@lib@dec@te@character@#1\endcsname=\pgfutil@empty%
+}%
+
+\def\tikz@lib@dec@te@addto@parameters#1#2{%
+ \expandafter\tikz@lib@dec@te@addto@macro\expandafter%
+ {\csname tikz@lib@dec@te@character@#1\endcsname}{#2}%
+}%
+\def\tikz@lib@dec@te@addmacroto@parameters#1#2{%
+ \def\tikz@lib@dec@te@marshal{\expandafter\tikz@lib@dec@te@addto@macro\expandafter%
+ {\csname tikz@lib@dec@te@character@#1\endcsname}}%
+ \expandafter\tikz@lib@dec@te@marshal\expandafter{\expandafter\def\expandafter#2\expandafter{#2}}%
+}%
+
+\def\tikz@lib@dec@te@getparameters#1{\csname tikz@lib@dec@te@character@#1\endcsname}%
+
+
+
+\let\tikz@lib@dec@te@textoptions=\pgfutil@empty
+\let\tikz@lib@dec@te@widthoptions=\pgfutil@empty
+\let\tikz@lib@dec@te@charactercountvar=\pgfutil@empty
+\let\tikz@lib@dec@te@charactertotalvar=\pgfutil@empty
+\let\tikz@lib@dec@te@lettercountvar=\pgfutil@empty
+\let\tikz@lib@dec@te@lettertotalvar=\pgfutil@empty
+\let\tikz@lib@dec@te@wordcountvar=\pgfutil@empty
+\let\tikz@lib@dec@te@wordctotalvar=\pgfutil@empty
+\let\tikz@lib@dec@te@transformtext=\pgfutil@empty%
+
+
+% Keys... lots of them...
+\pgfkeys{/pgf/decoration/text effects/.cd,
+ .unknown/.code={\let\tikz@lib@dec@te@key@tmp=\pgfkeyscurrentname%
+ \pgfkeysalso{/tikz/\tikz@lib@dec@te@key@tmp={#1}}},
+ path from text/.is if=tikz@lib@dec@te@pathfromtext,
+ path from text angle/.store in=\tikz@lib@dec@te@pathfromtextangle,
+ path from text angle=0,
+ fit text to path/.is if=tikz@lib@dec@te@fittexttopath,
+ characters/.style={/pgf/decoration/text effects/every character/.style={#1}},
+ characters/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character/.append style={#1}}},
+ character widths/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.style={#1}}},
+ character widths/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.append style={#1}}},
+ character count/.store in=\tikz@lib@dec@te@charactercountvar,
+ character count=,
+ character total/.store in=\tikz@lib@dec@te@charactertotalvar,
+ character total=,
+ letter count/.store in=\tikz@lib@dec@te@lettercountvar,
+ letter count=,
+ letter total/.store in=\tikz@lib@dec@te@lettertotalvar,
+ letter total=,
+ word count/.store in=\tikz@lib@dec@te@wordcountvar,
+ word count=,
+ word total/.store in=\tikz@lib@dec@te@wordtotalvar,
+ word total=,
+ %
+ style characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@stylecharacters{#1}{#2}},
+ text along path/.style={
+ inner xsep=0pt,
+ anchor=base,
+ transform shape
+ },
+ segment from width/.is if=tikz@lib@dec@te@segmentfromwidth,
+ segment from width=true,
+ word separator/.code={%
+ \def\tikz@lib@dec@te@tmp{#1}%
+ \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@space@text%
+ \let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken%
+ \else%
+ \def\tikz@lib@dec@te@wordsep{#1}
+ \fi},
+ word separator=space,
+ character command/.code={%
+ \def\tikz@lib@dec@te@tmp{#1}%
+ \ifx\tikz@lib@dec@te@tmp\pgfutil@empty%
+ \def\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@charactertypesetonly}%
+ \else%
+ \def\tikz@lib@dec@te@charactercommand{#1}%
+ \fi%
+ },
+ character command=,
+ every character width/.style={/pgf/decoration/text effects/every character/.try},
+ every character/.style={},
+ reverse text/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext%
+ {\tikz@lib@dec@te@reversetext}},
+ group letters into words/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext%
+ {\tikz@lib@dec@te@groupletters}},
+ group letters/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext%
+ {\tikz@lib@dec@te@groupletters}},
+ replace characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@replacecharacters{#1}{#2}},
+ scale text to path/.is if=tikz@lib@dec@te@scaletexttopath,
+ fit text to path/.is if=tikz@lib@dec@te@fittexttopath,
+ repeat text/.store in=\tikz@lib@dec@te@repeattext,
+ repeat text/.default=-1,
+ repeat text=0,
+}%
+
+
+\def\tikz@lib@dec@te@charactertypesetonly#1{#1}%
+
+\tikzset{%
+ text effects/.code={\pgfkeysalso{/pgf/decoration/text effects/.cd,#1}},
+}%
+
+
+
+
+
+
+% Prepare the decoration text
+%
+% This sets up all the character/letter/word, counts/totals
+% and calculates the default width of the characters/text
+% (which may be modified later).
+%
+\def\tikz@lib@dec@te@preparetext{%
+ % Step 1: scan all the characters in the decoration text
+ \let\tikz@lib@dec@te@text=\pgfdecorationtext%
+ \tikz@lib@dec@te@scancharacters{%
+ \expandafter\let\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@scancount @token\endcsname=%
+ \tikz@lib@dec@te@character%
+ }%
+ \let\tikz@lib@dec@te@charactertotalcount=\tikz@lib@dec@te@scancount%
+ % Step 2: reverse and/or group characters/letters.
+ \ifx\tikz@lib@dec@te@transformtext\pgfutil@empty%
+ \else%
+ \tikz@lib@dec@te@transformtext%
+ \fi%
+ % Step 3: get the character/letter/word counts
+ \def\tikz@lib@dec@te@charactercount{0}%
+ \def\tikz@lib@dec@te@wordcount{0}%
+ \def\tikz@lib@dec@te@wordsepcount{0}%
+ \def\tikz@lib@dec@te@lettercount{0}%
+ \def\tikz@lib@dec@te@lastcharacter{0}%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount%
+ \ifnum\tikz@lib@dec@te@lettercount>0\relax%
+ \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}%
+ \fi
+ \else%
+ \expandafter\let\expandafter\tikz@lib@dec@te@character\expandafter=\csname tikz@lib@dec@te@character@\pgfmathcounter @token\endcsname%
+ \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@charactercount}{1}%
+ \tikz@lib@dec@te@start@parameters{\tikz@lib@dec@te@charactercount}%
+ \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@charactercount}%
+ \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep%
+ \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@wordsepcount}{1}%
+ \ifnum\tikz@lib@dec@te@lettercount>0\relax%
+ \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}%
+ \fi
+ \def\tikz@lib@dec@te@lettercount{0}%
+ \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordseptrue}%
+ \else
+ \ifnum\tikz@lib@dec@te@lettercount=0\relax%
+ \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@wordcount{1}%
+ \fi%
+ \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@finalletterfalse}%
+ \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@lettercount}{1}%
+ \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordsepfalse}%
+ \expandafter\let\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname=\tikz@lib@dec@te@lettercount%
+ \fi%
+ \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@lettercount}%
+ \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordcount}%
+ \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@character}%
+ \let\tikz@lib@dec@te@lastcharactercount=\pgfmathcounter%
+ \repeatpgfmathloop%
+ \let\tikz@lib@dec@te@wordtotal=\tikz@lib@dec@te@wordcount%
+ % Step 4: add character/letter/word totals
+ \pgfmathloop
+ \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount%
+ \else%
+ \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@charactertotalcount}%
+ \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@wordtotal}%
+ \expandafter\let\expandafter\tikz@lib@dec@te@lettertotalcount\expandafter=\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname%
+ \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@lettertotalcount}%
+ \repeatpgfmathloop%
+ % Step 5: calculate the the text and character width
+ % but do not add to the parameters yet.
+ \def\tikz@lib@dec@te@textwidth{0pt}%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount%
+ \else%
+ \def\tikz@lib@dec@te@characterwidth{0pt}%
+ \tikz@lib@dec@te@getcharacterwidth{\pgfmathcounter}%
+ \expandafter\let\csname tikz@lib@dec@te@character@\pgfmathcounter @width\endcsname=\tikz@lib@dec@te@characterwidth%
+ \pgf@x=\tikz@lib@dec@te@characterwidth\relax%
+ \pgf@x=0.5\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}%
+ \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}%
+ \tikz@lib@dec@te@advancedimenmacro{\tikz@lib@dec@te@textwidth}{\tikz@lib@dec@te@characterwidth}%
+ \repeatpgfmathloop%
+}%
+
+% Does the category code of the space matter?
+\def\tikz@lib@dec@te@spacetoken{ }%
+
+\let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken
+
+
+% Scan and count the characters in \tikz@lib@dec@te@text
+%
+% Create macros \tikz@lib@dec@te@character@<n>@token containing
+% the nth character.
+%
+% Total number of characters is store in
+% \tikz@lib@dec@te@chractertotal@count
+%
+\def\tikz@lib@dec@te@scancharacters#1{%
+ \def\tikz@lib@dec@te@@@scancharacters@process{#1}%
+ \def\tikz@lib@dec@te@scancount{0}%
+ \expandafter\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@text\tikz@lib@dec@te@scancharacters}%
+
+\def\tikz@lib@dec@te@@scancharacters{%
+ \futurelet\tikz@lib@dec@te@token\tikz@lib@dec@te@@@scancharacters}%
+
+\def\tikz@lib@dec@te@@@scancharacters{%
+ \ifx\tikz@lib@dec@te@token\tikz@lib@dec@te@scancharacters%
+ \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@@scancharacters%
+ \else%
+ \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@scancount{1}%
+ \ifx\tikz@lib@dec@te@token\pgfutil@sptoken%
+ \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@space%
+ \else%
+ \ifx\tikz@lib@dec@te@token\bgroup%
+ \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@bgroup%
+ \else%
+ \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@normal%
+ \fi%
+ \fi%
+ \fi%
+ \tikz@lib@dec@te@next%
+}%
+
+\def\tikz@lib@dec@te@@@scancharacters@space{%
+ \let\tikz@lib@dec@te@character=\tikz@lib@dec@te@spacetoken%
+ \tikz@lib@dec@te@@@scancharacters@process%
+ \pgfutil@ifnextchar x\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@@scancharacters%
+}%
+
+\def\tikz@lib@dec@te@@@scancharacters@bgroup#1{%
+ \def\tikz@lib@dec@te@character{{#1}}%
+ \tikz@lib@dec@te@@@scancharacters@process%
+ \tikz@lib@dec@te@@scancharacters%
+}%
+
+\def\tikz@lib@dec@te@@@scancharacters@normal#1{%
+ \def\tikz@lib@dec@te@character{#1}%
+ \tikz@lib@dec@te@@@scancharacters@process%
+ \tikz@lib@dec@te@@scancharacters%
+}%
+
+
+\def\tikz@lib@dec@te@@@@scancharacters#1\tikz@lib@dec@te@scancharacters{}%
+
+
+% Reverse the order of the scanned characters in the text
+% (Actually reverse the ordering of the macros containing the characters)
+\def\tikz@lib@dec@te@reversetext{%
+ \c@pgf@counta=\tikz@lib@dec@te@charactertotalcount%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\c@pgf@counta%
+ \else%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\pgfmathcounter @token}{tikz@lib@dec@te@character@\the\c@pgf@counta @token}%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@tmp}%
+ \advance\c@pgf@counta by-1\relax%
+ \repeatpgfmathloop%
+}%
+
+% Group letters (i.e., anything that isn't the word separator)
+% as single characters (words).
+\def\tikz@lib@dec@te@groupletters{%
+ \c@pgf@counta=0\relax%
+ \let\tikz@lib@dec@te@tmp=\pgfutil@empty%
+ \let\tikz@lib@dec@te@@tmp=\pgfutil@empty%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount%
+ \ifx\tikz@lib@dec@te@@tmp\pgfutil@empty%
+ \else%
+ \advance\c@pgf@counta by1\relax%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}%
+ \fi%
+ \else%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}%
+ \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@wordsep%
+ \advance\c@pgf@counta by1\relax%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}%
+ \let\tikz@lib@dec@te@@tmp=\pgfutil@empty%
+ \advance\c@pgf@counta by1\relax%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@wordsep}%
+ \else%
+ \expandafter\tikz@lib@dec@te@addto@macro\expandafter{\expandafter\tikz@lib@dec@te@@tmp\expandafter}\expandafter{\tikz@lib@dec@te@tmp}%
+ \fi%
+ \repeatpgfmathloop%
+ \edef\tikz@lib@dec@te@charactertotalcount{\the\c@pgf@counta}%
+}%
+
+
+% Get width of node containing only the current character.
+\def\tikz@lib@dec@te@getcharacterwidth#1{%
+ \csname tikz@lib@dec@te@character@#1\endcsname%
+ \tikz@lib@dec@te@getoptions{every character width/.try}%
+ \let\tikz@lib@dec@te@lastcharacterwidth=\tikz@lib@dec@te@characterwidth%
+ \pgfpositionnodelater\tikz@lib@dec@te@@getcharacterwidth%
+ \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{%
+ \expandafter\node\expandafter[\tikz@lib@dec@te@options,scale=\tikz@lib@dec@scaledcharacterwidthfactor]%
+ {\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};%
+ \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@characterwidth@tmp%
+ }{%
+ \tikz@lib@dec@te@getcharacter@replacementwidth{\tikz@lib@dec@te@character}%
+ \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@character@replacementwidth%
+ }%
+}%
+
+% Update the character parameters with the widths.
+\def\tikz@lib@dec@te@addwidthstoparameters{%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount%
+ \else%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterwidth}{tikz@lib@dec@te@character@\pgfmathcounter @width}%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterprewidth}{tikz@lib@dec@te@character@\pgfmathcounter @prewidth}%
+ \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterpostwidth}{tikz@lib@dec@te@character@\pgfmathcounter @postwidth}%
+ \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterwidth}%
+ \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterprewidth}%
+ \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterpostwidth}%
+ \repeatpgfmathloop%
+}%
+
+% Get the options to applied to a character node.
+
+\def\tikz@lib@dec@te@addoptions#1{%
+ \expandafter\def\expandafter\tikz@lib@dec@te@options\expandafter{\tikz@lib@dec@te@options,#1}%
+}%
+
+\def\tikz@lib@dec@te@getoptions#1{%
+ \let\tikz@lib@dec@te@lastcharactercommand=\tikz@lib@dec@te@charactercommand%
+ \def\tikz@lib@dec@te@options{/pgf/decoration/text effects/.cd}%
+ \tikz@lib@dec@te@addoptions{#1}%
+ \let\tikzdecorationcharactercount=\tikz@lib@dec@te@charactercount%
+ \let\tikzdecorationcharactertotal=\tikz@lib@dec@te@charactertotalcount%
+ \let\tikzdecorationlettercount=\tikz@lib@dec@te@lettercount%
+ \let\tikzdecorationlettertotal=\tikz@lib@dec@te@lettertotalcount%
+ \let\tikzdecorationwordcount=\tikz@lib@dec@te@wordcount%
+ \let\tikzdecorationwordtotal=\tikz@lib@dec@te@wordtotal%
+ \let\tikzdecorationcharacter=\tikz@lib@dec@te@character%
+ %
+ % Define the count variables (if required)
+ \ifx\tikz@lib@dec@te@charactercountvar\pgfutil@empty%
+ \else%
+ \expandafter\let\tikz@lib@dec@te@charactercountvar=\tikz@lib@dec@te@charactercount%
+ \fi%
+ %
+ \ifx\tikz@lib@dec@te@charactertotalvar\pgfutil@empty%
+ \else%
+ \expandafter\let\tikz@lib@dec@te@charactertotalvar=\tikz@lib@dec@te@charactertotalcount%
+ \fi%
+ %
+ \ifx\tikz@lib@dec@te@wordcountvar\pgfutil@empty%
+ \else%
+ \expandafter\let\tikz@lib@dec@te@wordcountvar=\tikz@lib@dec@te@wordcount%
+ \fi%
+ %
+ \ifx\tikz@lib@dec@te@wordtotalvar\pgfutil@empty%
+ \else%
+ \expandafter\let\tikz@lib@dec@te@wordtotalvar=\tikz@lib@dec@te@wordtotal%
+ \fi%
+ %
+ \ifx\tikz@lib@dec@te@lettercountvar\pgfutil@empty%
+ \else%
+ \expandafter\let\tikz@lib@dec@te@lettercountvar=\tikz@lib@dec@te@lettercount%
+ \fi%
+ %
+ \ifx\tikz@lib@dec@te@lettertotalvar\pgfutil@empty%
+ \else%
+ \expandafter\let\tikz@lib@dec@te@lettertotalvar=\tikz@lib@dec@te@lettetotal%
+ \fi%
+ %
+ \edef\tikz@lib@dec@te@tmp{character \tikz@lib@dec@te@charactercount/.try,%
+ character {\meaning\tikz@lib@dec@te@character}/.try}%
+ \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}%
+ \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep%
+ \tikz@lib@dec@te@addoptions{/pgf/decoration/text effects/every word separator/.try}%
+ \else%
+ \ifnum\tikz@lib@dec@te@wordcount>0\relax%
+ \edef\tikz@lib@dec@te@tmp{every word/.try, word \tikz@lib@dec@te@wordcount/.try}%
+ \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}%
+ \ifnum\tikz@lib@dec@te@lettercount>0\relax%
+ \edef\tikz@lib@dec@te@tmp{every letter/.try,every \tikz@lib@dec@te@lettercount\space letter/.try}%
+ \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}%
+ \ifnum\tikz@lib@dec@te@lettercount=1\relax%
+ \edef\tikz@lib@dec@te@tmp{every first letter/.try}%
+ \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}%
+ \fi%
+ \iftikz@lib@dec@te@finalletter%
+ \tikz@lib@dec@te@addoptions{every final letter/.try}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+% Called by `late positioning' of the node
+% to get the width of the bounding box
+% of a character.
+\def\tikz@lib@dec@te@@getcharacterwidth{%
+ \iftikz@lib@dec@te@segmentfromwidth%
+ \pgf@x=\pgfpositionnodelatermaxx\relax%
+ \advance\pgf@x by-\pgfpositionnodelaterminx\relax%
+ \else%
+ \pgf@x=\pgfpositionnodelatermaxy\relax%
+ \advance\pgf@x by-\pgfpositionnodelaterminy\relax%
+ \fi%
+ \xdef\tikz@lib@dec@te@characterwidth@tmp{\the\pgf@x}%
+}%
+
+
+\def\tikz@lib@dec@te@drawcharacter{%
+ \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname%
+ \tikz@lib@dec@te@getoptions{every character/.try}%
+ \pgfpositionnodelater\relax%
+ \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{%
+ \expandafter\node\expandafter[\tikz@lib@dec@te@options, scale=\tikz@lib@dec@scaledcharacterwidthfactor]{\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};%
+ }{\tikz@lib@dec@te@drawcharacter@replacement{\tikz@lib@dec@te@character}}%
+}%
+
+% Replace the character #1 with a character@replacement
+%
+\def\tikz@lib@dec@te@drawcharacter@replacement#1{%
+ \pgfscope%
+ \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}%
+ \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname%
+ \endpgfscope%
+}%
+
+% Get the width of the character@replacement associated with
+% the character #1
+%
+\newbox\tikz@lib@dec@te@box
+\def\tikz@lib@dec@te@getcharacter@replacementwidth#1{%
+ \pgfinterruptpicture%
+ \setbox\tikz@lib@dec@te@box=\hbox{%
+ \pgfpicture
+ \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}%
+ \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname%
+ \endpgfpicture}%
+ \xdef\tikz@lib@dec@te@character@replacementwidth{\the\wd\tikz@lib@dec@te@box}%
+ \endpgfinterruptpicture%
+}%
+
+\def\tikz@lib@dec@scaledcharacterwidthfactor{1}%
+
+% Set up the decoration
+\def\tikz@lib@dec@te@state@setup@precomputation{%
+ \def\tikz@lib@te@alignshift{0pt}%
+ \iftikz@lib@dec@te@pathfromtext%
+ % The width of the text and characters has already been calculated.
+ \else%
+ \let\tikz@lib@dec@te@text=\pgfdecorationtext%
+ % Get the character tokens and the total number of characters.
+ \tikz@lib@dec@te@preparetext%
+ \iftikz@lib@dec@te@scaletexttopath%
+ % OK, *scaling* text to path is easy.
+ % Simply divide the path length by the text width to
+ % obtain the scaling factor which will be applied
+ % "at the last minute"...
+ \pgfmathdivide{\pgfdecoratedpathlength}{\tikz@lib@dec@te@textwidth}%
+ \let\tikz@lib@dec@scaledcharacterwidthfactor=\pgfmathresult%
+ \expandafter\pgfkeys\expandafter{\tikz@lib@dec@te@tmp}%
+ % ... and recalculate the (pre and post) widths.
+ \pgfmathloop
+ \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount%
+ \else%
+ \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax%
+ \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}%
+ %
+ \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax%
+ \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}%
+ \repeatpgfmathloop%
+ % Update parameters with thewidths.
+ \tikz@lib@dec@te@addwidthstoparameters%
+ \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength%
+ \else%
+ \iftikz@lib@dec@te@fittexttopath%
+ % *Fitting* text is less easy.
+ % The pre and post width of all except the first and last characters
+ % must be recalculated.
+ % Only the post width of the first character and the pre width
+ % of the final character are scaled as these characters should be
+ % fixed and the start and end of the path, respectively.
+ %
+ % We hope that the decoration engine is accurate enough to position
+ % the last word correctly.
+ \pgf@x=\pgfdecoratedpathlength%
+ \pgf@xa=\csname tikz@lib@dec@te@character@1@postwidth\endcsname\relax%
+ \pgf@xb=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @prewidth\endcsname\relax%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@x by-\pgf@xb%
+ \pgf@y=\tikz@lib@dec@te@textwidth\relax%
+ \advance\pgf@y by-\pgf@xa%
+ \advance\pgf@y by-\pgf@xb%
+ %
+ \pgfmathdivide{\the\pgf@x}{\the\pgf@y}%
+ \let\tikz@lib@dec@characterwidthscale=\pgfmathresult%
+ \pgfmathloop
+ \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount\relax%
+ \else%
+ \ifnum\pgfmathcounter>1\relax%
+ \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax%
+ \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}%
+ \fi%
+ \ifnum\pgfmathcounter<\tikz@lib@dec@te@charactertotalcount\relax%
+ \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax%
+ \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}%
+ \fi%
+ \repeatpgfmathloop%
+ % Update parameters with widths.
+ \tikz@lib@dec@te@addwidthstoparameters%
+ \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength%
+ \else%
+ % Calculate the distance to move along the path for alignment.
+ \pgfkeysgetvalue{/pgf/decoration/text align/align}{\tikz@lib@dec@align}%
+ \ifx\tikz@lib@dec@align\tikz@lib@dec@align@center@text%
+ \pgf@x=\pgfdecoratedpathlength\relax%
+ \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax%
+ \ifdim\pgf@x<0pt\relax%
+ \pgf@x=0pt\relax%
+ \fi%
+ \divide\pgf@x by2\relax%
+ % Adjust the pre-width of the first character...
+ \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax%
+ \advance\pgf@xa by\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}%
+ % ...and the post-width of the last character.
+ \pgf@xa=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname\relax%
+ \advance\pgf@xa by\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname{\the\pgf@xa}%
+ \else%
+ \ifx\tikz@lib@dec@align\tikz@lib@dec@align@right@text%
+ \pgf@x=\pgfdecoratedpathlength\relax%
+ \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax%
+ \ifdim\pgf@x<0pt\relax%
+ \pgf@x=0pt\relax%
+ \fi%
+ % Adjust the pre-width of the first character...
+ \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax%
+ \advance\pgf@xa by\pgf@x%
+ \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}%
+ \fi%
+ \fi%
+ \tikz@lib@dec@te@addwidthstoparameters%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+
+% Evil hack into the decoration code.
+%
+% If the path contains single move to and the `path from text'
+% key is set to true. The width of the text is calculated here
+% and the (straight line) path automatically calculated.
+%
+\def\pgf@decorate@path@check@moveto#1{%
+ \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop}%
+
+\def\pgf@decorate@token@stop{\pgf@decorate@stop}%
+\def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{%
+ \def\pgf@decorate@temp{#4}%
+ \pgf@x=#2\relax%
+ \pgf@y=#3\relax%
+ \ifx\pgf@decorate@temp\pgf@decorate@token@stop%
+ \iftikz@lib@dec@te@pathfromtext%
+ % Get the start position...
+ \pgfextract@process\tikz@lib@dec@te@pathstart{}%
+ \tikz@lib@dec@te@preparetext%
+ \tikz@lib@dec@te@addwidthstoparameters%
+ % ... and create a lineto path of the correct length.
+ \pgfsetpath\pgfutil@empty%
+ \pgfpathmoveto{\tikz@lib@dec@te@pathstart}%
+ \pgfpathlineto{\pgfpointadd{\tikz@lib@dec@te@pathstart}%
+ {\pgfpointpolar{\tikz@lib@dec@te@pathfromtextangle}{\tikz@lib@dec@te@textwidth}}}%
+ \pgfgetpath\pgfdecoratedpath%
+ \pgfsetpath\pgfutil@empty%
+ \else%
+ #5%
+ \fi%
+ \else%
+ \tikz@lib@dec@te@pathfromtextfalse%
+ #6%
+ \fi%
+}%
+
+
+\pgfdeclaredecoration{text effects along path}{setup}{%
+ \state{setup}[width=+0pt, next state=scan, persistent precomputation={%
+ \tikz@lib@dec@te@state@setup@precomputation%
+ \def\tikz@lib@dec@te@charactercount{0}%
+ }]{}%
+ %
+\state{scan}[width=+0pt, next state=pre token, persistent precomputation={%
+ \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@charactercount{1}%
+ % Usual switch to final state is based on distance.
+ % Here we also need it to be on the number of the
+ % current character.
+ \ifnum\tikz@lib@dec@te@charactercount>\tikz@lib@dec@te@charactertotalcount\relax%
+ \ifnum\tikz@lib@dec@te@repeattext=0\relax%
+ \def\pgf@decorate@next@state{final}%
+ \else%
+ \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@repeattext{-1}%
+ \def\tikz@lib@dec@te@charactercount{1}%
+ \fi%
+ \fi%
+ % Install parameters for this character.
+ \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname%
+}]{}%
+%
+\state{pre token}[width=+\tikz@lib@dec@te@characterprewidth, next state=token]{}%
+\state{token}[width=+0pt, next state=post token]
+{%
+ \tikz@lib@dec@te@drawcharacter%
+}%
+\state{post token}[width=+\tikz@lib@dec@te@characterpostwidth, next state=scan]{}%
+}%
+
+
+% Parse styles for individual characters
+% #1 a string of characters (e.g., aieou{\"U}{\"a"})
+% #2 the options for to apply to each character.
+%
+\def\tikz@lib@dec@te@parse@stylecharacters#1#2{%
+ \def\tikz@lib@dec@te@text{#1}%
+ \tikz@lib@dec@te@scancharacters{%
+ \pgfkeysalso{/pgf/decoration/text effects/character {\meaning\tikz@lib@dec@te@character}/.style={#2}}%
+ }%
+}%
+
+% Parse replacement code for for individual characters
+% #1 a string of characters (e.g., aieou{\"U}{\"a"})
+% #2 the code to execute to each character.
+%
+\def\tikz@lib@dec@te@parse@replacecharacters#1#2{%
+ \def\tikz@lib@dec@te@text{#1}%
+ \tikz@lib@dec@te@scancharacters{%
+ \expandafter\def\csname tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code\endcsname{#2}%
+ }%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryer.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryer.code.tex
new file mode 100644
index 0000000000..acb9b04997
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryer.code.tex
@@ -0,0 +1,40 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryer.code.tex}
+
+\usetikzlibrary{shapes.geometric}%
+
+% Styles for entity types:
+
+\tikzset{every entity/.style= {}}%
+\tikzset{entity/.style= {rectangle,draw,
+ minimum height=2\baselineskip,
+ minimum width=4\baselineskip,every entity}}%
+
+
+% Styles for relationship types:
+
+\tikzset{every relationship/.style= {}}%
+\tikzset{relationship/.style= {diamond,draw,
+ minimum size=1.5\baselineskip,
+ inner sep=1pt,
+ every relationship}}%
+
+
+% Styles for relationship types:
+
+\tikzset{every attribute/.style= {}}%
+\tikzset{attribute/.style= {minimum size=1.5\baselineskip,ellipse,draw,every attribute}}%
+\tikzset{key attribute/.style= {font=\itshape,attribute}}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfadings.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfadings.code.tex
new file mode 100644
index 0000000000..bddc83cb5c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfadings.code.tex
@@ -0,0 +1,48 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryfadings.code.tex}
+
+\usepgflibrary{fadings}%
+
+%
+% Environments for creating fadings
+%
+
+\def\tikzfadingfrompicture{%
+ \begingroup%
+ \setbox\pgfpic=\hbox\bgroup%
+ \tikzpicture%
+}%
+\def\endtikzfadingfrompicture{%
+ \global\let\tikz@smuggle=\tikz@fig@name%
+ \endtikzpicture
+ \egroup%
+ \pgfdeclarefading{\tikz@smuggle}{\box\pgfpic}%
+ \endgroup%
+}%
+
+% This makes it easier to maintain compatibility with the external lib:
+\def\starttikzfadingfrompicture{\tikzfadingfrompicture}%
+\def\stopttikzfadingfrompicture{\endtikzfadingfrompicture}%
+
+\def\tikzfading[#1]{%
+ {%
+ \setbox\pgfpic=\hbox{%
+ \tikzset{#1}%
+ \global\let\tikz@smuggle=\tikz@fig@name%
+ \tikz{%
+ \useasboundingbox(0,0) (100bp,100bp);
+ \node at (50bp,50bp) [rotate=\tikz@shade@angle]
+ {\pgfuseshading{\tikz@shading}};
+ }%
+ }%
+ \pgfdeclarefading{\tikz@smuggle}{\box\pgfpic}%
+ }%
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex
new file mode 100644
index 0000000000..b104a519c3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex
@@ -0,0 +1,132 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryfit.code.tex}
+
+\pgfqkeys{/tikz}{%
+ fit/.code=\tikz@lib@fit{#1},
+ rotate fit/.code={%
+ \pgfmathsetmacro\tikz@lib@fit@rotate{#1}%
+ \pgfkeysalso{/tikz/rotate=\tikz@lib@fit@rotate}%
+ },
+}%
+
+\def\tikz@lib@fit@rotate{0}%
+
+\def\tikz@lib@fit#1{%
+ \pgf@xb=-16000pt\relax%
+ \pgf@xa=16000pt\relax%
+ \pgf@yb=-16000pt\relax%
+ \pgf@ya=16000pt\relax%
+ %
+ % Now iterate over the coordinates
+ \tikz@lib@fit@scan#1\pgf@stop%
+ % Now, let's see what has happened
+ \ifdim\pgf@xa>\pgf@xa%
+ % Nothing... Ok, let's just ignore this.
+ \else%
+ % Ok, compute center and width and height
+ \pgf@x=\pgf@xb%
+ \advance\pgf@x by-\pgf@xa%
+ \pgf@y=\pgf@yb%
+ \advance\pgf@y by-\pgf@ya%
+ \advance\pgf@xa by.5\pgf@x%
+ \advance\pgf@ya by.5\pgf@y%
+ \ifdim\tikz@lib@fit@rotate pt=0pt\relax%
+ {%
+ \pgftransforminvert%
+ \pgf@pos@transform{\pgf@xa}{\pgf@ya}%
+ \global\pgf@xa\pgf@xa
+ \global\pgf@ya\pgf@ya
+ }
+ \else%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ {%
+ \pgf@xc=\pgf@xa%
+ \pgf@yc=\pgf@ya%
+ \pgftransforminvert%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}%
+ \pgftransformreset%
+ \pgftransformrotate{\tikz@lib@fit@rotate}%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}%
+ \global\pgf@x=\pgf@xc%
+ \global\pgf@y=\pgf@yc%
+ }%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@x=\pgf@xc%
+ \pgf@y=\pgf@yc%
+ \fi%
+ \edef\tikz@node@at{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \pgfkeysalso{/tikz/anchor=center,/tikz/text badly centered}%
+ \pgfkeysalso{/tikz/text width/.expanded=\the\pgf@x}%
+ \pgf@x=\pgf@y%
+ \pgf@y=.5\pgf@y%
+ \pgfkeysalso{
+ /tikz/transform shape=false,
+ /tikz/text height/.expanded=\the\pgf@y-.5\dp\pgfnodeparttextbox,
+ /tikz/text depth/.expanded=\the\pgf@x-\noexpand\the\ht\pgfnodeparttextbox}%
+ \pgfkeysalso{every fit/.try}%
+ \fi%
+}%
+
+\def\tikz@lib@fit@scan{%
+ \pgfutil@ifnextchar\pgf@stop{\pgfutil@gobble}
+ {\tikz@scan@one@point\tikz@lib@fit@scan@handle}}%
+
+\def\tikz@lib@fit@scan@handle#1{%
+ \iftikz@shapeborder%
+ % Ok, fit all four external anchors, if they exist
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{west}}%
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{east}}%
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{north}}%
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{south}}%
+ \else%
+ \tikz@lib@fit@adjust{#1}%
+ \fi%
+ \tikz@lib@fit@scan%
+}%
+
+\def\tikz@lib@fit@adjust#1{%
+ \ifdim\tikz@lib@fit@rotate pt=0pt\relax%
+ \pgf@process{\pgfpointtransformed{#1}}%
+ \else%
+ {%
+ \pgf@process{\pgfpointtransformed{#1}}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfgettransform\tikz@lib@fit@transform%
+ \pgftransforminvert%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}%
+ \pgftransformreset%
+ \pgftransformrotate{-\tikz@lib@fit@rotate}%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}%
+ \pgfsettransform\tikz@lib@fit@transform%
+ \pgf@pos@transform{\pgf@xc}{\pgf@yc}%
+ \global\pgf@x=\pgf@xc%
+ \global\pgf@y=\pgf@yc%
+ }%
+ \fi%
+ \ifdim\pgf@x<\pgf@xa%
+ \pgf@xa=\pgf@x%
+ \fi%
+ \ifdim\pgf@y<\pgf@ya%
+ \pgf@ya=\pgf@y%
+ \fi%
+ \ifdim\pgf@x>\pgf@xb%
+ \pgf@xb=\pgf@x%
+ \fi%
+ \ifdim\pgf@y>\pgf@yb%
+ \pgf@yb=\pgf@y%
+ \fi%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfixedpointarithmetic.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfixedpointarithmetic.code.tex
new file mode 100644
index 0000000000..76616a6ddd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfixedpointarithmetic.code.tex
@@ -0,0 +1,10 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{fixedpointarithmetic}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex
new file mode 100644
index 0000000000..4974fffa50
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex
@@ -0,0 +1,2444 @@
+% Copyright 2018 by Till Tantau
+% Copyright 2018 by Nico Van Cleemput
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryfolding.code.tex}
+
+
+%
+% Length of a standard line in a folding
+%
+
+\tikzoption{folding line length}{\pgfmathsetlength\tikz@lib@fold@length{#1}}%
+\newdimen\tikz@lib@fold@length
+\tikz@lib@fold@length=2cm
+
+
+% Faces
+% -----
+
+\def\tikz@lib@fold@triangle#1#2#3#4{%
+ \scope[xshift=.5\tikz@lib@fold@length,yshift=.28868\tikz@lib@fold@length]
+ #1
+ \endscope
+ \scope[shift={(60:\tikz@lib@fold@length)},rotate=-60]
+ #2
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #3
+ \endscope
+ \scope[rotate=60]
+ #4
+ \endscope
+}%
+
+\def\tikz@lib@fold@square#1#2#3#4#5{%
+ \scope[xshift=.5\tikz@lib@fold@length,yshift=.5\tikz@lib@fold@length]
+ #1
+ \endscope
+ \scope[yshift=\tikz@lib@fold@length]
+ #2
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,yshift=\tikz@lib@fold@length,rotate=-90]
+ #3
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #4
+ \endscope
+ \scope[rotate=90]
+ #5
+ \endscope
+}%
+
+\def\tikz@lib@fold@squarerhombusr#1#2#3#4#5{% right leaning "square-of-two" rhombus
+ \scope[xshift=.63\tikz@lib@fold@length,yshift=.4755\tikz@lib@fold@length,xslant=0.34]
+ #1
+ \endscope
+ \scope[shift={(70.529:\tikz@lib@fold@length)}]
+ #2
+ \endscope
+ \scope[shift={(35.264:1.63299\tikz@lib@fold@length)},rotate=-109.471]
+ #3
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #4
+ \endscope
+ \scope[rotate=70.529]
+ #5
+ \endscope
+}%
+
+\def\tikz@lib@fold@squarerhombusl#1#2#3#4#5{% left leaning "square-of-two" rhombus
+ \scope[xshift=.33\tikz@lib@fold@length,yshift=.4755\tikz@lib@fold@length,xslant=-0.34]
+ #1
+ \endscope
+ \scope[shift={(109.471:\tikz@lib@fold@length)}]
+ #2
+ \endscope
+ \scope[shift={(54.736:1.1547\tikz@lib@fold@length)},rotate=-70.529]
+ #3
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #4
+ \endscope
+ \scope[rotate=109.471]
+ #5
+ \endscope
+}%
+
+\def\tikz@lib@fold@goldenrhombusr#1#2#3#4#5{% right leaning golden rhombus
+ \scope[xshift=.724\tikz@lib@fold@length,yshift=.447\tikz@lib@fold@length, xslant=0.447]
+ #1
+ \endscope
+ \scope[shift={(63.435:\tikz@lib@fold@length)}]
+ #2
+ \endscope
+ \scope[shift={(31.717:1.701\tikz@lib@fold@length)},rotate=-116.565]
+ #3
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #4
+ \endscope
+ \scope[rotate=63.435]
+ #5
+ \endscope
+}%
+
+\def\tikz@lib@fold@goldenrhombusl#1#2#3#4#5{% left leaning golden rhombus
+ \scope[xshift=.276\tikz@lib@fold@length,yshift=.447\tikz@lib@fold@length, xslant=-0.447]
+ #1
+ \endscope
+ \scope[shift={(116.565:\tikz@lib@fold@length)}]
+ #2
+ \endscope
+ \scope[shift={(58.283:1.051\tikz@lib@fold@length)},rotate=-63.435]
+ #3
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #4
+ \endscope
+ \scope[rotate=116.565]
+ #5
+ \endscope
+}%
+
+\def\tikz@lib@fold@pentagon#1#2#3#4#5#6{%
+ \scope[xshift=.5\tikz@lib@fold@length,yshift=0.68819\tikz@lib@fold@length]
+ #1
+ \endscope
+ \scope[shift={(108:\tikz@lib@fold@length)},shift={(36:\tikz@lib@fold@length)},rotate=-36]
+ #2
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,shift={(72:\tikz@lib@fold@length)},rotate=-108]
+ #3
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #4
+ \endscope
+ \scope[rotate=108]
+ #5
+ \endscope
+ \scope[shift={(108:\tikz@lib@fold@length)},rotate=36]
+ #6
+ \endscope
+}%
+
+\def\tikz@lib@fold@hexagon#1#2#3#4#5#6#7{%
+ \scope
+ [shift={(60:\tikz@lib@fold@length)}]
+ #1
+ \endscope
+ \scope
+ [shift={(120:\tikz@lib@fold@length)},
+ shift={(60:\tikz@lib@fold@length)}]
+ #2
+ \endscope
+ \scope
+ [shift={(120:\tikz@lib@fold@length)},
+ shift={(60:\tikz@lib@fold@length)},
+ xshift=\tikz@lib@fold@length,
+ rotate=-60]
+ #3
+ \endscope
+ \scope
+ [xshift=\tikz@lib@fold@length,
+ shift={(60:\tikz@lib@fold@length)},
+ rotate=-120]
+ #4
+ \endscope
+ \scope
+ [xshift=\tikz@lib@fold@length,
+ rotate=180]
+ #5
+ \endscope
+ \scope
+ [rotate=120]
+ #6
+ \endscope
+ \scope
+ [shift={(120:\tikz@lib@fold@length)},
+ rotate=60]
+ #7
+ \endscope
+}%
+
+\def\tikz@lib@fold@octagon#1#2#3#4#5#6#7#8#9{%
+ \scope[xshift=.5\tikz@lib@fold@length,yshift=1.20711\tikz@lib@fold@length]
+ #1
+ \endscope
+ \scope[yshift=2.41421\tikz@lib@fold@length]
+ #2
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,yshift=2.41421\tikz@lib@fold@length,rotate=-45]
+ #3
+ \endscope
+ \scope[xshift=1.70711\tikz@lib@fold@length,yshift=1.70711\tikz@lib@fold@length,rotate=-90]
+ #4
+ \endscope
+ \scope[xshift=1.70711\tikz@lib@fold@length,yshift=.70711\tikz@lib@fold@length,rotate=-135]
+ #5
+ \endscope
+ \scope[xshift=\tikz@lib@fold@length,rotate=180]
+ #6
+ \endscope
+ \scope[rotate=135]
+ #7
+ \endscope
+ \scope[xshift=-.70711\tikz@lib@fold@length,yshift=.70711\tikz@lib@fold@length,rotate=90]
+ #8
+ \endscope
+ \scope[xshift=-.70711\tikz@lib@fold@length,yshift=1.70711\tikz@lib@fold@length,rotate=45]
+ #9
+ \endscope
+}%
+
+\def\tikz@lib@fold@decagon#1#2#3#4#5#6#7{%
+ \scope[shift={(72:1.61803\tikz@lib@fold@length)}] %decagon inside a circle with radius the golden ratio has side length 1
+ #1
+ \endscope
+ \scope
+ [shift={(36:\tikz@lib@fold@length)},
+ shift={(72:\tikz@lib@fold@length)},
+ shift={(108:\tikz@lib@fold@length)},
+ shift={(144:\tikz@lib@fold@length)}]
+ #2
+ \endscope
+ \scope
+ [xshift=\tikz@lib@fold@length,
+ shift={(36:\tikz@lib@fold@length)},
+ shift={(72:\tikz@lib@fold@length)},
+ shift={(108:\tikz@lib@fold@length)},
+ shift={(144:\tikz@lib@fold@length)},
+ rotate=-36]
+ #3
+ \endscope
+ \scope
+ [xshift=\tikz@lib@fold@length,
+ shift={(36:\tikz@lib@fold@length)},
+ shift={(72:\tikz@lib@fold@length)},
+ shift={(108:\tikz@lib@fold@length)},
+ rotate=-72]
+ #4
+ \endscope
+ \scope
+ [xshift=\tikz@lib@fold@length,
+ shift={(36:\tikz@lib@fold@length)},
+ shift={(72:\tikz@lib@fold@length)},
+ rotate=-108]
+ #5
+ \endscope
+ \scope
+ [xshift=\tikz@lib@fold@length,
+ shift={(36:\tikz@lib@fold@length)},
+ rotate=-144]
+ #6
+ \endscope
+ \scope
+ [xshift=\tikz@lib@fold@length,
+ rotate=180]
+ #7
+ \endscope
+ \tikz@lib@fold@decagonbis
+}%
+
+\def\tikz@lib@fold@decagonbis#1#2#3#4{%
+ \scope
+ [rotate=144]
+ #1
+ \endscope
+ \scope
+ [shift={(144:\tikz@lib@fold@length)},
+ rotate=108]
+ #2
+ \endscope
+ \scope
+ [shift={(144:\tikz@lib@fold@length)},
+ shift={(108:\tikz@lib@fold@length)},
+ rotate=72]
+ #3
+ \endscope
+ \scope
+ [shift={(144:\tikz@lib@fold@length)},
+ shift={(108:\tikz@lib@fold@length)},
+ shift={(72:\tikz@lib@fold@length)},
+ rotate=36]
+ #4
+ \endscope
+}%
+
+\def\tikz@lib@fold@path{\draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt);}%
+\def\tikz@lib@fold@cut@path{\draw[every cut](0,0) -- (\tikz@lib@fold@length,0pt);}%
+\def\tikz@lib@fold@ear@path{
+ \path[every ear] (0,0) -- (.5\tikz@lib@fold@length,.2\tikz@lib@fold@length) --(\tikz@lib@fold@length,0pt) --(0,0) -- cycle;
+ \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt);
+ \draw[every cut] (0,0) -- (.5\tikz@lib@fold@length,.2\tikz@lib@fold@length) --(\tikz@lib@fold@length,0pt);}%
+\def\tikz@lib@fold@ear@custom@left@path#1{
+ \path[every ear] (0,0) -- (#1:.66\tikz@lib@fold@length) -- (\tikz@lib@fold@length,0pt) --(0,0) -- cycle;
+ \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt);
+ \draw[every cut] (0,0) -- (#1:.66\tikz@lib@fold@length) -- (\tikz@lib@fold@length,0pt);}%
+\def\tikz@lib@fold@ear@custom@right@path#1{
+ \path[every ear] (0,0) -- (\tikz@lib@fold@length,0pt) -- ++(-#1:-.66\tikz@lib@fold@length) --(0,0) -- cycle;
+ \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt);
+ \draw[every cut] (\tikz@lib@fold@length,0pt) -- ++(-#1:-.66\tikz@lib@fold@length) -- (0,0);}%
+
+\tikzset{every ear/.style={}}%
+\tikzset{every cut/.style={}}%
+\tikzset{every fold/.style={help lines}}%
+
+\tikzoption{face 1}{\def\tikz@lib@fold@face@A{#1}}%
+\tikzoption{face 2}{\def\tikz@lib@fold@face@B{#1}}%
+\tikzoption{face 3}{\def\tikz@lib@fold@face@C{#1}}%
+\tikzoption{face 4}{\def\tikz@lib@fold@face@D{#1}}%
+\tikzoption{face 5}{\def\tikz@lib@fold@face@E{#1}}%
+\tikzoption{face 6}{\def\tikz@lib@fold@face@F{#1}}%
+\tikzoption{face 7}{\def\tikz@lib@fold@face@G{#1}}%
+\tikzoption{face 8}{\def\tikz@lib@fold@face@H{#1}}%
+\tikzoption{face 9}{\def\tikz@lib@fold@face@I{#1}}%
+\tikzoption{face 10}{\def\tikz@lib@fold@face@J{#1}}%
+\tikzoption{face 11}{\def\tikz@lib@fold@face@K{#1}}%
+\tikzoption{face 12}{\def\tikz@lib@fold@face@L{#1}}%
+\tikzoption{face 13}{\def\tikz@lib@fold@face@M{#1}}%
+\tikzoption{face 14}{\def\tikz@lib@fold@face@N{#1}}%
+\tikzoption{face 15}{\def\tikz@lib@fold@face@O{#1}}%
+\tikzoption{face 16}{\def\tikz@lib@fold@face@P{#1}}%
+\tikzoption{face 17}{\def\tikz@lib@fold@face@Q{#1}}%
+\tikzoption{face 18}{\def\tikz@lib@fold@face@R{#1}}%
+\tikzoption{face 19}{\def\tikz@lib@fold@face@S{#1}}%
+\tikzoption{face 20}{\def\tikz@lib@fold@face@T{#1}}%
+\tikzoption{face 21}{\def\tikz@lib@fold@face@U{#1}}%
+\tikzoption{face 22}{\def\tikz@lib@fold@face@V{#1}}%
+\tikzoption{face 23}{\def\tikz@lib@fold@face@W{#1}}%
+\tikzoption{face 24}{\def\tikz@lib@fold@face@X{#1}}%
+\tikzoption{face 25}{\def\tikz@lib@fold@face@Y{#1}}%
+\tikzoption{face 26}{\def\tikz@lib@fold@face@Z{#1}}%
+\tikzoption{face 27}{\def\tikz@lib@fold@face@AA{#1}}%
+\tikzoption{face 28}{\def\tikz@lib@fold@face@AB{#1}}%
+\tikzoption{face 29}{\def\tikz@lib@fold@face@AC{#1}}%
+\tikzoption{face 30}{\def\tikz@lib@fold@face@AD{#1}}%
+\tikzoption{face 31}{\def\tikz@lib@fold@face@AE{#1}}%
+\tikzoption{face 32}{\def\tikz@lib@fold@face@AF{#1}}%
+\tikzoption{face 33}{\def\tikz@lib@fold@face@AG{#1}}%
+\tikzoption{face 34}{\def\tikz@lib@fold@face@AH{#1}}%
+\tikzoption{face 35}{\def\tikz@lib@fold@face@AI{#1}}%
+\tikzoption{face 36}{\def\tikz@lib@fold@face@AJ{#1}}%
+\tikzoption{face 37}{\def\tikz@lib@fold@face@AK{#1}}%
+\tikzoption{face 38}{\def\tikz@lib@fold@face@AL{#1}}%
+\tikzoption{face 39}{\def\tikz@lib@fold@face@AM{#1}}%
+\tikzoption{face 40}{\def\tikz@lib@fold@face@AN{#1}}%
+\tikzoption{face 41}{\def\tikz@lib@fold@face@AO{#1}}%
+\tikzoption{face 42}{\def\tikz@lib@fold@face@AP{#1}}%
+\tikzoption{face 43}{\def\tikz@lib@fold@face@AQ{#1}}%
+\tikzoption{face 44}{\def\tikz@lib@fold@face@AR{#1}}%
+\tikzoption{face 45}{\def\tikz@lib@fold@face@AS{#1}}%
+\tikzoption{face 46}{\def\tikz@lib@fold@face@AT{#1}}%
+\tikzoption{face 47}{\def\tikz@lib@fold@face@AU{#1}}%
+\tikzoption{face 48}{\def\tikz@lib@fold@face@AV{#1}}%
+\tikzoption{face 49}{\def\tikz@lib@fold@face@AW{#1}}%
+\tikzoption{face 50}{\def\tikz@lib@fold@face@AX{#1}}%
+\tikzoption{face 51}{\def\tikz@lib@fold@face@AY{#1}}%
+\tikzoption{face 52}{\def\tikz@lib@fold@face@AZ{#1}}%
+\tikzoption{face 53}{\def\tikz@lib@fold@face@BA{#1}}%
+\tikzoption{face 54}{\def\tikz@lib@fold@face@BB{#1}}%
+\tikzoption{face 55}{\def\tikz@lib@fold@face@BC{#1}}%
+\tikzoption{face 56}{\def\tikz@lib@fold@face@BD{#1}}%
+\tikzoption{face 57}{\def\tikz@lib@fold@face@BE{#1}}%
+\tikzoption{face 58}{\def\tikz@lib@fold@face@BF{#1}}%
+\tikzoption{face 59}{\def\tikz@lib@fold@face@BG{#1}}%
+\tikzoption{face 60}{\def\tikz@lib@fold@face@BH{#1}}%
+\tikzoption{face 61}{\def\tikz@lib@fold@face@BI{#1}}%
+\tikzoption{face 62}{\def\tikz@lib@fold@face@BJ{#1}}%
+\tikzoption{face 63}{\def\tikz@lib@fold@face@BK{#1}}%
+\tikzoption{face 64}{\def\tikz@lib@fold@face@BL{#1}}%
+\tikzoption{face 65}{\def\tikz@lib@fold@face@BM{#1}}%
+\tikzoption{face 66}{\def\tikz@lib@fold@face@BN{#1}}%
+\tikzoption{face 67}{\def\tikz@lib@fold@face@BO{#1}}%
+\tikzoption{face 68}{\def\tikz@lib@fold@face@BP{#1}}%
+\tikzoption{face 69}{\def\tikz@lib@fold@face@BQ{#1}}%
+\tikzoption{face 70}{\def\tikz@lib@fold@face@BR{#1}}%
+\tikzoption{face 71}{\def\tikz@lib@fold@face@BS{#1}}%
+\tikzoption{face 72}{\def\tikz@lib@fold@face@BT{#1}}%
+\tikzoption{face 73}{\def\tikz@lib@fold@face@BU{#1}}%
+\tikzoption{face 74}{\def\tikz@lib@fold@face@BV{#1}}%
+\tikzoption{face 75}{\def\tikz@lib@fold@face@BW{#1}}%
+\tikzoption{face 76}{\def\tikz@lib@fold@face@BX{#1}}%
+\tikzoption{face 77}{\def\tikz@lib@fold@face@BY{#1}}%
+\tikzoption{face 78}{\def\tikz@lib@fold@face@BZ{#1}}%
+\tikzoption{face 79}{\def\tikz@lib@fold@face@CA{#1}}%
+\tikzoption{face 80}{\def\tikz@lib@fold@face@CB{#1}}%
+\tikzoption{face 81}{\def\tikz@lib@fold@face@CC{#1}}%
+\tikzoption{face 82}{\def\tikz@lib@fold@face@CD{#1}}%
+\tikzoption{face 83}{\def\tikz@lib@fold@face@CE{#1}}%
+\tikzoption{face 84}{\def\tikz@lib@fold@face@CF{#1}}%
+\tikzoption{face 85}{\def\tikz@lib@fold@face@CG{#1}}%
+\tikzoption{face 86}{\def\tikz@lib@fold@face@CH{#1}}%
+\tikzoption{face 87}{\def\tikz@lib@fold@face@CI{#1}}%
+\tikzoption{face 88}{\def\tikz@lib@fold@face@CJ{#1}}%
+\tikzoption{face 89}{\def\tikz@lib@fold@face@CK{#1}}%
+\tikzoption{face 90}{\def\tikz@lib@fold@face@CL{#1}}%
+\tikzoption{face 91}{\def\tikz@lib@fold@face@CM{#1}}%
+\tikzoption{face 92}{\def\tikz@lib@fold@face@CN{#1}}%
+
+
+\let\tikz@lib@fold@face@A=\pgfutil@empty
+\let\tikz@lib@fold@face@B=\pgfutil@empty
+\let\tikz@lib@fold@face@C=\pgfutil@empty
+\let\tikz@lib@fold@face@D=\pgfutil@empty
+\let\tikz@lib@fold@face@E=\pgfutil@empty
+\let\tikz@lib@fold@face@F=\pgfutil@empty
+\let\tikz@lib@fold@face@G=\pgfutil@empty
+\let\tikz@lib@fold@face@H=\pgfutil@empty
+\let\tikz@lib@fold@face@I=\pgfutil@empty
+\let\tikz@lib@fold@face@J=\pgfutil@empty
+\let\tikz@lib@fold@face@K=\pgfutil@empty
+\let\tikz@lib@fold@face@L=\pgfutil@empty
+\let\tikz@lib@fold@face@M=\pgfutil@empty
+\let\tikz@lib@fold@face@N=\pgfutil@empty
+\let\tikz@lib@fold@face@O=\pgfutil@empty
+\let\tikz@lib@fold@face@P=\pgfutil@empty
+\let\tikz@lib@fold@face@Q=\pgfutil@empty
+\let\tikz@lib@fold@face@R=\pgfutil@empty
+\let\tikz@lib@fold@face@S=\pgfutil@empty
+\let\tikz@lib@fold@face@T=\pgfutil@empty
+\let\tikz@lib@fold@face@U=\pgfutil@empty
+\let\tikz@lib@fold@face@V=\pgfutil@empty
+\let\tikz@lib@fold@face@W=\pgfutil@empty
+\let\tikz@lib@fold@face@X=\pgfutil@empty
+\let\tikz@lib@fold@face@Y=\pgfutil@empty
+\let\tikz@lib@fold@face@Z=\pgfutil@empty
+\let\tikz@lib@fold@face@AA=\pgfutil@empty
+\let\tikz@lib@fold@face@AB=\pgfutil@empty
+\let\tikz@lib@fold@face@AC=\pgfutil@empty
+\let\tikz@lib@fold@face@AD=\pgfutil@empty
+\let\tikz@lib@fold@face@AE=\pgfutil@empty
+\let\tikz@lib@fold@face@AF=\pgfutil@empty
+\let\tikz@lib@fold@face@AG=\pgfutil@empty
+\let\tikz@lib@fold@face@AH=\pgfutil@empty
+\let\tikz@lib@fold@face@AI=\pgfutil@empty
+\let\tikz@lib@fold@face@AJ=\pgfutil@empty
+\let\tikz@lib@fold@face@AK=\pgfutil@empty
+\let\tikz@lib@fold@face@AL=\pgfutil@empty
+\let\tikz@lib@fold@face@AM=\pgfutil@empty
+\let\tikz@lib@fold@face@AN=\pgfutil@empty
+\let\tikz@lib@fold@face@AO=\pgfutil@empty
+\let\tikz@lib@fold@face@AP=\pgfutil@empty
+\let\tikz@lib@fold@face@AQ=\pgfutil@empty
+\let\tikz@lib@fold@face@AR=\pgfutil@empty
+\let\tikz@lib@fold@face@AS=\pgfutil@empty
+\let\tikz@lib@fold@face@AT=\pgfutil@empty
+\let\tikz@lib@fold@face@AU=\pgfutil@empty
+\let\tikz@lib@fold@face@AV=\pgfutil@empty
+\let\tikz@lib@fold@face@AW=\pgfutil@empty
+\let\tikz@lib@fold@face@AX=\pgfutil@empty
+\let\tikz@lib@fold@face@AY=\pgfutil@empty
+\let\tikz@lib@fold@face@AZ=\pgfutil@empty
+\let\tikz@lib@fold@face@BA=\pgfutil@empty
+\let\tikz@lib@fold@face@BB=\pgfutil@empty
+\let\tikz@lib@fold@face@BC=\pgfutil@empty
+\let\tikz@lib@fold@face@BD=\pgfutil@empty
+\let\tikz@lib@fold@face@BE=\pgfutil@empty
+\let\tikz@lib@fold@face@BF=\pgfutil@empty
+\let\tikz@lib@fold@face@BG=\pgfutil@empty
+\let\tikz@lib@fold@face@BH=\pgfutil@empty
+\let\tikz@lib@fold@face@BI=\pgfutil@empty
+\let\tikz@lib@fold@face@BJ=\pgfutil@empty
+\let\tikz@lib@fold@face@BK=\pgfutil@empty
+\let\tikz@lib@fold@face@BL=\pgfutil@empty
+\let\tikz@lib@fold@face@BM=\pgfutil@empty
+\let\tikz@lib@fold@face@BN=\pgfutil@empty
+\let\tikz@lib@fold@face@BO=\pgfutil@empty
+\let\tikz@lib@fold@face@BP=\pgfutil@empty
+\let\tikz@lib@fold@face@BQ=\pgfutil@empty
+\let\tikz@lib@fold@face@BR=\pgfutil@empty
+\let\tikz@lib@fold@face@BS=\pgfutil@empty
+\let\tikz@lib@fold@face@BT=\pgfutil@empty
+\let\tikz@lib@fold@face@BU=\pgfutil@empty
+\let\tikz@lib@fold@face@BV=\pgfutil@empty
+\let\tikz@lib@fold@face@BW=\pgfutil@empty
+\let\tikz@lib@fold@face@BX=\pgfutil@empty
+\let\tikz@lib@fold@face@BY=\pgfutil@empty
+\let\tikz@lib@fold@face@BZ=\pgfutil@empty
+\let\tikz@lib@fold@face@CA=\pgfutil@empty
+\let\tikz@lib@fold@face@CB=\pgfutil@empty
+\let\tikz@lib@fold@face@CC=\pgfutil@empty
+\let\tikz@lib@fold@face@CD=\pgfutil@empty
+\let\tikz@lib@fold@face@CE=\pgfutil@empty
+\let\tikz@lib@fold@face@CF=\pgfutil@empty
+\let\tikz@lib@fold@face@CG=\pgfutil@empty
+\let\tikz@lib@fold@face@CH=\pgfutil@empty
+\let\tikz@lib@fold@face@CI=\pgfutil@empty
+\let\tikz@lib@fold@face@CJ=\pgfutil@empty
+\let\tikz@lib@fold@face@CK=\pgfutil@empty
+\let\tikz@lib@fold@face@CL=\pgfutil@empty
+\let\tikz@lib@fold@face@CM=\pgfutil@empty
+\let\tikz@lib@fold@face@CN=\pgfutil@empty
+
+
+\tikzset{numbered faces/.style={%
+ face 1={\node{1};},
+ face 2={\node{2};},
+ face 3={\node{3};},
+ face 4={\node{4};},
+ face 5={\node{5};},
+ face 6={\node{6};},
+ face 7={\node{7};},
+ face 8={\node{8};},
+ face 9={\node{9};},
+ face 10={\node{10};},
+ face 11={\node{11};},
+ face 12={\node{12};},
+ face 13={\node{13};},
+ face 14={\node{14};},
+ face 15={\node{15};},
+ face 16={\node{16};},
+ face 17={\node{17};},
+ face 18={\node{18};},
+ face 19={\node{19};},
+ face 20={\node{20};},
+ face 21={\node{21};},
+ face 22={\node{22};},
+ face 23={\node{23};},
+ face 24={\node{24};},
+ face 25={\node{25};},
+ face 26={\node{26};},
+ face 27={\node{27};},
+ face 28={\node{28};},
+ face 29={\node{29};},
+ face 30={\node{30};},
+ face 31={\node{31};},
+ face 32={\node{32};},
+ face 33={\node{33};},
+ face 34={\node{34};},
+ face 35={\node{35};},
+ face 36={\node{36};},
+ face 37={\node{37};},
+ face 38={\node{38};},
+ face 39={\node{39};},
+ face 40={\node{40};},
+ face 41={\node{41};},
+ face 42={\node{42};},
+ face 43={\node{43};},
+ face 44={\node{44};},
+ face 45={\node{45};},
+ face 46={\node{46};},
+ face 47={\node{47};},
+ face 48={\node{48};},
+ face 49={\node{49};},
+ face 50={\node{50};},
+ face 51={\node{51};},
+ face 52={\node{52};},
+ face 53={\node{53};},
+ face 54={\node{54};},
+ face 55={\node{55};},
+ face 56={\node{56};},
+ face 57={\node{57};},
+ face 58={\node{58};},
+ face 59={\node{59};},
+ face 60={\node{60};},
+ face 61={\node{61};},
+ face 62={\node{62};},
+ face 63={\node{63};},
+ face 64={\node{64};},
+ face 65={\node{65};},
+ face 66={\node{66};},
+ face 67={\node{67};},
+ face 68={\node{68};},
+ face 69={\node{69};},
+ face 70={\node{70};},
+ face 71={\node{71};},
+ face 72={\node{72};},
+ face 73={\node{73};},
+ face 74={\node{74};},
+ face 75={\node{75};},
+ face 76={\node{76};},
+ face 77={\node{77};},
+ face 78={\node{78};},
+ face 79={\node{79};},
+ face 80={\node{80};},
+ face 81={\node{81};},
+ face 82={\node{82};},
+ face 83={\node{83};},
+ face 84={\node{84};},
+ face 85={\node{85};},
+ face 86={\node{86};},
+ face 87={\node{87};},
+ face 88={\node{88};},
+ face 89={\node{89};},
+ face 90={\node{90};},
+ face 91={\node{91};},
+ face 92={\node{92};}}}%
+
+% The foldings defined here:
+
+\tikzset{
+ pics/dodecahedron folding/.style = {code=\tikzfoldingdodecahedron[];},
+ pics/tetrahedron folding/.style = {code=\tikzfoldingtetrahedron[];},
+ pics/tetrahedron truncated folding/.style = {code=\tikzfoldingtruncatedtetrahedron[];},
+ pics/cube folding/.style = {code=\tikzfoldingcube[];},
+ pics/cube truncated folding/.style = {code=\tikzfoldingtruncatedcube[];},
+ pics/octahedron folding/.style = {code=\tikzfoldingoctahedron[];},
+ pics/octahedron truncated folding/.style = {code=\tikzfoldingtruncatedoctahedron[];},
+ pics/dodecahedron folding/.style = {code=\tikzfoldingdodecahedron[];},
+ pics/dodecahedron' folding/.style = {code=\tikzfoldingalternatedodecahedron[];},
+ pics/dodecahedron rhombic folding/.style = {code=\tikzfoldingrhombicdodecahedron[];},
+ pics/dodecahedron golden folding/.style = {code=\tikzfoldinggoldenrhombicdodecahedron[];},
+ pics/cuboctahedron folding/.style = {code=\tikzfoldingcuboctahedron[];},
+ pics/cuboctahedron truncated folding/.style = {code=\tikzfoldingtruncatedcuboctahedron[];},
+ pics/icosahedron folding/.style = {code=\tikzfoldingicosahedron[];},
+ pics/rhombicuboctahedron folding/.style = {code=\tikzfoldingrhombicuboctahedron[];},
+ pics/snub cube folding/.style = {code=\tikzfoldingsnubcube[];},
+ pics/icosidodecahedron folding/.style = {code=\tikzfoldingicosidodecahedron[];}
+}%
+
+
+
+% Platonic solids
+% ---------------
+
+\def\tikzfoldingdodecahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+%alternative dodecahedron: larger format possible
+
+\def\tikzfoldingalternatedodecahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@pentagon
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ \endgroup
+}%
+
+
+%tetrahedron
+
+\def\tikzfoldingtetrahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+%cube
+
+\def\tikzfoldingcube#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@square{\tikz@lib@fold@face@A}
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@D}
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+
+%octahedron
+
+\def\tikzfoldingoctahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ \endgroup
+}%
+
+
+%icosahedron
+
+\def\tikzfoldingicosahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@O}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@P}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@Q}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@R}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@S}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@T}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ \endgroup
+}%
+
+% Archimedean solids
+% ------------------
+
+%truncated tetrahedron
+
+\def\tikzfoldingtruncatedtetrahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+%cuboctahedron
+
+\def\tikzfoldingcuboctahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@square
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+%truncated cube
+
+\def\tikzfoldingtruncatedcube#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ \endgroup
+}%
+
+
+%truncated octahedron
+
+\def\tikzfoldingtruncatedoctahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ \endgroup
+}%
+
+
+%rhombicuboctahedron
+
+\def\tikzfoldingrhombicuboctahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@square
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@O}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@P}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@Q}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@R}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@S}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@T}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@U}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@V}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@W}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@triangle
+ {\tikz@lib@fold@face@X}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@Y}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@Z}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ \endgroup
+}%
+
+%truncated cuboctahedron
+
+\def\tikzfoldingtruncatedcuboctahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@square
+ {\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@C}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{15}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@custom@left@path{15}}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{15}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@custom@left@path{15}}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{15}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@custom@left@path{15}}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{15}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@custom@left@path{15}}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@O}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@P}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@Q}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@R}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@S}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@T}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{15}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@custom@left@path{15}}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@U}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{15}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@custom@left@path{15}}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@V}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@W}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@square
+ {\tikz@lib@fold@face@X}
+ {\tikz@lib@fold@octagon
+ {\tikz@lib@fold@face@Y}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@hexagon
+ {\tikz@lib@fold@face@Z}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{15}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@custom@left@path{15}}
+ {\tikz@lib@fold@ear@path}
+ }
+ \endgroup
+}%
+
+%snub cube
+
+\def\tikzfoldingsnubcube#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@square{\tikz@lib@fold@face@A}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@B}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@C}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@E}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@F}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@K}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@L}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@N}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@O}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@P}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@Q}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@R}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@S}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@T}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@U}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@V}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@W}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@X}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@Y}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@Z}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AA}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AB}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AC}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AD}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AE}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@AF}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AG}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AH}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AI}
+ {
+ \tikz@lib@fold@square{\tikz@lib@fold@face@AJ}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AK}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AL}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+% icosidodecahedron
+
+\def\tikzfoldingicosidodecahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@A}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@B}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@C}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@F}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@ear@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@J}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@L}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@M}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@O}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@P}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@Q}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@R}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@S}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@T}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@U}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@V}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@W}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@X}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@Y}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@Z}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ }
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AA}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@AB}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AC}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {
+ \tikz@lib@fold@pentagon{\tikz@lib@fold@face@AD}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AE}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {
+ \tikz@lib@fold@triangle{\tikz@lib@fold@face@AF}
+ {\tikz@lib@fold@ear@custom@right@path{24}}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+%rhombic (Catalan) dodecahedron ("type 1" - spheric)
+\def\tikzfoldingrhombicdodecahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@squarerhombusr{\tikz@lib@fold@face@B}
+ {\tikz@lib@fold@squarerhombusl{\scope[rotate=90]\tikz@lib@fold@face@C\endscope}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@squarerhombusr{\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@squarerhombusl{\scope[rotate=90]\tikz@lib@fold@face@F\endscope}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@squarerhombusr{\scope[rotate=180]\tikz@lib@fold@face@D\endscope}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@squarerhombusl{\scope[rotate=-90]\tikz@lib@fold@face@H\endscope}
+ {\tikz@lib@fold@squarerhombusr{\scope[rotate=180]\tikz@lib@fold@face@G\endscope}
+ {\tikz@lib@fold@squarerhombusl{\scope[rotate=-90]\tikz@lib@fold@face@L\endscope}
+ {\tikz@lib@fold@squarerhombusr{\scope[rotate=180]\tikz@lib@fold@face@K\endscope}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@squarerhombusl{\scope[rotate=90]\tikz@lib@fold@face@J\endscope}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@squarerhombusl{\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@squarerhombusr{\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+%golden rhombic dodecahedron ("type 2" - flattened)
+\def\tikzfoldinggoldenrhombicdodecahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@A}
+ {\tikz@lib@fold@goldenrhombusl{\scope[rotate=180]\tikz@lib@fold@face@B\endscope}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ {\tikz@lib@fold@goldenrhombusr{\scope[rotate=180]\tikz@lib@fold@face@E\endscope}
+ {\tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@G}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@goldenrhombusl{\scope[rotate=180]\tikz@lib@fold@face@D\endscope}
+ {\tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@I}
+ {\tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@L}
+ {\tikz@lib@fold@goldenrhombusr{\scope[rotate=180]\tikz@lib@fold@face@K\endscope}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@goldenrhombusl{\scope[rotate=180]\tikz@lib@fold@face@J\endscope}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@F}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ {\tikz@lib@fold@goldenrhombusr{\scope[rotate=180]\tikz@lib@fold@face@C\endscope}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ \endgroup
+}%
+
+%rhombic tricontahedron
+
+\def\tikzfoldingrhombictricontahedron#1[#2]#3;{%
+ \begingroup%
+ \tikzset{#2}%
+ \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@A}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@B}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@F}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@I}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@J}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@K}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@H}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@G}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@L}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@M}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@C}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@N}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@N}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@N}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@D}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@D}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@D}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ }
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@D}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@E}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@E}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@E}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@cut@path}
+ }
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@E}
+ { \tikz@lib@fold@goldenrhombusl{\tikz@lib@fold@face@E}
+ { \tikz@lib@fold@goldenrhombusr{\tikz@lib@fold@face@E}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@ear@path}
+ }
+ {\tikz@lib@fold@ear@path}
+ {\tikz@lib@fold@path}
+ {\tikz@lib@fold@path}
+ }
+ }
+ \endgroup
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfpu.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfpu.code.tex
new file mode 100644
index 0000000000..36e0afe133
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryfpu.code.tex
@@ -0,0 +1,10 @@
+% Copyright 2008/2018 by Christian Feuersaenger
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU General Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{fpu}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
new file mode 100644
index 0000000000..cf94f92367
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
@@ -0,0 +1,148 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Free Documentation License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{intersections}%
+
+% FIXME : the 'name path global' is not reset properly - and some
+% following 'name path' will append to it rather that reset it.
+
+\pgfkeys{%
+ /tikz/name path global/.code={%
+ % reset any "old" variables inherited from some other path
+ % - we do not accidentally want to append to an old path with the
+ % same name (or if someone provided the option twice)...
+ \expandafter\global\expandafter\let\csname tikz@intersect@path@name@#1\endcsname=\relax
+ \tikz@key@name@path{#1}{\gdef}%
+ },
+ /tikz/name path local/.code={%
+ \pgfkeys{/tikz/name path={#1}}%
+ },
+ /tikz/name path/.code={%
+ % hm. Do we need this "reset old option" as in 'name path global'
+ % for this case as well?
+ \tikz@key@name@path{#1}{\def}%
+ },
+}%
+
+% #1: the name to assign.
+% #2: one of '\def' or '\gdef'.
+\def\tikz@key@name@path#1#2{%
+ \tikz@addmode{%
+ \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath@round%
+ \pgfprocessround\tikz@intersect@temppath@round\tikz@intersect@temppath%
+ \ifx\tikz@intersect@namedpaths\pgfutil@empty%
+ \else%
+ \tikz@intersect@namedpaths%
+ \fi%
+ \tikz@intersect@addto@path@names{#1}{#2}%
+ }%
+}%
+
+% #1: the name to assign.
+% #2: one of '\def' or '\gdef'.
+\def\tikz@intersect@addto@path@names#1#2{%
+ \edef\tikz@marshal{#2\expandafter\noexpand\csname tikz@intersect@path@name@#1\endcsname}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@marshal%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@marshal\expandafter{\tikz@intersect@temppath}}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\tikz@intersect@namedpaths\expandafter{\tikz@marshal}%
+}%
+
+% at the end of evey \path command ...
+\let\tikz@finish@orig=\tikz@finish
+\def\tikz@finish{%
+ \tikz@finish@orig%
+ \tikz@intersect@finish%
+}%
+
+% ... make the named path variables available
+\def\tikz@intersect@finish{%
+ \tikz@intersect@namedpaths%
+}%
+
+\let\tikz@intersect@namedpaths=\pgfutil@empty
+\let\tikz@intersect@path@a=\pgfutil@empty
+\let\tikz@intersect@path@b=\pgfutil@empty
+\let\tikz@intersect@name=\pgfutil@empty
+\let\tikz@intersect@total=\pgfutil@empty
+
+\tikzset{
+ every scope/.append style={
+ execute at begin scope={\let\tikz@intersect@namedpaths@outside\tikz@intersect@namedpaths},
+ execute at end scope={\global\let\tikz@intersect@namedpaths\tikz@intersect@namedpaths@outside},
+ },
+ name intersections/.code={%
+ \tikzset{/tikz/intersection/.cd,
+ by=,
+ #1}%
+ \pgfutil@ifundefined{tikz@intersect@path@name@\tikz@intersect@path@a}{%
+ \tikzerror{I do not know the path named `\tikz@intersect@path@a'. Perhaps you misspelt it}}%
+ {\pgfutil@ifundefined{tikz@intersect@path@name@\tikz@intersect@path@b}{%
+ \tikzerror{I do not know the path named `\tikz@intersect@path@b'. Perhaps you misspelt it}}%
+ {%
+ \pgfintersectionofpaths%
+ {%
+ \expandafter\pgfsetpath\csname tikz@intersect@path@name@\tikz@intersect@path@a\endcsname%
+ }%
+ {%
+ \expandafter\pgfsetpath\csname tikz@intersect@path@name@\tikz@intersect@path@b\endcsname%
+ }%
+ \ifx\tikz@intersect@total\pgfutil@empty%
+ \else%
+ \expandafter\let\tikz@intersect@total=\pgfintersectionsolutions%
+ \fi%
+ \ifx\tikz@intersect@name\pgfutil@empty%
+ \def\tikz@intersect@@name{intersection}%
+ \else%
+ \let\tikz@intersect@@name=\tikz@intersect@name%
+ \fi%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgfintersectionsolutions\relax%
+ \else%
+ \path[reset cm]\pgfextra{\pgftransformshift{\pgfpointintersectionsolution{\pgfmathcounter}}}%
+ coordinate (\tikz@intersect@@name-\pgfmathcounter);
+ \repeatpgfmathloop%
+ \ifx\tikz@intersect@by\pgfutil@empty%
+ \else%
+ \foreach\tikz@intersect@name[count=\tikz@intersection@count] in \tikz@intersect@by%
+ {\expandafter\tikz@intersect@name@parse\tikz@intersect@name\pgf@stop}%
+ \fi%
+ }%
+ }%
+ },%
+ intersection/.cd,
+ of/.code=\tikz@intersect@path@names@parse#1\tikz@stop,%
+ name/.store in=\tikz@intersect@name,
+ total/.store in=\tikz@intersect@total,
+ by/.store in=\tikz@intersect@by,
+ sort by/.code=\edef\tikz@intersect@sort@by{#1}\tikz@intersect@check@sort@by%
+}%
+
+
+\def\tikz@intersect@check@sort@by{%
+ \ifx\tikz@intersect@sort@by\tikz@intersect@path@a%
+ \pgfintersectionsortbyfirstpath%
+ \else%
+ \ifx\tikz@intersect@sort@by\tikz@intersect@path@b%
+ \pgfintersectionsortbysecondpath%
+ \else%
+ \pgf@intersect@sortfalse%
+ \fi%
+ \fi%
+}%
+\def\tikz@intersect@path@names@parse#1 and #2\tikz@stop{%
+ \def\tikz@intersect@path@a{#1}%
+ \def\tikz@intersect@path@b{#2}%
+}%
+
+\def\tikz@intersect@name@parse{\pgfutil@ifnextchar[\tikz@intersect@name@parse@opt{\tikz@intersect@name@parse@opt[]}}%}
+\def\tikz@intersect@name@parse@opt[#1]#2\pgf@stop{%
+ \coordinate [#1] (#2) at (\tikz@intersect@@name-\tikz@intersection@count);
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarylindenmayersystems.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarylindenmayersystems.code.tex
new file mode 100644
index 0000000000..6763c733e9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarylindenmayersystems.code.tex
@@ -0,0 +1,81 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{lindenmayersystems}%
+
+\def\tikz@@lsystem-system{%
+ \pgfutil@ifnextchar[{\tikz@lsystem@options}{\tikz@lsystem@options[]}}%
+
+\def\tikz@lsystem indenmayer system{%
+ \pgfutil@ifnextchar[{\tikz@lsystem@options}{\tikz@lsystem@options[]}}%
+
+\def\tikz@lsystem@options[#1]{%
+ \tikzset{#1}%
+ \ifx\tikz@lsystem@rules\pgfutil@empty%
+ \else%
+ \tikz@lsystem@declare%
+ \def\tikz@lsystem@name{tikz@temp}%
+ \fi%
+ \ifx\tikz@lsystem@anchor\pgfutil@empty%
+ \pgfpathmoveto{\pgfqpoint{\tikz@lastxsaved}{\tikz@lastysaved}}%
+ \pgflindenmayersystem{\tikz@lsystem@name}{\tikz@lsystem@axiom}{\tikz@lsystem@order}%
+ \else%
+ \pgfextract@process\tikz@lsystem@pos{\pgfqpoint{\tikz@lastxsaved}{\tikz@lastysaved}}%
+ \setbox\pgfnodeparttextbox=\hbox{%
+ \pgfinterruptpicture%
+ \pgfpicture%
+ \pgfpathmoveto{\pgfpointorigin}%
+ \pgflindenmayersystem{\tikz@lsystem@name}{\tikz@lsystem@axiom}{\tikz@lsystem@order}%
+ \begingroup%
+ \tikz@finish%
+ \endpgfpicture%
+ \endpgfinterruptpicture%
+ }%
+ {%
+ \pgftransformshift{\tikz@lsystem@pos}%
+ \tikzset{inner sep=0pt, outer sep=0pt, minimum size=0pt}%
+ \pgfmultipartnode{rectangle}{\tikz@lsystem@anchor}{lindenmayer system}{\pgfusepath{discard}}%
+ }%
+ \fi%
+ \tikz@scan@next@command}%
+
+\tikzset{%
+ lindenmayer system/.style={/pgf/lindenmayer system/.cd, #1,/tikz/.cd},
+ l-system/.style={lindenmayer system={#1}},
+}%
+\pgfkeys{/pgf/lindenmayer system/.cd,
+ name/.code=\edef\tikz@lsystem@name{#1}\let\tikz@lsystem@rules=\pgfutil@empty,%
+ axiom/.store in=\tikz@lsystem@axiom,%
+ order/.store in=\tikz@lsystem@order,
+ .unknown/.code={%
+ \pgfutil@ifundefined{pgf@lsystem@\pgfkeyscurrentname}{%
+ \pgfkeys{/errors/unknown key={/pgf/lindenmayer system/\pgfkeyscurrentname}{#1}}%
+ \let\tikz@lsystem@name=\pgfutil@empty%
+ }%
+ {\edef\tikz@lsystem@name{\pgfkeyscurrentname}}
+ },%
+ anchor/.store in=\tikz@lsystem@anchor,%
+ rule set/.store in=\tikz@lsystem@rules
+}%
+\let\tikz@lsystem@anchor=\pgfutil@empty%
+\let\tikz@lsystem@rules=\pgfutil@empty%
+
+\def\tikz@lsystem@declare{%
+ \expandafter\let\csname pgf@lsystem@tikz@temp\endcsname=\relax%
+ \pgfdeclarelindenmayersystem{tikz@temp}{%
+ \expandafter\tikz@lsystem@parse@rules\tikz@lsystem@rules,\tikz@stop,%
+ }%
+}%
+\def\tikz@lsystem@parse@rules#1,{%
+ \ifx#1\tikz@stop%
+ \else%
+ \rule{#1}%
+ \expandafter\tikz@lsystem@parse@rules%
+ \fi%
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex
new file mode 100644
index 0000000000..ec00bc4b8a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex
@@ -0,0 +1,731 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usetikzlibrary{fpu}
+
+\edef\tikz@math@at@catcode{\the\catcode`\@}%
+\catcode`\@=11
+
+\def\tikz@math@gobblespaces#1{\pgfutil@ifnextchar x{#1}{#1}}%
+
+\def\tikz@math@meaning@macro{macro}%
+\def\tikz@math@meaning@dimen{dimen}%
+\def\tikz@math@meaning@count{count}%
+\def\tikz@math@meaning@null{null}%
+
+\def\tikz@math@getmeaning#1{\expandafter\tikz@math@@getmeaning\meaning#1\tikz@math@getmeaning@stop}%
+
+\def\tikz@math@@getmeaning#1#2#3#4#5\tikz@math@getmeaning@stop{%
+ \if#1u% undefined
+ \let\tikz@math@meaning=\tikz@math@meaning@macro%
+ \else%
+ \if#1m%
+ \let\tikz@math@meaning=\tikz@math@meaning@macro%
+ \else%
+ \if#2d%
+ \let\tikz@math@meaning=\tikz@math@meaning@dimen%
+ \else%
+ \if#2c%
+ \let\tikz@math@meaning=\tikz@math@meaning@count%
+ \else%
+ \if#3k% A skip. Treat like a dimen.
+ \let\tikz@math@meaning=\tikz@math@meaning@dimen%
+ \else%
+ \let\tikz@math@meaning=\tikz@math@meaning@null%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+\def\tikz@math@firstoftwo#1#2{#1}%
+\def\tikz@math@secondoftwo#1#2{#2}%
+
+
+\def\tikz@math@getvarstring#1{%
+ \begingroup%
+ \escapechar=-1\relax%
+ \expandafter\tikz@math@@getvarstring\string#1\tikz@math}%
+
+\def\tikz@math@@getvarstring#1\tikz@math#2{%
+ \endgroup%
+ \def#2{#1}%
+}%
+
+\long\def\tikz@math@collecttosemicolon@other#1#2;{%
+ \def\tikz@math@collected{#2}#1}%
+\def\tikz@math@semicolon@other{;}%
+
+{\catcode`\;=13
+\long\gdef\tikz@math@collecttosemicolon@active#1#2;{%
+ \def\tikz@math@collected{#2}#1}%
+\gdef\tikz@math@semicolon@active{;}%
+}%
+
+
+\def\tikz@math@setvartype#1#2{%
+ \expandafter\let\csname tikz@math@var@vartype@\string#1\endcsname=#2%
+}%
+
+
+\def\tikz@math@getvartype#1#2{%
+ \def\tikz@math@marshal{\let#1=}%
+ \expandafter\tikz@math@marshal\csname
+ tikz@math@var@vartype@\string#2\endcsname%
+}%
+
+
+
+\def\tikz@math@ifvarcoordinate#1{%
+ \expandafter\ifx\csname
+ tikz@math@var@vartype@\string#1\endcsname\tikz@math@keyword@coordinate%
+ \let\tikz@math@next=\tikz@math@firstoftwo%
+ \else%
+ \let\tikz@math@next=\tikz@math@secondoftwo%
+ \fi%
+ \tikz@math@next%
+}%
+
+\def\tikz@math@ifvarinteger#1{%
+ \expandafter\ifx\csname
+ tikz@math@var@vartype@\string#1\endcsname\tikz@math@keyword@integer%
+ \let\tikz@math@next=\tikz@math@firstoftwo%
+ \else%
+ \let\tikz@math@next=\tikz@math@secondoftwo%
+ \fi%
+ \tikz@math@next%
+}%
+
+
+\def\tikz@math@setvarindexed#1{%
+ \expandafter\let\csname
+ tikz@math@var@subtype@\string#1\endcsname=\tikz@math@subtype@indexed%
+}%
+
+\def\tikz@math@clearvarindexed#1{%
+ \expandafter\let\csname tikz@math@var@subtype@\string#1\endcsname=\relax%
+}%
+
+\def\tikz@math@ifvarindexed#1{%
+ \expandafter\ifx\csname tikz@math@var@subtype@\string#1\endcsname\relax%
+ \let\tikz@math@next=\tikz@math@secondoftwo%
+ \else%
+ \let\tikz@math@next=\tikz@math@firstoftwo%
+ \fi%
+ \tikz@math@next%
+}%
+
+\def\tikz@math@stop{@}%
+
+\let\tikz@math@parse@hook@before=\pgfutil@empty
+\let\tikz@math@parse@hook@after=\pgfutil@empty
+
+\def\tikz@math{%
+ \ifnum\catcode`\;=13\relax%
+ \let\tikz@math@semicolon=\tikz@math@semicolon@active%
+ \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@active%
+ \else%
+ \let\tikz@math@semicolon=\tikz@math@semicolon@other%
+ \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@other%
+ \fi%
+ \tikz@math@parse@hook@before%
+ \tikz@@math}%
+
+
+
+
+\long\def\tikz@@math#1{%
+ \def\tikz@math@marshal{\tikz@math@parse#1}%
+ \expandafter\expandafter\expandafter\tikz@math@marshal\expandafter\tikz@math@stop\tikz@math@semicolon}%
+
+\def\tikz@math@parse{\pgfutil@ifnextchar\bgroup\tikz@math@@parse@bgroup\tikz@math@@parse@nobgroup}%
+
+
+\def\tikz@math@@parse@bgroup{%
+ \tikz@math@collecttosemicolon{%
+ % MW: Don't know how reliable this test is.
+ \ifx\pgf@selectfontorig\tikz@math@undefined%
+ \begingroup\tikz@math@collected\endgroup%
+ \else%
+ \begingroup\csname nullfont\endcsname\tikz@math@collected\endgroup%
+ \fi\tikz@math@parse}}%
+
+
+
+\def\tikz@math@@parse@nobgroup{\tikz@math@collecttosemicolon{\tikz@math@@parse@@nobgroup}}%
+
+\def\tikz@math@@parse@@nobgroup{%
+ \let\tikz@math@tmp=\tikz@math@collected%
+ \ifx\tikz@math@tmp\tikz@math@stop%
+ \def\tikz@math@next{\expandafter\tikz@math@parse@finish\tikz@math@semicolon}%
+ \else%
+ \def\tikz@math@next{\expandafter\expandafter\expandafter\tikz@math@parse@keyword@check\expandafter\tikz@math@tmp\tikz@math@semicolon}%
+ \fi%
+ \tikz@math@next%
+}%
+
+\def\tikz@math@parse@finish{%
+ \tikz@math@collecttosemicolon{\tikz@math@parse@hook@after}%
+}%
+
+
+
+\newif\iftikz@math@let
+\def\tikz@math@parse@keyword@check#1{%
+ \tikz@math@letfalse%
+ \tikz@math@getmeaning{#1}%
+ \ifx\tikz@math@meaning\tikz@math@meaning@null%
+ \let\tikz@math@next=\tikz@math@parse@keyword%
+ \else%
+ \let\tikz@math@next=\tikz@math@parse@nokeyword%
+ \fi%
+ \tikz@math@next#1}%
+
+
+\def\tikz@math@parse@keyword{%
+ \let\tikz@math@parsed@keyword=\pgfutil@empty%
+ \futurelet\tikz@math@parse@token\tikz@math@@parse@keyword}%
+
+\def\tikz@math@@parse@keyword{%
+ \ifx\tikz@math@parse@token\pgfutil@sptoken%
+ \let\tikz@math@next=\tikz@math@@@parse@keyword%
+ \else%
+ \ifx\tikz@math@parse@token(%
+ \let\tikz@math@next=\tikz@math@@@parse@keyword%
+ \else%
+ \ifx\tikz@math@parse@token\bgroup%
+ \let\tikz@math@next=\tikz@math@@@parse@keyword%
+ \else%
+ \let\tikz@math@next=\tikz@math@@@@parse@keyword%
+ \fi%
+ \fi%
+ \fi%
+ \tikz@math@next}%
+
+\def\tikz@math@error#1{\pgfutil@packageerror{tikz}{tikz math library: #1}{}}%
+
+\def\tikz@math@@@parse@keyword{%
+ \expandafter\ifx\csname tikz@math@process@keyword@\tikz@math@parsed@keyword\endcsname\relax%
+ \expandafter\ifx\csname pgfmath\tikz@math@parsed@keyword\endcsname\relax%
+ \tikz@math@error{Unknown function or keyword '\tikz@math@parsed@keyword'}%
+ \else%
+ \def\tikz@math@next{\tikz@math@collecttosemicolon{\tikz@math@function@noassign}}%
+ \fi%
+ \else%
+ \expandafter\def\expandafter\tikz@math@next\expandafter{\csname tikz@math@process@keyword@\tikz@math@parsed@keyword\endcsname}%
+ \fi%
+ \tikz@math@next}%
+
+\def\tikz@math@@@@parse@keyword#1{%
+ \edef\tikz@math@parsed@keyword{\tikz@math@parsed@keyword#1}%
+ \futurelet\tikz@math@parse@token\tikz@math@@parse@keyword%
+}%
+
+\def\tikz@math@function@noassign{%
+ \pgfmathparse{\tikz@math@parsed@keyword\tikz@math@collected}%
+ \tikz@math@parse%
+}%
+
+
+
+
+\def\tikz@math@process@keyword@count{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@count}}%
+\def\tikz@math@process@keyword@@count{%
+\def\tikz@math@assign@register{\csname newcount\endcsname}%
+\expandafter\tikz@math@gobblespaces\expandafter\tikz@math@process@registers\tikz@math@collected,@,}%
+
+\def\tikz@math@process@keyword@length{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@length}}%
+\def\tikz@math@process@keyword@@length{%
+\def\tikz@math@assign@register{\csname newdimen\endcsname}%
+\expandafter\tikz@math@gobblespaces\expandafter\tikz@math@process@registers\tikz@math@collected,@,}%
+
+
+\def\tikz@math@process@registers#1#2,{%
+ \def\tikz@math@var{#1}%
+ \ifx\tikz@math@var\tikz@math@stop%
+ \let\tikz@math@next=\tikz@math@parse%
+ \else%
+ \tikz@math@assign@register#1\relax%
+ \let\tikz@math@next=\tikz@math@process@registers%
+ \fi%
+ \tikz@math@gobblespaces\tikz@math@next%
+}%
+
+
+\def\tikz@math@process@keyword@if#1then{%
+ \def\tikz@math@if@condition{#1}%
+ \tikz@math@gobblespaces\tikz@math@parse@if@iftrue%
+}%
+\def\tikz@math@parse@if@iftrue#1{%
+ \def\tikz@math@if@trueaction{#1}%
+ \pgfutil@ifnextchar e{\tikz@math@parse@else}{\tikz@math@if@doif}}%
+
+\def\tikz@math@parse@else else{\tikz@math@gobblespaces\tikz@math@if@doifelse}%
+
+\def\tikz@math@if@doif{\tikz@math@collecttosemicolon{\tikz@math@if@@doif}}%
+
+\def\tikz@math@if@@doif{%
+ \pgfmathparse{\tikz@math@if@condition}%
+ \ifpgfmathfloatparseactive%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \fi%
+ \ifdim\pgfmathresult pt=0pt\relax%
+ \else%
+ \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}%
+ \fi%
+ \tikz@math@parse%
+}%
+\def\tikz@math@if@doifelse{\tikz@math@collecttosemicolon{\tikz@math@if@@doifelse}}%
+\def\tikz@math@if@@doifelse{%
+ \pgfmathparse{\tikz@math@if@condition}%
+ \ifpgfmathfloatparseactive%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \fi%
+ \let\tikz@math@if@falseaction=\tikz@math@collected%
+ \ifdim\pgfmathresult pt=0pt\relax%
+ \expandafter\tikz@math\expandafter{\tikz@math@if@falseaction}%
+ \else%
+ \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}%
+ \fi%
+ \tikz@math@parse%
+}%
+\def\tikz@math@process@keyword@let{%
+ \tikz@math@lettrue%
+ \tikz@math@gobblespaces\tikz@math@parse@nokeyword%
+}%
+
+
+\def\tikz@math@parse@nokeyword#1{%
+ \def\tikz@math@var{#1}%
+ \tikz@math@getvarstring{#1}\tikz@math@varstring%
+ \let\tikz@math@vartype=\pgfutil@empty%
+ \ifx\tikz@math@var\tikz@math@stop%
+ \let\tikz@math@next=\tikz@math@parse@finish%
+ \else%
+ \ifx\tikz@math@semicolon\tikz@math@var%
+ \let\tikz@math@next=\tikz@math@parse%
+ \else%
+ \let\tikz@math@next=\tikz@math@parse@index@check%
+ \fi%
+ \fi%
+ \tikz@math@next}%
+
+\def\tikz@math@parse@index@check{%
+ \pgfutil@ifnextchar={\tikz@math@parse@noindex}{\tikz@math@parse@index}}%
+
+\def\tikz@math@parse@noindex{%
+ \expandafter\tikz@math@clearvarindexed\tikz@math@var%
+ \let\tikz@math@current@index=\pgfutil@empty%
+ \tikz@math@parse@afterindex%
+}%
+
+\def\tikz@math@parse@index#1{%
+ \def\tikz@math@tmp{#1}%
+ \expandafter\tikz@math@setvarindexed\tikz@math@var% {}
+ \edef\tikz@math@current@index{#1}%
+ \tikz@math@parse@afterindex%
+}%
+\def\tikz@math@parse@afterindex#1={\tikz@math@gobblespaces\tikz@math@parse@assignment}%
+
+\def\tikz@math@parse@assignment{\tikz@math@collecttosemicolon{\tikz@math@parse@@assignment}}%
+\def\tikz@math@parse@@assignment{%
+ \expandafter\expandafter\expandafter\tikz@math@doassignment\expandafter\expandafter\expandafter%
+ {\expandafter\tikz@math@var\expandafter}\expandafter{\tikz@math@collected}%
+ \tikz@math@parse%
+}%
+
+\def\tikz@math@dollar@char{$}%
+\def\tikz@math@dollar@char{$}% For annoying syntax highlighters
+
+\def\tikz@math@doassignment#1#2{%
+ \tikz@math@ifvarcoordinate{#1}{%
+ \def\tikz@math@var{#1}% Unfortunately, we must do this again.
+ \tikz@math@getvarstring{#1}\tikz@math@varstring% And this
+ \expandafter\pgfutil@in@\tikz@math@dollar@char{#2}%
+ \edef\tikz@math@expression{#2}%
+ \ifpgfutil@in@%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\tikz@math@expression%
+ \else%
+ \expandafter\ifx\csname tikz@library@calc@loaded\endcsname\relax%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\tikz@math@expression%
+ \else%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\expandafter%
+ (\expandafter$\tikz@math@expression$)%
+ \fi%
+ \fi%
+ }{%
+ \iftikz@math@let% Not really a let
+ \ifx\tikz@math@current@index\pgfutil@empty%
+ \edef#1{#2}%
+ \else%
+ \edef\tikz@math@tmp{#2}%
+ \expandafter\expandafter\expandafter\tikz@math@assign@index\expandafter\expandafter\expandafter%
+ {\expandafter\tikz@math@varstring\expandafter}\expandafter{\tikz@math@tmp}%
+ \fi%
+ \tikz@math@letfalse%
+ \else%
+ \ifx\tikz@math@current@index\pgfutil@empty%
+ \tikz@math@getmeaning{#1}%
+ \ifx\tikz@math@meaning\tikz@math@meaning@dimen%
+ \pgfmathsetlength{#1}{#2}%
+ \let\tikz@math@last@assigned@value=\pgfmathresult%
+ \else%
+ \ifx\tikz@math@meaning\tikz@math@meaning@count%
+ \pgfmathsetcount{#1}{#2}%
+ \let\tikz@math@last@assigned@value=\pgfmathresult%
+ \else%
+ \tikz@math@ifvarinteger{#1}{\pgfmathparse{int(#2)}}{\pgfmathparse{#2}}%
+ \let\tikz@math@last@assigned@value=\pgfmathresult%
+ \let#1=\pgfmathresult%
+ \fi%
+ \fi%
+ \else%
+ \tikz@math@ifvarinteger{#1}{\pgfmathparse{int(#2)}}{\pgfmathparse{#2}}%
+ \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring}\pgfmathresult%
+ \let\tikz@math@last@assigned@value=\pgfmathresult%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+
+\def\tikz@math@assign@index#1#2{%
+ \expandafter\def\csname#1\endcsname##1{\csname
+ tikz@math@var@indexed@#1@##1\endcsname}%
+ \expandafter\edef\csname
+ tikz@math@var@indexed@#1@\tikz@math@current@index\endcsname{#2}\relax%
+}%
+
+
+
+\def\tikz@math@assign@coordinate#1{%
+ \pgf@process{#1}%
+ \ifx\tikz@math@current@index\pgfutil@empty%
+ \expandafter\edef\csname\tikz@math@varstring\endcsname{\the\pgf@x,\the\pgf@y}%
+ \expandafter\edef\csname\tikz@math@varstring x\endcsname{\the\pgf@x}%
+ \expandafter\edef\csname\tikz@math@varstring y\endcsname{\the\pgf@y}%
+ \else%
+ \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring}{\the\pgf@x,\the\pgf@y}%
+ \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring x}{\the\pgf@x}%
+ \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring y}{\the\pgf@y}%
+ \fi%
+}%
+
+
+
+\def\tikz@math@keyword@coordinate{coordinate}%
+\def\tikz@math@process@keyword@coordinate{%
+ \let\tikz@math@vartype=\tikz@math@keyword@coordinate%
+ \tikz@math@gobblespaces\tikz@math@process@vartypes%
+}%
+
+\def\tikz@math@keyword@integer{integer}%
+\def\tikz@math@process@keyword@integer{%
+ \let\tikz@math@vartype=\tikz@math@keyword@integer%
+ \tikz@math@gobblespaces\tikz@math@process@vartypes%
+}%
+\def\tikz@math@process@keyword@int{%
+ \tikz@math@process@keyword@integer%
+}%
+
+\def\tikz@math@keyword@real{real}%
+\def\tikz@math@process@keyword@real{%
+ \let\tikz@math@vartype=\tikz@math@keyword@real%
+ \tikz@math@gobblespaces\tikz@math@process@vartypes%
+}%
+
+\def\tikz@math@process@keyword@point{\tikz@math@process@keyword@coordinate}%
+
+
+\def\tikz@math@process@vartypes{\tikz@math@collecttosemicolon{\tikz@math@process@@vartypes}}%
+
+\def\tikz@math@process@@vartypes{%
+ \expandafter\tikz@math@@process@vartypes\tikz@math@collected,@,\tikz@math%
+}%
+
+\def\tikz@math@@process@vartypes#1#2,{%
+ \def\tikz@math@var{#1}%
+ \tikz@math@getvarstring{#1}\tikz@math@varstring%
+ \ifx\tikz@math@var\tikz@math@stop%
+ \let\tikz@math@next=\tikz@math@@@process@vartypes%
+ \else%
+ \expandafter\tikz@math@setvartype\tikz@math@var\tikz@math@vartype%
+ \def\tikz@math@next{\tikz@math@gobblespaces\tikz@math@@process@vartypes}%
+ \fi%
+ \tikz@math@next%
+}%
+
+\def\tikz@math@process@keyword@print{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@print}}%
+\def\tikz@math@process@keyword@@print{%
+ \begingroup\tikz@math@collected\endgroup\tikz@math@parse%
+}%
+
+\def\tikz@math@@@process@vartypes#1\tikz@math{%
+ \tikz@math@parse%
+}%
+
+\newcount\tikz@math@for@depth
+
+\def\tikz@math@for@namedef#1{\expandafter\def\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname}%
+\def\tikz@math@for@nameedef#1{\expandafter\edef\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname}%
+\def\tikz@math@for@namelet#1{\expandafter\let\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname}%
+
+\def\tikz@math@for@namegetvalue#1#2{%
+ \def\tikz@math@marshal{\let#2=}%
+ \expandafter\tikz@math@marshal\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname}%
+
+\def\tikz@math@process@keyword@for{%
+ \tikz@math@for%
+}%
+
+\def\tikz@math@for@external{%
+ \ifnum\catcode`\;=13\relax%
+ \let\tikz@math@semicolon=\tikz@math@semicolon@active%
+ \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@active%
+ \else%
+ \let\tikz@math@semicolon=\tikz@math@semicolon@other%
+ \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@other%
+ \fi
+ \advance\tikz@math@for@depth by1\relax%
+ \tikz@math@for@namedef{execute}{\tikz@math@for@external@execute}%
+ \tikz@math@for@namedef{finished}{\relax}%
+ \tikz@math@gobblespaces\tikz@math@for@parsevar}%
+
+\def\tikz@math@for@external@execute#1{#1}%
+
+\def\tikz@math@for{%
+ \advance\tikz@math@for@depth by1\relax%
+ \tikz@math@for@namedef{execute}{\tikz@math}%
+ \tikz@math@for@namedef{finished}{\tikz@math@parse}%
+ \tikz@math@gobblespaces\tikz@math@for@parsevar}%
+
+
+\def\tikz@math@for@parsevar#1{%
+ \tikz@math@for@namedef{var}{#1}%
+ \tikz@math@for@parsein}%
+
+\def\tikz@math@getindex#1{%
+ \tikz@math@@getindex#1\tikz@math@getindex\tikz@math@@getindex%
+}%
+
+\def\tikz@math@@getindex#1#2\tikz@math@@getindex{#1}%
+
+\def\tikz@math@for@parsein#1in{%
+ \def\tikz@math@tmp{#1}%
+ \ifx\tikz@math@tmp\pgfutil@empty%
+ \tikz@math@for@namedef{index}{}%
+ \else%
+ \tikz@math@for@nameedef{index}{\tikz@math@getindex{#1}}%
+ \fi%
+ \tikz@math@gobblespaces\tikz@math@for@parselist%
+}%
+
+
+\long\def\tikz@math@for@parselist#1{%
+ \edef\tikz@math@for@list{#1}%
+ \tikz@math@gobblespaces{%
+ \tikz@math@collecttosemicolon{\tikz@math@for@parseaction}}}%
+
+\def\tikz@math@for@parseaction{%
+ \tikz@math@for@namedef{prevvalue}{}%
+ \tikz@math@for@namedef{prevprevvalue}{}%
+ \tikz@math@for@namelet{action}=\tikz@math@collected%
+ \expandafter\tikz@math@for@scan\tikz@math@for@list,\tikz@math,\tikz@@math%
+}%
+
+\def\tikz@math@token{\tikz@math}%
+
+
+\def\tikz@math@for@scan#1,{%
+ \def\tikz@math@for@value{#1}%
+ \ifx\tikz@math@for@value\tikz@math@token%
+ \let\tikz@math@next=\tikz@math@for@scan@end%
+ \else%
+ \ifx\tikz@math@for@value\pgfutil@empty%
+ \let\tikz@math@next=\tikz@math@for@scan@end%
+ \else%
+ \pgfutil@in@{...}{#1}%
+ \ifpgfutil@in@%
+ \let\tikz@math@next=\tikz@math@for@scan@dots%
+ \else%
+ \tikz@math@for@namegetvalue{var}{\tikz@math@var}%
+ \tikz@math@for@namegetvalue{index}{\tikz@math@current@index}%
+ \tikz@math@for@namegetvalue{action}{\tikz@math@action}%
+ \expandafter\tikz@math@getvarstring\expandafter{\tikz@math@var}\tikz@math@varstring%
+ \expandafter\tikz@math@doassignment\expandafter{\tikz@math@var}{#1}%
+ \tikz@math@for@namelet{value}=\tikz@math@last@assigned@value%
+ \tikz@math@for@namegetvalue{execute}{\tikz@math@execute}%
+ \expandafter\tikz@math@execute\expandafter{\tikz@math@action}%
+ \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}%
+ \tikz@math@for@namelet{prevprevvalue}=\tikz@math@prevvalue%
+ \tikz@math@for@namegetvalue{value}{\tikz@math@value}%
+ \tikz@math@for@namelet{prevvalue}=\tikz@math@value%
+ \let\tikz@math@next=\tikz@math@for@scan%
+ \fi%
+ \fi%
+ \fi%
+ \tikz@math@next%
+}%
+
+\newdimen\tikz@math@dimen
+
+\def\tikz@math@for@scan@dots#1,{%
+ \pgfmathparse{#1}\let\tikz@math@value=\pgfmathresult%
+ \tikz@math@for@nameedef{endvalue}{\tikz@math@value}%
+ \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}%
+ \tikz@math@for@namegetvalue{prevprevvalue}{\tikz@math@prevprevvalue}%
+ \tikz@math@dimen=\tikz@math@prevvalue pt\relax%
+ \ifx\tikz@math@prevprevvalue\pgfutil@empty%
+ \ifdim\tikz@math@prevvalue pt<\tikz@math@value pt\relax%%
+ \def\tikz@math@step{1pt}%
+ \else%
+ \def\tikz@math@step{-1pt}%
+ \fi%
+ \else%
+ \tikz@math@dimen=\tikz@math@prevvalue pt\relax%
+ \advance\tikz@math@dimen by-\tikz@math@prevprevvalue pt\relax%
+ \edef\tikz@math@step{\the\tikz@math@dimen}%
+ \fi%
+ \ifdim\tikz@math@step<0pt\relax%
+ \tikz@math@for@namedef{comparitor}{<}%
+ \else%
+ \tikz@math@for@namedef{comparitor}{>}%
+ \fi%
+ \tikz@math@for@nameedef{step}{\tikz@math@step}%
+ \tikz@math@for@doloop%
+}%
+
+\def\tikz@math@for@doloop{%
+ \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}%
+ \tikz@math@for@namegetvalue{step}{\tikz@math@step}%
+ \tikz@math@for@namegetvalue{comparitor}{\tikz@math@comparitor}%
+ \tikz@math@for@namegetvalue{endvalue}{\tikz@math@endvalue}%
+ \tikz@math@dimen=\tikz@math@prevvalue pt\relax%
+ \advance\tikz@math@dimen by\tikz@math@step\relax%
+ \ifdim\tikz@math@dimen\tikz@math@comparitor\tikz@math@endvalue pt\relax%
+ \let\tikz@math@next=\tikz@math@for@endloop%
+ \else%
+ \tikz@math@for@nameedef{value}{\pgfmath@tonumber{\tikz@math@dimen}}%
+ \tikz@math@for@namegetvalue{var}{\tikz@math@var}%
+ \expandafter\tikz@math@getvarstring\expandafter{\tikz@math@var}\tikz@math@varstring%
+ \tikz@math@for@namegetvalue{index}{\tikz@math@current@index}%
+ \tikz@math@for@namegetvalue{action}{\tikz@math@action}%
+ \tikz@math@for@namegetvalue{value}{\tikz@math@value}%
+ \expandafter\expandafter\expandafter\tikz@math@doassignment\expandafter\expandafter\expandafter%
+ {\expandafter\tikz@math@var\expandafter}\expandafter{\tikz@math@value}%
+ \tikz@math@for@namegetvalue{execute}{\tikz@math@execute}%
+ \expandafter\tikz@math@execute\expandafter{\tikz@math@action}%
+ \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}%
+ \tikz@math@for@namelet{prevprevvalue}=\tikz@math@prevvalue%
+ \tikz@math@for@namegetvalue{value}{\tikz@math@value}%
+ \tikz@math@for@namelet{prevvalue}=\tikz@math@value%
+ \let\tikz@math@next=\tikz@math@for@doloop%
+ \fi%
+ \tikz@math@next%
+}%
+
+\def\tikz@math@for@endloop{%
+\tikz@math@for@scan}%
+
+
+
+
+\def\tikz@math@for@scan@end#1\tikz@@math{%
+\tikz@math@for@namegetvalue{finished}{\tikz@math@next}%
+\advance\tikz@math@for@depth by-1\relax%
+\tikz@math@next}%
+
+
+
+
+
+\def\tikz@math@process@keyword@return{%
+ \tikz@math@collecttosemicolon{\pgfmathparse{\tikz@math@collected}\tikz@math@parse}}%
+
+\def\tikz@math@process@keyword@function{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@function}}%
+\def\tikz@math@process@keyword@@function{%
+ \let\tikz@math@function@name=\pgfutil@empty%
+ \let\tikz@math@function@arguments=\pgfutil@empty%
+ \let\tikz@math@function@body=\pgfutil@empty%
+ \expandafter\expandafter\expandafter\tikz@math@@declarefunction\expandafter\tikz@math@collected\tikz@math@semicolon%
+}%
+
+\def\tikz@math@@declarefunction{%
+ \pgfutil@ifnextchar\bgroup\tikz@math@@@collectbody\tikz@math@@@declarefunction}%
+
+
+\def\tikz@math@@@declarefunction#1{%
+ \if#1(%)
+ \let\tikz@math@next=\tikz@math@@@collectarguments%
+ \else%
+ \expandafter\def\expandafter\tikz@math@function@name\expandafter{\tikz@math@function@name#1}%
+ \let\tikz@math@next=\tikz@math@@declarefunction%
+ \fi%
+ \tikz@math@next%
+}%
+\def\tikz@math@@@collectarguments#1){%
+ \def\tikz@math@function@arguments{#1}%
+ \tikz@math@@declarefunction%
+}%
+
+\newtoks\tikz@math@toks
+\tikz@math@toks={#}%
+\edef\tikz@math@char@hash{\the\tikz@math@toks}%
+\tikz@math@toks={}%
+
+\def\tikz@math@@@collectbody{\tikz@math@collecttosemicolon{\tikz@math@@@@collectbody}}%
+
+\def\tikz@math@@@@collectbody{%
+ \tikz@math@toks={}%
+ \c@pgf@counta=0\relax%
+ \ifx\tikz@math@function@arguments\pgfutil@empty%
+ \else%
+ \expandafter\tikz@math@createargumentlist\tikz@math@function@arguments,,%
+ \expandafter\tikz@math@addto@toks\expandafter{\tikz@math@collected}%
+ \fi%
+ \edef\tikz@math@local@temp{%
+ \noexpand\pgfmathdeclarefunction{\tikz@math@function@name}{\the\c@pgf@counta}%
+ {\noexpand\def\noexpand\return{0}\noexpand\tikz@math{\the\tikz@math@toks}}%
+ }%
+ \tikz@math@local@temp
+ \tikz@math@parse%
+}%
+
+\def\tikz@math@addto@toks#1{%
+ \expandafter\tikz@math@toks\expandafter{\the\tikz@math@toks#1}}%
+
+\def\tikz@math@createargumentlist{%
+ \pgfutil@ifnextchar
+ x\tikz@math@@createargumentlist\tikz@math@@createargumentlist}%
+
+\def\tikz@math@comma{,}%
+\def\tikz@math@@createargumentlist#1,{%
+ \def\tikz@math@tmp{#1}%
+ \ifx\tikz@math@tmp\pgfutil@empty%
+ \let\tikz@math@next=\relax%
+ \else%
+ \advance\c@pgf@counta by1\relax%
+ \tikz@math@addto@toks{#1=}%
+ \expandafter\expandafter\expandafter\tikz@math@addto@toks\expandafter\expandafter\expandafter%
+ {\expandafter\tikz@math@char@hash\the\c@pgf@counta;}%
+ \let\tikz@math@next=\tikz@math@createargumentlist%
+ \fi%
+ \tikz@math@next%
+}%
+
+
+
+\let\tikzmath=\tikz@math
+\tikzset{evaluate/.code={\tikz@math{#1}}}%
+\let\tikzmathfor=\tikz@math@for@external
+
+
+\catcode`\@=\tikz@math@at@catcode\relax
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex
new file mode 100644
index 0000000000..5118189376
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex
@@ -0,0 +1,144 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarymatrix.code.tex}
+
+
+% A matrix of nodes contains a node in each cell.
+
+\tikzset{matrix of nodes/.style={%
+ matrix,%
+ cells={anchor=base},%
+ execute at begin cell=\tikz@lib@matrix@start@cell,%
+ execute at end cell=\tikz@lib@matrix@end@cell,%
+ execute at empty cell=\tikz@lib@matrix@empty@cell,
+ execute at begin matrix=\iftikz@handle@active@code\tikz@orig@shorthands\fi,%
+}}%
+
+\def\tikz@lib@matrix@empty@cell{\iftikz@lib@matrix@empty\node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]{};\fi}%
+
+\newif\iftikz@lib@matrix@plain
+
+\def\tikz@lib@matrix@start@cell{%
+ \pgfutil@ifnextchar|{\tikz@lib@matrix@with@options}{\tikz@lib@matrix@normal@start@cell}}%
+
+\def\tikz@lib@matrix@with@options|#1|{\tikz@lib@matrix@plainfalse\node%
+ [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]#1\bgroup\tikz@lib@matrix@startup}%
+
+
+\def\tikz@lib@matrix@normal@start@cell{\pgfutil@ifnextchar\let{\tikz@lib@matrix@check}{\tikz@lib@matrix@plainfalse\node
+ [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup}}%
+
+\def\tikz@lib@matrix@check#1{% evil hackery to find out about start of path
+ \pgfutil@ifnextchar\tikz@signal@path{\tikz@lib@matrix@plaintrue\let}{\tikz@lib@matrix@plainfalse\node
+ [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup\let}%
+}%
+
+\def\tikz@lib@matrix@end@cell{%
+ \iftikz@lib@matrix@plain%
+ \else%
+ \expandafter\egroup\expandafter;%
+ \fi%
+}%
+
+\def\tikz@lib@matrix@startup{%
+ \pgfutil@ifnextchar\bgroup{%
+ % Save meaning of \\:
+ \let\tikz@lib@matrix@saved@eol=\\%
+ % Now smuggle meaning inside following group.
+ \let\\=\pgfmatrixendrow%
+ \afterassignment\tikz@lib@matrix@smuggle%
+ \let\tikz@next}
+ {\let\\=\pgfmatrixendrow}%
+}%
+\def\tikz@lib@matrix@smuggle{%
+ \bgroup%
+ \let\\=\tikz@lib@matrix@saved@eol%
+}%
+
+
+% Fill empty nodes in a matrix of nodes
+
+\newif\iftikz@lib@matrix@empty
+
+\tikzoption{nodes in empty cells}[true]{\csname tikz@lib@matrix@empty#1\endcsname}%
+
+
+% Same as a matrix of nodes, but switch on math mode in each cell
+\tikzset{matrix of math nodes/.style={%
+ matrix of nodes,
+ nodes={%
+ execute at begin node=$,%
+ execute at end node=$%
+ }%
+}}%
+
+
+
+% Provide a delimiter
+
+\tikzoption{left delimiter}{\tikzset{append after command={\tikz@delimiter%
+ {south east}%
+ {south west}%
+ {every delimiter,every left delimiter}%
+ {south}%
+ {north}%
+ {#1}%
+ {.}%
+ {\pgf@y}}}}%
+
+\tikzoption{right delimiter}{\tikzset{append after command={\tikz@delimiter%
+ {south west}%
+ {south east}%
+ {every delimiter,every right delimiter}%
+ {south}%
+ {north}%
+ {.}%
+ {#1}%
+ {\pgf@y}}}}%
+
+\tikzoption{above delimiter}{\tikzset{append after command={\tikz@delimiter%
+ {south east}%
+ {north west}%
+ {every delimiter,every above delimiter,rotate=-90}%
+ {west}%
+ {east}%
+ {#1}%
+ {.}%
+ {\pgf@x}}}}%
+
+\tikzoption{below delimiter}{\tikzset{append after command={\tikz@delimiter%
+ {south west}%
+ {south west}%
+ {every delimiter,every below delimiter,rotate=-90}%
+ {west}%
+ {east}%
+ {.}%
+ {#1}%
+ {\pgf@x}}}}%
+
+\def\tikz@delimiter#1#2#3#4#5#6#7#8{%
+ \bgroup
+ \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name\tikz@node@is@a@labelfalse}%
+ node[outer sep=0pt,inner sep=0pt,draw=none,fill=none,anchor=#1,at=(\tikz@last@fig@name.#2),#3]
+ {%
+ {\nullfont\pgf@process{\pgfpointdiff{\pgfpointanchor{\tikz@last@fig@name}{#4}}{\pgfpointanchor{\tikz@last@fig@name}{#5}}}}%
+ $\left#6\vcenter{\hrule height .5#8 depth .5#8 width0pt}\right#7$%
+ }
+ \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name}%
+ \egroup%
+}%
+
+\tikzset{every delimiter/.style={}}%
+\tikzset{every left delimiter/.style={}}%
+\tikzset{every right delimiter/.style={}}%
+\tikzset{every above delimiter/.style={}}%
+\tikzset{every below delimiter/.style={}}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex
new file mode 100644
index 0000000000..ff5959c4f3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex
@@ -0,0 +1,417 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarymindmap.code.tex}
+
+
+\usetikzlibrary{trees,decorations}%
+
+
+% A decoration for connecting circle nodes
+%
+% Parameters: start radius, end radius, amplitude, angle
+
+\pgfdeclaredecoration{circle connection bar}{initial}
+{%
+ \state{initial}[width=0pt,next state=bar]
+ {
+ {
+ \pgftransformxshift{-\pgfkeysvalueof{/pgf/decoration/start radius}}%
+ \pgfpathmoveto{\pgfpointpolar{\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/start radius}}}
+ \pgfpatharc{\pgfdecorationsegmentangle}{-\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/start radius}}
+ \pgfutil@tempcnta=-\pgfdecorationsegmentangle\relax
+ \advance\pgfutil@tempcnta by90\relax
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/decoration/start radius}}
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfdecorationsegmentamplitude}
+ \pgfpathcurveto
+ {\pgfpointadd
+ {\pgfpointpolar{-\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/start radius}}}
+ {\pgfpointpolar{\the\pgfutil@tempcnta}{.25\pgfutil@tempdima}}}
+ {\pgfqpoint{1.25\pgfutil@tempdima}{-.5\pgfutil@tempdimb}}
+ {\pgfqpoint{1.5\pgfutil@tempdima}{-.5\pgfutil@tempdimb}}
+ \pgfpathlineto{\pgfpoint{1.5\pgfutil@tempdima}{.5\pgfutil@tempdimb}}
+ \pgfutil@tempcnta=\pgfdecorationsegmentangle\relax
+ \advance\pgfutil@tempcnta by-90\relax
+ \pgfpathcurveto
+ {\pgfpoint{1.25\pgfutil@tempdima}{.5\pgfutil@tempdimb}}
+ {\pgfpointadd
+ {\pgfpointpolar{\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/start radius}}}
+ {\pgfpointpolar{\the\pgfutil@tempcnta}{.25\pgfutil@tempdima}}}
+ {\pgfpointpolar{\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/start radius}}}
+ \pgfpathclose
+ }
+ }%
+ \state{bar}[width=0pt,next state=end]
+ {
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/decoration/start radius}}%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/decoration/end radius}}%
+ \pgfmathsetlength\pgf@xc{\pgfdecorationsegmentamplitude}%
+ \pgfpathrectangle
+ {\pgfqpoint{.5\pgfutil@tempdima}{-.5\pgf@xc}}
+ {\pgfpoint{\pgfdecoratedremainingdistance+-.5\pgfutil@tempdimb+-.5\pgfutil@tempdima}{\pgf@xc}}
+ }%
+ \state{end}[width=0pt,next state=final]
+ {
+ {
+ \pgftransformxshift{\pgfdecoratedremainingdistance}%
+ \pgftransformxscale{-1}%
+ \pgftransformxshift{-\pgfkeysvalueof{/pgf/decoration/end radius}}%
+ \pgfpathmoveto{\pgfpointpolar{\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/end radius}}}
+ \pgfpatharc{\pgfdecorationsegmentangle}{-\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/end radius}}
+ \pgfutil@tempcnta=-\pgfdecorationsegmentangle\relax
+ \advance\pgfutil@tempcnta by90\relax
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/decoration/end radius}}
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfdecorationsegmentamplitude}%
+ \pgfpathcurveto
+ {\pgfpointadd
+ {\pgfpointpolar{-\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/end radius}}}
+ {\pgfpointpolar{\the\pgfutil@tempcnta}{.25\pgfutil@tempdima}}}
+ {\pgfqpoint{1.25\pgfutil@tempdima}{-.5\pgfutil@tempdimb}}
+ {\pgfqpoint{1.5\pgfutil@tempdima}{-.5\pgfutil@tempdimb}}
+ \pgfpathlineto{\pgfpoint{1.5\pgfutil@tempdima}{.5\pgfutil@tempdimb}}
+ \pgfutil@tempcnta=\pgfdecorationsegmentangle\relax
+ \advance\pgfutil@tempcnta by-90\relax
+ \pgfpathcurveto
+ {\pgfpoint{1.25\pgfutil@tempdima}{.5\pgfutil@tempdimb}}
+ {\pgfpointadd
+ {\pgfpointpolar{\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/end radius}}}
+ {\pgfpointpolar{\the\pgfutil@tempcnta}{.25\pgfutil@tempdima}}}
+ {\pgfpointpolar{\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/end radius}}}
+ \pgfpathclose
+ }
+ }%
+ \state{final}
+ {}%
+}%
+
+
+
+\pgfkeys{/pgf/decoration/angle=20}%
+
+% To paths for connecting circle nodes
+
+\tikzset{circle connection bar/.style=
+{to path={
+ \pgfextra{%
+ \tikz@lib@mindmap@check{\tikztostart}%
+ \tikz@compute@circle@radii\tikz@compute@segmentamplitude%
+ }
+ [every circle connection bar]
+ decorate [decoration=circle connection bar]
+ { -- (\tikztotarget) \tikztonodes}
+},
+append after command={[fill=\tikz@concept@color,draw=none]}
+}}%
+\tikzset{every circle connection bar/.style={}}%
+
+\def\tikz@compute@circle@radii{%
+ \pgf@process{\pgfpointtransformed{\pgfpointanchor{\tikztostart}{center}}}%
+ \pgf@xa=\pgf@x%
+ \pgf@process{\pgfpointtransformed{\pgfpointanchor{\tikztostart}{west}}}%
+ \advance\pgf@xa by-\pgf@x%
+ \pgfkeys{/pgf/decoration/start radius/.expanded=\the\pgf@xa}%
+ \pgf@process{\pgfpointtransformed{\pgfpointanchor{\tikztotarget}{center}}}%
+ \pgf@xa=\pgf@x%
+ \pgf@process{\pgfpointtransformed{\pgfpointanchor{\tikztotarget}{west}}}%
+ \advance\pgf@xa by-\pgf@x%
+ \pgfkeys{/pgf/decoration/end radius/.expanded=\the\pgf@xa}%
+}%
+\def\tikz@compute@segmentamplitude{%
+ \pgf@x=\pgfkeysvalueof{/pgf/decoration/start radius}\relax%
+ \ifdim\pgf@x>\pgfkeysvalueof{/pgf/decoration/end radius}\relax%
+ \pgf@x=\pgfkeysvalueof{/pgf/decoration/end radius}\relax%
+ \fi%
+ \pgf@x=.175\pgf@x\relax%
+ \edef\pgfdecorationsegmentamplitude{\the\pgf@x}%
+}%
+
+
+
+% Check whether start and end are nodes!
+
+\def\tikz@lib@mindmap@check#1{%
+ \pgfutil@ifundefined{pgf@sh@ns@#1}%
+ {\tikzerror{You are attempting to connect two things by a circle
+ connection bar where one is not a node}}{%
+ \expandafter\ifx\csname pgf@sh@ns@#1\endcsname\tikz@lib@coordinate@text%
+ \tikzerror{You are attempting to connect node of shape
+ 'coordinate' by a circle connection bar. The shape should be
+ 'circle' or something similar, instead.}
+ \fi%
+ }
+}%
+
+\def\tikz@lib@coordinate@text{coordinate}%
+
+
+% Switch color in a mindmap
+
+\tikzoption{circle connection bar switch color}{\tikz@parse@switch#1\pgf@unique}%
+\def\tikz@parse@switch from (#1) to (#2)\pgf@unique{%
+ \tikzset{to path={%
+ \pgfextra{%
+ \tikz@lib@mindmap@check{\tikztostart}%
+ \tikz@compute@circle@radii\tikz@compute@segmentamplitude%
+ \global\let\tikz@lib@save@start=\tikztostart%
+ \global\let\tikz@lib@save@target=\tikztotarget%
+ \pgfkeysgetvalue{/pgf/decoration/start radius}\pgf@temp%
+ \global\let\tikz@lib@saved@start@radius=\pgf@temp%
+ \pgfkeysgetvalue{/pgf/decoration/end radius}\pgf@temp%
+ \global\let\tikz@lib@saved@end@radius=\pgf@temp%
+ }%
+ [every circle connection bar]
+ decorate [decoration=circle connection bar]
+ { -- (\tikztotarget) \tikztonodes}
+ },
+ append after command={
+ [fill=none,draw=none,path picture=\tikz@lib@shade@pic]
+ \pgfextra{
+ \pgfutil@colorlet{tikz@switch@from}{#1}%
+ \pgfutil@colorlet{tikz@switch@to}{#2}%
+ }}
+ }
+}%
+
+\def\tikz@lib@shade@pic{%
+ % We have to draw the shading...
+ % compute start point:
+ \pgftransformreset%
+ \pgf@process{\pgfpointnormalised{\pgfpointdiff{\pgfpointanchor{\tikz@lib@save@start}{center}}{\pgfpointanchor{\tikz@lib@save@target}{center}}}}%
+ \edef\tikz@lib@mm@vec{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfmathsetlength\pgf@xc{\tikz@lib@saved@start@radius}
+ \pgf@process{\pgfpointadd{\pgfpointtransformed{\pgfpointanchor{\tikz@lib@save@start}{center}}}
+ {\pgfpointscale{\pgf@sys@tonumber{\pgf@xc}}{\tikz@lib@mm@vec}}}
+ \edef\tikz@lib@mm@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfmathsetlength\pgf@xc{\tikz@lib@saved@end@radius}
+ \pgf@process{\pgfpointdiff{\tikz@lib@mm@start}{\pgfpointadd{\pgfpointtransformed{\pgfpointanchor{\tikz@lib@save@target}{center}}}
+ {\pgfpointscale{-\pgf@sys@tonumber{\pgf@xc}}{\tikz@lib@mm@vec}}}}
+ \edef\tikz@lib@mm@end{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgftransformshift{\tikz@lib@mm@start}
+ \pgflowlevelsynccm
+ \pgf@process{\tikz@lib@mm@vec}
+ {
+ \pgf@xa=-\pgf@x%
+ \pgftransformcm{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
+ {\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@xa}}%
+ {\pgfpointorigin}%
+ \pgf@process{\pgfpointtransformed{\tikz@lib@mm@end}}%
+ \expandafter
+ }
+ \edef\tikz@lib@mm@length{\the\pgf@x}%
+ \pgf@process{\tikz@lib@mm@vec}
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
+ {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}%
+ {\pgfpointorigin}%
+ % Y scale:
+ \pgfmathsetlength\pgf@y{\tikz@lib@saved@start@radius}%
+ \pgfmathsetlength\pgf@ya{\tikz@lib@saved@end@radius}%
+ \ifdim\pgf@y<\pgf@ya%
+ \pgf@y=\pgf@ya%
+ \fi%
+ \pgf@y=0.01992528\pgf@y%
+ \pgftransformyscale{\pgf@sys@tonumber{\pgf@y}}%
+ \pgfpathrectanglecorners
+ {\pgfpoint{-\tikz@lib@saved@start@radius}{-50bp}}
+ {\pgfpoint{1pt}{50bp}}
+ \pgfsetfillcolor{tikz@switch@from}
+ \pgfusepath{fill}
+ \pgfpathrectanglecorners
+ {\pgfpoint{\tikz@lib@mm@length+\tikz@lib@saved@end@radius}{-50bp}}
+ {\pgfpoint{\tikz@lib@mm@length-1pt}{50bp}}
+ \pgfsetfillcolor{tikz@switch@to}
+ \pgfusepath{fill}
+ % X scale:
+ \pgf@x=\tikz@lib@mm@length%
+ \pgf@x=0.009962\pgf@x%
+ \pgftransformxscale{\pgf@sys@tonumber{\pgf@x}}%
+ \pgftransformxshift{50bp}
+ \pgflowlevelsynccm%
+ \pgfuseshading{tikz@shade@bar}
+}%
+
+\tikzoption{concept color}{%
+ \let\tikz@old@concept@color=\tikz@concept@color%
+ \def\tikz@edge@to@parent@path{
+ (\tikzparentnode)
+ to[circle connection bar switch color=from (\tikz@old@concept@color) to (#1)]
+ (\tikzchildnode)}
+ \def\tikz@concept@color{#1}%
+}%
+
+\pgfdeclarehorizontalshading[tikz@switch@from,tikz@switch@to]{tikz@shade@bar}{100bp}{%
+ color(0pt)=(tikz@switch@from);
+ color(100bp)=(tikz@switch@to)}%
+
+
+
+
+% A concept node
+
+\tikzset{concept/.style= {circle,fill=\tikz@concept@color,draw=\tikz@concept@color,every concept}}%
+\tikzset{every concept/.style= {}}%
+
+\def\tikz@concept@color{black}%
+
+\tikzset{tikz@concept@setting/.style={edge from parent path={(\tikzparentnode) to [circle connection bar] (\tikzchildnode)}}}%
+\tikzset{tikz@concept@color@set/.style={}}%
+
+
+\tikzset{extra concept/.style= {concept color=black!50,level 2 concept,concept,every extra concept}}%
+\tikzset{every extra concept/.style={}}%
+
+\tikzset{concept connection/.style={line width=1mm,shorten <=2mm,shorten >=2mm,cap=round,draw=black!50}}%
+
+
+% A mindmap
+
+\tikzset{mindmap/.style=
+ {fill,draw,very thick,outer sep=0pt,inner sep=1pt,%
+ every child/.append style={style=tikz@concept@setting,style=tikz@concept@color@set},%
+ root concept,
+ level 1/.append style={level 1 concept},
+ level 2/.append style={level 2 concept},
+ level 3/.append style={level 3 concept},
+ level 4/.append style={level 4 concept},
+ text centered,%
+ segment angle=20,
+ style=every mindmap,
+ }}%
+\tikzset{every mindmap/.style={}}%
+
+
+\tikzset{root concept/.style= {minimum size=4cm,text width=3.5cm,font=\pgfutil@font@large}}%
+\tikzset{level 1 concept/.style={minimum size=2.25cm,
+ level distance=5cm,
+ text width=2cm,
+ sibling angle=60,
+ font=\pgfutil@font@small}}%
+\tikzset{level 2 concept/.style={minimum size=1.75cm,%
+ level distance=2.9cm,%
+ text width=1.5cm,%
+ sibling angle=60,%
+ font=\pgfutil@font@footnotesize}}%
+\tikzset{level 3 concept/.style={minimum size=1.15cm,%
+ text width=1cm,%
+ level distance=2.4cm,%
+ sibling angle=30,%
+ font=\pgfutil@font@tiny}}%
+\tikzset{level 4 concept/.style={minimum size=0.9cm,%
+ text width=0.7cm,
+ level distance=1.85cm,%
+ sibling angle=30,%
+ font=\pgfutil@font@tiny}}%
+
+\tikzset{small mindmap/.style=
+ {%
+ root concept/.style={minimum size=2.3cm,text width=2.1cm,font=\pgfutil@font@footnotesize},
+ level 1 concept/.style={%
+ minimum size=1.5cm,
+ level distance=2.8cm,
+ text width=1.4cm,
+ sibling angle=75,
+ font=\pgfutil@font@scriptsize},%
+ level 2 concept/.style={%
+ minimum size=1.1cm,%
+ level distance=2.2cm,%
+ text width=1.1cm,%
+ sibling angle=60,%
+ font=\pgfutil@font@tiny},%
+ level 3 concept/.style={%
+ level 2 concept,
+ sibling angle=30,%
+ font=\pgfutil@font@tiny},%
+ level 4 concept/.style={%
+ level 3 concept,
+ },
+ mindmap,%
+ line width=2pt,
+ }}%
+
+\tikzset{large mindmap/.style=
+ {%
+ root concept/.style={minimum size=5.6cm,text width=4.5cm,font=\pgfutil@font@Large},
+ level 1 concept/.style={%
+ minimum size=3.2cm,
+ level distance=7cm,
+ text width=2.8cm,
+ sibling angle=60,
+ font=},%
+ level 2 concept/.style={%
+ minimum size=2.45cm,%
+ level distance=4cm,%
+ text width=2.2cm,%
+ sibling angle=60,%
+ font=\pgfutil@font@small%
+ },%
+ level 3 concept/.style={%
+ minimum size=1.63cm,%
+ text width=1.4cm,%
+ level distance=3.38cm,%
+ sibling angle=30,%
+ font=\pgfutil@font@scriptsize},%
+ level 4 concept/.style={%
+ minimum size=1.27cm,%
+ text width=1cm,
+ level distance=2.60cm,%
+ sibling angle=30,%
+ font=\pgfutil@font@tiny},%
+ mindmap,%
+ line width=2pt,
+ }}%
+
+\tikzset{huge mindmap/.style=
+ {%
+ root concept/.style={minimum size=8cm,text width=7cm,font=\pgfutil@font@huge},
+ level 1 concept/.style={%
+ minimum size=4.5cm,
+ level distance=10cm,
+ text width=4cm,
+ sibling angle=60,
+ font=\pgfutil@font@large},%
+ level 2 concept/.style={%
+ minimum size=3.5cm,%
+ level distance=5.8cm,%
+ text width=3cm,%
+ sibling angle=60,%
+ font=%
+ },%
+ level 3 concept/.style={%
+ minimum size=2.3cm,%
+ text width=2cm,%
+ level distance=4.8cm,%
+ sibling angle=30,%
+ font=\pgfutil@font@footnotesize},%
+ level 4 concept/.style={%
+ minimum size=1.7cm,%
+ text width=1.4cm,
+ level distance=3.7cm,%
+ sibling angle=30,%
+ font=\pgfutil@font@scriptsize},%
+ mindmap,%
+ line width=3pt,
+ }}%
+
+
+% Annotations
+
+\tikzset{annotation/.style={shape=rectangle,
+ minimum size=0pt,
+ text width=3.5cm,
+ outer sep=1.5mm,
+ inner sep=1mm,
+ text badly ragged,
+ rounded corners,
+ font=\pgfutil@font@tiny,
+ every annotation}}%
+\tikzset{every annotation/.style={}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.code.tex
new file mode 100644
index 0000000000..8ef495bbba
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.code.tex
@@ -0,0 +1,31 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarypatterns.code.tex}
+
+\usepgflibrary{patterns}%
+
+\tikzoption{pattern color}{\edef\tikz@pattern@color{#1}}%
+\tikzoption{pattern}[]{%
+ \edef\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@nonetext%
+ \tikz@addmode{\tikz@mode@fillfalse}%
+ \else%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \tikz@addoption{\pgfsetfillpattern{#1}{\tikz@pattern@color}}%
+ \def\tikz@pattern{#1}%
+ \fi%
+ \tikz@addmode{\tikz@mode@filltrue}%
+ \fi%
+}%
+\def\tikz@pattern@color{black}%
+\def\tikz@pattern{dots}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.meta.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.meta.code.tex
new file mode 100644
index 0000000000..de96fd9093
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypatterns.meta.code.tex
@@ -0,0 +1,98 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{patterns.meta}%
+
+\tikzset{%
+ pattern color/.code=\edef\tikz@pattern@color{#1},
+ pattern/.code={%
+ \edef\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@nonetext%
+ \tikz@addmode{\tikz@mode@fillfalse}%
+ \else%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \tikz@addoption{\pgfsetfillpattern{#1}{\tikz@pattern@color}}%
+ \def\tikz@pattern{#1}%
+ \fi%
+ \tikz@addmode{\tikz@mode@filltrue}%
+ \fi%
+ }
+}%
+
+\def\tikz@pattern@color{black}%
+\def\tikz@pattern{}%
+
+\tikzset{patterns/.cd,
+ .unknown/.code={%
+ \let\tikz@pat@key=\pgfkeyscurrentname%
+ \pgfkeys{/pgf/patterns/\tikz@pat@key/.try={#1}}%
+ },
+ bottom left/.style={/pgf/patterns/bottom left={\tikz@scan@one@point\pgf@pat@process#1}},
+ top right/.style={/pgf/patterns/top right={\tikz@scan@one@point\pgf@pat@process#1}},
+ bounding box/.style args={#1(#2)#3and#4(#5)#6}{%
+ /tikz/patterns/bottom left={(#2)},
+ /tikz/patterns/top right={#4(#5)},
+ },
+ tile size/.style={/pgf/patterns/tile size={\tikz@scan@one@point\pgf@pat@process#1}},
+ tile transformation/.style={/pgf/patterns/tile transformation={%
+ \let\tikz@transform=\relax\pgfkeys{/tikz/.cd,#1}}%
+ },
+ infer tile bounding box/.code={
+ \def\pgf@pat@codeafter{%
+ \xdef\tikz@pat@installbb{%
+ \noexpand\pgfkeys{/tikz/patterns/bounding box={%
+ (\the\pgf@picminx-#1,\the\pgf@picminy-#1) and
+ (\the\pgf@picmaxx+#1,\the\pgf@picmaxy+#1)
+ },
+ /tikz/patterns/tile size={%
+ (\the\pgf@picmaxx-\the\pgf@picminx,
+ \the\pgf@picmaxy-\the\pgf@picminy)}}}%
+ }%
+ \let\pgf@pat@declarepost=\tikz@pat@installbb%
+ },
+ infer tile bounding box/.default=0pt,
+}%
+
+\def\tikzdeclarepattern#1{%
+ \begingroup%
+ \def\pgf@pat@codebefore{%
+ \let\tikz@transform=\relax%
+ \pgftransformreset% <- Hmm?
+ \tikz@declarepattern@install%
+ \ifnum\pgf@pat@type=0\relax%
+ \let\pgfsetstrokecolor=\pgfutil@gobble%
+ \let\pgfsetfillcolor=\pgfutil@gobble%
+ \fi%
+ \def\tikz@fig{\tikzerror{You cannot use `\string\node' inside a pattern}}%
+ \def\tikz@edge@plain{\tikzerror{You cannot use `edge' inside a pattern}}%
+ \def\tikz@to{\tikzerror{You cannot use `to' paths inside a pattern}}%
+ \tikzset{pattern/.code={\tikzerror{You cannot nest patterns}},
+ pattern color/.style={pattern}}%
+ }%
+ \pgfdeclarepattern{/tikz/patterns/.cd,#1}%
+ \endgroup%
+ }%
+
+\def\tikz@declarepattern@install{%
+ \let\tikz@compat@color@set=\tikz@compat@color@set@insidepatttern%
+ \tikz@installcommands%
+}%
+
+\let\tikz@compat@color@set@orig=\tikz@compat@color@set
+\def\tikz@compat@color@set@insidepatttern#1{%
+ \tikz@compat@color@set@orig{#1}%
+ \pgfsetfillcolor{#1}\pgfsetstrokecolor{#1}%
+}%
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryperspective.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryperspective.code.tex
new file mode 100644
index 0000000000..f9651ea973
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryperspective.code.tex
@@ -0,0 +1,111 @@
+% Copyright 2019 by Max Snippe
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryperspective.code.tex}
+
+% Initialize affine transformation matrix for perspective view
+% [aa ab ac 0]
+% [ba bb bc 0]
+% [ca cb cc 0]
+% [da db dc 1]
+\pgfmathsetmacro\pgf@H@tpp@aa{+1}
+ \pgfmathsetmacro\pgf@H@tpp@ab{+0}
+ \pgfmathsetmacro\pgf@H@tpp@ac{+0}
+\pgfmathsetmacro\pgf@H@tpp@ba{+0}
+ \pgfmathsetmacro\pgf@H@tpp@bb{+1}
+ \pgfmathsetmacro\pgf@H@tpp@bc{+0}
+\pgfmathsetmacro\pgf@H@tpp@ca{+0}
+ \pgfmathsetmacro\pgf@H@tpp@cb{+0}
+ \pgfmathsetmacro\pgf@H@tpp@cc{+1}
+\pgfmathsetmacro\pgf@H@tpp@da{+0}
+ \pgfmathsetmacro\pgf@H@tpp@db{+0}
+ \pgfmathsetmacro\pgf@H@tpp@dc{+0}
+
+\def\pgfpointperspectivexyz#1#2#3{%
+ \pgfmathsetmacro\pgf@pp@w%
+ { \pgf@H@tpp@da*(#1) + \pgf@H@tpp@db*(#2) + \pgf@H@tpp@dc*(#3) + 1}
+ \pgfmathsetmacro\pgf@pp@x%
+ {(\pgf@H@tpp@aa*(#1) + \pgf@H@tpp@ab*(#2) + \pgf@H@tpp@ac*(#3))/\pgf@pp@w}
+ \pgfmathsetmacro\pgf@pp@y%
+ {(\pgf@H@tpp@ba*(#1) + \pgf@H@tpp@bb*(#2) + \pgf@H@tpp@bc*(#3))/\pgf@pp@w}
+ \pgfmathsetmacro\pgf@pp@z%
+ {(\pgf@H@tpp@ca*(#1) + \pgf@H@tpp@cb*(#2) + \pgf@H@tpp@cc*(#3))/\pgf@pp@w}
+%
+ \pgf@x=\pgf@pp@x\pgf@xx%
+ \advance\pgf@x by \pgf@pp@y\pgf@yx%
+ \advance\pgf@x by \pgf@pp@z\pgf@zx%
+ \pgf@y=\pgf@pp@x\pgf@xy%
+ \advance\pgf@y by \pgf@pp@y\pgf@yy%
+ \advance\pgf@y by \pgf@pp@z\pgf@zy}
+
+\tikzdeclarecoordinatesystem{three point perspective}
+{%
+ \tikzset{cs/.cd,x=0,y=0,z=0,#1}%
+ \pgfpointperspectivexyz{\tikz@cs@x}{\tikz@cs@y}{\tikz@cs@z}
+}
+\tikzaliascoordinatesystem{tpp}{three point perspective}
+
+\pgfkeys{
+ /perspective/.cd,
+ p/.code args={(#1,#2,#3)}{
+ \pgfmathparse{ifthenelse(#1,int(1),int(0))}
+ \ifnum\pgfmathresult=0\else
+ \pgfmathsetmacro\pgf@H@tpp@ba{#2/#1}
+ \pgfmathsetmacro\pgf@H@tpp@ca{#3/#1}
+ \pgfmathsetmacro\pgf@H@tpp@da{ 1/#1}
+ \fi
+ },
+ q/.code args={(#1,#2,#3)}{
+ \pgfmathparse{ifthenelse(#2,int(1),int(0))}
+ \ifnum\pgfmathresult=0\else
+ \pgfmathsetmacro\pgf@H@tpp@ab{#1/#2}
+ \pgfmathsetmacro\pgf@H@tpp@cb{#3/#2}
+ \pgfmathsetmacro\pgf@H@tpp@db{ 1/#2}
+ \fi
+ },
+ r/.code args={(#1,#2,#3)}{
+ \pgfmathparse{ifthenelse(#3,int(1),int(0))}
+ \ifnum\pgfmathresult=0\else
+ \pgfmathsetmacro\pgf@H@tpp@ac{#1/#3}
+ \pgfmathsetmacro\pgf@H@tpp@bc{#2/#3}
+ \pgfmathsetmacro\pgf@H@tpp@dc{ 1/#3}
+ \fi
+ },
+}
+
+\tikzset{
+ perspective/.append code={\pgfkeys{/perspective/.cd,#1}},
+ perspective/.default={
+ p={(10,0,0)},
+ q={(0,10,0)},
+ r={(0,0,20)}},
+}
+
+\tikzset{
+ 3d view/.code 2 args={%
+ % Set elevation and azimuth angles
+ \pgfmathsetmacro\pgf@view@az{#1}%
+ \pgfmathsetmacro\pgf@view@el{#2}%
+ % Calculate projections of rotation matrix
+ \pgfmathsetmacro\pgf@xvec@x{cos(\pgf@view@az)}%
+ \pgfmathsetmacro\pgf@xvec@y{-sin(\pgf@view@az)*sin(\pgf@view@el)}%
+ \pgfmathsetmacro\pgf@yvec@x{sin(\pgf@view@az)}%
+ \pgfmathsetmacro\pgf@yvec@y{cos(\pgf@view@az)*sin(\pgf@view@el)}%
+ \pgfmathsetmacro\pgf@zvec@x{+0}%
+ \pgfmathsetmacro\pgf@zvec@y{cos(\pgf@view@el)}%
+ % Set base vectors
+ \pgfsetxvec{\pgfpoint{\pgf@xvec@x cm}{\pgf@xvec@y cm}}%
+ \pgfsetyvec{\pgfpoint{\pgf@yvec@x cm}{\pgf@yvec@y cm}}%
+ \pgfsetzvec{\pgfpoint{\pgf@zvec@x cm}{\pgf@zvec@y cm}}%
+ },
+ 3d view/.default={-30}{15},
+ isometric view/.style={3d view={-45}{atan(1/sqrt(2))}},
+}
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex
new file mode 100644
index 0000000000..80c34c175e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex
@@ -0,0 +1,146 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarypetri.code.tex}
+
+
+% Styles for places:
+
+\tikzset{every place/.style= {}}%
+\tikzset{place/.style= {circle,draw,inner sep=0pt,
+ minimum size=5ex,
+ every place}}%
+
+
+% Styles for transition:
+
+\tikzset{every transition/.style= {}}%
+\tikzset{transition/.style= {rectangle,draw,inner sep=0pt,
+ minimum size=4mm,
+ every transition}}%
+
+
+% Styles for relationship types:
+
+\tikzset{pre/.style= {<-,shorten <=1pt}}%
+\tikzset{post/.style= {->,shorten >=1pt}}%
+\tikzset{pre and post/.style= {<->,shorten >=1pt,shorten <=1pt}}%
+
+
+
+% Styles for marks:
+
+\tikzset{every token/.style= {}}%
+\tikzset{token/.style= {fill=black,draw=none,circle,
+ inner sep=0.5pt,minimum size=1ex,
+ text=white,font=\pgfutil@font@tiny,every token}}%
+
+\tikzoption{token distance}{\def\tikz@token@distance{#1}}%
+\def\tikz@token@distance{1.5ex}%
+
+\tikzset{children are tokens/.style= {growth function=\tikz@grow@tokens,edge from parent path=}}%
+
+\tikzoption{tokens}{%
+ \ifnum#1>0\relax%
+ \tikzset{append after command={}
+ {[children are tokens]child foreach \tikz@dummy in {1,...,#1} {node[token]{}}}}%
+ \fi}%
+
+\tikzoption{colored tokens}{%
+ \tikzset{append after command={}%
+ {[children are tokens]child foreach \tikz@child@color in {#1} {node[token,\tikz@child@color]{}}}}%
+ }%
+
+\tikzoption{structured tokens}{%
+ \tikzset{append after command={}%
+ {[children are tokens]child foreach \tikzpetrichildname in {#1} {node[token]{\tikzpetrichildname}}}}%
+ }%
+
+
+\def\tikz@grow@tokens{%
+ \pgfmathsetlength{\pgf@xa}{\tikz@token@distance}%
+ \pgfmathsetlength{\pgf@ya}{\tikz@token@distance}%
+ \pgf@xc=0pt%
+ \pgf@yc=0pt%
+ \csname tikz@grow@tokens@placer@\the\tikznumberofchildren @\the\tikznumberofcurrentchild\endcsname%
+ \pgftransformshift{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+}%
+
+\def\tikz@def@grow@tokens#1#2#3#4{%
+ \expandafter\def\csname tikz@grow@tokens@placer@#1@#2\endcsname{%
+ \pgf@xc=#3\pgf@xa%
+ \pgf@yc=#4\pgf@ya}%
+}%
+
+
+% Single token
+\tikz@def@grow@tokens{1}{1}{0}{0}%
+
+% Two tokens
+\tikz@def@grow@tokens{2}{1}{-.5}{0}%
+\tikz@def@grow@tokens{2}{2}{.5}{0}%
+
+% Three tokens
+\tikz@def@grow@tokens{3}{1}{0} {0.57}%
+\tikz@def@grow@tokens{3}{2}{-.5}{-.306025}%
+\tikz@def@grow@tokens{3}{3}{.5} {-.306025}%
+
+% Four tokens
+\tikz@def@grow@tokens{4}{1}{-.5}{.5}%
+\tikz@def@grow@tokens{4}{2}{.5}{.5}%
+\tikz@def@grow@tokens{4}{3}{-.5}{-.5}%
+\tikz@def@grow@tokens{4}{4}{.5}{-.5}%
+
+% Five tokens
+\tikz@def@grow@tokens{5}{1}{0}{.85}%
+\tikz@def@grow@tokens{5}{2}{-0.808398}{0.26266}%
+\tikz@def@grow@tokens{5}{3}{0.808398}{0.26266}%
+\tikz@def@grow@tokens{5}{4}{-0.499617}{-0.687664}%
+\tikz@def@grow@tokens{5}{5}{0.499617}{-0.687664}%
+
+% Six tokens
+\tikz@def@grow@tokens{6}{1}{-1}{.5}%
+\tikz@def@grow@tokens{6}{2}{0}{.5}%
+\tikz@def@grow@tokens{6}{3}{1}{.5}%
+\tikz@def@grow@tokens{6}{4}{-1}{-.5}%
+\tikz@def@grow@tokens{6}{5}{0}{-.5}%
+\tikz@def@grow@tokens{6}{6}{1}{-.5}%
+
+% Seven tokens
+\tikz@def@grow@tokens{7}{1}{0}{1}%
+\tikz@def@grow@tokens{7}{2}{-1}{.5}%
+\tikz@def@grow@tokens{7}{3}{0}{0}%
+\tikz@def@grow@tokens{7}{4}{1}{.5}%
+\tikz@def@grow@tokens{7}{5}{-1}{-.5}%
+\tikz@def@grow@tokens{7}{6}{0}{-1}%
+\tikz@def@grow@tokens{7}{7}{1}{-.5}%
+
+% Eight tokens
+\tikz@def@grow@tokens{8}{1}{-.5}{1}%
+\tikz@def@grow@tokens{8}{2}{.5}{1}%
+\tikz@def@grow@tokens{8}{3}{-1}{0}%
+\tikz@def@grow@tokens{8}{4}{0}{0}%
+\tikz@def@grow@tokens{8}{5}{1}{0}%
+\tikz@def@grow@tokens{8}{6}{-1}{-1}%
+\tikz@def@grow@tokens{8}{7}{0}{-1}%
+\tikz@def@grow@tokens{8}{8}{1}{-1}%
+
+% Eight tokens
+\tikz@def@grow@tokens{9}{1}{-1}{1}%
+\tikz@def@grow@tokens{9}{2}{0}{1}%
+\tikz@def@grow@tokens{9}{3}{1}{1}%
+\tikz@def@grow@tokens{9}{4}{-1}{0}%
+\tikz@def@grow@tokens{9}{5}{0}{0}%
+\tikz@def@grow@tokens{9}{6}{1}{0}%
+\tikz@def@grow@tokens{9}{7}{-1}{-1}%
+\tikz@def@grow@tokens{9}{8}{0}{-1}%
+\tikz@def@grow@tokens{9}{9}{1}{-1}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplothandlers.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplothandlers.code.tex
new file mode 100644
index 0000000000..e6db2b62ff
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplothandlers.code.tex
@@ -0,0 +1,14 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryplothandlers.code.tex}
+
+\usepgflibrary{plothandlers}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplotmarks.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplotmarks.code.tex
new file mode 100644
index 0000000000..15eea57201
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryplotmarks.code.tex
@@ -0,0 +1,14 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryplotmarks.code.tex}
+
+\usepgflibrary{plotmarks}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypositioning.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypositioning.code.tex
new file mode 100644
index 0000000000..b410975c32
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarypositioning.code.tex
@@ -0,0 +1,118 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarypositioning.code.tex}
+
+
+\tikzset{above/.code=\tikz@lib@place@handle@{#1}{south}{0}{1}{north}{1}}%
+\tikzset{above left/.code=\tikz@lib@place@handle@{#1}{south east}{-1}{1}{north west}{0.707106781}}%
+\tikzset{above right/.code=\tikz@lib@place@handle@{#1}{south west}{1}{1}{north east}{0.707106781}}%
+\tikzset{base left/.code =\tikz@lib@place@handle@{#1}{base east}{-1}{0}{base west}{1}}%
+\tikzset{base right/.code=\tikz@lib@place@handle@{#1}{base west}{1}{0}{base east}{1}}%
+\tikzset{below/.code=\tikz@lib@place@handle@{#1}{north}{0}{-1}{south}{1}}%
+\tikzset{below left/.code=\tikz@lib@place@handle@{#1}{north east}{-1}{-1}{south west}{0.707106781}}%
+\tikzset{below right/.code=\tikz@lib@place@handle@{#1}{north west}{1}{-1}{south east}{0.707106781}}%
+\tikzset{left/.code =\tikz@lib@place@handle@{#1}{east}{-1}{0}{west}{1}}%
+\tikzset{mid left/.code =\tikz@lib@place@handle@{#1}{mid east}{-1}{0}{mid west}{1}}%
+\tikzset{mid right/.code=\tikz@lib@place@handle@{#1}{mid west}{1}{0}{mid east}{1}}%
+\tikzset{right/.code=\tikz@lib@place@handle@{#1}{west}{1}{0}{east}{1}}%
+
+\newif\iftikz@lib@ignore@size
+
+% Hook into resets:
+\pgfutil@g@addto@macro\tikz@node@reset@hook{\tikz@addtransform{\tikz@lib@pos@call}\let\tikz@lib@pos@call=\relax}%
+
+\tikzset{on grid/.is if=tikz@lib@ignore@size}%
+
+\tikzset{node distance=1cm and 1cm}%
+
+\def\tikz@lib@place@handle@#1#2#3#4#5#6{%
+ \def\tikz@anchor{#2}%
+ \let\tikz@do@auto@anchor=\relax%
+ \edef\tikz@temp{#1}%
+ \def\tikz@lib@place@single@factor{#6}%
+ \expandafter\tikz@lib@place@handle@@\expandafter{\tikz@temp}{#3}{#4}{#5}%
+}%
+\def\tikz@lib@place@handle@@#1#2#3#4{%
+ \pgfutil@in@{of }{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@place@of#1\tikz@stop{#4}%
+ \else%
+ \edef\tikz@lib@place@nums{#1}%
+ \fi%
+ \ifx\tikz@lib@place@nums\pgfutil@empty%
+ % Ok, nothing to do, we have set the anchor and we are happy...
+ \else%
+ \expandafter\tikz@lib@place@parse@nums\expandafter{\tikz@lib@place@nums}%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#3\pgf@y%
+ \edef\tikz@lib@pos@call{\noexpand\pgftransformshift{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \fi%
+}%
+
+\def\tikz@lib@place@parse@nums#1{%
+ \pgfutil@in@{and}{#1}%
+ \ifpgfutil@in@%
+ \tikz@lib@place@parse@nums@#1\tikz@stop%
+ \else%
+ \tikz@lib@place@parse@nums@#1and#1\tikz@stop%
+ \pgf@x=\tikz@lib@place@single@factor\pgf@x%
+ \pgf@y=\tikz@lib@place@single@factor\pgf@y%
+ \fi
+}%
+\def\tikz@lib@place@parse@nums@#1and#2\tikz@stop{%
+ \pgfmathparse{#2}%
+ \ifpgfmathunitsdeclared%
+ \pgf@xa=\pgfmathresult pt%
+ \pgf@ya=0pt%
+ \else%
+ \let\tikz@lib@temp=\pgfmathresult%
+ \pgf@process{\pgfpointxy{\tikz@lib@temp}{0}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \fi%
+ \pgfmathparse{#1}%
+ \ifpgfmathunitsdeclared%
+ \advance\pgf@ya by\pgfmathresult pt%
+ \else%
+ \let\tikz@lib@temp=\pgfmathresult%
+ \pgf@process{\pgfpointxy{0}{\tikz@lib@temp}}%
+ \advance\pgf@xa by\pgf@x%
+ \advance\pgf@ya by\pgf@y%
+ \fi%
+ \pgf@x=\pgf@xa%
+ \pgf@y=\pgf@ya%
+}%
+
+\def\tikz@lib@place@of#1of #2\tikz@stop#3{%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\pgfutil@empty%
+ \tikz@lib@place@of@{\tikz@node@distance}{#2}{#3}%
+ \else%
+ \tikz@lib@place@of@{#1}{#2}{#3}%
+ \fi%
+}%
+\def\tikz@lib@place@of@#1#2#3{%
+ \tikz@scan@one@point\tikz@lib@place@remember(#2)%
+ \iftikz@shapeborder%
+ % Ok, this is relative to a border.
+ \iftikz@lib@ignore@size%
+ \edef\tikz@node@at{\noexpand\pgfpointanchor{\tikz@shapeborder@name}{center}}%
+ \def\tikz@anchor{center}%
+ \else%
+ \edef\tikz@node@at{\noexpand\pgfpointanchor{\tikz@shapeborder@name}{#3}}%
+ \fi%
+ \fi%
+ \edef\tikz@lib@place@nums{#1}%
+}%
+\def\tikz@lib@place@remember#1{\def\tikz@node@at{#1}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex
new file mode 100644
index 0000000000..41ce3faaf5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex
@@ -0,0 +1,90 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryquotes.code.tex}
+
+\def\tikz@quote@parser#1{\tikz@quote@@parser#1\pgf@stop}%
+\def\tikz@quote@@parser"#1"{%
+ \pgfutil@ifnextchar\bgroup{%
+ \tikz@quote@@parser@group{#1}}{%
+ \pgfutil@ifnextchar'{%
+ \tikz@quote@@parser@apo{#1}}{%
+ \tikz@quote@@parser@normal{#1}}}}%
+\def\tikz@quote@@parser@apo#1'{%
+ \pgfutil@ifnextchar\bgroup{\tikz@quote@@parser@apo@group{#1}}{\tikz@quote@@parser@apo@normal{#1}}}%
+\def\tikz@quote@@parser@group#1#2#3\pgf@stop{%
+ \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{#2}}%
+ \expandafter\pgfkeysalso\expandafter{\tikz@temp}%
+}%
+\def\tikz@quote@@parser@normal#1#2\pgf@stop{%
+ \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{#2}}%
+ \expandafter\pgfkeysalso\expandafter{\tikz@temp}%
+}%
+\def\tikz@quote@@parser@apo@group#1#2#3\pgf@stop{%
+ \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{',#2}}%
+ \expandafter\pgfkeysalso\expandafter{\tikz@temp}%
+}%
+\def\tikz@quote@@parser@apo@normal#1#2\pgf@stop{%
+ \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{',#2}}%
+ \expandafter\pgfkeysalso\expandafter{\tikz@temp}%
+}%
+
+\pgfkeys{/handlers/first char syntax=true}%
+
+\def\tikz@enable@node@quotes{%
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string"}{\tikz@quote@parser}%
+ \let\tikz@quotes@as\tikz@node@quotes@as%
+}%
+\def\tikz@enable@edge@quotes{%
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string"}{\tikz@quote@parser}%
+ \let\tikz@quotes@as\tikz@edge@quotes@as%
+}%
+\def\tikz@enable@pic@quotes{%
+ \pgfkeyssetvalue{/handlers/first char syntax/\expandafter\meaning\string"}{\tikz@quote@parser}%
+ \let\tikz@quotes@as\tikz@pic@quotes@as%
+}%
+
+\tikzset{
+ node quotes mean/.code={\def\tikz@node@quotes@as##1##2{#1}},
+ edge quotes mean/.code={\def\tikz@edge@quotes@as##1##2{#1}},
+ pic quotes mean/.code={\def\tikz@pic@quotes@as##1##2{#1}},
+ quotes mean pin/.style={node quotes mean={
+ pin={[direction shorthands,every pin quotes/.try,##2]##1}}},
+ quotes mean label/.style={node quotes mean={
+ label={[direction shorthands,every label quotes/.try,##2]##1}}},
+ quotes mean label,
+ edge quotes mean={edge node={node [every edge quotes,#2]{#1}}},
+ pic quotes mean={pic text={#1},pic text options={every pic quotes/.try,#2}},
+ every edge quotes/.style={auto},
+ direction shorthands/.code={%
+ \pgfkeyslet{/tikz/centered/.@cmd}\tikz@label@@centered
+ \pgfkeyslet{/tikz/above/.@cmd}\tikz@label@@above
+ \pgfkeyslet{/tikz/below/.@cmd}\tikz@label@@below
+ \pgfkeyslet{/tikz/left/.@cmd}\tikz@label@@left
+ \pgfkeyslet{/tikz/right/.@cmd}\tikz@label@@right
+ \pgfkeyslet{/tikz/above left/.@cmd}\tikz@label@@above@left
+ \pgfkeyslet{/tikz/above right/.@cmd}\tikz@label@@above@right
+ \pgfkeyslet{/tikz/below left/.@cmd}\tikz@label@@below@left
+ \pgfkeyslet{/tikz/below right/.@cmd}\tikz@label@@below@right
+ }
+}%
+
+\def\tikz@label@@centered#1\pgfeov{\pgfkeysalso{label position=center,pin position=center}}%
+\def\tikz@label@@above#1\pgfeov{\pgfkeysalso{label position=90,pin position=90}}%
+\def\tikz@label@@below#1\pgfeov{\pgfkeysalso{label position=-90,pin position=-90}}%
+\def\tikz@label@@left#1\pgfeov{\pgfkeysalso{label position=180,pin position=180}}%
+\def\tikz@label@@right#1\pgfeov{\pgfkeysalso{label position=0,pin position=0}}%
+\def\tikz@label@@above@left#1\pgfeov{\pgfkeysalso{label position=135,pin position=135}}%
+\def\tikz@label@@below@left#1\pgfeov{\pgfkeysalso{label position=-135,pin position=-135}}%
+\def\tikz@label@@above@right#1\pgfeov{\pgfkeysalso{label position=45,pin position=45}}%
+\def\tikz@label@@below@right#1\pgfeov{\pgfkeysalso{label position=-45,pin position=-45}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryrdf.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryrdf.code.tex
new file mode 100644
index 0000000000..74e77ac3e2
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryrdf.code.tex
@@ -0,0 +1,291 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryrdf.code.tex}
+
+
+
+\def\tikz@add@rdf@pre@option#1{\expandafter\def\expandafter\tikz@rdf@pre@options\expandafter{\tikz@rdf@pre@options#1}}%
+\def\tikz@add@rdf@post@option#1{\expandafter\def\expandafter\tikz@rdf@post@options\expandafter{\tikz@rdf@post@options#1}}%
+
+\let\tikz@rdf@pre@options\pgfutil@empty
+\let\tikz@rdf@post@options\pgfutil@empty
+
+\tikzset{
+ %
+ % Switching on the engine
+ %
+ rdf engine on/.code={%
+ \def\tikz@clear@rdf@options{\let\tikz@rdf@pre@options\pgfutil@empty\let\tikz@rdf@post@options\pgfutil@empty}%
+ \def\tikz@do@rdf@pre@options{\tikz@rdf@pre@options\let\tikz@rdf@pre@options\pgfutil@empty}%
+ \def\tikz@do@rdf@post@options{\tikz@rdf@post@options\let\tikz@rdf@post@options\pgfutil@empty}%
+ \pgfkeys{/tikz/rdf engine/.code=\tikz@add@rdf@pre@option{\pgfqkeys{/tikz/rdf engine}{##1}}}%
+ },
+ rdf engine/.cd,
+ %
+ every statement/.style=,
+ %
+ % Namespaces
+ %
+ prefix/.code=\pgfrdfprefix{#1},
+ %
+ % Core commands
+ %
+ statement/.code={%
+ {%
+ \pgfkeys{/tikz/rdf engine/every statement}%
+ \pgfqkeys{/tikz/rdf engine/statements}{#1}%
+ \iftikz@rdf@is@a@container\tikz@rdf@init@container\fi%
+ \iftikz@rdf@is@a@member\tikz@rdf@make@member\fi%
+ \tikz@rdf@make@triple%
+ \expandafter}\tikz@rdf@action%
+ },
+ get scope curie/.code={%
+ \ifx\tikz@id@name\pgfutil@empty%
+ \def\tikz@id@name{@rdf}%
+ \fi%
+ \pgfidrefnextuse\tikz@temp{\tikz@id@name}%
+ \edef#1{\tikzrdfhashmark\tikz@temp}%
+ },
+ get new resource curie/.code={%
+ \pgfsys@new@id\tikz@temp%
+ \edef#1{\tikzrdfhashmark\tikz@temp}%
+ },
+ scope is new context/.style={get scope curie=\tikzrdfcontext}
+}%
+
+\def\tikzrdfcontext{\tikzrdfhashmark}%empty by default
+
+\tikzset{
+ rdf engine/statements/.cd,
+ %
+ % Core properties of statements
+ %
+ subject/.code={%
+ \def\tikz@rdf@target{\tikz@rdf@subject}%
+ \tikz@rdf@parse{#1}%
+ },
+ predicate/.code={%
+ \def\tikz@rdf@target{\tikz@rdf@predicate}%
+ \tikz@rdf@parse{#1}%
+ },
+ object/.code={%
+ \let\tikz@rdf@object@literal\relax%
+ \let\tikz@rdf@object\relax%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@rdf@current@scope@text%
+ \tikz@rdf@object@scope@contenttrue%
+ \else%
+ \tikz@rdf@object@scope@contentfalse%
+ \def\tikz@rdf@target{\tikz@rdf@object}%
+ \tikz@rdf@parse{#1}%
+ \fi%
+ },
+ %
+ % Shorthands
+ %
+ has type/.style={predicate=rdf:type,object={#1}},
+ %
+ % Containers
+ %
+ is a bag/.style={has type=rdf:Bag, is a container},
+ is a sequence/.style={has type=rdf:Seq, is a container},
+ is an alternative/.style={has type=rdf:Alt, is a container},
+ %
+ is a container/.code={\tikz@rdf@is@a@containertrue},
+ %
+ has as member/.code={\tikz@rdf@is@a@membertrue},%
+}%
+
+\def\tikz@rdf@current@scope@text{scope content}%
+
+\let\tikz@rdf@subject\relax
+\let\tikz@rdf@predicate\pgfutil@empty
+\let\tikz@rdf@object\relax
+\let\tikz@rdf@object@literal\relax
+\let\tikz@rdf@container\relax
+
+\newif\iftikz@rdf@object@scope@content
+\newif\iftikz@rdf@is@a@container
+\newif\iftikz@rdf@is@a@member
+
+
+\def\tikz@rdf@parse#1{%
+ \edef\tikz@temp{#1}%
+ \expandafter\tikz@rdf@parse@#1\relax%
+}%
+
+\def\tikz@rdf@parse@{%
+ \pgfutil@ifnextchar({\tikz@rdf@parse@name}{%)
+ \pgfutil@ifnextchar"{\tikz@rdf@parse@literals}{%
+ \tikz@rdf@parse@curie%
+ }%
+ }%
+}%
+
+\def\tikz@rdf@parse@name(#1)\relax{%
+ \pgfidrefprevuse\tikz@rdf@the@id{#1}\expandafter\edef\tikz@rdf@target{\tikzrdfhashmark\tikz@rdf@the@id}%
+}%
+\def\tikz@rdf@parse@literals"#1"{%
+ \ifx\tikz@rdf@target\tikz@rdf@object@name%
+ \def\tikz@rdf@object@literal{#1}%
+ \else%
+ \tikzerror{Only RDF objects can be literals}%
+ \fi%
+ \pgfutil@ifnextchar\relax\pgfutil@gobble\tikz@rdf@parse@literals@rest%
+}%
+\def\tikz@rdf@parse@literals@rest and scope content\relax{%
+ \tikz@rdf@object@scope@contenttrue%
+}%
+
+\def\tikz@rdf@object@name{\tikz@rdf@object}%
+\def\tikz@rdf@parse@curie#1\relax{%
+ \expandafter\def\tikz@rdf@target{#1}%
+}%
+
+{%
+ \catcode`\#=11
+ \gdef\tikzrdfhashmark{#}%
+}%
+
+
+\def\tikz@rdf@make@triple{%
+ % First, ensure that subject, predicate and object are set:
+ \ifx\tikz@rdf@subject\relax%
+ \tikzerror{RDF statement misses subject}%
+ \else%
+ \ifx\tikz@rdf@predicate\relax%
+ \tikzerror{RDF statement misses predicate}%
+ \else%
+ \iftikz@rdf@object@scope@content%
+ \edef\tikz@marshal{\noexpand\tikz@rdf@make@content@triple{\tikz@rdf@subject}{\tikz@rdf@predicate}{\tikz@rdf@object@literal}}%
+ \tikz@marshal%
+ \else%
+ \ifx\tikz@rdf@object\relax%
+ \ifx\tikz@rdf@object@literal\relax%
+ \tikzerror{RDF statement misses object}%
+ \else%
+ \edef\tikz@marshal{\noexpand\tikz@rdf@make@literal@triple{\tikz@rdf@subject}{\tikz@rdf@predicate}{\tikz@rdf@object@literal}}%
+ \tikz@marshal%
+ \fi%
+ \else%
+ \edef\tikz@marshal{\noexpand\tikz@rdf@make@normal@triple{\tikz@rdf@subject}{\tikz@rdf@predicate}{\tikz@rdf@object}}%
+ \tikz@marshal%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+\def\tikz@rdf@make@content@triple#1#2#3{%
+ \def\tikz@rdf@action{%
+ \def\tikz@rdf@invoke@code{%
+ \def\tikz@temp{#3}%
+ \ifx\tikz@temp\tikz@rdf@object@literal@text\else%
+ \pgfrdfcontent{#3}%
+ \fi%
+ \pgfrdfabout{#1}%
+ \pgfrdfdatatype{rdf:XMLLiteral}%
+ \foreach \tikz@rdf@pred in {#2}{%
+ \ifx\tikz@rdf@pred\pgfutil@empty\else%
+ \expandafter\pgfrdfproperty\expandafter{\tikz@rdf@pred}%
+ \fi%
+ }%
+ }%
+ }%
+}%
+
+\def\tikz@rdf@make@literal@triple#1#2#3{%
+ \def\tikz@rdf@action{%
+ \tikz@add@rdf@post@option{%
+ {%
+ \pgfrdfabout{#1}%
+ \foreach \tikz@rdf@pred in {#2}{%
+ \ifx\tikz@rdf@pred\pgfutil@empty\else%
+ \expandafter\pgfrdfproperty\expandafter{\tikz@rdf@pred}%
+ \fi%
+ }%
+ \pgfrdfcontent{#3}%
+ \pgfidscope%
+ \endpgfidscope%
+ }%
+ }%
+ }%
+}%
+
+\def\tikz@rdf@make@normal@triple#1#2#3{%
+ \def\tikz@rdf@action{%
+ \tikz@add@rdf@post@option{%
+ {%
+ \pgfrdfabout{#1}%
+ \foreach \tikz@rdf@pred in {#2}{%
+ \ifx\tikz@rdf@pred\pgfutil@empty\else%
+ \expandafter\pgfrdfproperty\expandafter{\tikz@rdf@pred}%
+ \fi%
+ }%
+ \pgfrdfresource{#3}%
+ \pgfidscope%
+ \endpgfidscope%
+ }%
+ }%
+ }%
+}%
+
+\def\tikz@rdf@object@literal@text{\tikz@rdf@object@literal}%
+
+
+
+
+% Containers
+
+\def\tikz@rdf@init@container{%
+ \ifx\tikz@rdf@subject\relax%
+ \tikzerror{RDF statement misses subject}%
+ \else%
+ \expandafter\gdef\csname tikz@rdf@c@\tikz@rdf@subject\endcsname{0}%
+ \fi%
+}%
+
+
+\def\tikz@rdf@make@member{%
+ \ifx\tikz@rdf@subject\relax%
+ \tikzerror{RDF statement misses subject}%
+ \else%
+ % Get number:
+ \expandafter\let\expandafter\tikz@temp\csname tikz@rdf@c@\tikz@rdf@subject\endcsname%
+ \ifx\tikz@temp\relax%
+ \tikzerror{RDF subject is not a container}%
+ \else%
+ \c@pgf@counta\tikz@temp%
+ \advance\c@pgf@counta by1\relax%
+ \expandafter\xdef\csname tikz@rdf@c@\tikz@rdf@subject\endcsname{\the\c@pgf@counta}%
+ \edef\tikz@rdf@predicate{rdf:_\the\c@pgf@counta}%
+ \fi%
+ \fi%
+}%
+
+
+
+
+
+% Hooks:
+
+\let\tikz@rdf@invoke@code\relax
+
+\def\tikz@rdf@id@hook{%
+ \tikz@rdf@invoke@code%
+ \let\tikz@rdf@invoke@code\relax%
+}%
+
+% Add hook:
+\expandafter\def\expandafter\tikz@id@hook\expandafter{\tikz@id@hook\tikz@rdf@id@hook}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryscopes.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryscopes.code.tex
new file mode 100644
index 0000000000..68856d591e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryscopes.code.tex
@@ -0,0 +1,42 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryscopes.code.tex}
+
+% Redefine the after command hook...
+
+\def\tikz@lib@scope@check{%
+ \pgfutil@ifnextchar\tikz@intersect@finish{%
+ \tikz@intersect@finish\afterassignment\tikz@lib@scope@check\let\tikz@next%
+ }{%
+ \pgfutil@ifnextchar\par{%
+ \afterassignment\tikz@lib@scope@check\let\tikz@next%
+ }%
+ {\pgfutil@ifnextchar\bgroup{%gotcha
+ \afterassignment\tikz@lib@scope@gotcha\let\tikz@next%
+ }%
+ {}%
+ }%
+ }%
+}%
+
+\def\tikz@lib@scope@gotcha{%
+ \pgfutil@ifnextchar[{%]
+ \tikz@lib@scope@action%
+ }{%
+ % false alarm
+ \bgroup%
+ }%
+}%
+\def\tikz@lib@scope@action[#1]{%
+ \scope[#1]\bgroup\aftergroup\endscope%
+ \tikz@lib@scope@check%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadings.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadings.code.tex
new file mode 100644
index 0000000000..2cf08776f3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadings.code.tex
@@ -0,0 +1,21 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshadings.code.tex}
+
+\usepgflibrary{shadings}%
+
+\tikzset{
+ lower left/.style={shading=bilinear interpolation,/utils/exec=\colorlet{lower left}{#1}},
+ upper left/.style={shading=bilinear interpolation,/utils/exec=\colorlet{upper left}{#1}},
+ lower right/.style={shading=bilinear interpolation,/utils/exec=\colorlet{lower right}{#1}},
+ upper right/.style={shading=bilinear interpolation,/utils/exec=\colorlet{upper right}{#1}}
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadows.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadows.code.tex
new file mode 100644
index 0000000000..3bd60e99fa
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshadows.code.tex
@@ -0,0 +1,146 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshadows.code.tex}
+
+\usetikzlibrary{fadings}%
+
+
+% General options
+\tikzset{
+ /tikz/shadow scale/.initial=1,
+ /tikz/shadow xshift/.initial=0pt,
+ /tikz/shadow yshift/.initial=0pt,
+}%
+
+% Basic shadow style
+\tikzset{
+ general shadow/.style={
+ preaction={
+ #1,
+ transform canvas={
+ scale around=\pgfkeysvalueof{/tikz/shadow scale}:(current path bounding box.center),
+ shift={(\pgfkeysvalueof{/tikz/shadow xshift},\pgfkeysvalueof{/tikz/shadow yshift})}
+ },
+ }
+ },
+ every shadow/.style={}
+}%
+
+
+
+%
+% Adds a simple drop shadow to a path
+%
+
+\tikzset{
+ /tikz/drop shadow/.style={
+ general shadow={%
+ shadow scale=1,
+ shadow xshift=.5ex,
+ shadow yshift=-.5ex,
+ opacity=.5,
+ fill=black!50,
+ every shadow,
+ #1
+ }
+ }
+}%
+
+
+%
+% Adds a circular drop shadow to a path
+%
+
+\tikzset{
+ /tikz/circular drop shadow/.style={
+ general shadow={%
+ shadow scale=1.1,
+ shadow xshift=.3ex,
+ shadow yshift=-.3ex,
+ fill=black!50,
+ path fading={circle with fuzzy edge 15 percent},
+ every shadow,
+ #1
+ }
+ }
+}%
+
+
+
+%
+% Adds a circular glow to a path
+%
+
+\tikzset{
+ /tikz/circular glow/.style={
+ general shadow={%
+ shadow scale=1.25,
+ shadow xshift=0pt,
+ shadow yshift=0pt,
+ fill=black!50,
+ path fading={circle with fuzzy edge 15 percent},
+ every shadow,
+ #1,
+ }
+ }
+}%
+
+
+
+
+
+%
+% Adds a "copy" version of the path behind it.
+%
+
+\tikzset{
+ /tikz/copy shadow/.style={
+ general shadow={%
+ /utils/exec={\let\tikz@lib@shadow@fill=\tikz@fillcolor\let\tikz@lib@shadow@draw=\tikz@strokecolor},
+ shadow scale=1,
+ shadow xshift=.5ex,
+ shadow yshift=.5ex,
+ fill=\tikz@lib@shadow@fill,
+ draw=\tikz@lib@shadow@draw,
+ every shadow,
+ #1
+ }
+ }
+}%
+
+
+%
+% Adds two "copies" of the path behind it.
+%
+
+\tikzset{
+ /tikz/double copy shadow/.style={
+ general shadow={%
+ /utils/exec={\let\tikz@lib@shadow@fill=\tikz@fillcolor\let\tikz@lib@shadow@draw=\tikz@strokecolor},
+ shadow scale=1,
+ shadow xshift=.5ex,
+ shadow yshift=.5ex,
+ fill=\tikz@lib@shadow@fill,
+ draw=\tikz@lib@shadow@draw,
+ #1,
+ shadow xshift/.expanded=2*\pgfkeysvalueof{/tikz/shadow xshift},
+ shadow yshift/.expanded=2*\pgfkeysvalueof{/tikz/shadow yshift},
+ },
+ general shadow={%
+ /utils/exec={\let\tikz@lib@shadow@fill=\tikz@fillcolor\let\tikz@lib@shadow@draw=\tikz@strokecolor},
+ shadow scale=1,
+ shadow xshift=.5ex,
+ shadow yshift=.5ex,
+ fill=\tikz@lib@shadow@fill,
+ draw=\tikz@lib@shadow@draw,
+ #1,
+ },
+ }
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.arrows.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.arrows.code.tex
new file mode 100644
index 0000000000..c20e6a73cc
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.arrows.code.tex
@@ -0,0 +1,16 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.arrows.code.tex}
+
+\usepgflibrary{shapes.arrows}%
+
+\pgfkeys{/tikz/arrow box arrows/.code={\pgf@lib@arrowbox@parsearrows{#1}}}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.callouts.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.callouts.code.tex
new file mode 100644
index 0000000000..2a3de5548a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.callouts.code.tex
@@ -0,0 +1,35 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{shapes.callouts}%
+
+\pgfkeys{/tikz/callout absolute pointer/.code={%
+ \tikz@scan@one@point\tikz@lib@callout@checkforplus#1\relax%
+ }%
+}%
+
+\def\tikz@lib@callout@checkforplus#1{%
+ \pgfutil@ifnextchar+{\def\tikz@lib@callout@originalpoint{#1}\tikz@lib@callout@scan@relative}%
+ {\pgf@lib@callout@makeabsolutepointer{#1}}}%
+
+\def\tikz@lib@callout@scan@relative+{%
+ \pgfutil@ifnextchar+{\tikz@lib@callout@scan@plusplus}{\tikz@lib@callout@scan@plus}}%
+\def\tikz@lib@callout@scan@plusplus+{\tikz@scan@one@point\tikz@lib@callout@add}%
+\def\tikz@lib@callout@scan@plus{\tikz@scan@one@point\tikz@lib@callout@add}%
+\def\tikz@lib@callout@add#1{%
+ \expandafter\pgf@lib@callout@makeabsolutepointer\expandafter{%
+ \expandafter\pgfpointadd\expandafter{\tikz@lib@callout@originalpoint}{#1}}%
+}%
+
+\pgfkeys{/tikz/callout relative pointer/.code={%
+ \tikz@scan@one@point\pgf@lib@callout@makerelativepointer#1\relax%
+ }%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.code.tex
new file mode 100644
index 0000000000..2efb5c3308
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.code.tex
@@ -0,0 +1,19 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.code.tex}
+
+\usetikzlibrary{shapes.geometric}%
+\usetikzlibrary{shapes.misc}%
+\usetikzlibrary{shapes.symbols}%
+\usetikzlibrary{shapes.arrows}%
+\usetikzlibrary{shapes.callouts}%
+\usetikzlibrary{shapes.multipart}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.IEC.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.IEC.code.tex
new file mode 100644
index 0000000000..c34229b137
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.IEC.code.tex
@@ -0,0 +1,38 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.gates.logic.IEC.code.tex}
+
+\usepgflibrary{shapes.gates.logic.IEC}%
+
+\tikzset{%
+ use IEC style logic gates/.code={%
+ \tikzset{%
+ and gate/.style={shape=and gate IEC},
+ nand gate/.style={shape=nand gate IEC},
+ or gate/.style={shape=or gate IEC},
+ nor gate/.style={shape=nor gate IEC},
+ xor gate/.style={shape=xor gate IEC},
+ xnor gate/.style={shape=xnor gate IEC},
+ not gate/.style={shape=not gate IEC},
+ buffer gate/.style={shape=buffer gate IEC},
+ and gate symbol/.style={and gate IEC symbol={##1}},
+ nand gate symbol/.style={nand gate IEC symbol={##1}},
+ or gate symbol/.style={or gate IEC symbol={##1}},
+ nor gate symbol/.style={nor gate IEC symbol={##1}},
+ xor gate symbol/.style={xor gate IEC symbol={##1}},
+ xnor gate symbol/.style={xnor gate IEC symbol={##1}},
+ not gate symbol/.style={not gate IEC symbol={##1}},
+ buffer gate symbol/.style={buffer gate IEC symbol={##1}},
+ logic gate symbol align/.style={/pgf/logic gate IEC symbol align={##1}},
+ logic gate symbol color/.style={/pgf/logic gate IEC symbol color={##1}}
+ }%
+ }%
+}%
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.US.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.US.code.tex
new file mode 100644
index 0000000000..66503414a0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.US.code.tex
@@ -0,0 +1,40 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.gates.logic.US.code.tex}
+
+\usepgflibrary{shapes.gates.logic.US}%
+
+\tikzset{%
+ use US style logic gates/.code={%
+ \tikzset{%
+ and gate/.style={shape=and gate US},
+ nand gate/.style={shape=nand gate US},
+ or gate/.style={shape=or gate US},
+ nor gate/.style={shape=nor gate US},
+ xor gate/.style={shape=xor gate US},
+ xnor gate/.style={shape=xnor gate US},
+ not gate/.style={shape=not gate US},
+ buffer gate/.style={shape=buffer gate US}
+ }%
+ },
+ use CDH style logic gates/.code={%
+ \tikzset{%
+ and gate/.style={shape=and gate CDH},
+ nand gate/.style={shape=nand gate CDH},
+ or gate/.style={shape=or gate US},
+ nor gate/.style={shape=nor gate US},
+ xor gate/.style={shape=xor gate US},
+ xnor gate/.style={shape=xnor gate US},
+ not gate/.style={shape=not gate US},
+ buffer gate/.style={shape=buffer gate US}
+ }
+ }
+}%
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.geometric.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.geometric.code.tex
new file mode 100644
index 0000000000..3e923b940f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.geometric.code.tex
@@ -0,0 +1,14 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.geometric.code.tex}
+
+\usepgflibrary{shapes.geometric}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.misc.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.misc.code.tex
new file mode 100644
index 0000000000..617c5f4034
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.misc.code.tex
@@ -0,0 +1,14 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.misc.code.tex}
+
+\usepgflibrary{shapes.misc}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.multipart.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.multipart.code.tex
new file mode 100644
index 0000000000..91183aaf78
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.multipart.code.tex
@@ -0,0 +1,36 @@
+% Copyright 2018 by Till Tantau and Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.multipart.code.tex}
+
+\usepgflibrary{shapes.multipart}%
+
+\pgfkeys{/tikz/rectangle split/parts/.code={%
+ \pgfkeys{/pgf/rectangle split parts={#1}}%
+ }%
+}%
+
+\pgfkeys{/tikz/rectangle split use custom fill/.code={%
+ \pgfkeys{/pgf/rectangle split use custom fill={#1}}%
+ \pgfkeys{/tikz/fill=none}}%
+}%
+
+\pgfkeys{/tikz/rectangle split draw splits/.is if=pgfrectanglesplitdrawsplits}%
+
+\pgfkeys{/tikz/rectangle split part align/.code={%
+ \pgfkeys{/pgf/rectangle split part align={#1}}%
+ }%
+}%
+
+\pgfkeys{/tikz/rectangle split part fill/.code={%
+ \pgfkeys{/pgf/rectangle split part fill={#1}}%
+ }%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.symbols.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.symbols.code.tex
new file mode 100644
index 0000000000..b616b54c88
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryshapes.symbols.code.tex
@@ -0,0 +1,17 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryshapes.symbols.code.tex}
+
+\pgfkeysifdefined{/tikz/shape border uses incircle}{}{%
+ \pgfkeys{/tikz/shape border uses incircle/.is if=pgfshapeborderusesincircle}}%
+
+\usepgflibrary{shapes.symbols}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex
new file mode 100644
index 0000000000..9acb6de915
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex
@@ -0,0 +1,77 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarysnakes.code.tex}
+
+\pgfwarning{Snakes have been superseded by
+decorations. Please use the decoration libraries instead of the snakes
+library}%
+
+\usetikzlibrary{decorations.pathmorphing,decorations.pathreplacing,decorations.shapes}%
+
+
+% Old snakes stuff:
+
+\tikzoption{snake}[]{%
+ \def\tikz@@snake{#1}%
+ \ifx\tikz@@snake\pgfutil@empty%
+ \tikz@snakedtrue%
+ \else%
+ \ifx\tikz@@snake\tikz@nonetext%
+ \tikz@snakedfalse%
+ \else%
+ \tikz@snakedtrue%
+ \let\tikz@snake=\tikz@@snake%
+ \fi%
+ \fi}%
+
+\tikzoption{raise snake}{\def\pgf@snake@raise{\pgftransformyshift{#1}}}%
+\tikzoption{mirror snake}[true]{%
+ \csname if#1\endcsname
+ \def\pgf@snake@mirror{\pgftransformyscale{-1}}%
+ \else%
+ \let\pgf@snake@mirror=\pgfutil@empty%
+ \fi
+}%
+
+\tikzoption{gap before snake}{\def\tikz@presnake{{moveto}{#1}{\noexpand\tikz@snake@install@trans}{}}}%
+\tikzoption{line before snake}{\def\tikz@presnake{{lineto}{#1}{\noexpand\tikz@snake@install@trans}{}}}%
+
+\tikzoption{gap after snake}{\def\tikz@postsnake{{moveto}{#1}{\noexpand\tikz@snake@install@trans}{}}\def\tikz@mainsnakelength{\pgfsnakeremainingdistance-#1}}%
+\tikzoption{line after snake}{\def\tikz@postsnake{{lineto}{#1}{\noexpand\tikz@snake@install@trans}{}}\def\tikz@mainsnakelength{\pgfsnakeremainingdistance-#1}}%
+
+\tikzoption{gap around snake}{%
+ \def\tikz@presnake{{moveto}{#1}{\noexpand\tikz@snake@install@trans}{}}%
+ \def\tikz@postsnake{{moveto}{#1}{\noexpand\tikz@snake@install@trans}{}}%
+ \def\tikz@mainsnakelength{\pgfsnakeremainingdistance-#1}%
+}%
+\tikzoption{line around snake}{%
+ \def\tikz@presnake{{lineto}{#1}{\noexpand\tikz@snake@install@trans}{}}%
+ \def\tikz@postsnake{{lineto}{#1}{\noexpand\tikz@snake@install@trans}{}}%
+ \def\tikz@mainsnakelength{\pgfsnakeremainingdistance-#1}%
+}%
+\let\pgf@snake@mirror=\pgfutil@empty
+\let\pgf@snake@raise=\pgfutil@empty
+
+\def\tikz@snake@install@trans{\pgfsetsnakesegmenttransformation{\pgf@snake@mirror\pgf@snake@raise}}%
+
+\def\tikz@snake{zigzag}%
+
+\let\tikz@presnake=\pgfutil@empty
+\let\tikz@postsnake=\pgfutil@empty
+\def\tikz@mainsnakelength{\pgfsnakeremainingdistance}%
+
+
+\tikzset{snake triangles 45/.style= {snake=triangles,segment object length=2.41421356\pgfsnakesegmentamplitude}}%
+\tikzset{snake triangles 60/.style= {snake=triangles,segment object length=1.73205081\pgfsnakesegmentamplitude}}%
+\tikzset{snake triangles 90/.style= {snake=triangles,segment object length=\pgfsnakesegmentamplitude}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex
new file mode 100644
index 0000000000..a5fea2a79b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex
@@ -0,0 +1,134 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryspy.code.tex}
+
+
+
+% Spy styles
+
+\tikzset{
+ spy using outlines/.style={
+ spy scope={
+ every spy on node/.style={very thin,draw},
+ every spy in node/.style={thick,draw},
+ #1
+ }
+ },
+ spy using overlays/.style={
+ spy scope={
+ every spy on node/.style={fill,fill opacity=0.2,text opacity=1},
+ every spy in node/.style={fill,fill opacity=0.2,text opacity=1},
+ #1
+ }
+ },
+ connect spies/.style={
+ spy connection path={\draw[thin] (tikzspyonnode) -- (tikzspyinnode);}
+ }
+}%
+
+\newbox\tikz@lib@spybox
+
+\let\tikz@lib@spy@collection=\pgfutil@empty%
+
+\tikzset{spy scope/.style={
+ size/.style={minimum size={##1}},
+ height/.style={minimum height={##1}},
+ width/.style={minimum width={##1}},
+ execute at begin scope={%
+ \let\tikz@lib@spy@save=\tikz@lib@spy@collection%
+ \setbox\tikz@lib@spybox=\hbox\bgroup\bgroup%
+ \let\spy=\tikz@lib@spy@parse},
+ execute at end scope={%
+ \egroup\egroup%
+ {%
+ \copy\tikz@lib@spybox%
+ \tikz@lib@spy@collection%
+ }%
+ \global\let\tikz@lib@spy@collection=\tikz@lib@spy@save%
+ },%
+ tikz@lib@spy@style/.style={#1},
+ tikz@lib@reset@gs
+ },
+ lens/.store in=\tikz@lib@spy@lens,
+ lens=,
+ magnification/.style={lens={scale={#1}}},
+ spy connection path/.store in=\tikz@lib@spy@path,
+ spy connection path=
+}%
+
+\tikzset{
+ tikz@lib@reset@gs/.style={black,thin,solid,opaque,line cap=butt,line join=miter}
+}%
+
+\def\tikz@lib@spy@parse{%
+ \pgfutil@ifnextchar[{\tikz@lib@spy@parse@opt}{\tikz@lib@spy@parse@opt[]}%]
+}%
+\def\tikz@lib@spy@parse@opt[#1]{
+ \pgfutil@ifnextchar x{\tikz@lib@spy@parse@opta[#1]}{\tikz@lib@spy@parse@opta[#1]}%]
+}%
+\def\tikz@lib@spy@parse@opta[#1]on#2in node#3;{%
+ \pgfutil@g@addto@macro\tikz@lib@spy@collection{\tikz@lib@spy@do{#1}{#2}{#3}}%
+}%
+
+\def\tikz@lib@spy@do#1#2#3{%
+ \scope[tikz@lib@spy@style,#1]
+ \node [alias=tikzspyonnode,inner sep=0pt,outer sep=0pt,every spy on node/.try,
+ /utils/exec={
+ {%
+ \let\tikz@transform=\relax
+ \pgftransformreset%
+ \expandafter\tikzset\expandafter{\tikz@lib@spy@lens}
+ \pgftransforminvert%
+ \pgfgettransformentries\a\b\c\d\e\f%
+ \global\let\pgf@lib@svg@a=\a%
+ \global\let\pgf@lib@svg@b=\b%
+ \global\let\pgf@lib@svg@c=\c%
+ \global\let\pgf@lib@svg@d=\d%
+ }%
+ \tikz@addtransform{%
+ \tikz@scan@one@point\pgftransformshift#2%
+ \pgftransformcm{\pgf@lib@svg@a}{\pgf@lib@svg@b}{\pgf@lib@svg@c}{\pgf@lib@svg@d}{\pgfpointorigin}%
+ }
+ }]{};
+ \expandafter\pgfutil@switch\expandafter\pgfutil@ifstrequal\expandafter{\tikz@anchor}{%
+ {north} {\def\tikz@spy@anchor{south}}%
+ {north east}{\def\tikz@spy@anchor{south west}}%
+ {east} {\def\tikz@spy@anchor{west}}%
+ {south east}{\def\tikz@spy@anchor{north west}}%
+ {south} {\def\tikz@spy@anchor{north}}%
+ {south west}{\def\tikz@spy@anchor{north east}}%
+ {west} {\def\tikz@spy@anchor{east}}%
+ {north west}{\def\tikz@spy@anchor{south east}}%
+ }{}{\def\tikz@spy@anchor{center}}%
+ \node [alias=tikzspyinnode,inner sep=0pt,outer sep=0pt,at={#2},every spy in node/.try,
+ path picture={\node[anchor=\tikz@spy@anchor,tikz@lib@reset@gs]{\nullfont%
+ \pgfpicture\relax\pgfsetbaseline{default}\pgfsettrimleft{default}\pgfsettrimright{default}%
+ \pgftransformreset%
+ \let\tikz@transform=\relax%
+ \expandafter\tikzset\expandafter{\tikz@lib@spy@lens}%
+ \pgflowlevelsynccm%
+ \tikz@scan@one@point\tikz@lib@spy@shift#2%
+ \pgflowlevelsynccm%
+ \copy\tikz@lib@spybox%
+ \endpgfpicture};}]#3{};
+ \tikz@lib@spy@path
+ \endscope
+}%
+
+\def\tikz@lib@spy@shift#1{%
+ \pgf@process{#1}%
+ \pgf@x=-\pgf@x%
+ \pgf@y=-\pgf@y%
+ \pgftransformshift{}%
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex
new file mode 100644
index 0000000000..521bf96b60
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex
@@ -0,0 +1,33 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarysvg.path.code.tex}
+
+\usepgflibrary{svg.path}%
+
+\def\tikz@svg@path vg{\pgfutil@ifnextchar[\tikz@svg@@path{\tikz@svg@@path[]}}%}%
+
+\def\tikz@svg@@path[#1]{\pgfutil@ifnextchar"{\tikz@svg@@path@old{#1}}{\tikz@svg@@path@new{#1}}}%
+\def\tikz@svg@@path@new#1#2{\tikz@svg@@path@old{#1}"#2"}%
+\def\tikz@svg@@path@old#1"#2"{
+ {%
+ \tikzset{#1}%
+ \pgfpathsvg{#2}%
+ }%
+ {
+ \pgftransforminvert
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{\pgf@path@lastx}{\pgf@path@lasty}}}
+ }
+ \tikz@lastx=\pgf@x%
+ \tikz@lasty=\pgf@y%
+ \tikz@lastxsaved=\tikz@lastx%
+ \tikz@lastysaved=\tikz@lasty%
+ \tikz@updatecurrenttrue%
+ \tikz@scan@next@command
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarythrough.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarythrough.code.tex
new file mode 100644
index 0000000000..986235b75b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarythrough.code.tex
@@ -0,0 +1,36 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarythrough.code.tex}
+
+
+
+\tikzset{circle through/.code={%
+ \pgfkeysalso{shape=circle,inner sep=0pt,outer sep=0pt}%
+ % Save transformations (correct?)
+ \pgfgettransform{\tikz@lib@saved@transform}%
+ \tikz@scan@one@point\tikz@lib@circle@through#1%
+ }}%
+
+\def\tikz@lib@circle@through#1{%
+ \tikz@addoption{%
+ {%
+ \pgfsettransform{\tikz@lib@saved@transform}%
+ \pgf@process{\pgfpointtransformed{#1}}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointtransformed{\tikz@node@at}}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \pgfmathparse{2*veclen(\the\pgf@xa,\the\pgf@ya)}%
+ \global\let\tikz@lib@circle@size=\pgfmathresult%
+ }%
+ \pgfset{/pgf/minimum size/.expanded=\tikz@lib@circle@size}%
+ }%
+}%
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex
new file mode 100644
index 0000000000..ecf850ab40
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex
@@ -0,0 +1,381 @@
+% Copyright 2020 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarytopaths.code.tex}
+
+
+% Move to
+
+\tikzset{move to/.style= {to path={(\tikztotarget) \tikztonodes}}}
+
+
+% Straight to
+
+\tikzset{line to/.style= {to path={-- (\tikztotarget) \tikztonodes}}}
+
+
+% Curved to
+
+\tikzset{every curve to/.style= {}}
+\tikzset{curve to/.style= {to path=\tikz@to@curve@path}}
+
+\tikzoption{bend angle}{\pgfmathsetmacro\tikz@to@bend{#1}}
+
+\tikzoption{bend left}[]{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgfmathsetmacro\tikz@to@bend{#1}%
+ \fi%
+ \let\tikz@to@out=\tikz@to@bend%
+ \pgfmathsetmacro\tikz@to@in{180-(\tikz@to@out)}%
+ \tikz@to@switch@on%
+ \tikz@to@relativetrue%
+}
+
+\tikzoption{bend right}[]{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgfmathsetmacro\tikz@to@bend{#1}%
+ \fi%
+ % Now, negate
+ \pgfmathsetmacro\tikz@to@out{-(\tikz@to@bend)}
+ \pgfmathsetmacro\tikz@to@in{180-(\tikz@to@out)}
+ \tikz@to@switch@on%
+ \tikz@to@relativetrue%
+}
+
+\tikzoption{relative}[true]{\csname tikz@to@relative#1\endcsname}
+\newif\iftikz@to@relative
+\tikz@to@relativefalse
+
+\tikzoption{in}{\def\tikz@to@in{#1}\tikz@to@switch@on}
+\tikzoption{out}{\def\tikz@to@out{#1}\tikz@to@switch@on}
+
+\tikzoption{in looseness}{\tikz@to@set@in@looseness{#1}}
+\tikzoption{out looseness}{\tikz@to@set@out@looseness{#1}}
+\tikzoption{looseness}{\tikz@to@set@in@looseness{#1}\tikz@to@set@out@looseness{#1}}
+
+\tikzoption{in control}{\tikz@to@set@in@control{#1}}
+\tikzoption{out control}{\tikz@to@set@out@control{#1}}
+\tikzoption{controls}{\tikz@to@parse@controls#1\pgf@stop}
+
+\tikzoption{in min distance}{\tikz@to@set@distances{#1}{}{}{}}
+\tikzoption{in max distance}{\tikz@to@set@distances{}{#1}{}{}}
+\tikzoption{in distance}{\tikz@to@set@distances{#1}{#1}{}{}}
+\tikzoption{out min distance}{\tikz@to@set@distances{}{}{#1}{}}
+\tikzoption{out max distance}{\tikz@to@set@distances{}{}{}{#1}}
+\tikzoption{out distance}{\tikz@to@set@distances{}{}{#1}{#1}}
+\tikzoption{min distance}{\tikz@to@set@distances{#1}{}{#1}{}}
+\tikzoption{max distance}{\tikz@to@set@distances{}{#1}{}{#1}}
+\tikzoption{distance}{\tikz@to@set@distances{#1}{#1}{#1}{#1}}
+
+\def\tikz@to@set@distances#1#2#3#4{%
+ \tikz@to@setifnotempy{#1}{\tikz@to@in@min}{\let\tikz@to@end@compute=\tikz@to@end@compute@looseness}%
+ \tikz@to@setifnotempy{#2}{\tikz@to@in@max}{\let\tikz@to@end@compute=\tikz@to@end@compute@looseness}%
+ \tikz@to@setifnotempy{#3}{\tikz@to@out@min}{\let\tikz@to@start@compute=\tikz@to@start@compute@looseness}%
+ \tikz@to@setifnotempy{#4}{\tikz@to@out@max}{\let\tikz@to@start@compute=\tikz@to@start@compute@looseness}%
+ \tikz@to@switch@on%
+}
+
+\def\tikz@to@setifnotempy#1#2#3{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty\else\def#2{#1}#3\fi%
+}
+
+
+\def\tikz@to@set@in@looseness#1{%
+ \pgfmathsetmacro\tikz@to@in@looseness{#1}%
+ \let\tikz@to@end@compute=\tikz@to@end@compute@looseness%
+ \tikz@to@switch@on%
+}
+\def\tikz@to@set@out@looseness#1{%
+ \pgfmathsetmacro\tikz@to@out@looseness{#1}%
+ \let\tikz@to@start@compute=\tikz@to@start@compute@looseness%
+ \tikz@to@switch@on%
+}
+
+\def\tikz@to@parse@controls#1and#2\pgf@stop{\tikz@to@set@in@control{#2}\tikz@to@set@out@control{#1}}
+
+\def\tikz@to@set@in@control#1{%
+ \def\tikz@to@in@control{#1}%
+ \let\tikz@to@end@compute=\tikz@to@end@compute@control%
+ \tikz@to@switch@on%
+}
+\def\tikz@to@set@out@control#1{%
+ \def\tikz@to@out@control{#1}%
+ \let\tikz@to@start@compute=\tikz@to@start@compute@control%
+ \tikz@to@switch@on%
+}
+
+
+\def\tikz@to@bend{30}
+
+\def\tikz@to@out{45}
+\def\tikz@to@in{135}
+
+\def\tikz@to@out@looseness{1}
+\def\tikz@to@in@looseness{1}
+
+\def\tikz@to@in@min{0pt}
+\def\tikz@to@in@max{10000pt}
+\def\tikz@to@out@min{0pt}
+\def\tikz@to@out@max{10000pt}
+
+\def\tikz@to@switch@on{\let\tikz@to@path=\tikz@to@curve@path}
+
+\def\tikz@to@curve@path{%
+ [every curve to]
+ \pgfextra{\iftikz@to@relative\tikz@to@compute@relative\else\tikz@to@compute\fi}
+ \tikz@computed@path
+ \pgfextra{\tikz@updatenexttrue\tikz@updatecurrenttrue}%
+ \tikztonodes%
+}
+
+\def\tikz@to@modify#1#2{%
+ \pgfutil@ifundefined{pgf@sh@ns@#1}
+ {}%
+ {\edef#1{#1.#2}}
+}%
+
+\def\tikz@to@compute{%
+ \let\tikz@tofrom=\tikztostart%
+ \let\tikz@toto=\tikztotarget%
+ \tikz@to@modify\tikz@tofrom\tikz@to@out%
+ \tikz@to@modify\tikz@toto\tikz@to@in%
+ \ifx\tikz@to@start@compute\tikz@to@start@compute@looseness%
+ \tikz@to@compute@distance%
+ \else%
+ \ifx\tikz@from@start@compute\tikz@to@start@compute@looseness%
+ \tikz@to@compute@distance%
+ \fi%
+ \fi%
+ \tikz@to@start@compute%
+ \tikz@to@end@compute%
+ \edef\tikz@computed@path{.. controls \tikz@computed@start and \tikz@computed@end .. (\tikztotarget)}
+}
+
+\def\tikz@to@compute@distance{\tikz@scan@one@point\tikz@@to@compute@distance(\tikz@tofrom)}
+\def\tikz@@to@compute@distance#1{%
+ \def\tikz@first@point{#1}%
+ \tikz@scan@one@point\tikz@@@to@compute@distance(\tikz@toto)}
+\def\tikz@@@to@compute@distance#1{%
+ \iftikz@updatecurrent\else
+ \tikz@updatenextfalse
+ \fi
+ \def\tikz@second@point{#1}%
+ \tikz@to@compute@distance@main%
+}
+\def\tikz@to@compute@distance@main{%
+ \pgf@process{\pgfpointdiff{\tikz@first@point}{\tikz@second@point}}%
+ \ifdim\pgf@x<0pt\pgf@xa=-\pgf@x\else\pgf@xa=\pgf@x\fi%
+ \ifdim\pgf@y<0pt\pgf@ya=-\pgf@y\else\pgf@ya=\pgf@y\fi%
+ %
+ % Calculate length of second to first vector:
+ %
+ \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
+ \ifdim\pgf@x>\pgf@y%
+ \c@pgf@counta=\pgf@x%
+ \ifnum\c@pgf@counta=0\relax%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@xa=16\pgf@xa\relax%
+ \divide\pgf@xa by\c@pgf@counta%
+ \pgf@xa=16\pgf@xa\relax%
+ \fi%
+ \else%
+ \c@pgf@counta=\pgf@y%
+ \ifnum\c@pgf@counta=0\relax%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@ya=16\pgf@ya\relax%
+ \divide\pgf@ya by\c@pgf@counta%
+ \pgf@xa=16\pgf@ya\relax%
+ \fi%
+ \fi%
+ \pgf@x=0.3915\pgf@xa%
+ \pgf@xa=\tikz@to@out@looseness\pgf@x%
+ \pgf@xb=\tikz@to@in@looseness\pgf@x%
+ % Adjust as necessary
+ \pgfmathsetlength{\pgf@ya}{\tikz@to@out@min}
+ \ifdim\pgf@xa<\pgf@ya%
+ \pgf@xa=\pgf@ya%
+ \fi%
+ \pgfmathsetlength{\pgf@ya}{\tikz@to@out@max}
+ \ifdim\pgf@xa>\pgf@ya%
+ \pgf@xa=\pgf@ya%
+ \fi%
+ \pgfmathsetlength{\pgf@ya}{\tikz@to@in@min}
+ \ifdim\pgf@xb<\pgf@ya%
+ \pgf@xb=\pgf@ya%
+ \fi%
+ \pgfmathsetlength{\pgf@ya}{\tikz@to@in@max}
+ \ifdim\pgf@xb>\pgf@ya%
+ \pgf@xb=\pgf@ya%
+ \fi%
+}
+
+\def\tikz@to@start@compute@looseness{%
+ \edef\tikz@computed@start{([shift=({\tikz@to@out}:\the\pgf@xa)]\tikz@tofrom)}%
+}
+\def\tikz@to@end@compute@looseness{%
+ \edef\tikz@computed@end{([shift=({\tikz@to@in}:\the\pgf@xb)]\tikz@toto)}%
+}
+\def\tikz@to@start@compute@control{%
+ \let\tikz@computed@start=\tikz@to@out@control%
+}
+\def\tikz@to@end@compute@control{%
+ \let\tikz@computed@end=\tikz@to@in@control%
+}
+
+\let\tikz@to@start@compute=\tikz@to@start@compute@looseness%
+\let\tikz@to@end@compute=\tikz@to@end@compute@looseness%
+
+
+
+
+% Relative curves
+
+\def\tikz@to@compute@relative{%
+ \tikz@scan@one@point\tikz@@to@compute@relative(\tikztostart)%
+}
+\def\tikz@@to@compute@relative#1{%
+ \def\tikz@tofrom{#1}%
+ \tikz@scan@one@point\tikz@@@to@compute@relative(\tikztotarget)%
+}
+\def\tikz@@@to@compute@relative#1{%
+ \def\tikz@toto{#1}%
+ \begingroup
+ %
+ % Adjust start and target so that they lie on the border in the
+ % rotated coordinate system.
+ %
+ \pgfutil@ifundefined{pgf@sh@ns@\tikztostart}
+ {%
+ \let\tikz@first@point=\tikz@tofrom%
+ \let\tikz@tostart@tikz=\pgfutil@empty
+ }%
+ {%
+ % Start computation of new start.
+ {%
+ \tikz@tofrom%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ {%
+ \pgftransformreset%
+ \pgftransformshift{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \pgftransformrotate{\tikz@to@out}%
+ \pgftransformshift{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}%
+ \pgf@process{\pgfpointtransformed{\tikz@toto}}%
+ }%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfpointshapeborder{\tikztostart}{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \xdef\tikz@tofrom@smuggle{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ }%
+ \let\tikz@first@point=\tikz@tofrom@smuggle%
+ \tikz@first@point%
+ \edef\tikz@tostart@tikz{(\the\pgf@x,\the\pgf@y)}%
+ }%
+ \pgfutil@ifundefined{pgf@sh@ns@\tikztotarget}
+ {%
+ \let\tikz@second@point=\tikz@toto%
+ }%
+ {%
+ % Start computation of new target.
+ {%
+ \tikz@toto%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ {%
+ \pgftransformreset%
+ \pgftransformshift{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \pgftransformrotate{180}%
+ \pgftransformrotate{\tikz@to@in}%
+ \pgftransformshift{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}%
+ \pgf@process{\pgfpointtransformed{\tikz@tofrom}}%
+ }%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfpointshapeborder{\tikztotarget}{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \xdef\tikz@toto@smuggle{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ }%
+ \let\tikz@second@point=\tikz@toto@smuggle%
+ }%
+ \tikz@second@point%
+ \edef\tikz@totarget@tikz{(\the\pgf@x,\the\pgf@y)}%
+ %
+ % Compute distances
+ %
+ \tikz@to@compute@distance@main%
+ \edef\tikz@to@first@distance{\the\pgf@xa}%
+ \edef\tikz@to@second@distance{\the\pgf@xb}%
+ %
+ % Next step: Establish a transformed coordinate system so that the (modified)
+ % start is at the origin and the (modified) target is at (1,0)
+ %
+ \pgftransformreset%
+ \pgf@process{\tikz@first@point}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\tikz@second@point}%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \pgfpointnormalised{}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@xb=-\pgf@x%
+ \pgf@yb=-\pgf@y%
+ %
+ % Now compute the control points.
+ %
+ {%
+ \pgftransformshift{\tikz@first@point}%
+ \pgftransformcm{\pgf@sys@tonumber\pgf@xc}{\pgf@sys@tonumber\pgf@yc}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xc}%
+ {\pgfpointorigin}%
+ \pgf@process{\pgfpointtransformed{\pgfpointpolar{\tikz@to@out}{\tikz@to@first@distance}}}%
+ \xdef\tikz@computed@start{(\the\pgf@x,\the\pgf@y)}%
+ }
+ {%
+ \pgftransformshift{\tikz@second@point}%
+ \pgftransformcm{\pgf@sys@tonumber\pgf@xc}{\pgf@sys@tonumber\pgf@yc}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xc}%
+ {\pgfpointorigin}%
+ \pgf@process{\pgfpointtransformed{\pgfpointpolar{\tikz@to@in}{\tikz@to@second@distance}}}%
+ \xdef\tikz@computed@end{(\the\pgf@x,\the\pgf@y)}%
+ }
+ \xdef\tikz@computed@path{
+ \tikz@tostart@tikz
+ .. controls \tikz@computed@start and \tikz@computed@end ..
+ \tikz@totarget@tikz}%
+ \endgroup
+}
+
+
+
+% Loops
+
+\tikzset{loop/.style= {to path={
+ \pgfextra{\let\tikztotarget=\tikztostart}
+ [looseness=8,min distance=5mm,every loop]
+ \tikz@to@curve@path
+ }}}
+
+\tikzset{every loop/.style= {->,shorten >=1pt}}
+
+\tikzset{loop right/.style= {right,out=15,in=-15,loop}}
+\tikzset{loop above/.style= {above,out=105,in=75,loop}}
+\tikzset{loop left/.style= {left,out=195,in=165,loop}}
+\tikzset{loop below/.style= {below,out=285,in=255,loop}}
+
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytrees.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytrees.code.tex
new file mode 100644
index 0000000000..d457f979b9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibrarytrees.code.tex
@@ -0,0 +1,109 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarytrees.code.tex}
+
+
+
+%
+% Three point growth
+%
+
+\tikzoption{grow via three points}{\let\tikz@grow=\tikz@grow@three\tikz@parse@three#1}%
+
+\def\tikz@parse@three one child at#1(#2)#3and two children at#4(#5)#6and#7(#8){%
+ \def\tikz@tree@one@child{\tikz@scan@one@point\pgf@process(#2)}
+ \def\tikz@tree@left@child{\tikz@scan@one@point\pgf@process(#5)}
+ \def\tikz@tree@right@child{\tikz@scan@one@point\pgf@process(#8)}
+}%
+
+\def\tikz@grow@three{%
+ \pgf@process{\tikz@tree@one@child}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\tikz@tree@left@child}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \pgf@process{\tikz@tree@right@child}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xc by-\pgf@xa%
+ \advance\pgf@yc by-\pgf@ya%
+ \advance\pgf@xc by-\pgf@xb%
+ \advance\pgf@yc by-\pgf@yb%
+ \advance\tikznumberofchildren by-1\relax%
+ \pgf@xb=\tikznumberofchildren\pgf@xb\relax%
+ \pgf@yb=\tikznumberofchildren\pgf@yb\relax%
+ \advance\tikznumberofcurrentchild by-1\relax%
+ \pgf@xc=\tikznumberofcurrentchild\pgf@xc\relax%
+ \pgf@yc=\tikznumberofcurrentchild\pgf@yc\relax%
+ \advance\pgf@xa by\pgf@xb%
+ \advance\pgf@xa by\pgf@xc%
+ \advance\pgf@ya by\pgf@yb%
+ \advance\pgf@ya by\pgf@yc%
+ \edef\pgf@temp{\noexpand\pgftransformshift{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}}%
+ \pgf@temp%
+}%
+
+
+
+%
+% Circle grow
+%
+
+\tikzset{
+ grow cyclic/.style={
+ edge from parent/.append style={reset cm},
+ growth function=\tikz@grow@circle,
+ }
+}%
+
+\tikzset{sibling angle/.initial=20}%
+
+\def\tikz@grow@circle{%
+ \pgftransformrotate{%
+ (\pgfkeysvalueof{/tikz/sibling angle})*(-.5-.5*\tikznumberofchildren+\tikznumberofcurrentchild)}%
+ \pgftransformxshift{\the\tikzleveldistance}%
+}%
+
+\tikzoption{counterclockwise from}{\let\tikz@grow=\tikz@grow@circle@from\def\tikz@grow@circle@from@start{#1}}%
+
+\def\tikz@grow@circle@from{%
+ \pgftransformshift{\pgfpointpolar{\tikz@grow@circle@from@start+(\pgfkeysvalueof{/tikz/sibling angle})*(\tikznumberofcurrentchild-1)}{\the\tikzleveldistance}}%
+}%
+
+\tikzoption{clockwise from}{\let\tikz@grow=\tikz@grow@circle@from@\def\tikz@grow@circle@from@start{#1}}%
+
+\def\tikz@grow@circle@from@{%
+ \pgftransformshift{\pgfpointpolar{\tikz@grow@circle@from@start-(\pgfkeysvalueof{/tikz/sibling angle})*(\tikznumberofcurrentchild-1)}{\the\tikzleveldistance}}%
+}%
+
+
+
+%
+% Connections
+%
+
+\tikzset{edge from parent fork down/.style=
+ {edge from parent path={(\tikzparentnode\tikzparentanchor) -- +(0pt,-.5\tikzleveldistance) -| (\tikzchildnode\tikzchildanchor)}}}%
+
+\tikzset{edge from parent fork up/.style=
+ {edge from parent path={(\tikzparentnode\tikzparentanchor) -- +(0pt,.5\tikzleveldistance) -| (\tikzchildnode\tikzchildanchor)}}}%
+
+\tikzset{edge from parent fork left/.style=
+ {edge from parent path={(\tikzparentnode\tikzparentanchor) -- +(-.5\tikzleveldistance,0pt) |- (\tikzchildnode\tikzchildanchor)}}}%
+
+\tikzset{edge from parent fork right/.style=
+ {edge from parent path={(\tikzparentnode\tikzparentanchor) -- +(.5\tikzleveldistance,0pt) |- (\tikzchildnode\tikzchildanchor)}}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryturtle.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryturtle.code.tex
new file mode 100644
index 0000000000..889806f8d5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryturtle.code.tex
@@ -0,0 +1,84 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryturtle.code.tex}
+
+
+\tikzset{turtle/.style={/tikz/turtle/.cd,#1}}%
+
+% The current angle is stored in this key.
+\tikzset{turtle/direction/.code=\gdef\tikz@lib@turtle@dir{#1},turtle/direction=90}%
+
+% The current angle is stored in this key.
+\tikzset{turtle/distance/.initial=1cm}%
+
+% The to path options that are used to move the turtle
+\tikzset{turtle/how/.style=}%
+
+% Let the turtle jump home
+\tikzset{turtle/home/.style={/tikz/insert path={(0,0) [turtle/direction=90]}}}%
+
+% Moves the turtle forward by the given distance or, if no distance is
+% given, by turtle distance
+\tikzset{
+ turtle/forward/.default=\pgfkeysvalueof{/tikz/turtle/distance},
+ turtle/forward/.style={/tikz/insert path={to[/tikz/turtle/how]++({\tikz@lib@turtle@dir}:{#1})}}
+}%
+
+
+
+% Moves the turtle backward by the given distance or, if no distance is
+% given, by turtle distance
+\tikzset{
+ turtle/back/.default=\pgfkeysvalueof{/tikz/turtle/distance},
+ turtle/back/.style={turtle forward={-(#1)}}
+}%
+
+
+
+% Turns the turtle left by the given number of degrees
+\tikzset{
+ turtle/left/.default=90,
+ turtle/left/.code={%
+ \pgfmathparse{(#1)+(\tikz@lib@turtle@dir)}%
+ \ifdim\pgfmathresult pt>360pt\relax%
+ \pgfmathparse{\pgfmathresult-360}%
+ \fi%
+ \global\let\tikz@lib@turtle@dir\pgfmathresult
+ }
+}%
+
+
+% Turns the turtle left by the given number of degrees
+\tikzset{
+ turtle/right/.default=90,
+ turtle/right/.code={%
+ \pgfmathparse{#1}
+ \pgfmathparse{(\tikz@lib@turtle@dir)-\pgfmathresult}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathparse{\pgfmathresult+360}%
+ \fi%
+ \global\let\tikz@lib@turtle@dir\pgfmathresult
+ }
+}%
+
+
+% Shortcuts:
+\tikzset{turtle/.cd,
+ fd/.style={forward={#1}},
+ fd/.default=\pgfkeysvalueof{/tikz/turtle/distance},
+ bk/.style={back={#1}},
+ bk/.default=\pgfkeysvalueof{/tikz/turtle/distance},
+ lt/.style={left={#1}},
+ lt/.default=90,
+ rt/.style={right={#1}},
+ rt/.default=90}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryviews.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryviews.code.tex
new file mode 100644
index 0000000000..8ced1b64f3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/libraries/tikzlibraryviews.code.tex
@@ -0,0 +1,45 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibraryviews.code.tex}
+
+
+\tikzset{
+ meet/.style={execute at begin scope={\tikz@lib@view@parse{meet}#1\pgf@stop},execute at end scope={\endpgfviewboxscope}},
+ view/.style={meet = {#1}},
+ slice/.style={execute at begin scope={\tikz@lib@view@parse{slice}#1\pgf@stop},execute at end scope={\endpgfviewboxscope}},
+}%
+
+\def\tikz@lib@view@parse#1#2\pgf@stop{%
+ \tikz@scan@one@point\tikz@lib@view@a#2\pgf@stop%
+ \pgfviewboxscope{\tikz@lib@view@stored@a}{\tikz@lib@view@stored@b}{\tikz@lib@view@stored@c}{\tikz@lib@view@stored@d}{#1}%
+}%
+\def\tikz@lib@view@a#1{%
+ \def\tikz@lib@view@stored@a{#1}%
+ \pgfutil@ifnextchar r{\tikz@lib@view@a@rec}{\tikz@scan@one@point\tikz@lib@view@b}%
+}%
+\def\tikz@lib@view@a@rec rectangle{\tikz@scan@one@point\tikz@lib@view@b}%
+\def\tikz@lib@view@b#1{%
+ \def\tikz@lib@view@stored@b{#1}%
+ \pgfutil@ifnextchar\pgf@stop{%
+ \let\tikz@lib@view@stored@c\tikz@lib@view@stored@a%
+ \let\tikz@lib@view@stored@d\tikz@lib@view@stored@b%
+ \pgfutil@gobble%
+ }{\tikz@lib@view@b@at}%
+}%
+\def\tikz@lib@view@b@at at{\tikz@scan@one@point\tikz@lib@view@c}%
+\def\tikz@lib@view@c#1{%
+ \def\tikz@lib@view@stored@c{#1}%
+ \pgfutil@ifnextchar r{\tikz@lib@view@c@rec}{\tikz@scan@one@point\tikz@lib@view@d}%
+}%
+\def\tikz@lib@view@c@rec rectangle{\tikz@scan@one@point\tikz@lib@view@d}%
+\def\tikz@lib@view@d#1{\def\tikz@lib@view@stored@d{#1}\pgfutil@ifnextchar\pgf@stop\pgfutil@gobble{\tikzerror{Wrong syntax for meet or slice key}}}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/frontendlayer/tikz/tikz.code.tex b/graphics/pgf/base/tex/generic/frontendlayer/tikz/tikz.code.tex
new file mode 100644
index 0000000000..9b76858b3a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/frontendlayer/tikz/tikz.code.tex
@@ -0,0 +1,5599 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesPackageRCS{tikz.code.tex}
+
+
+\def\tikzerror#1{\pgfutil@packageerror{tikz}{#1}{}}
+
+% Always-present libraries (|\usepgflibrary| defined in
+% \file{pgfutil-common.tex}).
+\usepgflibrary{plothandlers}
+
+\newdimen\tikz@lastx
+\newdimen\tikz@lasty
+\newdimen\tikz@lastxsaved
+\newdimen\tikz@lastysaved
+\newdimen\tikz@lastmovetox
+\newdimen\tikz@lastmovetoy
+
+\newdimen\tikzleveldistance
+\newdimen\tikzsiblingdistance
+
+\newbox\tikz@figbox
+\newbox\tikz@figbox@bg
+\newbox\tikz@tempbox
+\newbox\tikz@tempbox@bg
+
+\newcount\tikztreelevel
+\newcount\tikznumberofchildren
+\newcount\tikznumberofcurrentchild
+
+\newcount\tikz@fig@count
+
+\newif\iftikz@node@is@a@label
+\newif\iftikz@snaked
+\newif\iftikz@decoratepath
+
+\let\tikz@options\pgfutil@empty
+% |\tikz@addoption| adds \texttt{#1} at the end of the replacement
+% text of |\tikz@options| without expansion.
+\def\tikz@addoption#1{%
+ \expandafter\def\expandafter\tikz@options\expandafter{\tikz@options#1}}%
+% Same as |tikz@addoption| for |\tikz@mode|. Note that |\tikz@mode| is
+% initially let to |\pgfutil@empty| later (see path usage options).
+\def\tikz@addmode#1{%
+ \expandafter\def\expandafter\tikz@mode\expandafter{\tikz@mode#1}}%
+% Same as |tikz@addoption| for |\tikz@transform|. Works even if
+% |\tikz@transform| is not defined. In that case, nothing is added to
+% |\tikz@transform|: \texttt{#1} is expanded.
+\def\tikz@addtransform#1{%
+ \ifx\tikz@transform\relax
+ #1%
+ \else
+ \expandafter\def\expandafter\tikz@transform\expandafter{\tikz@transform#1}%
+ \fi
+}%
+
+
+% TikZ options management.
+
+% Setting up the tikz key family (key management needs
+% \file{pgfkeys.code.tex});
+\pgfkeys{/tikz/.is family}%
+
+% |\tikzset| is a shortcut to set keys that belongs to the tikz
+% family.
+\def\tikzset{\pgfqkeys{/tikz}}%
+
+% Note: |\tikzoption| is supported for compatibility only. |\tikzset|
+% should be used instead.
+\def\tikzoption#1{%
+ \pgfutil@ifnextchar[%]
+ {\tikzoption@opt{#1}}{\tikzoption@noopt{#1}}}%
+\def\tikzoption@opt#1[#2]#3{%
+ \pgfkeysdef{/tikz/#1}{#3}%
+ \pgfkeyssetvalue{/tikz/#1/.@def}{#2}}%
+\def\tikzoption@noopt#1#2{%
+ \pgfkeysdef{/tikz/#1}{#2}%
+ \pgfkeyssetvalue{/tikz/#1/.@def}{\pgfkeysvaluerequired}}%
+
+% Baseline options
+\tikzoption{baseline}[0pt]{%
+ \pgfutil@ifnextchar(%)
+ {\tikz@baseline@coordinate}{\tikz@baseline@simple}#1\@nil}%
+\def\tikz@baseline@simple#1\@nil{\pgfsetbaseline{#1}}%
+\def\tikz@baseline@coordinate#1\@nil{%
+ \pgfsetbaselinepointlater{\tikz@scan@one@point\pgfutil@firstofone#1}}%
+
+\tikzoption{trim left}[0pt]{\pgfutil@ifnextchar({\tikz@trim@coordinate{left}}{\tikz@trim@simple{left}}#1\@nil}%)%
+\tikzoption{trim right}{\pgfutil@ifnextchar({\tikz@trim@coordinate{right}}{\tikz@trim@simple{right}}#1\@nil}%)%
+\def\tikz@trim@simple#1#2\@nil{\csname pgfsettrim#1\endcsname{#2}}%
+\def\tikz@trim@coordinate#1#2\@nil{\csname pgfsettrim#1pointlater\endcsname{\tikz@scan@one@point\pgfutil@firstofone#2}}%
+
+% Draw options
+\tikzoption{line width}{\tikz@semiaddlinewidth{#1}}%
+
+\def\tikz@semiaddlinewidth#1{\tikz@addoption{\pgfsetlinewidth{#1}}\pgfmathsetlength\pgflinewidth{#1}}%
+
+\tikzoption{cap}{\tikz@addoption{\csname pgfset#1cap\endcsname}}%
+\tikzoption{join}{\tikz@addoption{\csname pgfset#1join\endcsname}}%
+\tikzoption{line cap}{\tikz@addoption{\csname pgfset#1cap\endcsname}}%
+\tikzoption{line join}{\tikz@addoption{\csname pgfset#1join\endcsname}}%
+\tikzoption{miter limit}{\tikz@addoption{\pgfsetmiterlimit{#1}}}%
+
+\tikzoption{dash pattern}{% syntax: on 2pt off 3pt on 4pt ...
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\pgfutil@empty%
+ \def\tikz@dashpattern{}%
+ \tikz@addoption{\pgfsetdash{}{0pt}}%
+ \else%
+ \def\tikz@dashpattern{}%
+ \expandafter\tikz@scandashon\pgfutil@gobble#1o\@nil%
+ \edef\tikz@temp{{\tikz@dashpattern}{\noexpand\tikz@dashphase}}%
+ \expandafter\tikz@addoption\expandafter{\expandafter\pgfsetdash\tikz@temp}%
+ \fi}%
+\tikzoption{dash phase}{%
+ \def\tikz@dashphase{#1}%
+ \edef\tikz@temp{{\tikz@dashpattern}{\noexpand\tikz@dashphase}}%
+ \expandafter\tikz@addoption\expandafter{\expandafter\pgfsetdash\tikz@temp}%
+}%
+\tikzoption{dash}{\tikz@parse@full@dash#1\pgf@stop}%
+\def\tikz@parse@full@dash#1phase#2\pgf@stop{%
+ \def\tikz@dashphase{#2}%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\pgfutil@empty%
+ \def\tikz@dashpattern{}%
+ \tikz@addoption{\pgfsetdash{}{0pt}}%
+ \else%
+ \def\tikz@dashpattern{}%
+ \expandafter\tikz@scandashon\pgfutil@gobble#1o\@nil%
+ \edef\tikz@temp{{\tikz@dashpattern}{\noexpand\tikz@dashphase}}%
+ \expandafter\tikz@addoption\expandafter{\expandafter\pgfsetdash\tikz@temp}%
+ \fi%
+}%
+\def\tikz@dashphase{0pt}%
+\def\tikz@dashpattern{}%
+
+\def\tikz@scandashon n#1o{%
+ \expandafter\def\expandafter\tikz@dashpattern\expandafter{\tikz@dashpattern{#1}}%
+ \pgfutil@ifnextchar\@nil{\pgfutil@gobble}{\tikz@scandashoff}}%
+\def\tikz@scandashoff ff#1o{%
+ \expandafter\def\expandafter\tikz@dashpattern\expandafter{\tikz@dashpattern{#1}}%
+ \pgfutil@ifnextchar\@nil{\pgfutil@gobble}{\tikz@scandashon}}%
+
+% use a decoration to expand the `off' section of a dash pattern.
+% https://tex.stackexchange.com/a/133357
+\tikzset{
+ dash expand off/.code={%
+ \ifcsname tikz@library@decorations@loaded\endcsname\else
+ \tikzerror{You need \string\usetikzlibrary{decorations} for ``dash expand off''}%
+ \fi
+ \tikz@addoption{%
+ \pgfgetpath\currentpath
+ \pgfprocessround{\currentpath}{\currentpath}%
+ \pgf@decorate@parsesoftpath{\currentpath}{\currentpath}%
+ % All of \on, \off, \dashphase, \rest, and \onoff are unit-free.
+ % Parse \on and \off from the current path
+ \pgfmathsetmacro\on{\expandafter\pgfutil@firstoftwo\tikz@dashpattern}%
+ \pgfmathsetmacro\off{\expandafter\pgfutil@secondoftwo\tikz@dashpattern}%
+ % \dashphase = max(\on - \dashphase, 0)
+ \pgfmathsetmacro\tikz@dashphase{\tikz@dashphase}%
+ \pgfmathsubtract@{\on}{\tikz@dashphase}%
+ \pgfmathmax@{\pgfmathresult,0}%
+ \let\dashphase=\pgfmathresult
+ % \rest = \pgf@decorate@totalpathlength - \on + 2\dashphase
+ \edef\rest{\pgf@sys@tonumber\dimexpr\pgf@decorate@totalpathlength - \on pt + 2\dimexpr\dashphase pt\relax\relax}%
+ % \onoff = \on + \off
+ \edef\onoff{\pgf@sys@tonumber\dimexpr\on pt+\off pt\relax}%
+ % \nfullonoff = max(floor(\rest/\onoff), 1)
+ \pgfmathdivide@{\rest}{\onoff}%
+ \pgfmathfloor@{\pgfmathresult}%
+ \pgfmathmax@{\pgfmathresult,1}%
+ % \offexpand = max(\rest/\nfullonoff - \on, \off)
+ \pgfmathdivide@{\rest}{\pgfmathresult}%
+ \pgfmathsubtract@{\pgfmathresult}{\on}%
+ \pgfmathmax@{\pgfmathresult,\off}%
+ \edef\tikz@marshal{\noexpand\pgfsetdash{{+\on pt}{+\pgfmathresult pt}}{+\dashphase pt}}%
+ \tikz@marshal
+ }%
+ }
+}
+
+\tikzoption{draw opacity}{\tikz@addoption{\pgfsetstrokeopacity{#1}}}%
+
+% Double draw options
+\tikzoption{double}[]{%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@nonetext%
+ \tikz@addmode{\tikz@mode@doublefalse}%
+ \else%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \pgfsetinnerstrokecolor{#1}%
+ \fi%
+ \tikz@addmode{\tikz@mode@doubletrue}%
+ \tikzset{every double/.try}%
+ \fi}%
+\tikzoption{double distance}{%
+ \pgfmathsetlength{\pgf@x}{#1}%
+ \edef\tikz@double@setup{%
+ \pgf@x=\the\pgf@x%
+ \advance\pgf@x by2\pgflinewidth%
+ \pgflinewidth=\pgf@x%
+ \noexpand\pgfsetlinewidth{\pgflinewidth}%
+ \noexpand\pgfsetinnerlinewidth{\the\pgf@x}%
+ }%
+ \tikzset{double}}%
+\def\tikz@double@setup{%
+ \pgf@x=2\pgflinewidth%
+ \advance\pgf@x by0.6pt%
+ \pgflinewidth=\pgf@x%
+ \pgfsetlinewidth{\pgflinewidth}%
+ \pgfsetinnerlinewidth{0.6pt}%
+}%
+\tikzset{double distance between line centers/.code={
+ \pgfmathsetlength{\pgf@x}{#1}%
+ \edef\tikz@double@setup{%
+ \pgf@x=\pgflinewidth%
+ \pgf@xa=\the\pgf@x%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@xa by-\pgflinewidth%
+ \pgflinewidth=\pgf@x%
+ \noexpand\pgfsetlinewidth{\pgflinewidth}%
+ \noexpand\pgfsetinnerlinewidth{\pgf@xa}%
+ }%
+ \tikzset{double}}}%
+\tikzset{double equal sign distance/.style={double distance between line centers=0.45ex}}%
+
+
+
+
+% Fill options
+
+\tikzoption{even odd rule}[]{\tikz@addoption{\pgfseteorule}}%
+\tikzoption{nonzero rule}[]{\tikz@addoption{\pgfsetnonzerorule}}%
+
+\tikzoption{fill opacity}{\tikz@addoption{\pgfsetfillopacity{#1}}}%
+
+
+% Joined fill/draw options
+
+\tikzoption{opacity}{\tikz@addoption{\pgfsetstrokeopacity{#1}\pgfsetfillopacity{#1}}}%
+
+
+% Blend mode
+
+\tikzset{blend mode/.code={\tikz@addoption{\pgfsetblendmode{#1}}}}%
+
+
+% Main color options
+\tikzoption{color}{%
+ \tikz@addoption{%
+ \ifx\tikz@fillcolor\pgfutil@empty%
+ \ifx\tikz@strokecolor\pgfutil@empty%
+ \else%
+ \pgfsys@color@reset@inorderfalse%
+ \let\tikz@strokecolor\pgfutil@empty%
+ \let\tikz@fillcolor\pgfutil@empty%
+ \fi%
+ \else%
+ \pgfsys@color@reset@inorderfalse%
+ \let\tikz@strokecolor\pgfutil@empty%
+ \let\tikz@fillcolor\pgfutil@empty%
+ \fi%
+ \pgfutil@colorlet{tikz@color}{#1}%
+ \pgfutil@colorlet{.}{tikz@color}%
+ %
+ \pgfsetcolor{.}%
+ \pgfsys@color@reset@inordertrue%
+ }%
+ \def\tikz@textcolor{#1}}%
+
+
+
+% Rounding options
+\tikzoption{rounded corners}[4pt]{\pgfsetcornersarced{\pgfpoint{#1}{#1}}}%
+\tikzoption{sharp corners}[]{\pgfsetcornersarced{\pgfpointorigin}}%
+
+% Radii and arc options
+\tikzset{x radius/.initial=0pt}%
+\tikzset{y radius/.initial=0pt}%
+\tikzset{%
+ radius/.code={%
+ \pgfmathparse{#1}%
+ \ifpgfmathunitsdeclared
+ \pgfkeyssetevalue{/tikz/x radius}{\pgfmathresult pt}%
+ \pgfkeyssetevalue{/tikz/y radius}{\pgfmathresult pt}%
+ \else
+ \pgfkeyssetevalue{/tikz/x radius}{\pgfmathresult}%
+ \pgfkeyssetevalue{/tikz/y radius}{\pgfmathresult}%
+ \fi
+ }%
+}%
+\tikzset{start angle/.initial=}%
+\tikzset{end angle/.initial=}%
+\tikzset{delta angle/.initial=}%
+
+
+% Coordinate options
+\tikzoption{x}{\tikz@handle@vec{\pgfsetxvec}{\tikz@handle@x}#1\relax}%
+\tikzoption{y}{\tikz@handle@vec{\pgfsetyvec}{\tikz@handle@y}#1\relax}%
+\tikzoption{z}{\tikz@handle@vec{\pgfsetzvec}{\tikz@handle@z}#1\relax}%
+
+\def\tikz@handle@vec#1#2{\pgfutil@ifnextchar({\tikz@handle@coordinate#1}{\tikz@handle@single#2}}%
+\def\tikz@handle@coordinate#1{\tikz@scan@one@point#1}%
+\def\tikz@handle@single#1#2\relax{#1{#2}}%
+\def\tikz@handle@x#1{\pgfsetxvec{\pgfpoint{#1}{0pt}}}%
+\def\tikz@handle@y#1{\pgfsetyvec{\pgfpoint{0pt}{#1}}}%
+\def\tikz@handle@z#1{\pgfsetzvec{\pgfpoint{#1}{#1}}}%
+
+
+% Transformation options
+\tikzoption{scale}{\tikz@addtransform{\pgftransformscale{#1}}}%
+\tikzoption{scale around}{\tikz@addtransform{\def\tikz@aroundaction{\pgftransformscale}\tikz@doaround{#1}}}%
+\tikzoption{xscale}{\tikz@addtransform{\pgftransformxscale{#1}}}%
+\tikzoption{xslant}{\tikz@addtransform{\pgftransformxslant{#1}}}%
+\tikzoption{yscale}{\tikz@addtransform{\pgftransformyscale{#1}}}%
+\tikzoption{yslant}{\tikz@addtransform{\pgftransformyslant{#1}}}%
+\tikzoption{rotate}{\tikz@addtransform{\pgftransformrotate{#1}}}%
+\tikzoption{rotate around}{\tikz@addtransform{\def\tikz@aroundaction{\pgftransformrotate}\tikz@doaround{#1}}}%
+\def\tikz@doaround#1{%
+ \edef\tikz@temp{#1}% get rid of active stuff
+ \expandafter\tikz@doparseA\tikz@temp%
+}%
+\def\tikz@doparseA#1:{%
+ \def\tikz@temp@rot{#1}%
+ \tikz@scan@one@point\tikz@doparseB%
+}%
+\def\tikz@doparseB#1{%
+ \pgf@process{#1}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgftransformshift{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \tikz@aroundaction{\tikz@temp@rot}%
+ \pgftransformshift{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}%
+}%
+
+\tikzoption{shift}{\tikz@addtransform{\tikz@scan@one@point\pgftransformshift#1\relax}}%
+\tikzoption{xshift}{\tikz@addtransform{\pgftransformxshift{#1}}}%
+\tikzoption{yshift}{\tikz@addtransform{\pgftransformyshift{#1}}}%
+\tikzoption{cm}{\tikz@addtransform{\tikz@parse@cm#1\relax}}%
+\tikzoption{reset cm}[]{\tikz@addtransform{\pgftransformreset}}%
+\tikzoption{shift only}[]{\tikz@addtransform{\pgftransformresetnontranslations}}%
+
+\def\tikz@parse@cm#1,#2,#3,#4,{%
+ \def\tikz@p@cm{{#1}{#2}{#3}{#4}}%
+ \tikz@scan@one@point\tikz@parse@cmA}%
+\def\tikz@parse@cmA#1{%
+ \expandafter\pgftransformcm\tikz@p@cm{#1}%
+}%
+
+\tikzset{transform canvas/.code=%
+ {%
+ \tikz@addoption
+ {%
+ {%
+ \pgftransformreset%
+ \let\tikz@transform=\relax%
+ \tikzset{#1}%
+ \pgflowlevelsynccm%
+ }%
+ \pgf@relevantforpicturesizefalse%
+ }%
+ }%
+}%
+
+\tikzset{turn/.code={%
+ \pgf@x=0pt%
+ \pgf@y\pgf@x%
+ \pgf@process{\tikz@tangent}%
+ \advance\pgf@x by-\tikz@lastx%
+ \advance\pgf@y by-\tikz@lasty%
+ \pgfpointnormalised{}% x/y = normalised vector
+ \pgf@x=-\pgf@x%
+ \pgf@ya=-\pgf@y%
+ \pgftransformcm%
+ {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@ya}}%
+ {\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@x}}{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}%
+ }%
+}%
+
+\def\tikz@tangent@lookup{%
+ \pgfgetpath\tikz@temp%
+ \pgfprocesspathextractpoints\tikz@temp%
+ \pgfpointsecondlastonpath%
+}%
+
+% Code for rotating the xyz coordinate system
+% around the x, y, or z vector.
+%
+\def\tikz@xyz@rotate@let{%
+ \let\pgf@z=\pgf@yc%
+ \let\pgf@za=\pgf@xc%
+}%
+
+\def\tikz@xyz@rotate@xyz@xaxis#1#2#3#4{%
+ \tikz@xyz@rotate@let%
+ \pgf@x=#1\relax%
+ \pgf@ya=#2\relax%
+ \pgf@za=#3\relax%
+ \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult%
+ \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult%
+ \pgf@y=\tikz@xyz@cos\pgf@ya%
+ \advance\pgf@y by-\tikz@xyz@sin\pgf@za%
+ \pgf@z=\tikz@xyz@sin\pgf@ya%
+ \advance\pgf@z by\tikz@xyz@cos\pgf@za%
+}%
+
+\def\tikz@xyz@rotate@xyz@yaxis#1#2#3#4{%
+ \tikz@xyz@rotate@let%
+ \pgf@xa=#1\relax%
+ \pgf@y=#2\relax%
+ \pgf@za=#3\relax%
+ \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult%
+ \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult%
+ \pgf@x=\tikz@xyz@cos\pgf@xa%
+ \advance\pgf@x by\tikz@xyz@sin\pgf@za%
+ \pgf@z=-\tikz@xyz@sin\pgf@xa%
+ \advance\pgf@z by\tikz@xyz@cos\pgf@za%
+}%
+
+\def\tikz@xyz@rotate@xyz@zaxis#1#2#3#4{%
+ \tikz@xyz@rotate@let%
+ \pgf@xa=#1\relax%
+ \pgf@ya=#2\relax%
+ \pgf@z=#3\relax%
+ \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult%
+ \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult%
+ \pgf@x=\tikz@xyz@cos\pgf@xa%
+ \advance\pgf@x by-\tikz@xyz@sin\pgf@ya%
+ \pgf@y=\tikz@xyz@sin\pgf@xa%
+ \advance\pgf@y by\tikz@xyz@cos\pgf@ya%
+}%
+
+\tikzset{rotate around x/.code={%
+ \tikz@xyz@rotate@let%
+ \pgfmathparse{#1}\let\tikz@xyz@angle=\pgfmathresult%
+ \tikz@xyz@rotate@xyz@xaxis{0pt}{1pt}{0pt}{\tikz@xyz@angle}%
+ \pgfextract@process\tikz@xyz@rotate@yvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}%
+ \tikz@xyz@rotate@xyz@xaxis{0pt}{0pt}{1pt}{\tikz@xyz@angle}%
+ \pgfsetzvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}%
+ \pgfsetyvec{\tikz@xyz@rotate@yvec}%
+ },
+ rotate around y/.code={%
+ \tikz@xyz@rotate@let%
+ \pgfmathparse{#1}\let\tikz@xyz@angle=\pgfmathresult%
+ \tikz@xyz@rotate@xyz@yaxis{1pt}{0pt}{0pt}{\tikz@xyz@angle}%
+ \pgfextract@process\tikz@xyz@rotate@xvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}%
+ \tikz@xyz@rotate@xyz@yaxis{0pt}{0pt}{1pt}{\tikz@xyz@angle}%
+ \pgfsetzvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}%
+ \pgfsetxvec{\tikz@xyz@rotate@xvec}%
+ },
+ rotate around z/.code={%
+ \tikz@xyz@rotate@let%
+ \pgfmathparse{#1}\let\tikz@xyz@angle=\pgfmathresult%
+ \tikz@xyz@rotate@xyz@zaxis{1pt}{0pt}{0pt}{\tikz@xyz@angle}%
+ \pgfextract@process\tikz@xyz@rotate@xvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}%
+ \tikz@xyz@rotate@xyz@zaxis{0pt}{1pt}{0pt}{\tikz@xyz@angle}%
+ \pgfsetyvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}%
+ \pgfsetxvec{\tikz@xyz@rotate@xvec}%
+ },
+}%
+
+% Grid options
+\tikzoption{xstep}{\def\tikz@grid@x{#1}}%
+\tikzoption{ystep}{\def\tikz@grid@y{#1}}%
+\tikzoption{step}{\tikz@handle@vec{\tikz@step@point}{\tikz@step@single}#1\relax}%
+\def\tikz@step@single#1{\def\tikz@grid@x{#1}\def\tikz@grid@y{#1}}%
+\def\tikz@step@point#1{\pgf@process{#1}\edef\tikz@grid@x{\the\pgf@x}\edef\tikz@grid@y{\the\pgf@y}}%
+
+\def\tikz@grid@x{1cm}%
+\def\tikz@grid@y{1cm}%
+
+
+% Current point updates
+\newif\iftikz@current@point@local
+\tikzset{current point is local/.is if=tikz@current@point@local}%
+
+% Path usage options
+\newif\iftikz@mode@double
+\newif\iftikz@mode@fill
+\newif\iftikz@mode@draw
+\newif\iftikz@mode@clip
+\newif\iftikz@mode@boundary
+\newif\iftikz@mode@shade
+\newif\iftikz@mode@fade@path
+\newif\iftikz@mode@fade@scope
+\let\tikz@mode=\pgfutil@empty
+
+\def\tikz@nonetext{none}%
+
+\tikzoption{path only}[]{\let\tikz@mode=\pgfutil@empty}%
+\tikzset{
+ shade/.is choice,
+ shade/.default=true,
+ shade/true/.code=\tikz@addmode{\tikz@mode@shadetrue},
+ shade/false/.code=\tikz@addmode{\tikz@mode@shadefalse},
+ shade/none/.code=\tikz@addmode{\tikz@mode@shadefalse},
+}%
+
+\tikzoption{fill}[]{%
+ \edef\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@nonetext%
+ \tikz@addmode{\tikz@mode@fillfalse}%
+ \else%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \tikz@addoption{\pgfsetfillcolor{#1}}%
+ \def\tikz@fillcolor{#1}%
+ \fi%
+ \tikz@addmode{\tikz@mode@filltrue}%
+ \fi%
+}%
+\tikzoption{draw}[]{%
+ \edef\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@nonetext%
+ \tikz@addmode{\tikz@mode@drawfalse}%
+ \else%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \tikz@addoption{\pgfsetstrokecolor{#1}}%
+ \def\tikz@strokecolor{#1}%
+ \fi%
+ \tikz@addmode{\tikz@mode@drawtrue}%
+ \fi%
+}%
+\tikzoption{clip}[]{\tikz@addmode{\tikz@mode@cliptrue}}%
+\tikzoption{use as bounding box}[]{\tikz@addmode{\tikz@mode@boundarytrue}}%
+
+\tikzoption{save path}{\tikz@addmode{\pgfsyssoftpath@getcurrentpath#1\global\let#1=#1}}%
+\tikzoption{use path}{\tikz@addmode{\pgfsyssoftpath@setcurrentpath#1}}%
+
+\let\tikz@fillcolor=\pgfutil@empty
+\let\tikz@strokecolor=\pgfutil@empty
+
+% Insert a path using an option
+\tikzset{insert path/.code=\tikz@scan@next@command#1\pgf@stop}%
+
+% Pattern options
+\tikzset{pattern/.code=\tikzerror{You need to say \string\usetikzlibrary{patterns}},
+ pattern color/.style=pattern}%
+
+% Path pictures
+\tikzset{path picture/.code=\tikz@addmode{\def\tikz@path@picture{#1}}}%
+
+% Fading options
+\tikzset{path fading/.code={
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@nonetext%
+ \tikz@addmode{\tikz@mode@fade@pathfalse}%
+ \else%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \def\tikz@path@fading{#1}%
+ \fi%
+ \tikz@addmode{\tikz@mode@fade@pathtrue}%
+ \fi%
+ },
+ path fading/.default=,
+ scope fading/.code={
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\tikz@nonetext%
+ \tikz@addmode{\tikz@mode@fade@scopefalse}%
+ \else%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \def\tikz@scope@fading{#1}%
+ \fi%
+ \tikz@addmode{\tikz@mode@fade@scopetrue}%
+ \fi%
+ },
+ scope fading/.default=}%
+\tikzset{fit fading/.is if=tikz@fade@adjust}%
+\tikzset{fading transform/.store in=\tikz@fade@transform}%
+\tikzset{fading angle/.style={fading transform={rotate={#1}}}}%
+
+\newif\iftikz@fade@adjust%
+\tikz@fade@adjusttrue%
+\let\tikz@fade@transform\pgfutil@empty%
+
+\pgfutil@colorlet{transparent}{pgftransparent}%
+\def\tikz@do@fade@transform{\let\tikz@transform=\relax\expandafter\tikzset\expandafter{\tikz@fade@transform}}%
+
+
+
+% Transparency groups
+\newif\iftikz@transparency@group%
+\tikzset{/tikz/transparency group/.code=\tikz@transparency@grouptrue\def\tikz@transparency@group@options{isolated=true,#1}\let\tikz@blend@group\pgfutil@empty}%
+\tikzset{/tikz/blend group/.code=\tikz@transparency@grouptrue\def\tikz@transparency@group@options{isolated=true}\def\tikz@blend@group{\pgfsetblendmode{#1}}}%
+
+\let\tikz@blend@group\pgfutil@empty
+
+% Shading options
+\tikzoption{shading}{\def\tikz@shading{#1}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{shading angle}{\def\tikz@shade@angle{#1}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{top color}{%
+ \pgfutil@colorlet{tikz@axis@top}{#1}%
+ \pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
+ \def\tikz@shading{axis}\def\tikz@shade@angle{0}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{bottom color}{%
+ \pgfutil@colorlet{tikz@axis@bottom}{#1}%
+ \pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
+ \def\tikz@shading{axis}\def\tikz@shade@angle{0}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{middle color}{%
+ \pgfutil@colorlet{tikz@axis@middle}{#1}%
+ \def\tikz@shading{axis}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{left color}{%
+ \pgfutil@colorlet{tikz@axis@top}{#1}%
+ \pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
+ \def\tikz@shading{axis}\def\tikz@shade@angle{90}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{right color}{%
+ \pgfutil@colorlet{tikz@axis@bottom}{#1}%
+ \pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
+ \def\tikz@shading{axis}\def\tikz@shade@angle{90}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{ball color}{\pgfutil@colorlet{tikz@ball}{#1}\def\tikz@shading{ball}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{inner color}{\pgfutil@colorlet{tikz@radial@inner}{#1}\def\tikz@shading{radial}\tikz@addmode{\tikz@mode@shadetrue}}%
+\tikzoption{outer color}{\pgfutil@colorlet{tikz@radial@outer}{#1}\def\tikz@shading{radial}\tikz@addmode{\tikz@mode@shadetrue}}%
+
+\def\tikz@shading{axis}%
+\def\tikz@shade@angle{0}%
+
+\pgfdeclareverticalshading[tikz@axis@top,tikz@axis@middle,tikz@axis@bottom]{axis}{100bp}{%
+ color(0bp)=(tikz@axis@bottom);
+ color(25bp)=(tikz@axis@bottom);
+ color(50bp)=(tikz@axis@middle);
+ color(75bp)=(tikz@axis@top);
+ color(100bp)=(tikz@axis@top)}%
+
+\pgfutil@colorlet{tikz@axis@top}{gray}%
+\pgfutil@colorlet{tikz@axis@middle}{gray!50!white}%
+\pgfutil@colorlet{tikz@axis@bottom}{white}%
+
+\pgfdeclareradialshading[tikz@ball]{ball}{\pgfqpoint{-10bp}{10bp}}{%
+ color(0bp)=(tikz@ball!15!white);
+ color(9bp)=(tikz@ball!75!white);
+ color(18bp)=(tikz@ball!70!black);
+ color(25bp)=(tikz@ball!50!black);
+ color(50bp)=(black)}%
+
+\pgfutil@colorlet{tikz@ball}{blue}%
+
+\pgfdeclareradialshading[tikz@radial@inner,tikz@radial@outer]{radial}{\pgfpointorigin}{%
+ color(0bp)=(tikz@radial@inner);
+ color(25bp)=(tikz@radial@outer);
+ color(50bp)=(tikz@radial@outer)}%
+
+\pgfutil@colorlet{tikz@radial@inner}{gray}%
+\pgfutil@colorlet{tikz@radial@outer}{white}%
+
+
+% Pin options
+\tikzset{
+ pin distance/.store in=\tikz@pin@distance,
+ pin distance=3ex,
+ pin position/.store in=\tikz@pin@default@pos,
+ pin position=above,
+ pin edge/.store in=\tikz@pin@edge@style,
+ pin edge={},
+ tikz@pin@post/.code={\global\let\tikz@pin@edge@style@smuggle=\tikz@pin@edge@style},
+ tikz@pre@pin@edge/.code={%
+ \toks0=\expandafter{\tikz@pin@edge@style@smuggle}%
+ \edef\pgf@marshal{\noexpand\tikzset{tikz@pin@options/.style={\the\toks0}}}%
+ \pgf@marshal
+ },%
+}%
+
+\tikzset{%
+ pin/.code={%
+ \begingroup
+ \ifnum\the\catcode`\:=\active\relax
+ \def\tikz@next{%
+ \endgroup
+ \tikz@parse@pin@active@i{#1}}%
+ \else
+ \def\tikz@next{%
+ \endgroup
+ \pgfutil@ifnextchar[%]
+ {\tikz@parse@pin@nonactive}
+ {\tikz@parse@pin@nonactive[]}#1:\pgf@nil}%
+ \fi
+ \tikz@next}}%
+
+\begingroup
+ \catcode`\:=\active\relax
+
+ \gdef\tikz@parse@pin@active@i#1{%
+ \pgfutil@ifnextchar[%]
+ {\tikz@parse@pin@active}
+ {\tikz@parse@pin@active[]}#1:\pgf@nil}%
+
+ \long\gdef\tikz@parse@pin@active[#1]#2:#3\pgf@nil{%
+ \def\tikz@temp{#3}%
+ \ifx\tikz@temp\pgfutil@empty
+ % no position, use default
+ \tikz@@parse@pin@active[#1]\tikz@pin@default@pos:#2:\pgf@nil%
+ \else
+ \tikz@@parse@pin@active[#1]#2:#3\pgf@nil%
+ \fi}%
+
+ \long\gdef\tikz@@parse@pin@active[#1]#2:#3:\pgf@nil{%
+ \tikzset{%
+ append after command = {%
+ \bgroup
+ [current point is local = true]
+ \pgfextra{\let\tikz@save@last@node=\tikzlastnode\tikz@node@is@a@labelfalse}%
+ node [tikz@label@angle = #2,
+ anchor=@auto,
+ every pin,
+ #1,
+ append after command = {%
+ (\tikz@save@last@node)
+ edge [every pin edge,
+ tikz@pre@pin@edge,
+ tikz@pin@options]
+ (\tikzlastnode)},
+ tikz@label@post = \tikz@pin@distance,
+ tikz@pin@post] {#3}
+ \egroup}}}%
+\endgroup
+
+\long\def\tikz@parse@pin@nonactive[#1]#2:#3\pgf@nil{%
+ \def\tikz@temp{#3}%
+ \ifx\tikz@temp\pgfutil@empty
+ % no position, use default
+ \tikz@@parse@pin@nonactive[#1]\tikz@pin@default@pos:#2:\pgf@nil%
+ \else
+ \tikz@@parse@pin@nonactive[#1]#2:#3\pgf@nil%
+ \fi}%
+
+\long\def\tikz@@parse@pin@nonactive[#1]#2:#3:\pgf@nil{%
+ \tikzset{%
+ append after command = {%
+ \bgroup
+ [current point is local = true]
+ \pgfextra{\let\tikz@save@last@node=\tikzlastnode\tikz@node@is@a@labelfalse}%
+ node [tikz@label@angle = #2,
+ anchor=@auto,
+ every pin,
+ #1,
+ append after command = {%
+ (\tikz@save@last@node)
+ edge [every pin edge,
+ tikz@pre@pin@edge,
+ tikz@pin@options]
+ (\tikzlastnode)},
+ tikz@label@post = \tikz@pin@distance,
+ tikz@pin@post] {#3}
+ \egroup}}}%
+
+% Label and pin options
+
+\tikzset{
+ label distance/.store in=\tikz@label@distance,
+ label distance=0pt,
+ label position/.store in=\tikz@label@default@pos,
+ label position=above,
+ absolute/.is if=tikz@absolute,
+ tikz@label@angle/.store in=\tikz@label@angle
+}%
+
+\newif\iftikz@absolute
+\def\tikz@on@text{center}%
+
+\tikzset{tikz@label@post/.code 2 args={
+ \edef\tikz@label@angle{\tikz@label@angle}%
+ \expandafter\pgfkeys@spdef\expandafter\tikz@label@angle\expandafter{\tikz@label@angle}%
+ \csname tikz@label@angle@is@\tikz@label@angle\endcsname
+ \ifx\tikz@label@angle\tikz@on@text%
+ \def\tikz@node@at{\pgfpointanchor{\tikzlastnode}{center}}%
+ \def\tikz@anchor{center}%
+ \else%
+ \iftikz@absolute%
+ \pgftransformreset%
+ \pgf@process{%
+ \pgfpointshapeborder{\tikzlastnode}%
+ {\pgfpointadd{\pgfpointanchor{\tikzlastnode}{center}}{\pgfpointpolar{\tikz@label@angle}{1pt}}}}%
+ \edef\tikz@node@at{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \tikz@compute@direction{\tikz@label@angle}%
+ \tikz@addtransform{\pgftransformshift{\pgfpointpolar{\tikz@label@angle}{#1}}}%
+ \else%
+ \pgf@process{\pgfpointanchor{\tikzlastnode}{\tikz@label@angle}}%
+ \edef\tikz@node@at{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@process{\pgfpointanchor{\tikzlastnode}{center}}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \tikz@label@simplefalse%
+ \ifdim\pgf@xc=\pgf@xb\relax%
+ \ifdim\pgf@yc=\pgf@yb\relax%
+ \tikz@label@simpletrue%
+ \fi%
+ \fi%
+ \iftikz@label@simple%
+ \tikz@compute@direction{\tikz@label@angle}%
+ \tikz@addtransform{\pgftransformshift{\pgfpointpolar{\tikz@label@angle}{#1}}}%
+ \else%
+ \pgf@process{\pgfpointnormalised{%
+ \pgfpointdiff{\pgfpointtransformed{\pgfqpoint{\pgf@xc}{\pgf@yc}}}{\pgfpointtransformed{\pgfqpoint{\pgf@xb}{\pgf@yb}}}}}%
+ \edef\pgf@marshal{%
+ \noexpand\tikz@addtransform{\noexpand\pgftransformshift{\noexpand\pgfpointscale{#1}{
+ \noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}}}%
+ \pgf@marshal%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@x=\pgf@yc%
+ \pgf@y=-\pgf@xc%
+ \ifx\tikz@anchor\tikz@auto@text%
+ \tikz@auto@anchor%
+ \fi%
+ \fi%
+ \fi%
+ \fi}
+}%
+
+\newif\iftikz@label@simple%
+
+\tikzset{%
+ label/.code={%
+ \begingroup
+ \ifnum\the\catcode`\:=\active\relax
+ \def\tikz@next{%
+ \endgroup
+ \tikz@parse@label@active@i{#1}}%
+ \else
+ \def\tikz@next{%
+ \endgroup
+ \pgfutil@ifnextchar[%]
+ {\tikz@parse@label@nonactive}
+ {\tikz@parse@label@nonactive[]}#1:\pgf@nil}%
+ \fi
+ \tikz@next}}%
+
+\begingroup
+ \catcode`\:=\active\relax
+
+ \gdef\tikz@parse@label@active@i#1{%
+ \pgfutil@ifnextchar[%]
+ {\tikz@parse@label@active}
+ {\tikz@parse@label@active[]}#1:\pgf@nil}%
+
+ \gdef\tikz@parse@label@active[#1]#2:#3\pgf@nil{%
+ \def\tikz@temp{#3}%
+ \ifx\tikz@temp\pgfutil@empty
+ % no position, use default
+ \tikz@@parse@label@active[#1]\tikz@label@default@pos:#2:\pgf@nil%
+ \else
+ \def\tikz@temp{#2}%
+ \ifx\tikz@temp\pgfutil@empty
+ \tikz@@parse@label@active[#1]\tikz@label@default@pos:#3\pgf@nil%
+ \else
+ \tikz@@parse@label@active[#1]#2:#3\pgf@nil%
+ \fi
+ \fi
+ }%
+
+ \gdef\tikz@@parse@label@active[#1]#2:#3:\pgf@nil{%
+ \tikzset{%
+ append after command = {%
+ \bgroup
+ [current point is local=true]
+ \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name\tikz@node@is@a@labelfalse}
+ node [tikz@label@angle = #2,
+ anchor=@auto,
+ every label,
+ #1,
+ tikz@label@post = \tikz@label@distance] {\iftikz@handle@active@nodes\expandafter\scantokens\else\expandafter\pgfutil@firstofone\fi{#3\noexpand}}
+ \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name}
+ \egroup}}}%
+\endgroup
+
+\def\tikz@parse@label@nonactive[#1]#2:#3\pgf@nil{%
+ \def\tikz@temp{#3}%
+ \ifx\tikz@temp\pgfutil@empty
+ % no position, use default
+ \tikz@@parse@label@nonactive[#1]\tikz@label@default@pos:#2:\pgf@nil%
+ \else
+ \def\tikz@temp{#2}%
+ \ifx\tikz@temp\pgfutil@empty
+ \tikz@@parse@label@nonactive[#1]\tikz@label@default@pos:#3\pgf@nil%
+ \else
+ \tikz@@parse@label@nonactive[#1]#2:#3\pgf@nil%
+ \fi
+ \fi
+}%
+
+\def\tikz@@parse@label@nonactive[#1]#2:#3:\pgf@nil{%
+ \tikzset{%
+ append after command = {%
+ \bgroup
+ [current point is local=true]
+ \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name\tikz@node@is@a@labelfalse}
+ node [tikz@label@angle = #2,
+ anchor=@auto,
+ every label,
+ #1,
+ tikz@label@post = \tikz@label@distance] {\iftikz@handle@active@nodes\expandafter\scantokens\else\expandafter\pgfutil@firstofone\fi{#3\noexpand}}
+ \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name}
+ \egroup}}}%
+
+\expandafter\def\csname tikz@label@angle@is@right\endcsname{\def\tikz@label@angle{0}}%
+\expandafter\def\csname tikz@label@angle@is@above right\endcsname{\def\tikz@label@angle{45}}%
+\expandafter\def\csname tikz@label@angle@is@above\endcsname{\def\tikz@label@angle{90}}%
+\expandafter\def\csname tikz@label@angle@is@above left\endcsname{\def\tikz@label@angle{135}}%
+\expandafter\def\csname tikz@label@angle@is@left\endcsname{\def\tikz@label@angle{180}}%
+\expandafter\def\csname tikz@label@angle@is@below left\endcsname{\def\tikz@label@angle{225}}%
+\expandafter\def\csname tikz@label@angle@is@below\endcsname{\def\tikz@label@angle{270}}%
+\expandafter\def\csname tikz@label@angle@is@below right\endcsname{\def\tikz@label@angle{315}}%
+
+\def\tikz@compute@direction#1{%
+ \ifx\tikz@anchor\tikz@auto@text%
+ \let\tikz@do@auto@anchor=\relax
+ \pgfmathsetcount{\c@pgf@counta}{#1}%
+ \ifnum\c@pgf@counta<0\relax
+ \advance\c@pgf@counta by 360\relax%
+ \fi%
+ \ifnum\c@pgf@counta>359\relax
+ \advance\c@pgf@counta by-360\relax%
+ \fi%
+ \ifnum\c@pgf@counta<4\relax%
+ \def\tikz@anchor{west}%
+ \else\ifnum\c@pgf@counta<87\relax%
+ \def\tikz@anchor{south west}%
+ \else\ifnum\c@pgf@counta<94\relax%
+ \def\tikz@anchor{south}%
+ \else\ifnum\c@pgf@counta<177\relax%
+ \def\tikz@anchor{south east}%
+ \else\ifnum\c@pgf@counta<184\relax%
+ \def\tikz@anchor{east}%
+ \else\ifnum\c@pgf@counta<267\relax%
+ \def\tikz@anchor{north east}%
+ \else\ifnum\c@pgf@counta<274\relax%
+ \def\tikz@anchor{north}%
+ \else\ifnum\c@pgf@counta<357\relax%
+ \def\tikz@anchor{north west}%
+ \else%
+ \def\tikz@anchor{west}%
+ \fi\fi\fi\fi\fi\fi\fi\fi%
+ \fi%
+}%
+\def\tikz@auto@text{@auto}%
+
+% General node options
+\tikzset{
+ name/.code={\edef\tikz@fig@name{\tikz@pp@name{#1}}\let\tikz@id@name\tikz@fig@name},%
+ name prefix/.initial=,%
+ name suffix/.initial=,%
+ local bounding box/.style={/pgf/local bounding box/.expanded=\tikz@pp@name{#1}}
+}%
+\def\tikz@pp@name#1{\csname pgfk@/tikz/name prefix\endcsname#1\csname pgfk@/tikz/name suffix\endcsname}%
+
+
+\tikzset{
+ node contents/.code=\def\tikz@node@content{#1},
+ pic type/.code=\def\tikz@node@content{#1}, % alias
+}%
+
+\tikzset{
+ behind path/.code=\def\tikz@whichbox{\tikz@figbox@bg},
+ in front of path/.code=\def\tikz@whichbox{\tikz@figbox}
+}%
+\def\tikz@whichbox{\tikz@figbox}%
+
+\tikzoption{at}{\tikz@scan@one@point\tikz@set@at#1}%
+\def\tikz@set@at#1{\def\tikz@node@at{#1}}%
+
+\tikzoption{shape}{\edef\tikz@shape{#1}}%
+
+\tikzoption{nodes}{\tikzset{every node/.append style={#1}}}%
+
+\tikzset{alias/.code={%
+ \tikz@fig@mustbenamed
+ \begingroup
+ \toks0=\expandafter{\tikz@alias}%
+ \edef\pgf@temp{\noexpand\pgfnodealias{\tikz@pp@name{#1}}{\noexpand\tikz@fig@name}}%
+ \toks1=\expandafter{\pgf@temp}%
+ \xdef\pgf@marshal{%
+ \noexpand\def\noexpand\tikz@alias{\the\toks0 \the\toks1 }%
+ }%
+ \endgroup
+ \pgf@marshal
+}}%
+
+% deprecated:
+\def\tikzaddafternodepathoption#1{#1\tikzset{prefix after command={\pgfextra{#1}}}}%
+\tikzset{after node path/.style={append after command={#1}}}%
+
+
+% Pic options
+\tikzset{pic text/.store in=\tikzpictext}%
+\let\tikzpictext\relax
+\tikzset{pic text options/.store in=\tikzpictextoptions}%
+\let\tikzpictextoptions\pgfutil@empty
+
+
+% Anchoring
+
+\tikzoption{anchor}{\def\tikz@anchor{#1}\let\tikz@do@auto@anchor=\relax}%
+
+\tikzoption{left}[]{\def\tikz@anchor{east}\tikz@possibly@transform{x}{-}{#1}}%
+\tikzoption{right}[]{\def\tikz@anchor{west}\tikz@possibly@transform{x}{}{#1}}%
+\tikzoption{above}[]{\def\tikz@anchor{south}\tikz@possibly@transform{y}{}{#1}}%
+\tikzoption{below}[]{\def\tikz@anchor{north}\tikz@possibly@transform{y}{-}{#1}}%
+\tikzoption{above left}[]%
+ {\def\tikz@anchor{south east}%
+ \tikz@possibly@transform{x}{-}{#1}\tikz@possibly@transform{y}{}{#1}}%
+\tikzoption{above right}[]%
+ {\def\tikz@anchor{south west}%
+ \tikz@possibly@transform{x}{}{#1}\tikz@possibly@transform{y}{}{#1}}%
+\tikzoption{below left}[]%
+ {\def\tikz@anchor{north east}%
+ \tikz@possibly@transform{x}{-}{#1}\tikz@possibly@transform{y}{-}{#1}}%
+\tikzoption{below right}[]%
+ {\def\tikz@anchor{north west}%
+ \tikz@possibly@transform{x}{}{#1}\tikz@possibly@transform{y}{-}{#1}}%
+\tikzset{centered/.code=\def\tikz@anchor{center}}%
+
+\tikzoption{node distance}{\def\tikz@node@distance{#1}}%
+\def\tikz@node@distance{1cm}%
+
+% The following are deprecated:
+\tikzoption{above of}{\tikz@of{#1}{90}}%
+\tikzoption{below of}{\tikz@of{#1}{-90}}%
+\tikzoption{left of}{\tikz@of{#1}{180}}%
+\tikzoption{right of}{\tikz@of{#1}{0}}%
+\tikzoption{above left of}{\tikz@of{#1}{135}}%
+\tikzoption{below left of}{\tikz@of{#1}{-135}}%
+\tikzoption{above right of}{\tikz@of{#1}{45}}%
+\tikzoption{below right of}{\tikz@of{#1}{-45}}%
+\def\tikz@of#1#2{%
+ \def\tikz@anchor{center}%
+ \let\tikz@do@auto@anchor=\relax%
+ \tikz@addtransform{%
+ \expandafter\tikz@extract@node@dist\tikz@node@distance and\pgf@stop%
+ \pgftransformshift{\pgfpointpolar{#2}{\tikz@extracted@node@distance}}}%
+ \def\tikz@node@at{\pgfpointanchor{\tikz@pp@name{#1}}{center}}}%
+\def\tikz@extract@node@dist#1and#2\pgf@stop{%
+ \def\tikz@extracted@node@distance{#1}}%
+
+\tikzset{
+ transform shape nonlinear/.is choice,
+ transform shape nonlinear/.default=true,
+ transform shape nonlinear/true/.code=\let\tikz@nlt\relax,
+ transform shape nonlinear/false/.code=\def\tikz@nlt{\pgfapproximatenonlineartranslation},
+ transform shape nonlinear=false,
+}%
+
+
+\tikzoption{transform shape}[true]{%
+ \csname tikz@fullytransformed#1\endcsname%
+ \iftikz@fullytransformed%
+ \pgfresetnontranslationattimefalse%
+ \else%
+ \pgfresetnontranslationattimetrue%
+ \fi%
+}%
+
+\newif\iftikz@fullytransformed
+\pgfresetnontranslationattimetrue%
+
+\def\tikz@anchor{center}%
+\def\tikz@shape{rectangle}%
+
+\def\tikz@possibly@transform#1#2#3{%
+ \let\tikz@do@auto@anchor=\relax%
+ \def\tikz@test{#3}%
+ \ifx\tikz@test\pgfutil@empty%
+ \else%
+ \pgfmathsetlength{\pgf@x}{#3}%
+ \pgf@x=#2\pgf@x\relax%
+ \edef\tikz@marshal{\noexpand\tikz@addtransform{%
+ \expandafter\noexpand\csname pgftransform#1shift\endcsname{\the\pgf@x}}}%
+ \tikz@marshal%
+ \fi%
+}%
+
+
+% Inter-picture options
+\tikzoption{remember picture}[true]{\csname pgfrememberpicturepositiononpage#1\endcsname}
+\tikzset{
+ overlay/.is choice,
+ overlay/true/.code={\pgf@relevantforpicturesizefalse},
+ overlay/false/.code={\pgf@relevantforpicturesizetrue},
+ overlay/.default=true
+}
+
+
+
+% Line/curve label placement options
+\tikzoption{sloped}[true]{\csname pgfslopedattime#1\endcsname}%
+\tikzoption{allow upside down}[true]{\csname pgfallowupsidedownattime#1\endcsname}%
+
+\tikzoption{pos}{\edef\tikz@time{#1}\ifx\tikz@time\pgfutil@empty\else\pgfmathsetmacro\tikz@time{\tikz@time}\fi}%
+
+\tikzoption{auto}[]{\csname tikz@install@auto@anchor@#1\endcsname}%
+\tikzoption{swap}[]{%
+ \def\tikz@temp{left}%
+ \ifx\tikz@auto@anchor@direction\tikz@temp%
+ \def\tikz@auto@anchor@direction{right}%
+ \else%
+ \def\tikz@auto@anchor@direction{left}%
+ \fi%
+}%
+\tikzset{'/.style=swap}% shorthand
+
+
+\def\tikz@install@auto@anchor@{\let\tikz@do@auto@anchor=\tikz@auto@anchor@on}%
+\def\tikz@install@auto@anchor@false{\let\tikz@do@auto@anchor=\relax}%
+\def\tikz@install@auto@anchor@left{\let\tikz@do@auto@anchor=\tikz@auto@anchor@on\def\tikz@auto@anchor@direction{left}}%
+\def\tikz@install@auto@anchor@right{\let\tikz@do@auto@anchor=\tikz@auto@anchor@on\def\tikz@auto@anchor@direction{right}}%
+
+\let\tikz@do@auto@anchor=\relax%
+
+\def\tikz@auto@anchor@on{\csname tikz@auto@anchor@\tikz@auto@anchor@direction\endcsname}
+
+\def\tikz@auto@anchor@left{\tikz@auto@pre\tikz@auto@anchor\tikz@auto@post}%
+\def\tikz@auto@anchor@right{\tikz@auto@pre\tikz@auto@anchor@prime\tikz@auto@post}%
+
+\def\tikz@auto@anchor@direction{left}%
+
+% Text options
+\tikzoption{text}{\def\tikz@textcolor{#1}}%
+\tikzoption{font}{\def\tikz@textfont{#1}}%
+\tikzoption{node font}{\def\tikz@node@textfont{#1}}%
+\tikzoption{text opacity}{\def\tikz@textopacity{#1}}%
+\tikzoption{text width}{\def\tikz@text@width{#1}}%
+\tikzoption{text height}{\def\tikz@text@height{#1}}%
+\tikzoption{text depth}{\def\tikz@text@depth{#1}}%
+\tikzoption{text ragged}[]%
+{\def\tikz@text@action{\pgfutil@raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}}%
+\tikzoption{text badly ragged}[]{\def\tikz@text@action{\pgfutil@raggedright\relax}}%
+\tikzoption{text ragged left}[]%
+{\def\tikz@text@action{\pgfutil@raggedleft\leftskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}}%
+\tikzoption{text badly ragged left}[]{\def\tikz@text@action{\pgfutil@raggedleft\relax}}%
+\tikzoption{text justified}[]{\def\tikz@text@action{\leftskip0pt\rightskip0pt\relax}}%
+\tikzoption{text centered}[]{\def\tikz@text@action{%
+ \leftskip0pt plus2em%
+ \rightskip0pt plus2em%
+ \spaceskip.3333em \xspaceskip.5em%
+ \parfillskip=0pt%
+ \iftikz@warn@for@narrow@centered\else\hbadness10000\fi%
+ \let\\=\@centercr% for latex
+ \relax}}%
+\tikzoption{text badly centered}[]%
+{\def\tikz@text@action{%
+ \let\\=\@centercr% for latex
+ \parfillskip=0pt%
+ \rightskip\pgfutil@flushglue%
+ \leftskip\pgfutil@flushglue\relax}}%
+\tikzset{badness warnings for centered text/.is if=tikz@warn@for@narrow@centered}%
+\newif\iftikz@warn@for@narrow@centered
+
+\def\tikz@text@reset{%
+ \let\tikz@text@width=\pgfutil@empty
+ \let\tikz@text@height=\pgfutil@empty
+ \let\tikz@text@depth=\pgfutil@empty
+ \let\tikz@textcolor=\pgfutil@empty
+ \let\tikz@textfont=\pgfutil@empty
+ \let\tikz@textopacity=\pgfutil@empty
+ \let\tikz@node@textfont=\pgfutil@empty
+ \def\tikz@text@action{\pgfutil@raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}%
+}
+\tikz@text@reset
+
+
+% Alignment
+\tikzset{
+ node halign header/.initial=,
+ align/.is choice,
+ align/left/.style ={text ragged,node halign header=\tikz@align@left@header},
+ align/flush left/.style ={text badly ragged,node halign header=\tikz@align@left@header},
+ align/right/.style ={text ragged left,node halign header=\tikz@align@right@header},
+ align/flush right/.style ={text badly ragged left,node halign header=\tikz@align@right@header},
+ align/center/.style={text centered,node halign header=\tikz@align@center@header},
+ align/flush center/.style={text badly centered,node halign header=\tikz@align@center@header},
+ align/justify/.style ={text justified,node halign header=\tikz@align@left@header},
+ align/none/.style ={text justified,node halign header=},
+}%
+\def\tikz@align@left@header{##\hfil\cr}%
+\def\tikz@align@right@header{\hfil##\cr}%
+\def\tikz@align@center@header{\hfil##\hfil\cr}%
+
+
+
+% Arrow options
+\tikzoption{arrows}{\tikz@processarrows{#1}}%
+
+
+\tikzoption{>}{\pgfdeclarearrow{name=<->,means={#1}}}%
+\pgfdeclarearrow{name=|<->|, means={>[sep=0pt].|}}%
+
+\tikzoption{shorten <}{\pgfsetshortenstart{#1}}%
+\tikzoption{shorten >}{\pgfsetshortenend{#1}}%
+
+\def\tikz@processarrows#1{%
+ \def\tikz@current@arrows{#1}%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else%
+ \pgfsetarrows{#1}%
+ \fi%
+}%
+
+\def\tikz@current@arrows{-}%
+
+% Parabola options
+\tikzoption{bend}{\tikz@scan@one@point\tikz@set@parabola@bend#1\relax}%
+\tikzoption{bend pos}{\def\tikz@parabola@bend@factor{#1}}%
+\tikzoption{parabola height}{%
+ \def\tikz@parabola@bend@factor{.5}%
+ \def\tikz@parabola@bend{\pgfpointadd{\pgfpoint{0pt}{#1}}{\tikz@last@position@saved}}}%
+
+\def\tikz@parabola@bend{\tikz@last@position@saved}%
+\def\tikz@parabola@bend@factor{0}%
+
+\def\tikz@set@parabola@bend#1{\def\tikz@parabola@bend{#1}}%
+
+% Axis options
+\tikzoption{domain}{\edef\tikz@plot@domain{#1}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax}%
+\tikzoption{range}{\def\tikz@plot@range{#1}}%
+\tikzoption{yrange}{\def\tikz@plot@range{#1}}%
+\let\tikz@plot@range=\pgfutil@empty
+\tikzoption{xrange}{\def\tikz@plot@xrange{#1}}%
+\let\tikz@plot@xrange=\pgfutil@empty
+
+% Plot options
+\tikzoption{smooth}[]{\let\tikz@plot@handler=\pgfplothandlercurveto}%
+\tikzoption{smooth cycle}[]{\let\tikz@plot@handler=\pgfplothandlerclosedcurve}%
+\tikzoption{sharp plot}[]{\let\tikz@plot@handler\pgfplothandlerlineto}%
+\tikzoption{sharp cycle}[]{\let\tikz@plot@handler\pgfplothandlerpolygon}%
+
+\tikzoption{tension}{\pgfsetplottension{#1}}%
+
+\tikzoption{xcomb}[]{\let\tikz@plot@handler=\pgfplothandlerxcomb}%
+\tikzoption{ycomb}[]{\let\tikz@plot@handler=\pgfplothandlerycomb}%
+\tikzoption{polar comb}[]{\let\tikz@plot@handler=\pgfplothandlerpolarcomb}%
+\tikzoption{ybar}[]{\let\tikz@plot@handler=\pgfplothandlerybar}%
+\tikzoption{ybar interval}[]{\let\tikz@plot@handler=\pgfplothandlerybarinterval}%
+\tikzoption{xbar interval}[]{\let\tikz@plot@handler=\pgfplothandlerxbarinterval}%
+\tikzoption{xbar}[]{\let\tikz@plot@handler=\pgfplothandlerxbar}%
+\tikzoption{const plot}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto}%
+\tikzoption{const plot mark left}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto}%
+\tikzoption{const plot mark right}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlinetomarkright}%
+\tikzoption{const plot mark mid}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlinetomarkmid}%
+\tikzoption{jump mark right}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkright}%
+\tikzoption{jump mark mid}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkmid}%
+\tikzoption{jump mark left}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkleft}%
+
+\tikzoption{raw gnuplot}[true]{\csname tikz@plot@raw@gnuplot#1\endcsname}%
+\tikzoption{prefix}{\def\tikz@plot@prefix{#1}}%
+\tikzoption{id}{\def\tikz@plot@id{#1}}%
+
+\tikzoption{samples}{\pgfmathsetmacro\tikz@plot@samples{max(2,#1)}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax}%
+\tikzoption{samples at}{\def\tikz@plot@samplesat{#1}}%
+\tikzoption{parametric}[true]{\csname tikz@plot@parametric#1\endcsname}%
+
+\tikzoption{variable}{\def\tikz@plot@var{#1}}%
+
+\tikzoption{only marks}[]{\let\tikz@plot@handler\pgfplothandlerdiscard}%
+
+\tikzoption{mark}{%
+ \def\tikz@plot@mark{#1}%
+ \def\tikz@temp{none}%
+ \ifx\tikz@temp\tikz@plot@mark
+ \let\tikz@plot@mark=\pgfutil@empty
+ \fi
+}%
+\tikzset{
+ no marks/.style={mark=none},%
+ no markers/.style={mark=none},%
+ every mark/.style={},
+ mark options/.style={%
+ every mark/.style={#1}%
+ }}%
+\tikzoption{mark size}{\pgfsetplotmarksize{#1}}%
+
+\tikzoption{mark indices}{\def\tikz@mark@list{#1}}%
+\tikzoption{mark phase}{\pgfsetplotmarkphase{#1}}%
+\tikzoption{mark repeat}{\pgfsetplotmarkrepeat{#1}}%
+
+\let\tikz@mark@list=\pgfutil@empty
+
+\let\tikz@plot@handler=\pgfplothandlerlineto
+\let\tikz@plot@mark=\pgfutil@empty
+
+\def\tikz@plot@samples{25}%
+\def\tikz@plot@domain{-5:5}%
+\def\tikz@plot@var{\x}%
+\def\tikz@plot@samplesat{-5,-4.5833333,...,5}%
+\def\tikz@plot@samples@recalc#1:#2\relax{%
+ \begingroup
+ \pgfmathparse{#1}%
+ \let\tikz@temp@start=\pgfmathresult%
+ \pgfmathparse{#2}%
+ \let\tikz@temp@end=\pgfmathresult%
+ \pgfmathsetmacro\tikz@temp@diff{(\tikz@temp@end-\tikz@temp@start)/(\tikz@plot@samples-1)}%
+ %
+ % this particular item is for backwards compatibility.
+ % Pgfplots <= 1.8 called 'samples' in a context where the 'fpu' was
+ % active... and I fear there is no simple solution to replace the
+ % new \ifdim below. Sorry.
+ \pgfkeys{/pgf/fpu/output format/fixed/.try}%
+ %
+ \pgfmathsetmacro\tikz@temp@diff@abs{abs(\tikz@temp@diff)}%
+ \ifdim\tikz@temp@diff@abs pt<0.0001pt\relax%
+ \edef\tikz@plot@samplesat{\tikz@temp@start,\tikz@temp@end}%
+ \else%
+ \pgfmathparse{\tikz@temp@start+\tikz@temp@diff}%
+ \edef\tikz@plot@samplesat{\tikz@temp@start,\pgfmathresult,...,\tikz@temp@end}%
+ \fi%
+ \pgfmath@smuggleone\tikz@plot@samplesat
+ \endgroup
+}%
+
+
+\def\tikz@plot@prefix{\jobname.}%
+\def\tikz@plot@id{pgf-plot}%
+
+\newif\iftikz@plot@parametric
+\newif\iftikz@plot@raw@gnuplot
+
+
+%
+% To and edge options
+%
+\tikzoption{to path}{\def\tikz@to@path{#1}}%
+
+\def\tikz@to@path{-- (\tikztotarget) \tikztonodes}%
+
+\tikzset{edge macro/.store in=\tikz@edge@macro}%
+\let\tikz@edge@macro\pgfutil@empty
+
+\tikzset{
+ edge node/.code={
+ \expandafter\def\expandafter\tikz@tonodes\expandafter{\tikz@tonodes #1}
+ },
+ edge label/.style={/tikz/edge node={node[auto]{#1}}},
+ edge label'/.style={/tikz/edge node={node[auto,swap]{#1}}},
+}%
+
+
+% After command options
+\tikzset{
+ append after command/.code=\expandafter\def\expandafter\tikz@after@path\expandafter{\tikz@after@path#1},
+ prefix after command/.code={%
+ \def\tikz@temp{#1}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@after@path%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\tikz@temp\tikz@after@path}%
+ },
+}%
+\let\tikz@after@path\pgfutil@empty
+
+
+% Tree options
+\newif\iftikz@child@missing
+\pgfkeys{/tikz/missing/.is if=tikz@child@missing}%
+
+\tikzset{edge from parent macro/.initial=\tikz@edge@from@parent@macro}%
+\def\tikz@edge@from@parent@macro#1#2{
+ [style=edge from parent, #1, /utils/exec=\tikz@node@is@a@labeltrue] \tikz@edge@to@parent@path #2}%
+
+\tikzoption{edge from parent path}{\def\tikz@edge@to@parent@path{#1}}%
+
+\tikzoption{parent anchor}{\def\tikzparentanchor{.#1}\ifx\tikzparentanchor\tikz@border@text\let\tikzparentanchor\pgfutil@empty\fi}%
+\tikzoption{child anchor}{\def\tikzchildanchor{.#1}\ifx\tikzchildanchor\tikz@border@text\let\tikzchildanchor\pgfutil@empty\fi}%
+
+\tikzoption{level distance}{\pgfmathsetlength\tikzleveldistance{#1}}%
+\tikzoption{sibling distance}{\pgfmathsetlength\tikzsiblingdistance{#1}}%
+
+\tikzoption{growth function}{\let\tikz@grow=#1}%
+
+\tikzset{grow siblings on line/.style={growth function=\tikz@grow@direction}}%
+
+\tikzoption{growth parent anchor}{\def\tikz@growth@anchor{#1}}%
+\tikzoption{grow}{\tikz@set@growth{#1}\edef\tikz@special@level{\the\tikztreelevel}}%
+\tikzoption{grow'}{\tikz@set@growth{#1}\tikz@swap@growth\edef\tikz@special@level{\the\tikztreelevel}}%
+
+\def\tikz@growth@anchor{center}%
+
+\def\tikz@special@level{-1}% never
+
+\def\tikz@swap@growth{%
+ % Swap left and right
+ \let\tikz@temp=\tikz@angle@grow@right%
+ \let\tikz@angle@grow@right=\tikz@angle@grow@left%
+ \let\tikz@angle@grow@left=\tikz@temp%
+}%
+
+\def\tikz@set@growth#1{%
+ \let\tikz@grow=\tikz@grow@direction%
+ \expandafter\ifx\csname tikz@grow@direction@#1\endcsname\relax%
+ \c@pgf@counta=#1\relax%
+ \else%
+ \c@pgf@counta=\csname tikz@grow@direction@#1\endcsname%
+ \fi%
+ \edef\tikz@angle@grow{\the\c@pgf@counta}%
+ \advance\c@pgf@counta by-90\relax%
+ \edef\tikz@angle@grow@left{\the\c@pgf@counta}%
+ \advance\c@pgf@counta by180\relax%
+ \edef\tikz@angle@grow@right{\the\c@pgf@counta}%
+}%
+
+\def\tikz@border@text{.border}%
+\let\tikzparentanchor=\pgfutil@empty
+\let\tikzchildanchor=\pgfutil@empty
+\def\tikz@edge@to@parent@path{(\tikzparentnode\tikzparentanchor) -- (\tikzchildnode\tikzchildanchor)}%
+
+\tikzleveldistance=15mm%
+\tikzsiblingdistance=15mm%
+
+\def\tikz@grow@direction@down{-90}%
+\def\tikz@grow@direction@up{90}%
+\def\tikz@grow@direction@left{180}%
+\def\tikz@grow@direction@right{0}%
+
+\def\tikz@grow@direction@south{-90}%
+\def\tikz@grow@direction@north{90}%
+\def\tikz@grow@direction@west{180}%
+\def\tikz@grow@direction@east{0}%
+
+\expandafter\def\csname tikz@grow@direction@north east\endcsname{45}%
+\expandafter\def\csname tikz@grow@direction@north west\endcsname{135}%
+\expandafter\def\csname tikz@grow@direction@south east\endcsname{-45}%
+\expandafter\def\csname tikz@grow@direction@south west\endcsname{-135}%
+
+\def\tikz@grow@direction{%
+ \pgftransformshift{\pgfpointpolar{\tikz@angle@grow}{\tikzleveldistance}}%
+ \ifnum\tikztreelevel=\tikz@special@level%
+ \else%
+ \pgf@xc=.5\tikzsiblingdistance%
+ \c@pgf@counta=\tikznumberofchildren%
+ \advance\c@pgf@counta by1\relax%
+ \pgfutil@tempdima=\c@pgf@counta\pgf@xc%
+ \pgftransformshift{\pgfpointpolar{\tikz@angle@grow@left}{\pgfutil@tempdima}}%
+ \pgftransformshift{\pgfpointpolar{\tikz@angle@grow@right}{\tikznumberofcurrentchild\tikzsiblingdistance}}%
+ \fi%
+}%
+
+\tikzset{grow=down}%
+
+
+% Snakes are in a lib:
+\tikzset{snake/.code=\tikzerror{You need to say \string\usetikzlibrary{snakes}}}%
+
+% Decorations
+\tikzset{decorate/.code=\tikzerror{You need to load a decoration library}}%
+
+% Matrix options
+\usepgfmodule{matrix}%
+
+\tikzoption{matrix}[true]{\csname tikz@is@matrix#1\endcsname}%
+
+\tikzoption{matrix anchor}{\def\tikz@matrix@anchor{#1}}%
+
+\tikzoption{column sep}{\def\pgfmatrixcolumnsep{#1}}%
+\tikzoption{row sep}{\def\pgfmatrixrowsep{#1}}%
+
+\tikzoption{cells}{\tikzset{every cell/.append style={#1}}}%
+
+\tikzoption{ampersand replacement}{\def\tikz@ampersand@replacement{#1}}%
+
+\newif\iftikz@is@matrix
+\let\tikz@matrix@anchor=\pgfutil@empty
+\let\tikz@ampersand@replacement=\pgfutil@empty
+
+
+% Automatic shorthand management
+\tikzset{%
+ handle active characters in code/.is if=tikz@handle@active@code,
+ handle active characters in nodes/.is if=tikz@handle@active@nodes,
+}%
+\newif\iftikz@handle@active@code
+\newif\iftikz@handle@active@nodes
+
+
+% Execute option
+\tikzoption{execute at begin picture}{\expandafter\def\expandafter\tikz@atbegin@picture\expandafter{\tikz@atbegin@picture#1}}%
+\tikzoption{execute at end picture}{\expandafter\def\expandafter\tikz@atend@picture\expandafter{\tikz@atend@picture#1}}%
+\tikzoption{execute at begin scope}{\expandafter\def\expandafter\tikz@atbegin@scope\expandafter{\tikz@atbegin@scope#1}}%
+\tikzoption{execute at end scope}{\expandafter\def\expandafter\tikz@atend@scope\expandafter{\tikz@atend@scope#1}}%
+\tikzoption{execute at begin to}{\expandafter\def\expandafter\tikz@atbegin@to\expandafter{\tikz@atbegin@to#1}}%
+\tikzoption{execute at end to}{\expandafter\def\expandafter\tikz@atend@to\expandafter{\tikz@atend@to#1}}%
+\tikzoption{execute at begin node}{\expandafter\def\expandafter\tikz@atbegin@node\expandafter{\tikz@atbegin@node#1}}%
+\tikzoption{execute at end node}{\expandafter\def\expandafter\tikz@atend@node\expandafter{\tikz@atend@node#1}}%
+\tikzoption{execute at begin matrix}{\expandafter\def\expandafter\tikz@atbegin@matrix\expandafter{\tikz@atbegin@matrix#1}}%
+\tikzoption{execute at end matrix}{\expandafter\def\expandafter\tikz@atend@matrix\expandafter{\tikz@atend@matrix#1}}%
+\tikzoption{execute at begin cell}{\expandafter\def\expandafter\tikz@atbegin@cell\expandafter{\tikz@atbegin@cell#1}}%
+\tikzoption{execute at end cell}{\expandafter\def\expandafter\tikz@atend@cell\expandafter{\tikz@atend@cell#1}}%
+\tikzoption{execute at empty cell}{\expandafter\def\expandafter\tikz@at@emptycell\expandafter{\tikz@at@emptycell#1}}%
+
+\let\tikz@atbegin@picture=\pgfutil@empty
+\let\tikz@atend@picture=\pgfutil@empty
+\let\tikz@atbegin@scope=\pgfutil@empty
+\let\tikz@atend@scope=\pgfutil@empty
+\let\tikz@atbegin@to=\pgfutil@empty
+\let\tikz@atend@to=\pgfutil@empty
+\let\tikz@atbegin@node=\pgfutil@empty
+\let\tikz@atend@node=\pgfutil@empty
+\let\tikz@atbegin@cell=\pgfutil@empty
+\let\tikz@atend@cell=\pgfutil@empty
+\let\tikz@at@emptycell=\pgfutil@empty
+\let\tikz@atbegin@matrix=\pgfutil@empty
+\let\tikz@atend@matrix=\pgfutil@empty
+
+
+% Pre and post actions
+\tikzset{preaction/.code=\expandafter\def\expandafter\tikz@preactions\expandafter{\tikz@preactions\tikz@extra@preaction{#1}}}%
+\tikzset{postaction/.code=\expandafter\def\expandafter\tikz@postactions\expandafter{\tikz@postactions\tikz@extra@postaction{#1}}}%
+\let\tikz@preactions=\pgfutil@empty
+\let\tikz@postactions=\pgfutil@empty
+
+% Styles
+\tikzoption{set style}{\tikzstyle#1}%
+
+% Handled in a special way.
+\def\tikzstyle{\pgfutil@ifnextchar\bgroup\tikz@style@parseA\tikz@style@parseB}%
+\def\tikz@style@parseB#1={\tikz@style@parseA{#1}=}%
+\def\tikz@style@parseA#1#2=#3[#4]{% check for an optional argument
+ \pgfutil@in@[{#2}%]
+ \ifpgfutil@in@%
+ \tikz@style@parseC{#1}#2={#4}%
+ \else%
+ \tikz@style@parseD{#1}#2={#4}%
+ \fi%
+}%
+
+\def\tikz@style@parseC#1[#2]#3=#4{%
+ \pgfkeys{/tikz/#1/.default={#2}}%
+ \pgfutil@in@+{#3}%
+ \ifpgfutil@in@%
+ \pgfkeys{/tikz/#1/.append style={#4}}%
+ \else%
+ \pgfkeys{/tikz/#1/.style={#4}}%
+ \fi}%
+\def\tikz@style@parseD#1#2=#3{%
+ \pgfutil@in@+{#2}%
+ \ifpgfutil@in@%
+ \pgfkeys{/tikz/#1/.append style={#3}}%
+ \else%
+ \pgfkeys{/tikz/#1/.style={#3}}%
+ \fi}%
+
+
+%
+%
+% Predefined styles
+%
+%
+
+\tikzset{help lines/.style= {color=gray,line width=0.2pt}}%
+
+\tikzset{every picture/.style= {}}%
+\tikzset{every path/.style= {}}%
+\tikzset{every scope/.style= {}}%
+\tikzset{every plot/.style= {}}%
+\tikzset{every node/.style= {}}%
+\tikzset{every child/.style= {}}%
+\tikzset{every child node/.style= {}}%
+\tikzset{every to/.style= {}}%
+\tikzset{every cell/.style= {}}%
+\tikzset{every matrix/.style= {}}%
+\tikzset{every edge/.style= {draw}}%
+\tikzset{every label/.style= {draw=none,fill=none}}%
+\tikzset{every pin/.style= {draw=none,fill=none}}%
+\tikzset{every pin edge/.style= {help lines}}%
+
+\tikzset{ultra thin/.style= {line width=0.1pt}}%
+\tikzset{very thin/.style= {line width=0.2pt}}%
+\tikzset{thin/.style= {line width=0.4pt}}%
+\tikzset{semithick/.style= {line width=0.6pt}}%
+\tikzset{thick/.style= {line width=0.8pt}}%
+\tikzset{very thick/.style= {line width=1.2pt}}%
+\tikzset{ultra thick/.style= {line width=1.6pt}}%
+
+\tikzset{solid/.style= {dash pattern=}}%
+\tikzset{dotted/.style= {dash pattern=on \pgflinewidth off 2pt}}%
+\tikzset{densely dotted/.style= {dash pattern=on \pgflinewidth off 1pt}}%
+\tikzset{loosely dotted/.style= {dash pattern=on \pgflinewidth off 4pt}}%
+\tikzset{dashed/.style= {dash pattern=on 3pt off 3pt}}%
+\tikzset{densely dashed/.style= {dash pattern=on 3pt off 2pt}}%
+\tikzset{loosely dashed/.style= {dash pattern=on 3pt off 6pt}}%
+\tikzset{dashdotted/.style= {dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt}}%
+\tikzset{dash dot/.style= {dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt}}%
+\tikzset{densely dashdotted/.style= {dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt}}%
+\tikzset{densely dash dot/.style= {dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt}}%
+\tikzset{loosely dashdotted/.style= {dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt}}%
+\tikzset{loosely dash dot/.style= {dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt}}%
+\tikzset{dashdotdotted/.style= {dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt}}%
+\tikzset{densely dashdotdotted/.style= {dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt}}%
+\tikzset{loosely dashdotdotted/.style= {dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt}}%
+\tikzset{dash dot dot/.style= {dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt}}%
+\tikzset{densely dash dot dot/.style= {dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt}}%
+\tikzset{loosely dash dot dot/.style= {dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt}}%
+
+
+\tikzset{transparent/.style= {opacity=0}}%
+\tikzset{ultra nearly transparent/.style={opacity=0.05}}%
+\tikzset{very nearly transparent/.style= {opacity=0.1}}%
+\tikzset{nearly transparent/.style= {opacity=0.25}}%
+\tikzset{semitransparent/.style= {opacity=0.5}}%
+\tikzset{nearly opaque/.style= {opacity=0.75}}%
+\tikzset{very nearly opaque/.style= {opacity=0.9}}%
+\tikzset{ultra nearly opaque/.style= {opacity=0.95}}%
+\tikzset{opaque/.style= {opacity=1}}%
+
+\tikzset{at start/.style= {pos=0}}%
+\tikzset{very near start/.style= {pos=0.125}}%
+\tikzset{near start/.style= {pos=0.25}}%
+\tikzset{midway/.style= {pos=0.5}}%
+\tikzset{near end/.style= {pos=0.75}}%
+\tikzset{very near end/.style= {pos=0.875}}%
+\tikzset{at end/.style= {pos=1}}%
+
+\tikzset{bend at start/.style= {bend pos=0,bend={+(0,0)}}}%
+\tikzset{bend at end/.style= {bend pos=1,bend={+(0,0)}}}%
+
+\tikzset{edge from parent/.style= {draw}}%
+
+
+
+% Animation callbacks
+\tikzset{
+ animate/.code=\tikzerror{You need to say \string\usetikzlibrary{animations} to use animations}
+}
+
+% ID callbacks
+\newif\iftikz@is@node
+\let\tikz@id@name\pgfutil@empty
+\let\tikz@id@hook\pgfutil@empty
+\def\tikz@call@id@hook{\ifx\tikz@id@hook\pgfutil@empty\else\tikz@id@hook\pgfuseid{\tikz@id@name}\fi}%
+
+
+% RDF stuff
+\let\tikz@clear@rdf@options\relax
+\let\tikz@do@rdf@post@options\relax
+\let\tikz@do@rdf@pre@options\relax
+
+
+%
+% Setting keys
+%
+
+\pgfkeys{/tikz/style/.style={#1}}%
+
+\pgfkeys{/tikz/.unknown/.code=%
+ % Is it a pgf key?
+ \let\tikz@key\pgfkeyscurrentname%
+ \pgfkeys{/pgf/\tikz@key/.try={#1}}%
+ \ifpgfkeyssuccess%
+ \else%
+ \expandafter\pgfutil@in@\expandafter!\expandafter{\tikz@key}%
+ \ifpgfutil@in@%
+ % this is a color!
+ \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}%
+ \edef\tikz@textcolor{\tikz@key}%
+ \else%
+ \pgfutil@doifcolorelse{\tikz@key}
+ {%
+ \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}%
+ \edef\tikz@textcolor{\tikz@key}%
+ }%
+ {%
+ % Ok, second chance: This might be an arrow specification:
+ \expandafter\pgfutil@in@\expandafter-\expandafter{\tikz@key}%
+ \ifpgfutil@in@%
+ % Ah, an arrow spec!
+ \expandafter\tikz@processarrows\expandafter{\tikz@key}%
+ \else%
+ % Ok, third chance: A shape!
+ \expandafter\ifx\csname pgf@sh@s@\tikz@key\endcsname\relax%
+ \pgfkeys{/errors/unknown key/.expand
+ once=\expandafter{\expandafter/\expandafter t\expandafter i\expandafter k\expandafter z\expandafter/\tikz@key}{#1}}%
+ \else%
+ \edef\tikz@shape{\tikz@key}%
+ \fi%
+ \fi%
+ }%
+ \fi%
+ \fi%
+}%
+\def\tikz@compat@color@set#1{%
+ \pgfutil@color{#1}\pgfutil@colorlet{pgffillcolor}{#1}%
+ \expandafter\let\expandafter\pgf@temp\csname\string\color@pgffillcolor\endcsname%
+ % for arrow tips:
+ \global\let\pgf@strokecolor@global=\pgf@temp
+ \global\let\pgf@fillcolor@global=\pgf@temp
+}%
+
+\def\tikz@startup@env{%
+ \ifnum\the\catcode`\;=\active\relax\expandafter\let\expandafter\tikz@origsemi\expandafter=\tikz@activesemicolon\fi%
+ \ifnum\the\catcode`\:=\active\relax\expandafter\let\expandafter\tikz@origcolon\expandafter=\tikz@activecolon\fi%
+ \ifnum\the\catcode`\|=\active\relax\expandafter\let\expandafter\tikz@origbar\expandafter=\tikz@activebar\fi%
+ \tikz@deactivatthings%
+ \iftikz@handle@active@code%
+ \tikz@switchoff@shorthands%
+ \fi%
+}%
+
+%
+% Main TikZ Environment
+%
+\newif\iftikz@inside@picture
+\tikz@inside@picturefalse
+\def\tikz@check@inside@picture{%
+ \iftikz@inside@picture%
+ \pgfwarning{Nesting tikzpictures is NOT supported}%
+ \fi%
+ \tikz@inside@picturetrue%
+}
+
+\def\tikzpicture{%
+ \begingroup%
+ \tikz@startup@env%
+ \tikz@collect@scope@anims\tikz@picture}%
+\def\tikz@picture[#1]{%
+ %\tikz@check@inside@picture%
+ \pgfpicture%
+ \let\tikz@atbegin@picture=\pgfutil@empty%
+ \let\tikz@atend@picture=\pgfutil@empty%
+ \let\tikz@transform=\relax%
+ \def\tikz@time{.5}%
+ \tikz@installcommands%
+ \scope[every picture,#1]%
+ \iftikz@handle@active@code%
+ \tikz@switchoff@shorthands%
+ \fi%
+ \expandafter\tikz@atbegin@picture%
+ \tikz@lib@scope@check%
+}%
+\def\endtikzpicture{%
+ \tikz@atend@picture%
+ \global\let\pgf@shift@baseline@smuggle=\pgf@baseline%
+ \global\let\pgf@trimleft@final@smuggle=\pgf@trimleft%
+ \global\let\pgf@trimright@final@smuggle=\pgf@trimright%
+ \global\let\pgf@remember@smuggle=\ifpgfrememberpicturepositiononpage%
+ \pgf@remember@layerlist@globally
+ \endscope%
+ \let\pgf@baseline=\pgf@shift@baseline@smuggle%
+ \let\pgf@trimleft=\pgf@trimleft@final@smuggle%
+ \let\pgf@trimright=\pgf@trimright@final@smuggle%
+ \let\ifpgfrememberpicturepositiononpage=\pgf@remember@smuggle%
+ \pgf@restore@layerlist@from@global
+ \endpgfpicture\endgroup}%
+
+
+% Inlined picture
+%
+% #1 - some code to be put in a tikzpicture environment.
+%
+% If the command is not followed by braces, everything up to the next
+% semicolon is used as argument.
+%
+% Example:
+%
+% The rectangle \tikz{\draw (0,0) rectangle (1em,1ex)} has width 1em and
+% height 1ex.
+
+
+\def\tikz{%
+ \begingroup%
+ \tikz@startup@env%
+ \tikz@collect@scope@anims\tikz@opt}%
+\def\tikz@opt[#1]{\tikzpicture[#1]\pgfutil@ifnextchar\bgroup{\tikz@}{\tikz@@single}}%
+\def\tikz@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endtikzpicture\aftergroup\endgroup\let\pgf@temp=}%
+\def\tikz@@single#1{%
+ \expandafter\ifx\csname tikz@protected@command\string#1\endcsname\relax%
+ \expandafter\tikz@@%
+ \else%
+ \begingroup\def\tikz@path@do@at@end{\endgroup\endtikzpicture\endgroup}%
+ \fi%
+ #1%
+}%
+
+\expandafter\let\csname tikz@protected@command\string\draw\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\pattern\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\fill\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\filldraw\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\shade\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\shadedraw\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\clip\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\graph\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\useasboundingbox\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\node\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\coordinate\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\matrix\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\datavisualization\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\path\endcsname\pgfutil@empty%
+\expandafter\let\csname tikz@protected@command\string\pic\endcsname\pgfutil@empty%
+
+% Comment by TT: I hope I fixed the \tikz \foreach problem. The new
+% version will take a conservative approach and will only do fancy
+% stuff when the next keyword after \tikz is one of the following:
+% \draw, \fill, \filldraw, \graph, \matrix,
+\def\tikz@@{%
+ \let\tikz@next=\tikz@collectnormalsemicolon%
+ \ifnum\the\catcode`\;=\active\relax%
+ \let\tikz@next=\tikz@collectactivesemicolon%
+ \fi%
+ \tikz@next}%
+\def\tikz@collectnormalsemicolon#1;{#1;\endtikzpicture\endgroup}
+{
+ \catcode`\;=\active
+ \gdef\tikz@collectactivesemicolon#1;{#1;\endtikzpicture\endgroup}
+}%
+% End old code
+
+% Invokes '#1' if the command is invoked within a tikzpicture and
+% '#2' if not.
+\def\tikzifinpicture#1#2{%
+ \pgfutil@ifundefined{filldraw}{#2}{#1}% TT: This is a wrong
+ % test! Who uses this?...
+}%
+
+
+\def\tikz@collect@scope@anims#1{%
+ \pgfutil@ifnextchar[#1{#1[]}%]
+}%
+
+%
+% Environment for scoping graphic state settings
+%
+\def\tikz@scope@env{%
+ \pgfscope%
+ \begingroup%
+ \let\tikz@atbegin@scope=\pgfutil@empty%
+ \let\tikz@atend@scope=\pgfutil@empty%
+ \let\tikz@options=\pgfutil@empty%
+ \tikz@clear@rdf@options%
+ \let\tikz@mode=\pgfutil@empty%
+ \let\tikz@id@name=\pgfutil@empty%
+ \tikz@transparency@groupfalse%
+ \tikzset{every scope/.try}%
+ \tikz@collect@scope@anims\tikz@scope@opt%
+}%
+\def\tikz@scope@opt[#1]{%
+ \tikzset{#1}%
+ \tikz@options%
+ \tikz@do@rdf@pre@options%
+ \iftikz@transparency@group\expandafter\pgftransparencygroup\expandafter[\tikz@transparency@group@options]\tikz@blend@group\fi%
+ \tikz@is@nodefalse%
+ \tikz@call@id@hook%
+ \pgfidscope%
+ \tikz@do@rdf@post@options%
+ \begingroup%
+ \let\tikz@id@name\pgfutil@empty%
+ \expandafter\tikz@atbegin@scope%
+ \expandafter\pgfclearid%
+ \tikz@lib@scope@check%
+}%
+\def\endtikz@scope@env{%
+ \tikz@atend@scope%
+ \endgroup%
+ \endpgfidscope%
+ \iftikz@transparency@group\endpgftransparencygroup\fi%
+ \endgroup%
+ \endpgfscope%
+ \tikz@lib@scope@check%
+}%
+
+
+\def\tikz@scoped{\tikz@collect@scope@anims\tikz@scoped@opt}%
+\def\tikz@scoped@opt[#1]{\scope[#1]\pgfutil@ifnextchar\bgroup{\tikz@scoped@}{\tikz@scoped@@single}}%
+\def\tikz@scoped@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endscope\let\pgf@temp=}%
+\def\tikz@scoped@@single#1{%
+ \expandafter\ifx\csname tikz@scoped@protected@command\string#1\endcsname\relax%
+ \expandafter\tikz@scoped@@%
+ \else%
+ \begingroup\def\tikz@scoped@path@do@at@end{\endgroup\endscope}%
+ \fi%
+ #1%
+}%
+\def\tikz@scoped@@{%
+ \let\tikz@scoped@next=\tikz@scoped@collectnormalsemicolon%
+ \ifnum\the\catcode`\;=\active\relax%
+ \let\tikz@scoped@next=\tikz@scoped@collectactivesemicolon%
+ \fi%
+ \tikz@scoped@next}%
+\def\tikz@scoped@collectnormalsemicolon#1;{#1;\endscope}
+{
+ \catcode`\;=\active
+ \gdef\tikz@scoped@collectactivesemicolon#1;{#1;\endscope}
+}%
+
+
+% Install a shortcut command which is only valid inside of a
+% tikzpicture.
+%
+% It works in the same way as the '\path' shortcut does: it introduces
+% a \let#1=#2 at the beginning of tikzpicture.
+%
+% #1: shortcut command inside of tikzpicture
+% #2: real command name
+\def\tikzaddtikzonlycommandshortcutlet#1#2{%
+ \expandafter\def\expandafter\tikz@installcommands\expandafter{\tikz@installcommands
+ \let#1=#2%
+ }%
+}%
+
+% Has the same effect as \tikzaddtikzonlycommandshortcutlet but uses
+% \def#1{#2} instead of \let.
+\def\tikzaddtikzonlycommandshortcutdef#1#2{%
+ \expandafter\def\expandafter\tikz@installcommands\expandafter{\tikz@installcommands
+ \def#1{#2}%
+ }%
+}%
+
+%
+% Install the abbreviated commands
+%
+\def\tikz@installcommands{%
+ \let\tikz@origscope=\scope%
+ \let\tikz@origscoped=\scoped%
+ \let\tikz@origendscope=\endscope%
+ \let\tikz@origstartscope=\startscope%
+ \let\tikz@origstopscope=\stopscope%
+ \let\tikz@origpath=\path%
+ \let\tikz@origagainpath=\againpath%
+ \let\tikz@origdraw=\draw%
+ \let\tikz@origpattern=\pattern%
+ \let\tikz@origfill=\fill%
+ \let\tikz@origfilldraw=\filldraw%
+ \let\tikz@origshade=\shade%
+ \let\tikz@origshadedraw=\shadedraw%
+ \let\tikz@origclip=\clip%
+ \let\tikz@origuseasboundingbox=\useasboundingbox%
+ \let\tikz@orignode=\node%
+ \let\tikz@origpic=\pic%
+ \let\tikz@origcoordinate=\coordinate%
+ \let\tikz@origmatrix=\matrix%
+ \let\tikz@origcalendar=\calendar%
+ \let\tikz@origdv=\datavisualization%
+ \let\tikz@origgraph=\graph%
+ %
+ \let\scope=\tikz@scope@env%
+ \let\scoped=\tikz@scoped%
+ \let\endscope=\endtikz@scope@env%
+ \let\startscope=\scope%
+ \let\stopscope=\endscope%
+ \let\path=\tikz@command@path%
+ \let\againpath=\tikz@command@againpath%
+ %
+ \def\draw{\path[draw]}%
+ \def\pattern{\path[pattern]}%
+ \def\fill{\path[fill]}%
+ \def\filldraw{\path[fill,draw]}%
+ \def\shade{\path[shade]}%
+ \def\shadedraw{\path[shade,draw]}%
+ \def\clip{\path[clip]}%
+ \def\graph{\path graph}%
+ \def\useasboundingbox{\path[use as bounding box]}%
+ \def\node{\tikz@path@overlay{node}}%
+ \def\pic{\tikz@path@overlay{pic}}%
+ \def\coordinate{\tikz@path@overlay{coordinate}}%
+ \def\matrix{\tikz@path@overlay{node[matrix]}}%
+ \def\calendar{\tikz@lib@cal@calendar}%
+ \def\datavisualization{\tikz@lib@datavisualization}%
+}%
+\ifx\tikz@lib@cal@calendar\@undefined
+\def\tikz@lib@cal@calendar{\tikzerror{You need to say \string\usetikzlibrary{calendar} to use the \string\calendar{} command}}%
+\fi
+\ifx\tikz@lib@datavisualization\@undefined
+\def\tikz@lib@datavisualization{\tikzerror{You need to say \string\usetikzlibrary{datavisualization} to use the \string\datavisualization{} command}}%
+\fi
+
+\def\tikz@path@overlay#1{%
+ \let\tikz@signal@path=\tikz@signal@path% for detection at begin of matrix cell
+ \pgfutil@ifnextchar<{\tikz@path@overlayed{#1}}{\path #1}}%
+\def\tikz@path@overlayed#1<#2>{\path<#2> #1}%
+
+\def\tikz@uninstallcommands{%
+ \let\scope=\tikz@origscope%
+ \let\scoped=\tikz@origscoped%
+ \let\endscope=\tikz@origendscope%
+ \let\startscope=\tikz@origstartscope%
+ \let\stopscope=\tikz@origstopscope%
+ \let\path=\tikz@origpath%
+ \let\againpath=\tikz@origagainpath%
+ \let\draw=\tikz@origdraw%
+ \let\pattern=\tikz@origpattern%
+ \let\fill=\tikz@origfill%
+ \let\filldraw=\tikz@origfilldraw%
+ \let\shade=\tikz@origshade%
+ \let\shadedraw=\tikz@origshadedraw%
+ \let\clip=\tikz@origclip%
+ \let\useasboundingbox=\tikz@origuseasboundingbox%
+ \let\node=\tikz@orignode%
+ \let\pic=\tikz@origpic%
+ \let\coordinate=\tikz@origcoordinate%
+ \let\matrix=\tikz@origmatrix%
+ \let\calendar=\tikz@origcalendar%
+ \let\datavisualization=\tikz@origdv%
+ \let\graph=\tikz@origgraph%
+}%
+
+
+{%
+ \catcode`\;=12
+ \gdef\tikz@nonactivesemicolon{;}%
+ \catcode`\:=12
+ \gdef\tikz@nonactivecolon{:}%
+ \catcode`\|=12
+ \gdef\tikz@nonactivebar{|}%
+ \catcode`\!=12
+ \gdef\tikz@nonactiveexlmark{!}%
+ \catcode`\;=\active
+ \catcode`\:=\active
+ \catcode`\|=\active
+ \catcode`\"=\active
+ \catcode`\!=\active
+ \gdef\tikz@activesemicolon{;}%
+ \gdef\tikz@activecolon{:}%
+ \gdef\tikz@activebar{|}%
+ \gdef\tikz@activequotes{"}%
+ \global\let\tikz@active@quotes@token="%
+ \gdef\tikz@activeexlmark{!}%
+ \gdef\tikz@deactivatthings{%
+ \def;{\tikz@nonactivesemicolon}%
+ \def:{\tikz@nonactivecolon}%
+ \def|{\tikz@nonactivebar}%
+ \def!{\tikz@nonactiveexlmark}%
+ }%
+}%
+
+\let\tikz@orig@shorthands\pgfutil@empty
+\def\tikz@switchoff@shorthands{%
+ \ifx\tikz@orig@shorthands\pgfutil@empty%
+ \edef\tikz@orig@shorthands{%
+ \catcode\noexpand`\noexpand\;\the\catcode`\;\relax%
+ \catcode\noexpand`\noexpand\:\the\catcode`\:\relax%
+ \catcode\noexpand`\noexpand\|\the\catcode`\|\relax%
+ \catcode\noexpand`\noexpand\!\the\catcode`\!\relax%
+ \catcode\noexpand`\noexpand\,\the\catcode`\,\relax%
+ \catcode\noexpand`\noexpand\<\the\catcode`\<\relax%
+ \catcode\noexpand`\noexpand\>\the\catcode`\>\relax%
+ \catcode\noexpand`\noexpand\"\the\catcode`\"\relax%
+ \catcode\noexpand`\noexpand\'\the\catcode`\'\relax%
+ \catcode\noexpand`\noexpand\-\the\catcode`\-\relax%
+ \catcode\noexpand`\noexpand\=\the\catcode`\=\relax%
+ \catcode\noexpand`\noexpand\.\the\catcode`\.\relax%
+ \catcode\noexpand`\noexpand\$\the\catcode`\$\relax%
+ }%
+ \catcode`\;12\relax%
+ \catcode`\:12\relax%
+ \catcode`\|12\relax%
+ \catcode`\!12\relax%
+ \catcode`\,12\relax%
+ \catcode`\<12\relax%
+ \catcode`\>12\relax%
+ \catcode`\"12\relax%
+ \catcode`\'12\relax%
+ \catcode`\-12\relax%
+ \catcode`\=12\relax%
+ \catcode`\.12\relax%
+ \catcode`\$3\relax%
+ \fi%
+}%
+
+
+
+% Constructs a path and draws/fills them according to the current
+% settings.
+
+\def\tikz@command@path{%
+ \let\tikz@signal@path=\tikz@signal@path% for detection at begin of matrix cell
+ \pgfutil@ifnextchar[{\tikz@check@earg}%]
+ {\pgfutil@ifnextchar<{\tikz@doopt}{\tikz@@command@path}}}%
+\pgfutil@protected\def\tikz@signal@path{\tikz@signal@path}%
+\def\tikz@check@earg[#1]{%
+ \pgfutil@ifnextchar<{\tikz@swap@args[#1]}{\tikz@@command@path[#1]}}
+\def\tikz@swap@args[#1]<#2>{\tikz@command@path<#2>[#1]}%
+
+\def\tikz@doopt{%
+ \let\tikz@next=\tikz@eargnormalsemicolon%
+ \ifnum\the\catcode`\;=\active\relax%
+ \let\tikz@next=\tikz@eargactivesemicolon%
+ \fi%
+ \tikz@next}%
+\long\def\tikz@eargnormalsemicolon<#1>#2;{\alt<#1>{\tikz@@command@path#2;}{\tikz@path@do@at@end}}%
+{
+ \catcode`\;=\active
+ \long\global\def\tikz@eargactivesemicolon<#1>#2;{\alt<#1>{\tikz@@command@path#2;}{\tikz@path@do@at@end}}%
+}
+
+\def\tikz@@command@path{%
+ \edef\tikzscope@linewidth{\the\pgflinewidth}%
+ \begingroup%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \let\tikz@path@do@at@end=\tikz@lib@scope@check%
+ \let\tikz@options=\pgfutil@empty%
+ \tikz@clear@rdf@options%
+ \let\tikz@mode=\pgfutil@empty%
+ \let\tikz@moveto@waiting=\relax%
+ \let\tikz@timer=\relax%
+ \let\tikz@tangent=\relax%
+ \let\tikz@collected@onpath=\pgfutil@empty%
+ \let\tikz@preactions=\pgfutil@empty%
+ \let\tikz@postactions=\pgfutil@empty%
+ \tikz@snakedfalse%
+ \tikz@decoratepathfalse%
+ \tikz@node@is@a@labelfalse%
+ \tikz@resetexpandcount
+ \pgf@path@lastx=0pt%
+ \pgf@path@lasty=0pt%
+ \tikz@lastx=0pt%
+ \tikz@lasty=0pt%
+ \tikz@lastxsaved=0pt%
+ \tikz@lastysaved=0pt%
+ \tikzset{every path/.try}%
+ \tikz@scan@next@command%
+}%
+\def\tikz@scan@next@command{%
+ \ifx\tikz@collected@onpath\pgfutil@empty%
+ \else%
+ \tikz@invoke@collected@onpath%
+ \fi%
+ \afterassignment\tikz@handle\let\pgf@let@token=%
+}%
+\newcount\tikz@expandcount
+\def\tikz@resetexpandcount{\tikz@expandcount=100\relax}
+\let\tikz@collected@onpath=\pgfutil@empty%
+
+\edef\tikz@frozen@relax@token{\ifnum0=0\fi}
+
+% Central dispatcher for commands
+\def\tikz@handle{%
+ \pgfutil@switch\pgfutil@ifx\pgf@let@token{%
+ {(}{\let\pgfutil@next\tikz@movetoabs}%)
+ {+}{\let\pgfutil@next\tikz@movetorel}%
+ {-}{\let\pgfutil@next\tikz@lineto}%
+ {.}{\let\pgfutil@next\tikz@dot}%
+ {r}{\let\pgfutil@next\tikz@rect}%
+ {n}{\let\pgfutil@next\tikz@fig}%
+ {[}{\let\pgfutil@next\tikz@parse@options}%]
+ {c}{\let\pgfutil@next\tikz@cchar}%
+ {\bgroup}{\let\pgfutil@next\tikz@beginscope}%
+ {\egroup}{\let\pgfutil@next\tikz@endscope}%
+ {;}{\let\pgfutil@next\tikz@finish}%
+ {a}{\let\pgfutil@next\tikz@a@char}%
+ {e}{\let\pgfutil@next\tikz@e@char}%
+ {g}{\let\pgfutil@next\tikz@g@char}%
+ {s}{\let\pgfutil@next\tikz@schar}%
+ {|}{\let\pgfutil@next\tikz@vh@lineto}%
+ {p}{\pgfsetmovetofirstplotpoint\let\pgfutil@next\tikz@pchar}%
+ {t}{\let\pgfutil@next\tikz@to}%
+ {\pgfextra}{\let\pgfutil@next\tikz@extra}%
+ {\foreach}{\let\pgfutil@next\tikz@foreach}%
+ {f}{\let\pgfutil@next\tikz@fchar}%
+ {\pgf@stop}{\let\pgfutil@next\relax}%
+ {\par}{\let\pgfutil@next\tikz@scan@next@command}%
+ {d}{\let\pgfutil@next\tikz@decoration}%
+ {l}{\let\pgfutil@next\tikz@l@char}%
+ {:}{\let\pgfutil@next\tikz@colon@char}%
+ {\relax}{\relax\let\pgfutil@next\tikz@scan@next@command}%
+ }{\tikz@resetexpandcount\pgfutil@next}{\tikz@expand}%
+}%
+
+\def\tikz@l@char{%
+ \pgfutil@ifnextchar e{\tikz@let@command}{%
+ \pgfutil@ifnextchar i{\tikz@lsystem}{%
+ \pgfutil@ifnextchar-{\tikz@@lsystem}{\tikz@expand}%
+ }%
+ }%
+}%
+
+\def\tikz@lsystem{%
+ \tikzerror{You need to say \string\usetikzlibrary{lindenmayersystems} to draw Lindenmayer systems}
+}%
+
+\def\tikz@@lsystem{%
+ \tikzerror{You need to say \string\usetikzlibrary{lindenmayersystems} to draw L-systems}
+}%
+
+\def\tikz@pchar{\pgfutil@ifnextchar l{\tikz@plot}{\pgfutil@ifnextchar i{\tikz@subpicture}{\tikz@parabola}}}%
+\def\tikz@cchar{%
+ \pgfutil@ifnextchar i{\tikz@circle}%
+ {\pgfutil@ifnextchar h{\tikz@children}{\tikz@cochar}}}%
+\def\tikz@cochar o{%
+ \pgfutil@ifnextchar o{\tikz@coordinate}{\tikz@cosine}}%
+\def\tikz@e@char{%
+ \pgfutil@ifnextchar l{\tikz@ellipse}{\tikz@@e@char}}%
+\def\tikz@a@char{%
+ \pgfutil@ifnextchar r{\tikz@arcA}{\tikzerror{Arc expected}}}%
+\def\tikz@@e@char dge{%
+ \pgfutil@ifnextchar f{\tikz@edgetoparent}{\tikz@edge@plain}}%
+
+\def\tikz@schar{\pgfutil@ifnextchar i{\tikz@sine}{\tikz@svg@path}}%
+
+\def\tikz@g@char r{\pgfutil@ifnextchar i{\tikz@grid}{\tikz@graph}}%
+
+% svg syntax
+% svg[options] {...}
+
+\def\tikz@svg@path{%
+ \tikzerror{You need to say \string\usetikzlibrary{svg.path} to use the svg path command}
+}%
+
+
+\def\tikz@finish{%
+ % Rendering pipeline
+ %
+ % Step 1: The path background box
+ %
+ \box\tikz@figbox@bg%
+ %
+ % Step 2: Decorate path
+ %
+ \iftikz@decoratepath%
+ \tikz@lib@dec@decorate@path%
+ \fi%
+ %
+ % Step 3: Preactions
+ %
+ \pgfsyssoftpath@getcurrentpath\tikz@actions@path%
+ \edef\tikz@restorepathsize{%
+ \global\pgf@pathmaxx=\the\pgf@pathmaxx%
+ \global\pgf@pathmaxy=\the\pgf@pathmaxy%
+ \global\pgf@pathminx=\the\pgf@pathminx%
+ \global\pgf@pathminy=\the\pgf@pathminy%
+ }%
+ \tikz@preactions%
+ %
+ % Step 4: Reset modes
+ %
+ \let\tikz@path@picture=\pgfutil@empty%
+ \tikz@mode@fillfalse%
+ \tikz@mode@drawfalse%
+ \tikz@mode@doublefalse%
+ \tikz@mode@clipfalse%
+ \tikz@mode@boundaryfalse%
+ \tikz@mode@fade@pathfalse%
+ \tikz@mode@fade@scopefalse%
+ \edef\tikz@pathextend{%
+ {\noexpand\pgfqpoint{\the\pgf@pathminx}{\the\pgf@pathminy}}%
+ {\noexpand\pgfqpoint{\the\pgf@pathmaxx}{\the\pgf@pathmaxy}}%
+ }%
+ \tikz@mode% installs the mode settings
+ % Path fading counts as an option:
+ \iftikz@mode@fade@path%
+ \tikz@addoption{%
+ \iftikz@fade@adjust%
+ \iftikz@mode@draw%
+ \pgfsetfadingforcurrentpathstroked{\tikz@path@fading}{\tikz@do@fade@transform}%
+ \else%
+ \pgfsetfadingforcurrentpath{\tikz@path@fading}{\tikz@do@fade@transform}%
+ \fi%
+ \else%
+ \pgfsetfading{\tikz@path@fading}{\tikz@do@fade@transform}%
+ \fi%
+ \tikz@mode@fade@pathfalse% no more fading...
+ }%
+ \fi%
+ %
+ % Step 5: Install scope fading
+ %
+ \iftikz@mode@fade@scope%
+ \iftikz@fade@adjust%
+ \iftikz@mode@draw%
+ \pgfsetfadingforcurrentpathstroked{\tikz@scope@fading}{\tikz@do@fade@transform}%
+ \else%
+ \pgfsetfadingforcurrentpath{\tikz@scope@fading}{\tikz@do@fade@transform}%
+ \fi%
+ \else%
+ \pgfsetfading{\tikz@scope@fading}{\tikz@do@fade@transform}%
+ \fi%
+ \tikz@mode@fade@scopefalse%
+ \fi%
+ %
+ % Step 5': Setup options
+ %
+ \ifx\tikz@options\pgfutil@empty%
+ \else%
+ \pgfsys@beginscope%
+ \let\pgfscope@stroke@color=\pgf@strokecolor@global%
+ \let\pgfscope@fill@color=\pgf@fillcolor@global%
+ \begingroup%
+ \tikz@options%
+ \fi%
+ \tikz@do@rdf@pre@options%
+ %
+ % Step 5'': Setup animations
+ %
+ \tikz@is@nodefalse%
+ \tikz@call@id@hook%
+ \iftikz@mode@clip\else%
+ \pgfidscope%
+ \tikz@do@rdf@post@options%
+ \begingroup%
+ \fi% open an animation scope here, unless clipping is done
+ %
+ % Step 6: Do a fill if shade or a path picture follows.
+ %
+ \iftikz@mode@fill%
+ \iftikz@mode@shade%
+ \pgfsyssoftpath@getcurrentpath\tikz@temppath
+ \pgfprocessround{\tikz@temppath}{\tikz@temppath}% change the path
+ \pgfsyssoftpath@setcurrentpath\tikz@temppath%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfpushtype%
+ \pgfusetype{.path fill}%
+ \pgfsys@fill%
+ \pgfpoptype%
+ \tikz@mode@fillfalse% no more filling...
+ \else%
+ \ifx\tikz@path@picture\pgfutil@empty%
+ \else%
+ \pgfsyssoftpath@getcurrentpath\tikz@temppath
+ \pgfprocessround{\tikz@temppath}{\tikz@temppath}% change the path
+ \pgfsyssoftpath@setcurrentpath\tikz@temppath%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfpushtype%
+ \pgfusetype{.path fill}%
+ \pgfsys@fill%
+ \pgfpoptype%
+ \tikz@mode@fillfalse% no more filling...
+ \fi%
+ \fi%
+ \fi%
+ %
+ % Step 7: Do a shade if necessary.
+ %
+ \iftikz@mode@shade%
+ \pgfsyssoftpath@getcurrentpath\tikz@temppath
+ \pgfprocessround{\tikz@temppath}{\tikz@temppath}% change the path
+ \pgfsyssoftpath@setcurrentpath\tikz@temppath%
+ \pgfpushtype%
+ \pgfusetype{.path shade}%
+ \pgfshadepath{\tikz@shading}{\tikz@shade@angle}%
+ \pgfpoptype%
+ \tikz@mode@shadefalse% no more shading...
+ \fi%
+ %
+ % Step 8: Do a path picture if necessary.
+ %
+ \ifx\tikz@path@picture\pgfutil@empty%
+ \else%
+ \begingroup%
+ \pgfusetype{.path picture}%
+ \pgfidscope%
+ \pgfsys@beginscope%
+ \let\tikz@id@name\pgfutil@empty%
+ \pgfclearid%
+ \pgfsyssoftpath@getcurrentpath\tikz@temppath
+ \pgfprocessround{\tikz@temppath}{\tikz@temppath}% change the path
+ \pgfsyssoftpath@setcurrentpath\tikz@temppath%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfsys@clipnext%
+ \pgfsys@discardpath%
+ \pgf@relevantforpicturesizefalse%
+ \expandafter\def\csname pgf@sh@ns@path picture bounding box\endcsname{rectangle}
+ \expandafter\edef\csname pgf@sh@np@path picture bounding box\endcsname{%
+ \def\noexpand\southwest{\noexpand\pgfqpoint{\the\pgf@pathminx}{\the\pgf@pathminy}}%
+ \def\noexpand\northeast{\noexpand\pgfqpoint{\the\pgf@pathmaxx}{\the\pgf@pathmaxy}}%
+ }
+ \expandafter\def\csname pgf@sh@nt@path picture bounding box\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
+ \expandafter\def\csname pgf@sh@pi@path picture bounding box\endcsname{\pgfpictureid}
+ \pgfinterruptpath%
+ \tikz@path@picture%
+ \endpgfinterruptpath%
+ \pgfsys@endscope%
+ \endpgfidscope%
+ \endgroup%
+ \let\tikz@path@picture=\pgfutil@empty%
+ \fi%
+ %
+ % Step 9: Double stroke, if necessary
+ %
+ \iftikz@mode@draw%
+ \iftikz@mode@double%
+ % Change line width
+ \begingroup%
+ \pgfsys@beginscope%
+ \tikz@double@setup%
+ \fi%
+ \fi%
+ %
+ % Step 10: Do stroke/fill/clip as needed
+ %
+ \pgfpushtype%
+ \edef\tikz@temp{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw,\fi%
+ \iftikz@mode@clip clip\fi%
+ }}%
+ \pgfusetype{.path}%
+ \tikz@temp%
+ \pgfpoptype%
+ \tikz@mode@fillfalse% no more filling
+ %
+ % Step 11: Double stroke, if necessary
+ %
+ \iftikz@mode@draw%
+ \iftikz@mode@double%
+ \pgfsys@endscope%
+ \endgroup%
+ \fi%
+ \fi%
+ \tikz@mode@drawfalse% no more stroking
+ %
+ % Step 12: Postactions
+ %
+ \tikz@postactions%
+ %
+ % Step 13: Add labels and nodes
+ %
+ \box\tikz@figbox%
+ %
+ % Step 14: Close animations
+ %
+ \iftikz@mode@clip\else\endgroup\endpgfidscope\fi%
+ %
+ % Step 14: Close option brace
+ %
+ \ifx\tikz@options\pgfutil@empty%
+ \else%
+ \endgroup%
+ \global\let\pgf@strokecolor@global=\pgfscope@stroke@color%
+ \global\let\pgf@fillcolor@global=\pgfscope@fill@color%
+ \pgfsys@endscope%
+ \iftikz@mode@clip%
+ \tikzerror{Extra options not allowed for clipping path command.}%
+ \fi%
+ \fi%
+ \iftikz@mode@clip%
+ \aftergroup\pgf@relevantforpicturesizefalse%
+ \fi%
+ \iftikz@mode@boundary%
+ \aftergroup\pgf@relevantforpicturesizefalse%
+ \fi%
+ \endgroup%
+ \global\pgflinewidth=\tikzscope@linewidth%
+ \tikz@path@do@at@end%
+}%
+\let\tikz@lib@scope@check\pgfutil@empty% this is a hook for the scopes library
+\def\tikz@path@do@at@end{\tikz@lib@scope@check}%
+\def\tikz@@pathtext{@path}%
+
+\def\pgf@outer@auto@adjust@hook{%
+ {%
+ \tikz@mode@drawfalse%
+ \tikz@mode%
+ \expandafter%
+ }%
+ \iftikz@mode@draw\else%
+ \pgfkeyslet{/pgf/outer xsep}\pgf@zero@text
+ \pgfkeyslet{/pgf/outer ysep}\pgf@zero@text
+ \fi%
+}%
+
+% Extra actions
+
+\def\tikz@extra@preaction#1{%
+ {%
+ \pgfsys@beginscope%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \path[#1];% do extra path
+ \pgfsyssoftpath@setcurrentpath\tikz@actions@path% restore
+ \tikz@restorepathsize%
+ \pgfsys@endscope%
+ }%
+}%
+
+\def\tikz@extra@postaction#1{%
+ {%
+ \pgfsys@beginscope%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \tikz@restorepathsize%
+ \path[#1]\pgfextra{\pgfsyssoftpath@setcurrentpath\tikz@actions@path};% do extra path
+ \pgf@resetpathsizes%
+ \pgfsys@endscope%
+ }%
+}%
+
+
+
+\def\tikz@skip#1{\tikz@scan@next@command#1}%
+\def\tikz@expand{%
+ \advance\tikz@expandcount by -1
+ \ifnum\tikz@expandcount<0\relax%
+ \expandafter\pgfutil@firstoftwo
+ \else
+ \expandafter\pgfutil@secondoftwo
+ \fi
+ {%
+ \tikzerror{Giving up on this path. Did you forget a semicolon?}%
+ % since the last token caused an error we should reinsert it and therefore save it
+ \global\let\tikz@expand@last@token=\pgf@let@token
+ \tikz@finish%
+ %
+ % To be combatible with `scopes` lib, which uses a redefined
+ % \tikz@lib@scope@check to check the next token, the reinsertion is done
+ % here, not at the end of (every) \tikz@finish.
+ %
+ \expandafter\let\expandafter\tikz@expand@last@token@\csname tikz@expand@last@token\endcsname
+ \global\let\tikz@expand@last@token=\relax
+ \tikz@expand@last@token@
+ }{%
+ \tikz@@expand
+ }%
+}
+
+\def\tikz@@expand{%
+ \expandafter\tikz@scan@next@command\pgf@let@token}%
+
+
+
+% Syntax for scopes:
+% {scoped path commands}
+
+\newif\iftikz@auto@end@path
+
+\def\tikz@beginscope{\begingroup\tikz@auto@end@pathfalse\tikz@scan@next@command}%
+\def\tikz@endscope{%
+ \iftikz@auto@end@path\expandafter\tikz@finish\expandafter\egroup\else\expandafter\tikz@@endscope\fi%
+}%
+\def\tikz@@endscope{%
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ \global\let\tikz@tangent@temp\tikz@tangent%
+ \edef\tikz@marshal{%
+ \tikz@lastx=\the\tikz@lastx%
+ \tikz@lasty=\the\tikz@lasty%
+ \iftikz@current@point@local%
+ \else%
+ \tikz@lastxsaved=\the\tikz@lastxsaved%
+ \tikz@lastysaved=\the\tikz@lastysaved%
+ \ifx\tikz@moveto@waiting\relax%
+ \let\tikz@moveto@waiting\relax%
+ \else%
+ \def\noexpand\tikz@moveto@waiting{\tikz@moveto@waiting}%
+ \fi%
+ \iftikz@shapeborder%
+ \noexpand\tikz@shapebordertrue%
+ \def\noexpand\tikz@shapeborder@name{\tikz@shapeborder@name}%
+ \else%
+ \noexpand\tikz@shapeborderfalse%
+ \fi%
+ \fi%
+ }%
+ \expandafter%
+ \endgroup\tikz@marshal%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \let\tikz@tangent\tikz@tangent@temp%
+ \tikz@scan@next@command}%
+
+
+% Syntax for pgfextra:
+% \pgfextra {normal tex text}
+% \pgfextra normal tex text \endpgfextra
+
+\def\tikz@extra{\pgfutil@ifnextchar\bgroup\tikz@@extra\relax}%
+\long\def\tikz@@extra#1{#1\tikz@scan@next@command}%
+\let\endpgfextra=\tikz@scan@next@command
+
+\def\pgfextra{pgfextra}%
+
+
+% Syntax for foreach:
+%
+% foreach \var in {list} {path text}
+%
+% or
+%
+% \foreach \var in {list} {path text}
+%
+% Example:
+%
+% \draw (0,0) \foreach \x in {1,2,3} {-- (\x,0) circle (1cm)} -- (5,5);
+
+\def\tikz@fchar oreach{\tikz@foreach}%
+
+\def\tikz@foreach{%
+ \def\pgffor@beginhook{%
+ \tikz@lastx=\tikz@foreach@save@lastx%
+ \tikz@lasty=\tikz@foreach@save@lasty%
+ \tikz@lastxsaved=\tikz@foreach@save@lastxsaved%
+ \tikz@lastysaved=\tikz@foreach@save@lastysaved%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \expandafter\tikz@scan@next@command\pgfutil@firstofone}%
+ \def\pgffor@endhook{\pgfextra{%
+ \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}%
+ \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}%
+ \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}%
+ \xdef\tikz@foreach@save@lastysaved{\the\tikz@lastysaved}%
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ \pgfutil@gobble}}%
+ \def\pgffor@afterhook{%
+ \tikz@lastx=\tikz@foreach@save@lastx%
+ \tikz@lasty=\tikz@foreach@save@lasty%
+ \tikz@lastxsaved=\tikz@foreach@save@lastxsaved%
+ \tikz@lastysaved=\tikz@foreach@save@lastysaved%
+ \let\pgffor@beginhook\relax%
+ \let\pgffor@endhook\relax%
+ \let\pgffor@afterhook\relax%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \tikz@scan@next@command}%
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}%
+ \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}%
+ \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}%
+ \xdef\tikz@foreach@save@lastysaved{\the\tikz@lastysaved}%
+ \foreach}%
+
+
+% Syntax for againpath:
+% \againpath \somepathname
+
+\def\tikz@command@againpath#1{%
+ \pgfextra{%
+ \pgfsyssoftpath@getcurrentpath\tikz@temp%
+ \expandafter\pgfutil@g@addto@macro\expandafter\tikz@temp\expandafter{#1}%
+ \pgfsyssoftpath@setcurrentpath\tikz@temp%
+ }%
+}%
+
+
+% animation syntax
+% :attribute = {...}
+
+\def\tikz@colon@char#1=#2{%
+ \tikz@scan@next@command{[animate={myself:{#1}={#2}}]}%
+}%
+
+
+
+%
+% When this if is set, a just-scanned point is a shape and its border
+% position still needs to be determined, depending on subsequent
+% commands.
+%
+
+\newif\iftikz@shapeborder
+
+
+% Syntax for moveto:
+% <point>
+\def\tikz@movetoabs{\tikz@moveto(}%
+\def\tikz@movetorel{\tikz@moveto+}%
+\def\tikz@moveto{%
+ \tikz@scan@one@point{\tikz@@moveto}}%
+\def\tikz@@moveto#1{%
+ \tikz@make@last@position{#1}%
+ \iftikz@shapeborder%
+ % ok, the moveto will have to wait. flag that we have a moveto in
+ % waiting:
+ \edef\tikz@moveto@waiting{\tikz@shapeborder@name}%
+ \else%
+ \tikz@@movetosave{\tikz@last@position}%
+ \let\tikz@moveto@waiting=\relax%
+ \fi%
+ \tikz@scan@next@command%
+}%
+
+ % Wrapper around \pgfpathmoveto that adds a save
+\def\tikz@@movetosave#1{%
+ {\pgftransformreset
+ \pgf@process{#1}%
+ \xdef\tikz@marshal{%
+ \tikz@lastmovetox=\the\pgf@x\relax%
+ \tikz@lastmovetoy=\the\pgf@y\relax%
+ }%
+ }%
+ \tikz@marshal
+ \pgfpathmoveto{#1}%
+}%
+
+
+\let\tikz@moveto@waiting=\relax % normally, nothing is waiting...
+
+\def\tikz@flush@moveto{%
+ \ifx\tikz@moveto@waiting\relax%
+ \else%
+ \tikz@@movetosave{\tikz@last@position}%
+ \fi%
+ \let\tikz@moveto@waiting=\relax%
+}%
+
+
+\def\tikz@flush@moveto@toward#1#2#3{%
+ % #1 = a point towards which the last moveto should be corrected
+ % #2 = a dimension to which the corrected x-coordinate should be stored
+ % #3 = a dimension for the corrected y-coordinate
+ \ifx\tikz@moveto@waiting\relax%
+ % do nothing
+ \else%
+ \pgf@process{\pgfpointshapeborder{\tikz@moveto@waiting}{#1}}%
+ #2=\pgf@x%
+ #3=\pgf@y%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \tikz@@movetosave{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \fi%
+ \let\tikz@moveto@waiting=\relax%
+}%
+
+
+%
+% Collecting labels on the path
+%
+
+\def\tikz@collect@coordinate@onpath#1c{%
+ \pgfutil@ifnextchar y{\tikz@cycle@expander@add#1}{\tikz@collect@coordinate@onpath@{#1}}}%
+\def\tikz@collect@coordinate@onpath@#1oordinate{%
+ \pgfutil@ifnextchar[{\tikz@@collect@coordinate@opt#1}{\tikz@@collect@coordinate@opt#1[]}}%}%
+\def\tikz@@collect@coordinate@opt#1[#2]{%
+ \pgfutil@ifnextchar({\tikz@@collect@coordinate#1[#2]}{%
+ \tikz@collect@label@onpath#1node[shape=coordinate,#2]{}}}%}%
+\def\tikz@@collect@coordinate#1[#2](#3){%
+ \tikz@collect@label@onpath#1node[shape=coordinate,#2](#3){}}%
+
+\newif\iftikz@collect@pic
+
+\def\tikz@collect@label@onpath#1node{%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath node}%
+ \let\tikz@collect@cont#1%
+ \tikz@collect@picfalse%
+ \tikz@collect@label@scan}%
+
+\def\tikz@collect@pic@onpath#1pic{%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath pic}%
+ \let\tikz@collect@cont#1
+ \tikz@collect@pictrue%
+ \tikz@collect@label@scan}%
+
+\def\tikz@collect@label@scan{%
+ \pgfutil@ifnextchar f{\tikz@collect@nodes}{%
+ \pgfutil@ifnextchar({\tikz@collect@paran}%
+ {\pgfutil@ifnextchar[{\tikz@collect@options}%
+ {\pgfutil@ifnextchar:{\tikz@collect@animation}%
+ {\pgfutil@ifnextchar\bgroup{\tikz@collect@arg}%
+ {\tikz@collect@cont}}}}}%
+}%}}%
+
+\def\tikz@collect@nodes foreach#1in{%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath foreach#1in}%
+ \pgfutil@ifnextchar\bgroup\tikz@collect@nodes@group\tikz@collect@nodes@one%
+}%
+\def\tikz@collect@nodes@one#1{%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath #1}%
+ \tikz@collect@label@scan%
+}%
+\def\tikz@collect@nodes@group#1{%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}%
+ \tikz@collect@label@scan%
+}%
+
+\def\tikz@collect@animation#1=#2{%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1={#2}}%
+ \tikz@collect@label@scan%
+}%
+\def\tikz@collect@paran#1){%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1)}%
+ \tikz@collect@label@scan%
+}%
+\def\tikz@collect@options#1]{%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1]}%
+ \tikz@collect@label@scan%
+}%
+\def\tikz@collect@arg#1{%
+ \iftikz@handle@active@nodes%
+ \iftikz@collect@pic%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}%
+ \else%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{\scantokens{#1}}}%
+ \fi%
+ \else%
+ \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}%
+ \fi%
+ \tikz@collect@cont%
+}%
+
+\def\tikz@invoke@collected@onpath{%
+ \tikz@node@is@a@labeltrue%
+ \let\tikz@temp=\tikz@collected@onpath%
+ \let\tikz@collected@onpath=\pgfutil@empty%
+ \expandafter\tikz@scan@next@command\tikz@temp\pgf@stop%
+ \tikz@node@is@a@labelfalse%
+}%
+
+
+%
+% Macros for the cycle command
+%
+
+\def\tikz@cycle@expander#1{\pgfutil@ifnextchar c{\tikz@cycle@expander@{#1}}{#1}}%
+\def\tikz@cycle@expander@#1c{\pgfutil@ifnextchar y{\tikz@cycle@expander@add{#1}}{#1c}}%
+\def\tikz@cycle@expander@add#1ycle{#1(current subpath start)--cycle}%
+
+
+
+
+% Syntax for lineto:
+% -- <point>
+
+\def\tikz@lineto{%
+ \pgfutil@ifnextchar |%
+ {\expandafter\tikz@hv@lineto\pgfutil@gobble}%
+ {\expandafter\pgfutil@ifnextchar\tikz@activebar{\expandafter\tikz@hv@lineto\pgfutil@gobble}%
+ {\expandafter\tikz@lineto@mid\pgfutil@gobble}}}%
+\def\tikz@lineto@mid{%
+ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@lineto@mid}%
+ {%
+ \pgfutil@ifnextchar c{\tikz@close}{%
+ \pgfutil@ifnextchar p{\tikz@lineto@plot@or@pic}{\tikz@scan@one@point{\tikz@@lineto}}}}}%
+\def\tikz@lineto@plot@or@pic p{%
+ \pgfutil@ifnextchar i{\tikz@collect@pic@onpath\tikz@lineto@mid p}{%
+ \pgfsetlinetofirstplotpoint\tikz@plot}%
+}%
+\def\tikz@@lineto#1{%
+ % Record the starting point for later labels on the path:
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}
+ \iftikz@shapeborder%
+ % ok, target is a shape. recalculate end
+ \pgf@process{\pgfpointshapeborder{\tikz@shapeborder@name}{\tikz@last@position}}%
+ \tikz@make@last@position{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \tikz@flush@moveto@toward{\tikz@last@position}\pgf@x\pgf@y%
+ \tikz@path@lineto{\tikz@last@position}%
+ \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \tikz@make@last@position{#1}%
+ \edef\tikz@moveto@waiting{\tikz@shapeborder@name}%
+ \else%
+ % target is a reasonable point...
+ % Record the starting point for later labels on the path:
+ \tikz@make@last@position{#1}%
+ \tikz@flush@moveto@toward{\tikz@last@position}\pgf@x\pgf@y%
+ \tikz@path@lineto{\tikz@last@position}%
+ \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \fi%
+ \let\tikz@timer=\tikz@timer@line%
+ \let\tikz@tangent\tikz@timer@start%
+ \tikz@scan@next@command%
+}%
+
+% snake or lineto?
+\def\tikz@path@lineto#1{%
+ \iftikz@snaked%
+ {
+ \pgfsyssoftpathmovetorelevantfalse%
+ \pgfpathsnakesto{\tikz@presnake,{\tikz@snake}{\tikz@mainsnakelength}{\noexpand\tikz@snake@install@trans}{},\tikz@postsnake}{#1}%
+ }
+ \else%
+ \pgfpathlineto{#1}%
+ \fi%
+}%
+
+% snake or lineto?
+\def\tikz@path@close#1{%
+ \iftikz@snaked%
+ {%
+ \pgftransformreset%
+ \pgfpathsnakesto{\tikz@presnake,{\tikz@snake}{\tikz@mainsnakelength}{\noexpand\tikz@snake@install@trans}{},\tikz@postsnake}{#1}%
+ }%
+ \fi%
+ \pgfpathclose%
+}%
+
+
+% Syntax for lineto horizontal/vertical:
+% -| <point>
+
+\def\tikz@hv@lineto{%
+ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@hv@lineto}{%
+ \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@hv@lineto}%
+ {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@hv@lineto}%
+ {\tikz@scan@one@point{\tikz@@hv@lineto}}}}}%
+\def\tikz@@hv@lineto#1{%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \pgf@yc=\tikz@lasty%
+ \tikz@make@last@position{#1}%
+ \edef\tikz@tangent{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\pgf@yc}}%
+ \tikz@flush@moveto@toward{\pgfqpoint{\tikz@lastx}{\pgf@yc}}\pgf@x\pgf@yc%
+ \iftikz@shapeborder%
+ % ok, target is a shape. have to work now:
+ {%
+ \pgf@process{\pgfpointshapeborder{\tikz@shapeborder@name}{\pgfqpoint{\tikz@lastx}{\pgf@yc}}}%
+ \tikz@make@last@position{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \tikz@path@lineto{\pgfqpoint{\tikz@lastx}{\pgf@yc}}%
+ \tikz@path@lineto{\tikz@last@position}%
+ \xdef\tikz@timer@end@temp{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% move out of group
+ }%
+ \let\tikz@timer@end=\tikz@timer@end@temp%
+ \edef\tikz@moveto@waiting{\tikz@shapeborder@name}%
+ \else%
+ \tikz@path@lineto{\pgfqpoint{\tikz@lastx}{\pgf@yc}}%
+ \tikz@path@lineto{\tikz@last@position}%
+ \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% move out of group
+ \fi%
+ \let\tikz@timer=\tikz@timer@hvline%
+ \tikz@scan@next@command%
+}%
+
+% Syntax for lineto vertical/horizontal:
+% |- <point>
+
+\def\tikz@vh@lineto-{\tikz@vh@lineto@next}%
+\def\tikz@vh@lineto@next{%
+ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@vh@lineto@next}{%
+ \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@vh@lineto@next}%
+ {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@vh@lineto@next}%
+ {\tikz@scan@one@point\tikz@@vh@lineto}}}}%
+\def\tikz@@vh@lineto#1{%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \pgf@xc=\tikz@lastx%
+ \tikz@make@last@position{#1}%
+ \edef\tikz@tangent{\noexpand\pgfqpoint{\the\pgf@xc}{\the\tikz@lasty}}%
+ \tikz@flush@moveto@toward{\pgfqpoint{\pgf@xc}{\tikz@lasty}}\pgf@xc\pgf@y%
+ \iftikz@shapeborder%
+ % ok, target is a shape. have to work now:
+ {%
+ \pgf@process{\pgfpointshapeborder{\tikz@shapeborder@name}{\pgfqpoint{\pgf@xc}{\tikz@lasty}}}%
+ \tikz@make@last@position{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \tikz@path@lineto{\pgfqpoint{\pgf@xc}{\tikz@lasty}}%
+ \tikz@path@lineto{\tikz@last@position}%
+ \xdef\tikz@timer@end@temp{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% move out of group
+ }%
+ \let\tikz@timer@end=\tikz@timer@end@temp%
+ \edef\tikz@moveto@waiting{\tikz@shapeborder@name}%
+ \else%
+ \tikz@path@lineto{\pgfqpoint{\pgf@xc}{\tikz@lasty}}%
+ \tikz@path@lineto{\tikz@last@position}%
+ \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \fi%
+ \let\tikz@timer=\tikz@timer@vhline%
+ \tikz@scan@next@command%
+}%
+
+% Syntax for cycle:
+% -- cycle
+\def\tikz@close c{%
+ \pgfutil@ifnextchar o{\tikz@collect@coordinate@onpath\tikz@lineto@mid c}% oops, a coordinate
+ {\tikz@@close c}}%
+\def\tikz@@close cycle{%
+ \tikz@flush@moveto%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}
+ \tikz@make@last@position{\expandafter\pgfpoint\pgfsyssoftpath@lastmoveto}%
+ \tikz@path@close{\expandafter\pgfpoint\pgfsyssoftpath@lastmoveto}%
+ \def\pgfstrokehook{}%
+ \edef\tikz@timer@end{%\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \noexpand\pgfqpoint{\the\tikz@lastmovetox}{\the\tikz@lastmovetoy}}%
+ \let\tikz@timer=\tikz@timer@line%
+ \let\tikz@tangent\tikz@timer@start%
+ \tikz@scan@next@command%
+}%
+
+
+% Syntax for options:
+% [options]
+\def\tikz@parse@options#1]{%
+ \tikzset{#1}%
+ \tikz@scan@next@command%
+}%
+
+% Syntax for edges:
+% edge [options] (coordinate)
+% edge [options] node {node text} (coordinate)
+% edge :attribute={...} [options] node {node text} (coordinate)
+\def\tikz@edge@plain{%
+ \begingroup%
+ \ifx\tikz@to@use@whom\pgfutil@undefined\else\tikz@to@use@whom\fi
+ \let\tikz@to@or@edge@function=\tikz@do@edge%
+ \let\tikz@@to@local@options\pgfutil@empty%
+ \let\tikz@collected@onpath=\pgfutil@empty%
+ \tikz@to@or@edge}%
+
+% Syntax for to paths:
+% to [options] (coordinate)
+% to [options] node {node text} (coordinate)
+% to :attribute={...} [options] node {node text} (coordinate)
+\def\tikz@to o{%
+ \tikz@to@use@last@coordinate%
+ \let\tikz@to@or@edge@function=\tikz@do@to%
+ \let\tikz@@to@local@options\pgfutil@empty%
+ \let\tikz@collected@onpath=\pgfutil@empty%
+ \tikz@to@or@edge}%
+
+\def\tikz@to@or@edge{%
+ \pgfutil@ifnextchar[{\tikz@to@or@edge@option}{%
+ \pgfutil@ifnextchar:{\tikz@to@or@edge@animation}{%
+ \tikz@@to@collect}}%]
+}%
+\def\tikz@to@or@edge@option[#1]{%
+ \expandafter\def\expandafter\tikz@@to@local@options\expandafter{\tikz@@to@local@options,#1}%
+ \tikz@to@or@edge%
+}%
+\def\tikz@to@or@edge@animation:#1=#2{%
+ \expandafter\def\expandafter\tikz@@to@local@options\expandafter{\tikz@@to@local@options,%
+ animate={myself:{#1}={#2}}}%
+ \tikz@to@or@edge%
+}%
+\def\tikz@@to@collect{%
+ \pgfutil@ifnextchar(\tikz@@to@or@edge@coordinate%)
+ {\pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@to@collect}%
+ {\pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@to@collect}%
+ {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@to@collect}%
+ {\pgfutil@ifnextchar +{\tikz@scan@one@point\tikz@@to@or@edge@math}%
+ {\tikzerror{(, +, coordinate, pic, or node expected}%)
+ \tikz@@to@or@edge@coordinate()}}}}}%
+}%
+
+\def\tikz@@to@or@edge@coordinate({%
+ \pgfutil@ifnextchar${%$
+ % Ok, parse directly
+ \tikz@scan@one@point\tikz@@to@or@edge@math(%
+ }{%
+ \pgfutil@ifnextchar[{%]
+ \tikz@scan@one@point\tikz@@to@or@edge@math(%
+ }{%
+ \tikz@@to@or@edge@@coordinate(%
+ }%
+ }%
+}%
+\def\tikz@@to@or@edge@math#1{%
+ \pgf@process{#1}%
+ \iftikz@updatecurrent\else
+ \tikz@updatenextfalse
+ \fi
+ \edef\tikztotarget{\the\pgf@x,\the\pgf@y}%
+ \tikz@to@or@edge@function%
+}%
+
+\def\tikz@@to@or@edge@@coordinate(#1){%
+ \def\tikztotarget{#1}%
+ \tikz@to@or@edge@function%
+}%
+
+\def\tikz@do@edge{%
+ \ifx\tikz@edge@macro\pgfutil@empty%
+ \setbox\tikz@whichbox=\hbox\bgroup%
+ \unhbox\tikz@whichbox%
+ \hbox\bgroup
+ \bgroup%
+ \pgfinterruptpath%
+ \pgfscope%
+ \let\tikz@transform=\pgfutil@empty%
+ \let\tikz@options=\pgfutil@empty%
+ \tikz@clear@rdf@options%
+ \let\tikz@tonodes=\tikz@collected@onpath%
+ \def\tikztonodes{{\pgfextra{\tikz@node@is@a@labeltrue}\tikz@tonodes}}%
+ \let\tikz@collected@onpath=\pgfutil@empty%
+ \tikz@options%
+ \tikz@do@rdf@pre@options%
+ \pgfidscope%
+ \tikz@do@rdf@post@options%
+ \tikz@transform%
+ \let\tikz@transform=\relax%
+ % Typeset node:
+ \let\tikz@after@path\pgfutil@empty%
+ \tikz@atbegin@to%
+ \tikz@enable@edge@quotes%
+ \path[style=every edge]\expandafter[\tikz@@to@local@options](\tikztostart)\tikz@to@path
+ \pgfextra{\global\let\tikz@after@path@smuggle=\tikz@after@path};%
+ \tikz@atend@to%
+ \endpgfidscope%
+ \endpgfscope%
+ \endpgfinterruptpath%
+ \egroup
+ \egroup%
+ \egroup%
+ \global\setbox\tikz@tempbox=\box\tikz@whichbox%
+ \expandafter\endgroup%
+ \expandafter\setbox\tikz@whichbox=\box\tikz@tempbox%
+ \else%
+ \expandafter\expandafter\expandafter\tikz@edge@macro%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@@to@local@options\expandafter}\expandafter{\tikz@collected@onpath}%
+ \endgroup%
+ \let\tikz@after@path@smuggle=\pgfutil@empty%
+ \fi%
+ \expandafter\tikz@scan@next@command\tikz@after@path@smuggle%
+}%
+
+\def\tikz@do@to{%
+ \let\tikz@tonodes=\tikz@collected@onpath%
+ \def\tikztonodes{{\pgfextra{\tikz@node@is@a@labeltrue}\tikz@tonodes}}%
+ \let\tikz@collected@onpath=\pgfutil@empty%
+ \tikz@scan@next@command%
+ {%
+ \pgfextra{\let\tikz@after@path\pgfutil@empty}%
+ \pgfextra{\tikz@atbegin@to}%
+ \pgfextra{\tikz@enable@edge@quotes}%
+ [style=every to]\expandafter[\tikz@@to@local@options]\tikz@to@path%
+ \pgfextra{\tikz@atend@to}%
+ \pgf@stop%
+ \expandafter\tikz@scan@next@command\expandafter%
+ }\tikz@after@path%
+ \pgfextra{\tikz@updatenexttrue\tikz@updatecurrenttrue}%
+}%
+
+
+\def\tikz@to@use@last@coordinate{%
+ \iftikz@shapeborder%
+ \edef\tikztostart{\tikz@shapeborder@name}%
+ \else%
+ \edef\tikztostart{\the\tikz@lastx,\the\tikz@lasty}%
+ \fi%
+}%
+\def\tikz@to@use@last@fig@name{%
+ \edef\tikztostart{\tikz@to@last@fig@name}%
+}%
+
+
+
+% Syntax for graph path command:
+% graph [options] {...}
+% See the graph library for details
+
+\def\tikz@graph aph{\tikz@lib@graph@parser}%
+
+\def\tikz@lib@graph@parser{\pgfutil@ifnextchar[\tikz@graph@error{\tikz@graph@error[]}}%]%
+\def\tikz@graph@error[#1]#2{%
+ \tikzerror{You need to say \string\usetikzlibrary{graphs} in order to use the graph syntax}%
+ \tikz@lib@graph@parser@done%
+}%
+
+\def\tikz@lib@graph@parser@done{%
+ \tikz@scan@next@command%
+}%
+
+
+
+
+% Syntax for edge from parent:
+% edge from parent [options]
+\def\tikz@edgetoparent from parent{\pgfutil@ifnextchar[\tikz@@edgetoparent{\tikz@@edgetoparent[]}}%}%
+\def\tikz@@edgetoparent[#1]{%
+ \let\tikz@edge@to@parent@needed=\pgfutil@empty%
+ \def\tikz@edgetoparent@options{#1}%
+ \begingroup%
+ \let\tikz@collected@onpath=\pgfutil@empty%
+ \tikz@edgetoparentcollect%
+}%
+\def\tikz@edgetoparentcollect{%
+ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@edgetoparentcollect}%
+ {%
+ \expandafter%
+ \endgroup%
+ \expandafter\tikz@edgetoparent@rollout\expandafter{\tikz@collected@onpath}%
+ }%
+}%
+
+\def\tikz@edgetoparent@rollout#1{%
+ \pgfkeysgetvalue{/tikz/edge from parent macro}\tikz@etop@temp
+ \expandafter\tikz@scan@next@command\expandafter\tikz@etop@temp\expandafter{\tikz@edgetoparent@options}{#1}%
+}%
+
+
+% Syntax for bezier curves
+% .. controls(point) and (point) .. (target)
+% .. controls(point) .. (target)
+% .. (target) % currently not supported
+
+\def\tikz@dot.{\tikz@@dot}%
+\def\tikz@@dot{%
+ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@dot}{%
+ \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@dot}%
+ {\pgfutil@ifnextchar c{\tikz@curveto@double}{\tikz@curveto@auto}}}%
+}%
+
+\def\tikz@curveto@double co{%
+ \pgfutil@ifnextchar o{\tikz@collect@coordinate@onpath\tikz@@dot co}
+ {\tikz@cureveto@@double}}%
+\def\tikz@cureveto@@double ntrols#1{%
+ \tikz@scan@one@point\tikz@curveA#1%
+}%
+\def\tikz@curveA#1{%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ {%
+ \tikz@lastxsaved=\tikz@lastx%
+ \tikz@lastysaved=\tikz@lasty%
+ \tikz@make@last@position{#1}%
+ \xdef\tikz@curve@first{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ }%
+ \pgfutil@ifnextchar a
+ {\tikz@curveBand}%
+ {\let\tikz@curve@second\tikz@curve@first\tikz@curveCdots}%
+}%
+\def\tikz@curveBand and{%
+ \tikz@scan@one@point\tikz@curveB%
+}%
+\def\tikz@curveB#1{%
+ \def\tikz@curve@second{#1}%
+ \tikz@curveCdots}
+\def\tikz@curveCdots{%
+ \afterassignment\tikz@curveCdot\let\pgfutil@next=}%
+\def\tikz@curveCdot.{%
+ \ifx\pgfutil@next.%
+ \else%
+ \tikzerror{Dot expected}%
+ \fi%
+ \iftikz@updatenext
+ \tikz@updatecurrenttrue%
+ \fi
+ \tikz@curveCcheck%
+}%
+\def\tikz@curveCcheck{%
+ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@curveCcheck}{%
+ \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@curveCcheck}%
+ {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@curveCcheck}
+ {\tikz@scan@one@point\tikz@curveC}}}%
+}%
+\def\tikz@curveC#1{%
+ \tikz@make@last@position{#1}%
+ \edef\tikz@curve@third{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ {%
+ \tikz@lastxsaved=\tikz@lastx%
+ \tikz@lastysaved=\tikz@lasty%
+ \tikz@make@last@position{\tikz@curve@second}%
+ \xdef\tikz@curve@second{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ }%
+ %
+ % Start recalculating things in case start and end are shapes.
+ %
+ % First, the start:
+ \ifx\tikz@moveto@waiting\relax%
+ \else%
+ \pgf@process{\pgfpointshapeborder{\tikz@moveto@waiting}{\tikz@curve@first}}%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \tikz@@movetosave{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \fi%
+ \let\tikz@timer@cont@one=\tikz@curve@first%
+ \let\tikz@timer@cont@two=\tikz@curve@second%
+ % Second, the end:
+ \iftikz@shapeborder%
+ % ok, target is a shape. recalculate third
+ {%
+ \pgf@process{\pgfpointshapeborder{\tikz@shapeborder@name}{\tikz@curve@second}}%
+ \tikz@make@last@position{\pgfqpoint{\pgf@x}{\pgf@y}}%
+ \edef\tikz@curve@third{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \pgfpathcurveto{\tikz@curve@first}{\tikz@curve@second}{\tikz@curve@third}%
+ \global\let\tikz@timer@end@temp=\tikz@curve@third% move out of group
+ }%
+ \let\tikz@timer@end=\tikz@timer@end@temp%
+ \edef\tikz@moveto@waiting{\tikz@shapeborder@name}%
+ \else%
+ \pgfpathcurveto{\tikz@curve@first}{\tikz@curve@second}{\tikz@curve@third}%
+ \let\tikz@timer@end=\tikz@curve@third
+ \let\tikz@moveto@waiting=\relax%
+ \fi%
+ \let\tikz@timer=\tikz@timer@curve%
+ \let\tikz@tangent=\tikz@curve@second%
+ \tikz@scan@next@command%
+}%
+
+
+% Syntax for rectangles:
+% rectangle <corner point>
+\def\tikz@rect ectangle{%
+ \tikz@flush@moveto%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \tikz@@rect}%
+\def\tikz@@rect{%
+ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@rect}{%
+ \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@rect}%
+ {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@rect}%
+ {
+ \pgf@xa=\tikz@lastx\relax%
+ \pgf@ya=\tikz@lasty\relax%
+ \tikz@scan@one@point\tikz@rectB}}}}%
+\def\tikz@rectB#1{%
+ \tikz@make@last@position{#1}%
+ \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \let\tikz@timer=\tikz@timer@line%
+ \tikz@@movetosave{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \tikz@path@lineto{\pgfqpoint{\pgf@xa}{\tikz@lasty}}%
+ \tikz@path@lineto{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}%
+ \tikz@path@lineto{\pgfqpoint{\tikz@lastx}{\pgf@ya}}%
+ \iftikz@snaked%
+ \tikz@path@lineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \fi%
+ \pgfpathclose%
+ \tikz@@movetosave{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}%
+ \def\pgfstrokehook{}%
+ \let\tikz@tangent\relax%
+ \tikz@scan@next@command%
+}%
+
+
+
+% Syntax for grids:
+% grid <corner point>
+\def\tikz@grid id{%
+ \tikz@flush@moveto%
+ \pgf@xa=\tikz@lastx\relax%
+ \pgf@ya=\tikz@lasty\relax%
+ \pgfutil@ifnextchar[{\tikz@gridA}{\tikz@gridA[]}}%}%
+\def\tikz@gridA[#1]{%
+ \def\tikz@grid@options{#1}%
+ \tikz@cycle@expander{\tikz@scan@one@point\tikz@gridB}}%
+\def\tikz@gridB#1{%
+ \tikz@make@last@position{#1}%
+ \let\tikz@tangent\relax%
+ {%
+ \let\tikz@after@path\pgfutil@empty%
+ \expandafter\tikzset\expandafter{\tikz@grid@options}
+ \tikz@checkunit{\tikz@grid@x}%
+ \iftikz@isdimension%
+ \pgf@process{\pgfpoint{\tikz@grid@x}{0pt}}%
+ \else%
+ \pgf@process{\pgfpointxy{\tikz@grid@x}{0}}%
+ \fi%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \tikz@checkunit{\tikz@grid@y}%
+ \iftikz@isdimension%
+ \pgf@process{\pgfpoint{0pt}{\tikz@grid@y}}%
+ \else%
+ \pgf@process{\pgfpointxy{0}{\tikz@grid@y}}%
+ \fi%
+ \advance\pgf@xb by\pgf@x%
+ \advance\pgf@yb by\pgf@y%
+ \pgfpathgrid[stepx=\pgf@xb,stepy=\pgf@yb]%
+ {\pgfqpoint{\pgf@xa}{\pgf@ya}}{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}%
+ \expandafter}%
+ \expandafter\tikz@scan@next@command\tikz@after@path%
+}%
+
+
+
+% Syntax for plot:
+% plot [local options] ... % starts with a moveto
+% -- plot [local options] ... % starts with a lineto
+\def\tikz@plot lot{%
+ \tikz@flush@moveto%
+ \pgfutil@ifnextchar[{\tikz@@plot}{\tikz@@plot[]}}%}%
+\def\tikz@@plot[#1]{%
+ \let\tikz@tangent\tikz@tangent@lookup%
+ \begingroup%
+ \let\tikz@after@path\pgfutil@empty%
+ \let\tikz@options=\pgfutil@empty%
+ \tikzset{every plot/.try}%
+ \tikzset{#1}%
+ \pgfutil@ifnextchar f{\tikz@plot@f}%
+ {\pgfutil@ifnextchar c{\tikz@plot@scan@points}%
+ {\pgfutil@ifnextchar ({\tikz@plot@expression}{%
+ \tikzerror{Cannot parse this plotting data}%
+ \endgroup}}}}%
+\def\tikz@plot@f f{\pgfutil@ifnextchar i{\tikz@plot@file}{\tikz@plot@function}}%
+
+\def\tikz@plot@file ile#1{\def\tikz@plot@data{\pgfplotxyfile{#1}}\tikz@@@plot}%
+\def\tikz@plot@scan@points coordinates#1{%
+ \pgfplothandlerrecord\tikz@plot@data%
+ \pgfplotstreamstart%
+ \pgfutil@ifnextchar\pgf@stop{\pgfplotstreamend\expandafter\tikz@@@plot\pgfutil@gobble}
+ {\tikz@scan@one@point\tikz@plot@next@point}%
+ #1\pgf@stop%
+}%
+\def\tikz@plot@next@point#1{%
+ \pgfplotstreampoint{#1}%
+ \pgfutil@ifnextchar\pgf@stop{\pgfplotstreamend\expandafter\tikz@@@plot\pgfutil@gobble}%
+ {\tikz@scan@one@point\tikz@plot@next@point}%
+}%
+\def\tikz@plot@function unction#1{%
+ \def\tikz@plot@filename{\tikz@plot@prefix\tikz@plot@id}%
+ \iftikz@plot@raw@gnuplot%
+ \def\tikz@plot@data{\pgfplotgnuplot[\tikz@plot@filename]{#1}}%
+ \else%
+ \iftikz@plot@parametric%
+ \def\tikz@plot@data{\pgfplotgnuplot[\tikz@plot@filename]{%
+ set samples \tikz@plot@samples;
+ set parametric;
+ plot [t=\tikz@plot@domain]
+ [\tikz@plot@xrange]
+ [\tikz@plot@range]
+ #1}}%
+ \else%
+ \def\tikz@plot@data{\pgfplotgnuplot[\tikz@plot@filename]{%
+ set samples \tikz@plot@samples;
+ plot [x=\tikz@plot@domain]
+ \ifx\tikz@plot@range\pgfutil@empty\else[\tikz@plot@range]\fi
+ #1}}%
+ \fi%
+ \fi%
+ \tikz@@@plot%
+}%
+
+\def\tikz@plot@no@resample{%
+ \pgfutil@IfFileExists{\tikz@plot@filename.table}%
+ {\def\tikz@plot@data{\pgfplotxyfile{\tikz@plot@filename.table}}}%
+ {}%
+}%
+
+\def\tikz@plot@expression(#1){%
+ \edef\tikz@plot@data{\noexpand\pgfplotfunction{\expandafter\noexpand\tikz@plot@var}{\tikz@plot@samplesat}}%
+ \expandafter\def\expandafter\tikz@plot@data\expandafter{\tikz@plot@data{\tikz@scan@one@point\pgfutil@firstofone(#1)}}%
+ \tikz@@@plot%
+}%
+
+\def\tikz@@@plot{%
+ \def\pgfplotlastpoint{\pgfpointorigin}%
+ \tikz@plot@handler%
+ \tikz@plot@data%
+ \global\let\tikz@@@temp=\pgfplotlastpoint%
+ \ifx\tikz@plot@mark\pgfutil@empty%
+ \else%
+ % Marks are drawn after the path.
+ \setbox\tikz@whichbox=\hbox{%
+ \unhbox\tikz@whichbox%
+ \hbox{{%
+ \pgfinterruptpath%
+ \pgfscope%
+ \let\tikz@options=\pgfutil@empty%
+ \let\tikz@transform=\pgfutil@empty%
+ \tikzset{every mark}%
+ \tikz@options%
+ \ifx\tikz@mark@list\pgfutil@empty%
+ \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}}%
+ \else
+ \pgfplothandlermarklisted{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}}{\tikz@mark@list}%
+ \fi
+ \tikz@plot@data%
+ \endpgfscope
+ \endpgfinterruptpath%
+ }}%
+ }%
+ \fi%
+ \global\setbox\tikz@tempbox=\box\tikz@whichbox%
+ \global\let\tikz@after@path@smuggle=\tikz@after@path
+ \expandafter\endgroup%
+ \expandafter\setbox\tikz@whichbox=\box\tikz@tempbox%
+ \tikz@make@last@position{\tikz@@@temp}%
+ \expandafter\tikz@scan@next@command\tikz@after@path@smuggle%
+}%
+
+
+\pgfdeclareplotmark{ball}
+{%
+ \def\tikz@shading{ball}%
+ \shade (0pt,0pt) circle (\pgfplotmarksize);%
+}%
+
+
+
+
+% Syntax for cosine curves:
+% cos <end of quarter-period>
+\def\tikz@cosine s{\tikz@cycle@expander{\tikz@scan@one@point\tikz@@cosine}}
+\def\tikz@@cosine#1{%
+ \let\tikz@tangent\tikz@tangent@lookup%
+ \tikz@flush@moveto%
+ \pgf@process{#1}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xc by-\tikz@lastx%
+ \advance\pgf@yc by-\tikz@lasty%
+ \advance\tikz@lastx by\pgf@xc%
+ \advance\tikz@lasty by\pgf@yc%
+ \tikz@lastxsaved=\tikz@lastx%
+ \tikz@lastysaved=\tikz@lasty%
+ \tikz@updatecurrenttrue%
+ \pgfpathcosine{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \tikz@scan@next@command%
+}%
+
+% Syntax for sine curves:
+% sin <end of quarter-period>
+\def\tikz@sine in{\tikz@cycle@expander{\tikz@scan@one@point\tikz@@sine}}
+\def\tikz@@sine#1{%
+ \let\tikz@tangent\tikz@tangent@lookup%
+ \tikz@flush@moveto%
+ \pgf@process{#1}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xc by-\tikz@lastx%
+ \advance\pgf@yc by-\tikz@lasty%
+ \advance\tikz@lastx by\pgf@xc%
+ \advance\tikz@lasty by\pgf@yc%
+ \tikz@lastxsaved=\tikz@lastx%
+ \tikz@lastysaved=\tikz@lasty%
+ \tikz@updatecurrenttrue%
+ \pgfpathsine{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+ \tikz@scan@next@command%
+}%
+
+% Syntax for parabolas:
+% parabola[options] bend <coordinate> <coordinate>
+\def\tikz@parabola arabola{%
+ \let\tikz@tangent\tikz@tangent@lookup%
+ \pgfutil@ifnextchar[{\tikz@parabola@options}{\tikz@parabola@options[]}}%}%
+
+\def\tikz@parabola@options[#1]{%
+ \def\tikz@parabola@option{#1}%
+ \pgfutil@ifnextchar b{\tikz@parabola@scan@bend}{\tikz@cycle@expander{\tikz@scan@one@point\tikz@parabola@semifinal}}}%
+\def\tikz@parabola@scan@bend bend{\tikz@scan@one@point\tikz@parabola@scan@bendB}%
+\def\tikz@parabola@scan@bendB#1{%
+ \def\tikz@parabola@bend{#1}%
+ \tikz@cycle@expander{\tikz@scan@one@point\tikz@parabola@semifinal}%
+}%
+\def\tikz@parabola@semifinal#1{%
+ \tikz@flush@moveto%
+ % Save original start:
+ \pgf@xb=\tikz@lastx%
+ \pgf@yb=\tikz@lasty%
+ \tikz@make@last@position{#1}%
+ \pgf@xc=\tikz@lastx%
+ \pgf@yc=\tikz@lasty%
+ \begingroup% now calculate bend:
+ \let\tikz@after@path\pgfutil@empty%
+ \expandafter\tikzset\expandafter{\tikz@parabola@option}%
+ \tikz@lastxsaved=\tikz@parabola@bend@factor\tikz@lastx%
+ \tikz@lastysaved=\tikz@parabola@bend@factor\tikz@lasty%
+ \advance\tikz@lastxsaved by\pgf@xb%
+ \advance\tikz@lastysaved by\pgf@yb%
+ \advance\tikz@lastxsaved by-\tikz@parabola@bend@factor\pgf@xb%
+ \advance\tikz@lastysaved by-\tikz@parabola@bend@factor\pgf@yb%
+ \expandafter\tikz@make@last@position\expandafter{\tikz@parabola@bend}%
+ % Calculate delta from bend
+ \advance\pgf@xc by-\tikz@lastx%
+ \advance\pgf@yc by-\tikz@lasty%
+ % Ok, now calculate delta to bend
+ \advance\tikz@lastx by-\pgf@xb%
+ \advance\tikz@lasty by-\pgf@yb%
+ \xdef\tikz@parabola@b{{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}}%
+ \expandafter\endgroup%
+ \expandafter\expandafter\expandafter\pgfpathparabola\expandafter\tikz@parabola@b%
+ \expandafter\tikz@scan@next@command\tikz@after@path%
+}%
+
+
+% Syntax for circles:
+% circle [options] % where options should set, at least, radius
+% circle (radius) % deprecated
+%
+% Syntax for ellipses:
+% ellipse [options] % identical to circle.
+% ellipse (x-radius and y-radius) % deprecated
+%
+% radii can be dimensionless, then they are in the xy-system
+\def\tikz@circle ircle{\tikz@flush@moveto\tikz@@circle}%
+\def\tikz@ellipse llipse{\tikz@flush@moveto\tikz@@circle}%
+\def\tikz@@circle{%
+ \let\tikz@tangent\relax%
+ \pgfutil@ifnextchar(\tikz@@@circle
+ {\pgfutil@ifnextchar[\tikz@circle@opt{%])
+ \advance\tikz@expandcount by -10\relax% go down quickly
+ \ifnum\tikz@expandcount<0\relax%
+ \let\pgfutil@next=\tikz@@circle@normal%
+ \else%
+ \let\pgfutil@next=\tikz@@circle@scanexpand%
+ \fi%
+ \pgfutil@next%
+ }}%
+}%
+\def\tikz@@circle@scanexpand{\expandafter\tikz@@circle}%
+\def\tikz@@circle@normal{\tikz@circle@opt[]}%
+
+\def\tikz@circle@opt[#1]{%
+ {%
+ \def\tikz@node@at{\tikz@last@position}%
+ \let\tikz@transform=\pgfutil@empty%
+ \tikzset{every circle/.try,#1}%
+ \pgftransformshift{\tikz@node@at}%
+ \tikz@transform%
+ \tikz@do@ellipse{\pgfkeysvalueof{/tikz/x radius}}{\pgfkeysvalueof{/tikz/y radius}}
+ }%
+ \tikz@scan@next@command%
+}%
+
+\def\tikz@@@circle(#1){%
+ {%
+ \pgftransformshift{\tikz@last@position}%
+ \pgfutil@in@{ and }{#1}%
+ \ifpgfutil@in@%
+ \tikz@@ellipseB(#1)%
+ \else%
+ \tikz@do@circle{#1}%
+ \fi%
+ }%
+ \tikz@scan@next@command%
+}%
+\def\tikz@@ellipseB(#1 and #2){%
+ \tikz@do@ellipse{#1}{#2}%
+}%
+\def\tikz@do@circle#1{%
+ \pgfmathparse{#1}%
+ \let\tikz@ellipse@x=\pgfmathresult
+ \ifpgfmathunitsdeclared
+ \pgfpathellipse{\pgfpointorigin}%
+ {\pgfqpoint{\tikz@ellipse@x pt}{0pt}}%
+ {\pgfpoint{0pt}{\tikz@ellipse@x pt}}%
+ \else
+ \pgfpathellipse{\pgfpointorigin}%
+ {\pgfpointxy{\tikz@ellipse@x}{0}}%
+ {\pgfpointxy{0}{\tikz@ellipse@x}}%
+ \fi
+}
+\def\tikz@do@ellipse#1#2{
+ \pgfmathparse{#1}%
+ \let\tikz@ellipse@x=\pgfmathresult%
+ \ifpgfmathunitsdeclared%
+ \pgfmathparse{#2}%
+ \let\tikz@ellipse@y=\pgfmathresult%
+ \ifpgfmathunitsdeclared%
+ \pgfpathellipse{\pgfpointorigin}{%
+ \pgfqpoint{\tikz@ellipse@x pt}{0pt}}{\pgfpoint{0pt}{\tikz@ellipse@y pt}}%
+ \else%
+ \tikzerror{You cannot mix dimensions and dimensionless values in an ellipse}%
+ \fi%
+ \else%
+ \pgfmathparse{#2}%
+ \let\tikz@ellipse@y=\pgfmathresult%
+ \ifpgfmathunitsdeclared%
+ \tikzerror{You cannot mix dimensions and dimensionless values in an ellipse}%
+ \else%
+ \pgfpathellipse{\pgfpointorigin}{%
+ \pgfpointxy{\tikz@ellipse@x}{0}}{\pgfpointxy{0}{\tikz@ellipse@y}}%
+ \fi%
+ \fi%
+}%
+
+% Syntax for arcs:
+% arc [options]
+%
+% (The syntax with parentheses is deprecated.)
+\def\tikz@arcA rc{\tikz@flush@moveto\tikz@arc@cont}%
+\def\tikz@arc@cont{%
+ \pgfutil@ifnextchar(%)
+ {\tikz@@arcto}{%
+ \pgfutil@ifnextchar[%]
+ {\tikz@arc@opt}%
+ {%
+ \advance\tikz@expandcount by -10\relax% go down quickly
+ \ifnum\tikz@expandcount<0\relax%
+ \let\pgfutil@next=\tikz@@arc@normal%
+ \else%
+ \let\pgfutil@next=\tikz@@arc@scanexpand%
+ \fi%
+ \pgfutil@next%
+ }%
+ }%
+}%
+\def\tikz@@arc@scanexpand{\expandafter\tikz@arc@cont}%
+\def\tikz@@arc@normal{\tikz@arc@opt[]}%
+
+
+\def\tikz@arc@opt[#1]{%
+ {%
+ \tikzset{every arc/.try,#1}%
+ \pgfkeysgetvalue{/tikz/start angle}\tikz@s
+ \pgfkeysgetvalue{/tikz/end angle}\tikz@e
+ \pgfkeysgetvalue{/tikz/delta angle}\tikz@d
+ \ifx\tikz@s\pgfutil@empty%
+ \pgfmathsetmacro\tikz@s{\tikz@e-\tikz@d}
+ \else
+ \ifx\tikz@e\pgfutil@empty%
+ \pgfmathsetmacro\tikz@e{\tikz@s+\tikz@d}
+ \fi%
+ \fi%
+ \xdef\pgf@marshal{\noexpand%
+ \tikz@do@arc{\tikz@s}{\tikz@e}
+ {\pgfkeysvalueof{/tikz/x radius}}
+ {\pgfkeysvalueof{/tikz/y radius}}}%
+ }%
+ \pgf@marshal%
+ \tikz@arcfinal%
+}%
+
+\def\tikz@@arcto(#1){%
+ \edef\tikz@temp{(#1)}%
+ \expandafter\tikz@@@arcto@check@slashand\tikz@temp%
+}%
+
+\def\tikz@@@arcto@check@slashand(#1:#2:#3){%
+ \pgfutil@in@{ and }{#3}%
+ \ifpgfutil@in@%
+ \tikz@parse@arc@and(#1:#2:#3)%
+ \else%
+ \tikz@parse@arc@and(#1:#2:{#3} and {#3})%
+ \fi%
+ \tikz@arcfinal%
+}%
+
+\def\tikz@parse@arc@and(#1:#2:#3 and #4){%
+ \tikz@do@arc{#1}{#2}{#3}{#4}%
+}%
+\def\tikz@do@arc#1#2#3#4{%
+ \let\tikz@tangent\tikz@tangent@lookup%
+ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \pgfmathsetmacro\tikz@timer@start@angle{#1}%
+ \pgfmathsetmacro\tikz@timer@end@angle{#2}%
+ \pgfmathparse{#3}%
+ \let\tikz@arc@x=\pgfmathresult%
+ \ifpgfmathunitsdeclared%
+ \pgfmathparse{#4}%
+ \let\tikz@arc@y=\pgfmathresult%
+ \ifpgfmathunitsdeclared%
+ \tikz@@@arcfinal{\pgfpatharc{\tikz@timer@start@angle}{\tikz@timer@end@angle}{\tikz@arc@x pt and \tikz@arc@y pt}}
+ {\pgfpointpolar{\tikz@timer@start@angle}{\tikz@arc@x pt and \tikz@arc@y pt}}
+ {\pgfpointpolar{\tikz@timer@end@angle}{\tikz@arc@x pt and \tikz@arc@y pt}}%
+ \edef\tikz@timer@zero@axis{\noexpand\pgfqpoint{\tikz@arc@x pt}{0pt}}
+ \edef\tikz@timer@ninety@axis{\noexpand\pgfqpoint{0pt}{\tikz@arc@y pt}}
+ \else%
+ \tikzerror{You cannot mix dimensions and dimensionless values in an arc}%
+ \fi%
+ \else%
+ \pgfmathparse{#4}%
+ \let\tikz@arc@y=\pgfmathresult%
+ \ifpgfmathunitsdeclared%
+ \tikzerror{You cannot mix dimensions and dimensionless values in an arc}%
+ \else%
+ \tikz@@@arcfinal{\pgfpatharcaxes{\tikz@timer@start@angle}{\tikz@timer@end@angle}{\pgfpointxy{\tikz@arc@x}{0}}{\pgfpointxy{0}{\tikz@arc@y}}}
+ {\pgfpointpolarxy{\tikz@timer@start@angle}{\tikz@arc@x and \tikz@arc@y}}{\pgfpointpolarxy{\tikz@timer@end@angle}{\tikz@arc@x and \tikz@arc@y}}%
+ \pgf@process{\pgfpointxy{\tikz@arc@x}{0}}
+ \edef\tikz@timer@zero@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgf@process{\pgfpointxy{0}{\tikz@arc@y}}
+ \edef\tikz@timer@ninety@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \fi%
+ \fi%
+}%
+
+\def\tikz@@@arcfinal#1#2#3{%
+ #1%
+ \pgf@process{#2}
+ \xdef\tikz@arc@save@first{\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@process{#3}
+ \xdef\tikz@arc@save@second{\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+}%
+
+\def\tikz@arcfinal{%
+ \pgf@process{\tikz@arc@save@first}%
+ \advance\tikz@lastx by-\pgf@x%
+ \advance\tikz@lasty by-\pgf@y%
+ \pgf@process{\tikz@arc@save@second}%
+ \advance\tikz@lastx by\pgf@x%
+ \advance\tikz@lasty by\pgf@y%
+ \tikz@lastxsaved=\tikz@lastx%
+ \tikz@lastysaved=\tikz@lasty%
+ \let\tikz@timer=\tikz@timer@arc%
+ \tikz@scan@next@command%
+}%
+
+
+% Syntax for coordinates:
+% coordinate[options] (coordinate name) at (point)
+% where ``at (point)'' is optional
+\def\tikz@coordinate ordinate{%
+ \pgfutil@ifnextchar[{\tikz@@coordinate@opt}{\tikz@@coordinate@opt[]}}%
+\def\tikz@@coordinate@opt[#1]{%
+ \pgfutil@ifnextchar({\tikz@@coordinate[#1]}
+ {\tikz@fig ode[shape=coordinate,#1]{}}}%}%
+\def\tikz@@coordinate[#1](#2){%
+ \pgfutil@ifnextchar a{\tikz@@coordinate@at[#1](#2)}
+ {\tikz@fig ode[shape=coordinate,#1](#2){}}}%
+\def\tikz@@coordinate@at[#1](#2)a{%
+ \pgfutil@ifnextchar t{\tikz@@coordinate@@at[#1](#2)a}%
+ {\tikz@fig ode[shape=coordinate,#1](#2){}a}%
+}%
+\def\tikz@@coordinate@@at[#1](#2)at#3({%
+ \def\tikz@coordinate@caller{\tikz@fig ode[shape=coordinate,#1](#2)at}%
+ \tikz@scan@one@point\tikz@@coordinate@at@math(%
+}%
+\def\tikz@@coordinate@at@math#1{%
+ \pgf@process{#1}%
+ \edef\tikz@temp{(\the\pgf@x,\the\pgf@y)}%
+ \expandafter\tikz@coordinate@caller\tikz@temp{}%
+}%
+
+
+
+% Syntax for nodes:
+% node foreach \var in {list} ... :attribute={...} [options] (node name) at (pos) {label text}
+%
+% all of :attribute, [options], (node name), at(pos), and foreach are
+% optional. There can be multiple options and the ordering is not
+% important as in node[draw] (a) [rotate=10] {text}, *except* that all
+% foreach statements must come first.
+%
+% A label text always ``ends'' the node.
+%
+\def\tikz@fig ode{%
+ \pgfutil@ifnextchar a\tikz@test@also{%
+ \pgfutil@ifnextchar f{\tikz@nodes@start}\tikz@normal@fig}}%
+\def\tikz@test@also a{\pgfutil@ifnextchar l\tikz@node@also{\tikz@normal@fig a}}%
+\def\tikz@normal@fig{%
+ \edef\tikz@save@line@width{\the\pgflinewidth}%
+ \begingroup%
+ \let\tikz@fig@name=\pgfutil@empty%
+ \begingroup%
+ \tikz@is@matrixfalse%
+ \let\nodepart=\tikz@nodepart%
+ \let\tikz@atbegin@scope=\pgfutil@empty%
+ \let\tikz@atend@scope=\pgfutil@empty%
+ \let\tikz@do@after@node=\tikz@scan@next@command%
+ \let\tikz@options=\pgfutil@empty%
+ \tikz@clear@rdf@options%
+ \let\tikz@id@name=\pgfutil@empty%
+ \let\tikz@after@path=\pgfutil@empty%
+ \let\tikz@transform=\pgfutil@empty%
+ \let\tikz@mode=\pgfutil@empty%
+ \tikz@decoratepathfalse%
+ \let\tikz@preactions=\pgfutil@empty%
+ \let\tikz@postactions=\pgfutil@empty%
+ \let\tikz@alias=\pgfutil@empty%
+ \def\tikz@node@at{\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}%
+ \let\tikz@time@for@matrix\tikz@time%
+ \let\tikz@node@content\relax%
+ \pgfgetpath\tikzpathuptonow%
+ \iftikz@node@is@a@label%
+ \else%
+ \let\tikz@time\pgfutil@empty%
+ \fi%
+ \tikz@node@reset@hook%
+ \tikzset{every node/.try}%
+ \tikz@@scan@fig}%
+\def\tikz@@scan@fig{%
+ \pgfutil@ifnextchar a{\tikz@fig@scan@at}
+ {\pgfutil@ifnextchar({\tikz@fig@scan@name}
+ {\pgfutil@ifnextchar[{\tikz@fig@scan@options}%
+ {\pgfutil@ifnextchar:{\tikz@fig@scan@animation}%
+ {\pgfutil@ifnextchar\bgroup{\tikz@fig@main}%
+ {\tikzerror{A node must have a (possibly empty) label text}%
+ \tikz@fig@main{}}}}}}}%}}%
+\def\tikz@fig@scan@at at{%
+ \tikz@scan@one@point\tikz@@fig@scan@at}%
+\def\tikz@@fig@scan@at#1{%
+ \def\tikz@node@at{#1}\tikz@@scan@fig}%
+\def\tikz@fig@scan@name(#1){%
+ \pgfkeysvalueof{/tikz/name/.@cmd}#1\pgfeov% CF : this is now ALWAYS consistent with 'name=' option; allows overrides.
+ \tikz@@scan@fig}%
+% make it \long to allow \par in "pin" options etc:
+\long\def\tikz@fig@scan@options[#1]{\iftikz@node@is@pic\tikz@enable@pic@quotes\else\tikz@enable@node@quotes\fi\tikzset{#1}\ifx\tikz@node@content\relax\expandafter\tikz@@scan@fig\else\tikz@expand@node@contents\fi}%
+\def\tikz@fig@scan@animation:#1=#2{\tikzset{animate={myself:{#1}={#2}}}\tikz@@scan@fig}%
+\def\tikz@expand@node@contents{%
+ \expandafter\tikz@@scan@fig\expandafter{\tikz@node@content}%
+}%
+\let\tikz@node@reset@hook=\pgfutil@empty%
+\let\tikz@node@begin@hook=\pgfutil@empty%
+\def\tikz@fig@main{%
+ \iftikz@node@is@pic%
+ \tikz@node@is@picfalse%
+ \expandafter\tikz@subpicture@handle%
+ \else%
+ \afterassignment\tikz@@fig@main\expandafter\let\expandafter\next\expandafter=%
+ \fi}%
+\def\tikz@@fig@main{%
+ \pgfutil@ifundefined{pgf@sh@s@\tikz@shape}%
+ {\tikzerror{Unknown shape ``\tikz@shape.'' Using ``rectangle'' instead}%
+ \def\tikz@shape{rectangle}}%
+ {}%
+ \expandafter\xdef\csname tikz@dcl@coord@\tikz@fig@name\endcsname{%
+ \csname tikz@scan@point@coordinate\endcsname}%
+ \tikzset{every \tikz@shape\space node/.try}%
+ \tikz@node@textfont%
+ \tikz@node@begin@hook%
+ \iftikz@is@matrix%
+ \let\tikz@next=\tikz@do@matrix%
+ \else%
+ \let\tikz@next=\tikz@do@fig%
+ \fi%
+ \tikz@next%
+}%
+\let\tikz@nodepart@list\pgfutil@empty
+\def\tikz@do@fig{%
+ % Ok, reset all node part boxes
+ \pgfutil@for\tikz@temp:=\tikz@nodepart@list\do{%
+ \expandafter\setbox\csname pgfnodepart\tikz@temp box\endcsname=\box\pgfutil@voidb@x%
+ }%
+ \setbox\pgfnodeparttextbox=\hbox%
+ \bgroup%
+ \pgfinterruptpicture%
+ \pgfsys@begin@text%
+ \pgfsys@text@to@black@hook%
+ \tikzset{every text node part/.try}%
+ \ifx\tikz@textopacity\pgfutil@empty%
+ \else%
+ \pgfsetfillopacity{\tikz@textopacity}%
+ \pgfsetstrokeopacity{\tikz@textopacity}%
+ \fi%
+ \ifx\tikz@text@width\pgfutil@empty%
+ \tikz@textfont%
+ \else%
+ \begingroup%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@width}%
+ \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}%
+ \tikz@textfont%
+ \tikz@text@action%
+ \fi%
+ \tikz@atbegin@node%
+ \bgroup%
+ \aftergroup\unskip%
+ % Some color stuff has been moved from here to outside; this is
+ % necessary for support of dvisvgm and of animation
+ % snapshots.
+ \ifx\tikz@textcolor\pgfutil@empty%
+ \else%
+ \pgfutil@colorlet{.}{\tikz@textcolor}%
+ \pgfutil@color{\tikz@textcolor}%
+ \fi%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \tikz@uninstallcommands%
+ \iftikz@handle@active@code%
+ \tikz@orig@shorthands%
+ \let\tikz@orig@shorthands\pgfutil@empty%
+ \fi%
+ \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi%
+ \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi%
+ \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi%
+ \aftergroup\tikz@fig@collectresetcolor%
+ \tikz@signal@halign@check%
+ \tikz@text@reset%
+ \tikz@halign@check%
+ \ignorespaces%
+}%
+\def\tikz@fig@collectresetcolor{%
+ % Hacks for special packages that mess with \aftergroup
+ \pgfutil@ifnextchar\reset@color% hack for color package
+ {\reset@color\afterassignment\tikz@fig@collectresetcolor\let\tikz@temp=}\tikz@fig@boxdone%
+}%
+\def\tikz@fig@boxdone{%
+ \tikz@atend@node%
+ \ifx\tikz@text@width\pgfutil@empty%
+ \else%
+ \pgfutil@endminipage%
+ \endgroup%
+ \fi%
+ \pgfsys@end@text%
+ \endpgfinterruptpicture%
+ \egroup%
+ \pgfutil@ifnextchar c{\tikz@fig@mustbenamed\tikz@fig@continue}%
+ {\pgfutil@ifnextchar[{\tikz@fig@mustbenamed\tikz@fig@continue}%
+ {\pgfutil@ifnextchar t{\tikz@fig@mustbenamed\tikz@fig@continue}
+ {\pgfutil@ifnextchar e{\tikz@fig@mustbenamed\tikz@fig@continue}
+ {\ifx\tikz@after@path\pgfutil@empty\expandafter\tikz@fig@continue\else\expandafter\tikz@fig@mustbenamed\expandafter\tikz@fig@continue\fi}}}}}%}%
+
+\tikzset{
+ matrix/inner style/every cell/.code={%
+ \tikzset{every cell/.try={\the\pgfmatrixcurrentrow}{\the\pgfmatrixcurrentcolumn}}%
+ },
+ matrix/inner style/column/.code={%
+ \tikzset{column \the\pgfmatrixcurrentcolumn/.try}%
+ },
+ matrix/inner style/even odd column/.code={
+ \ifodd\pgfmatrixcurrentcolumn%
+ \tikzset{every odd column/.try}%
+ \else%
+ \tikzset{every even column/.try}%
+ \fi
+ },
+ matrix/inner style/row/.code={%
+ \tikzset{row \the\pgfmatrixcurrentrow/.try}%
+ },
+ matrix/inner style/even odd row/.code={%
+ \ifodd\pgfmatrixcurrentrow%
+ \tikzset{every odd row/.try}%
+ \else%
+ \tikzset{every even row/.try}%
+ \fi
+ },
+ matrix/inner style/cell/.code={%
+ \tikzset{row \the\pgfmatrixcurrentrow\space column \the\pgfmatrixcurrentcolumn/.try}%
+ },
+ matrix/inner style order/.store in=\tikz@common@matrix@code@styleorder,
+ matrix/inner style order={
+ every cell,
+ column,
+ even odd column,
+ row,
+ even odd row,
+ cell
+ },
+}%
+
+\def\tikz@do@matrix{%
+ \tikzset{every matrix/.try}%
+ \tikz@node@transformations%
+ \tikz@fig@mustbenamed%
+ \setbox\tikz@whichbox=\hbox\bgroup%
+ \unhbox\tikz@whichbox%
+ \hbox\bgroup\bgroup%
+ \pgfinterruptpath%
+ \pgfscope%
+ \ifx\tikz@time\pgfutil@empty\let\tikz@time\tikz@time@for@matrix\fi%
+ \tikz@options%
+ \tikz@do@rdf@pre@options%
+ \tikz@is@nodefalse%
+ \tikz@call@id@hook%
+ \pgfidscope%
+ \tikz@do@rdf@post@options%
+ \begingroup%
+ \let\tikz@id@name\pgfutil@empty%
+ \pgfclearid%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \let\tikzmatrixname=\tikz@fig@name%
+ \edef\tikz@m@anchor{\ifx\tikz@matrix@anchor\pgfutil@empty\tikz@anchor\else\tikz@matrix@anchor\fi}%
+ \expandafter\pgfutil@in@\expandafter{\expandafter.\expandafter}\expandafter{\tikz@m@anchor}%
+ \ifpgfutil@in@%
+ \expandafter\tikz@matrix@split\tikz@m@anchor\relax%
+ \else%
+ \def\tikz@matrix@shift{\pgfpointorigin}%
+ \fi%
+ \let\tikz@transform=\relax%
+ \pgfmatrixbeforeassemblenode{\tikzset{every outer matrix/.try}}%
+ \pgfmatrix%
+ {\tikz@shape}%
+ {\tikz@m@anchor}%
+ {\tikz@fig@name}%
+ {%
+ \pgfutil@tempdima=\pgflinewidth%
+ {\begingroup\tikz@finish}%
+ \global\pgflinewidth=\pgfutil@tempdima%
+ }%
+ {\tikz@matrix@shift}%
+ {%
+ \tikz@matrix@make@active@ampersand%
+ \def\pgfmatrixbegincode{%
+ \pgfsys@beginscope%
+ \tikz@common@matrix@code%
+ \tikz@atbegin@cell%
+ }%
+ \def\tikz@common@matrix@code{%
+ \let\tikz@options=\pgfutil@empty%
+ \let\tikz@mode=\pgfutil@empty%
+ \pgfutil@for\pgf@temp:=\tikz@common@matrix@code@styleorder\do{%
+ \toks0=\expandafter{\romannumeral-`0\expandafter\pgfutil@trimspaces\expandafter{\pgf@temp}}%
+ \def\pgf@marshal{}%
+ \pgfutil@ifxempty\pgf@temp{}{%
+ \edef\pgf@marshal{\noexpand\tikzset{matrix/inner style/.cd,\the\toks0}}%
+ }%
+ \pgf@marshal
+ }%
+ \tikz@options%
+ }%
+ \def\pgfmatrixendcode{%
+ \tikz@atend@cell%
+ \pgfsys@endscope%
+ }%
+ \def\pgfmatrixemptycode{%
+ \pgfsys@beginscope%
+ \tikz@common@matrix@code%
+ \tikz@at@emptycell%
+ \pgfsys@endscope%
+ }%
+ \tikz@atbegin@matrix%
+ \aftergroup\tikz@do@matrix@cont}%
+ \bgroup%
+}%
+\def\tikz@do@matrix@cont{%
+ \tikz@atend@matrix%
+ \endgroup%
+ \endpgfidscope%
+ \endpgfscope
+ \endpgfinterruptpath%
+ \egroup\egroup%
+ \egroup%
+ %
+ \tikz@node@finish%
+}%
+{%
+ \catcode`\&=13
+ \gdef\tikz@matrix@make@active@ampersand{%
+ \ifx\tikz@ampersand@replacement\pgfutil@empty%
+ \catcode`\&=13%
+ \let&=\pgfmatrixnextcell%
+ \else%
+ \expandafter\let\tikz@ampersand@replacement=\pgfmatrixnextcell%
+ \fi%
+ }%
+}%
+
+
+\def\tikz@matrix@split#1.#2\relax{%
+ \def\tikz@m@anchor{text}%
+ \def\tikz@matrix@shift{\pgfpointanchor{#1}{#2}}%
+}%
+
+\def\tikz@fig@continue{%
+ \ifx\tikz@text@width\pgfutil@empty%
+ \else%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@width}%
+ \wd\pgfnodeparttextbox=\pgf@x%
+ \fi%
+ \ifx\tikz@text@height\pgfutil@empty%
+ \else%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@height}%
+ \ht\pgfnodeparttextbox=\pgf@x%
+ \fi%
+ \ifx\tikz@text@depth\pgfutil@empty%
+ \else%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@depth}%
+ \dp\pgfnodeparttextbox=\pgf@x%
+ \fi%
+ %
+ % Node transformation
+ %
+ \tikz@node@transformations%
+ \tikz@nlt%
+ %
+ \setbox\tikz@whichbox=\hbox{%
+ \unhbox\tikz@whichbox%
+ \hbox{{%
+ \pgfinterruptpath%
+ \pgfscope%
+ \tikz@options%
+ \tikz@do@rdf@pre@options%
+ \tikz@is@nodetrue%
+ \tikz@call@id@hook%
+ \pgfidscope%
+ \tikz@do@rdf@post@options%
+ \let\tikz@id@name\pgfutil@empty%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ % Add color modifications to text box
+ \setbox\pgfnodeparttextbox=\hbox{{%
+ \pgfsys@begin@text% Colors moved here...
+ \ifx\tikz@textcolor\pgfutil@empty%
+ \else%
+ \pgfutil@colorlet{.}{\tikz@textcolor}%
+ \fi%
+ \pgfsetcolor{.}%
+ \pgfusetype{.text}%
+ \pgfidscope%
+ \box\pgfnodeparttextbox%
+ \endpgfidscope%
+ \pgfsys@end@text%
+ }}%
+ \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{%
+ \pgfutil@tempdima=\pgflinewidth%
+ {\begingroup\tikz@finish}%
+ \global\pgflinewidth=\pgfutil@tempdima%
+ }%
+ \endpgfidscope%
+ \endpgfscope%
+ \endpgfinterruptpath%
+ }}%
+ }%
+ %
+ \tikz@alias%
+ \tikz@node@finish%
+}%
+
+
+\def\tikz@fig@mustbenamed{%
+ \ifx\tikz@fig@name\pgfutil@empty%
+ % Assign a dummy name
+ \global\advance\tikz@fig@count by1\relax
+ \edef\tikz@fig@name{tikz@f@\the\tikz@fig@count}%
+ \let\tikz@id@name\tikz@fig@name%
+ \fi%
+}%
+
+\def\tikz@node@transformations{%
+ %
+ % Possibly, we are ``online''
+ %
+ \ifx\tikz@time\pgfutil@empty%
+ \pgftransformshift{\tikz@node@at}%
+ \iftikz@fullytransformed%
+ \else%
+ \pgftransformresetnontranslations%
+ \fi%
+ \else%
+ \tikz@do@auto@anchor%
+ \tikz@timer%
+ \fi%
+ % Invoke local transformations
+ \tikz@transform%
+}%
+
+\def\tikz@node@finish{%
+ \global\let\tikz@last@fig@name=\tikz@fig@name%
+ \global\let\tikz@after@path@smuggle=\tikz@after@path%
+ % shift box outside group
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ \endgroup\endgroup%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \global\pgflinewidth=\tikz@save@line@width%
+ \tikz@do@after@path@smuggle%
+ \tikz@node@is@picfalse
+ \tikz@do@after@node%
+}%
+\let\tikz@fig@continue@orig=\tikz@fig@continue
+
+\def\tikz@do@after@node{\tikz@scan@next@command}%
+
+\def\tikz@do@after@path@smuggle{%
+ \let\tikz@to@last@fig@name=\tikz@last@fig@name%
+ \let\tikz@to@use@whom=\tikz@to@use@last@fig@name%
+ \let\tikzlastnode=\tikz@last@fig@name%
+ \ifx\tikz@after@path@smuggle\pgfutil@empty%
+ \else%
+ \ifpgflatenodepositioning%
+ \expandafter\expandafter\expandafter\tikz@call@late%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@last@fig@name\expandafter}\expandafter{\tikz@after@path@smuggle}%
+ \else%
+ \tikz@scan@next@command{\tikz@after@path@smuggle}\pgf@stop%
+ \fi%
+ \fi%
+}%
+
+\def\tikz@call@late#1#2{\pgfnodepostsetupcode{#1}{\path[late options={name={#1},append after command={#2}}];}}%
+
+\newif\iftikz@do@align
+
+% Alignment handling
+\def\tikz@signal@halign@check{%
+ \tikz@do@alignfalse
+ \ifx\tikz@text@width\pgfutil@empty%
+ \pgfkeysgetvalue{/tikz/node halign header}\tikz@align@header%
+ \ifx\tikz@align@header\pgfutil@empty%
+ \else%
+ \tikz@do@aligntrue%
+ \fi%
+ \fi%
+}
+\def\tikz@halign@check{%
+ \iftikz@do@align%
+ % Bingo
+ \setbox\tikz@align@aligned@box=\box\pgfutil@voidb@x% void
+ \let\\=\tikz@align@newline%
+ \expandafter\tikz@start@align%
+ \fi%
+}%
+\def\tikz@align@newline{\pgfutil@protect\tikz@align@newline@}%
+\def\tikz@align@newline@{\unskip\pgfutil@ifnextchar[\tikz@@align@newline{\tikz@@align@newline[0pt]}}%}%
+\def\tikz@@align@newline[#1]{\egroup\tikz@align@continue\pgfmathparse{#1}\let\tikz@align@temp=\pgfmathresult\tikz@start@align}%
+% Two safe boxes for alignment:
+\let\tikz@align@aligned@box=\pgfnodeparttextbox
+\let\tikz@align@line@box=\tikz@figbox
+
+\def\tikz@start@align{%
+ % Start collecting text:
+ \setbox\tikz@align@line@box=\hbox\bgroup\bgroup%
+ \aftergroup\tikz@align@collectresetcolor\ignorespaces%
+}%
+\def\tikz@align@collectresetcolor{%
+ \pgfutil@ifnextchar\reset@color%
+ {\reset@color\afterassignment\tikz@align@collectresetcolor\let\tikz@temp=}%
+ {\tikz@align@end@check}%
+}%
+\def\tikz@align@end@check{%
+ \egroup%
+ \ifvoid\tikz@align@aligned@box%
+ \setbox\tikz@align@aligned@box=\box\tikz@align@line@box%
+ \else%
+ \setbox\tikz@align@aligned@box=\vbox{%
+ \expandafter\expandafter\expandafter\halign\expandafter\expandafter\expandafter{\tikz@align@header%
+ \box\tikz@align@aligned@box\cr%
+ \noalign{\vskip\tikz@align@temp pt}%
+ \unhbox\tikz@align@line@box\unskip\cr}}%
+ \fi%
+ \pgfutil@ifnextchar\tikz@align@continue{}
+ {%
+ % Main continue
+ \box\tikz@align@aligned@box%
+ \egroup%
+ }%
+}%
+\def\tikz@align@continue{\tikz@@align@continue}%
+\let\tikz@@align@continue=\pgfutil@empty
+
+
+\def\tikz@node@also lso{\pgfutil@ifnextchar[\tikz@node@also@opt{\tikz@node@also@opt[]}}%
+\def\tikz@node@also@opt[#1]{
+ \pgfutil@ifnextchar(%)
+ {\tikz@node@also@opt@cont[#1]}%
+ {\tikzerror{Syntax error in node also: ``('' expected.}%
+ \tikz@scan@next@command}%
+}%
+\def\tikz@node@also@opt@cont[#1](#2){\tikzset{late options={name=#2,#1}}\tikz@scan@next@command}%
+
+
+
+% Syntax for parts of nodes:
+% node ... {... \nodepart[options]{name} ... \nodepart{name} ...}
+
+\def\tikz@nodepart{\pgfutil@ifnextchar[\tikz@@nodepart{\tikz@@nodepart[]}}%}%
+\def\tikz@@nodepart[#1]#2{%
+ \tikz@atend@node%
+ \unskip%
+ \gdef\tikz@nodepart@options{#1}%
+ \gdef\tikz@nodepart@name{#2}%
+ \global\let\tikz@fig@continue=\tikz@nodepart@continue%
+ \pgfutil@ifnextchar x{\egroup\relax}{\egroup\relax}% gobble spaces
+}%
+\def\tikz@nodepart@continue{%
+ \global\let\tikz@fig@continue=\tikz@fig@continue@orig%
+ \ifx\tikz@nodepart@list\pgfutil@empty%
+ \let\tikz@nodepart@list\tikz@nodepart@name%
+ \else%
+ \edef\tikz@nodepart@list{\tikz@nodepart@list,\tikz@nodepart@name}%
+ \fi%
+ % Now start new box:
+ \expandafter\setbox\csname pgfnodepart\tikz@nodepart@name box\endcsname=\hbox%
+ \bgroup%
+ \pgfinterruptpicture%
+ \pgfsys@begin@text%
+ \pgfsys@text@to@black@hook%
+ \tikzset{every \tikz@nodepart@name\space node part/.try}%
+ \expandafter\tikzset\expandafter{\tikz@nodepart@options}%
+ \ifx\tikz@textopacity\pgfutil@empty%
+ \else%
+ \pgfsetfillopacity{\tikz@textopacity}%
+ \pgfsetstrokeopacity{\tikz@textopacity}%
+ \fi%
+ % Colors moved here...
+ \ifx\tikz@textcolor\pgfutil@empty%
+ \else%
+ \pgfutil@colorlet{.}{\tikz@textcolor}%
+ \fi%
+ \pgfsetcolor{.}%
+ \ifx\tikz@text@width\pgfutil@empty%
+ \tikz@textfont%
+ \else%
+ \begingroup%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@width}%
+ \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}%
+ \tikz@textfont%
+ \tikz@text@action%
+ \fi%
+ \bgroup%
+ \aftergroup\unskip%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \tikz@uninstallcommands%
+ \iftikz@handle@active@code%
+ \tikz@orig@shorthands%
+ \let\tikz@orig@shorthands\pgfutil@empty%
+ \fi%
+ \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi%
+ \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi%
+ \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi%
+ \tikz@atbegin@node%
+ \aftergroup\tikz@fig@collectresetcolor%
+ \tikz@signal@halign@check%
+ \tikz@text@reset%
+ \tikz@halign@check%
+ \ignorespaces%
+}%
+
+
+%
+% Node foreach
+%
+
+\def\tikz@nodes@start{%
+ \let\tikz@nodes@list\pgfutil@empty%
+ \iftikz@node@is@pic%
+ \def\tikz@nodes@collect{pic }%
+ \else%
+ \def\tikz@nodes@collect{node }%
+ \fi%
+ \tikz@nodes%
+}%
+\def\tikz@nodes foreach{\pgfutil@ifnextchar x\tikz@nodes@\tikz@nodes@}% get rid of spaces
+\def\tikz@nodes@#1in{%
+ \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list\foreach#1in}%
+ \pgfutil@ifnextchar\bgroup\tikz@nodes@group\tikz@nodes@one%
+}%
+\def\tikz@nodes@one#1{%
+ \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list#1}%
+ \pgfutil@ifnextchar f\tikz@nodes\tikz@nodes@scan%
+}%
+\def\tikz@nodes@group#1{%
+ \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list{#1}}%
+ \pgfutil@ifnextchar f\tikz@nodes\tikz@nodes@scan%
+}%
+\def\tikz@nodes@scan{%
+ \pgfutil@ifnextchar a{\tikz@nodes@at}%
+ {\pgfutil@ifnextchar({\tikz@nodes@name}%
+ {\pgfutil@ifnextchar[{\tikz@nodes@opt}%
+ {\pgfutil@ifnextchar\bgroup{\tikz@nodes@main}%
+ {\tikzerror{Nodes must have a (possibly empty) label text}%
+ \tikz@fig@main{}}}}}}%}}%
+
+% Look ahead whether the next character is a (. If that is the case, we scan
+% until ), otherwise we grab a single token and append.
+\def\tikz@nodes@at at{\pgfutil@ifnextchar({\tikz@nodes@at@}{\tikz@nodes@at@@}}%
+\def\tikz@nodes@at@#1){%
+ \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect at#1)}%
+ \tikz@nodes@scan}%
+\def\tikz@nodes@at@@#1{%
+ \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect at#1}%
+ \tikz@nodes@scan}%
+
+\def\tikz@nodes@name#1){%
+ \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect#1)}%
+ \tikz@nodes@scan}%
+\def\tikz@nodes@opt#1]{%
+ \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect#1]}%
+ \tikz@nodes@scan}%
+\def\tikz@nodes@main#1{%
+ \iftikz@handle@active@nodes%
+ \iftikz@node@is@pic%
+ \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{#1}}%
+ \else%
+ \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{\scantokens{#1}}}%
+ \fi%
+ \else%
+ \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{#1}}%
+ \fi%
+ % Ok, got everything.
+ % Now, start building parse text.
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ \tikz@nodes@list{%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \expandafter\tikz@scan@next@command\tikz@nodes@collect\pgfextra\relax%
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ }%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \tikz@scan@next@command%
+}%
+
+
+
+%
+% "late" options can be used to "redo" a node
+%
+\tikzset{late options/.code=\tikz@late@options{#1}}%
+\def\tikz@late@options#1{%
+ % Do a "virtual" node:
+ \begingroup%
+ \iftikz@shapeborder%
+ \let\tikz@fig@name=\tikz@shapeborder@name%
+ \else%
+ \let\tikz@fig@name=\pgfutil@empty%
+ \fi%
+ \tikz@is@matrixfalse%
+ \let\tikz@options=\pgfutil@empty%
+ \tikz@clear@rdf@options%
+ \let\tikz@after@path=\pgfutil@empty%
+ \let\tikz@afternodepathoptions=\pgfutil@empty%
+ \let\tikz@alias=\pgfutil@empty%
+ \let\tikz@transform=\pgfutil@empty%
+ \tikz@decoratepathfalse%
+ \tikz@node@reset@hook%
+ \tikz@enable@node@quotes%
+ \tikzset{every node/.try,#1}%
+ \ifx\tikz@fig@name\pgfutil@empty%
+ \tikzerror{Late options must reference some existing node}%
+ \fi%
+ \tikz@node@begin@hook%
+ \tikz@alias%
+ \tikzgdlatenodeoptionacallback{\tikz@fig@name}%
+ \global\let\tikz@last@fig@name=\tikz@fig@name%
+ \global\let\tikz@after@path@smuggle=\tikz@after@path%
+ \endgroup%
+ \tikz@do@after@path@smuggle%
+}%
+
+
+% Auto placement
+
+\def\tikz@auto@pre{%
+ \begingroup
+ \pgfresetnontranslationattimefalse
+ \ifpgfslopedattime
+ \pgfslopedattimefalse%
+ \else
+ \pgfslopedattimetrue%
+ \fi
+ \pgfallowupsidedownattimetrue%
+ \tikz@timer%
+ \pgf@x=\pgf@pt@aa pt%
+ \pgf@y=\pgf@pt@ab pt%
+ \pgfpointnormalised{}%
+}%
+
+\def\tikz@auto@post{%
+ \global\let\tikz@anchor@smuggle=\tikz@anchor%
+ \endgroup%
+ \let\tikz@anchor=\tikz@anchor@smuggle%
+}%
+
+\def\tikz@auto@anchor{%
+ \ifdim\pgf@x>0.05pt%
+ \ifdim\pgf@y>0.05pt%
+ \def\tikz@anchor{south east}%
+ \else\ifdim\pgf@y<-0.05pt%
+ \def\tikz@anchor{south west}%
+ \else
+ \def\tikz@anchor{south}%
+ \fi\fi%
+ \else\ifdim\pgf@x<-0.05pt%
+ \ifdim\pgf@y>0.05pt%
+ \def\tikz@anchor{north east}%
+ \else\ifdim\pgf@y<-0.05pt%
+ \def\tikz@anchor{north west}%
+ \else
+ \def\tikz@anchor{north}%
+ \fi\fi%
+ \else%
+ \ifdim\pgf@y>0pt%
+ \def\tikz@anchor{east}%
+ \else%
+ \def\tikz@anchor{west}%
+ \fi%
+ \fi\fi%
+}%
+
+\def\tikz@auto@anchor@prime{%
+ \ifdim\pgf@x>0.05pt%
+ \ifdim\pgf@y>0.05pt%
+ \def\tikz@anchor{north west}%
+ \else\ifdim\pgf@y<-0.05pt%
+ \def\tikz@anchor{north east}%
+ \else
+ \def\tikz@anchor{north}%
+ \fi\fi%
+ \else\ifdim\pgf@x<-0.05pt%
+ \ifdim\pgf@y>0.05pt%
+ \def\tikz@anchor{south west}%
+ \else\ifdim\pgf@y<-0.05pt%
+ \def\tikz@anchor{south east}%
+ \else
+ \def\tikz@anchor{south}%
+ \fi\fi%
+ \else%
+ \ifdim\pgf@y>0pt%
+ \def\tikz@anchor{west}%
+ \else%
+ \def\tikz@anchor{east}%
+ \fi%
+ \fi\fi%
+}%
+
+
+%
+% Callbacks: Please see the documentation of the graph drawing
+% lib for info on these callbacks
+%
+\def\tikzgdeventcallback#1#2{}%
+\def\tikzgdeventgroupcallback#1{}%
+\def\tikzgdlatenodeoptionacallback#1{}%
+
+% Syntax for trees:
+% node {...} child [options] {...} child [options] {...} ...
+% node {...} child [options] foreach \var in {list} [options] {...} ...
+
+\def\tikz@children{%
+ % Start collecting the children:
+ \let\tikz@children@list=\pgfutil@empty%
+ \tikznumberofchildren=0\relax%
+ \tikz@collect@children c}%
+
+\def\tikz@collect@children{\pgfutil@ifnextchar c{\tikz@collect@children@cchar}{\tikz@children@collected}}%
+\def\tikz@collect@children@cchar c{\pgfutil@ifnextchar h{\tikz@collect@child}{\tikz@children@collected c}}%
+\def\tikz@collect@child hild{\pgfutil@ifnextchar[{\tikz@collect@childA}{\tikz@collect@childA[]}}%}%
+\def\tikz@collect@childA[#1]{\pgfutil@ifnextchar f{\tikz@collect@children@foreach[#1]}{\tikz@collect@childB[#1]}}%
+\def\tikz@collect@childB[#1]{%
+ \advance\tikznumberofchildren by1\relax
+ \expandafter\def\expandafter\tikz@children@list\expandafter{\tikz@children@list \tikz@childnode[#1]}%
+ \pgfutil@ifnextchar\bgroup{\tikz@collect@child@code}{\tikz@collect@child@code{}}}%
+\def\tikz@collect@child@code#1{%
+ \expandafter\def\expandafter\tikz@children@list\expandafter{\tikz@children@list{#1}}%
+ \tikz@collect@children%
+}%
+\def\tikz@collect@children@foreach[#1]foreach#2in#3{%
+ \pgfutil@ifnextchar\bgroup{\tikz@collect@children@foreachA{#1}{#2}{#3}}{\tikz@collect@children@foreachA{#1}{#2}{#3}{}}}%
+\def\tikz@collect@children@foreachA#1#2#3#4{%
+ \expandafter\def\expandafter\tikz@children@list\expandafter
+ {\tikz@children@list\tikz@childrennodes[#1]{#2}{#3}{#4}}%
+ \c@pgf@counta=\tikznumberofchildren%
+ \foreach#2in{#3}%
+ {%
+ \global\advance\c@pgf@counta by1\relax%
+ }%
+ \tikznumberofchildren=\c@pgf@counta%
+ \tikz@collect@children%
+}%
+\long\def\tikz@children@collected{%
+ \begingroup%
+ \advance\tikztreelevel by 1\relax%
+ \tikzgdeventgroupcallback{descendants}%
+ \let\tikz@options=\pgfutil@empty%
+ \tikz@clear@rdf@options%
+ \let\tikz@transform=\pgfutil@empty%
+ \tikzset{level/.try=\the\tikztreelevel,level \the\tikztreelevel/.try}%
+ \tikz@transform%
+ \let\tikz@transform=\relax%
+ \let\tikzparentnode=\tikz@last@fig@name%
+ \ifx\tikz@grow\relax\else%
+ % Transform to center of node
+ \pgftransformshift{\pgfpointanchor{\tikzparentnode}{\tikz@growth@anchor}}%
+ \fi%
+ \tikznumberofcurrentchild=0\relax%
+ \tikz@children@list%
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ \endgroup%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \tikz@scan@next@command%
+}%
+
+% Syntax for children:
+%
+% child [all children options] foreach \var in {values} [child options] {...}
+\def\tikz@childrennodes[#1]#2#3#4{%
+ \c@pgf@counta=\tikznumberofcurrentchild\relax%
+ \setbox\tikz@tempbox=\box\tikz@figbox%
+ \setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ \foreach#2in{#3}{%
+ \tikznumberofcurrentchild=\c@pgf@counta\relax%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+ \tikz@childnode[#1]{#4}%
+ % we must now make the current child number and the figbox survive
+ % the group
+ \global\c@pgf@counta=\tikznumberofcurrentchild\relax%
+ \global\setbox\tikz@tempbox=\box\tikz@figbox%
+ \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg%
+ }%
+ \tikznumberofcurrentchild=\c@pgf@counta\relax%
+ \setbox\tikz@figbox=\box\tikz@tempbox%
+ \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg%
+}%
+
+
+% Syntax for child:
+%
+% child
+%
+% child[options]
+%
+% child[options] {node (name) {child node text} ...
+% edge from parent[options] node {label text} node {label text}}
+
+\def\tikz@childnode[#1]#2{%
+ \advance\tikznumberofcurrentchild by1\relax%
+ {\tikzset{every child/.try,#1}\expandafter}%
+ \iftikz@child@missing%
+ \tikzgdeventcallback{node}{}%
+ \else%
+ \setbox\tikz@whichbox=\hbox\bgroup%
+ \unhbox\tikz@whichbox%
+ \hbox\bgroup\bgroup%
+ \pgfinterruptpath%
+ \pgfscope%
+ \let\tikz@transform=\pgfutil@empty%
+ \tikzset{every child/.try,#1}%
+ \tikz@options%
+ \tikz@transform%
+ \let\tikz@transform=\relax%
+ \tikz@grow%
+ % Typeset node:
+ \edef\tikz@parent@node@name{[name=\tikzparentnode-\the\tikznumberofcurrentchild,style=every child node]}%
+ \def\tikz@child@node@text{[shape=coordinate]{}}
+ \tikz@parse@child@node#2\pgf@stop%
+ \expandafter\expandafter\expandafter\node
+ \expandafter\tikz@parent@node@name
+ \tikz@child@node@text
+ \pgfextra{\global\let\tikz@childnode@name=\tikz@last@fig@name};%
+ \let\tikzchildnode=\tikz@childnode@name%
+ {%
+ \def\tikz@edge@to@parent@needed{edge from parent}
+ \ifx\tikz@child@node@rest\pgfutil@empty%
+ \path edge from parent;%
+ \else%
+ \path \tikz@child@node@rest \tikz@edge@to@parent@needed;%
+ \fi%
+ }%
+ \endpgfscope%
+ \endpgfinterruptpath%
+ \egroup\egroup%
+ \egroup%
+ \fi%
+}%
+
+\def\tikz@parse@child@node{%
+ \pgfutil@ifnextchar n{\tikz@parse@child@node@n}%
+ {\pgfutil@ifnextchar c{\tikz@parse@child@node@c}%
+ {\pgfutil@ifnextchar\pgf@stop\tikz@parse@child@node@rest\tikz@parse@child@node@expand}}}%
+\def\tikz@parse@child@node@expand{%
+ \advance\tikz@expandcount by-1\relax%
+ \ifnum\tikz@expandcount<0\relax%
+ \expandafter\tikz@parse@child@node@rest%
+ \else%
+ \expandafter\expandafter\expandafter\tikz@parse@child@node%
+ \fi%
+}%
+\def\tikz@parse@child@node@rest#1\pgf@stop{\tikz@resetexpandcount\def\tikz@child@node@rest{#1}}%
+\def\tikz@parse@child@node@c c{\tikz@resetexpandcount\pgfutil@ifnextchar o{\tikz@parse@child@node@co}{\tikz@parse@child@node@rest c}}%
+\def\tikz@parse@child@node@co o{\pgfutil@ifnextchar o{\tikz@parse@child@node@coordinate}{\tikz@parse@child@node@rest co}}%
+\def\tikz@parse@child@node@coordinate ordinate{%
+ \pgfutil@ifnextchar ({\tikz@@parse@child@node@coordinate}{%
+ \def\tikz@child@node@text{[shape=coordinate]{}}%
+ \tikz@parse@child@node@rest}}%}%
+\def\tikz@@parse@child@node@coordinate(#1){%
+ \pgfutil@ifnextchar a{\tikz@p@c@n@c@at(#1)}{%
+ \def\tikz@child@node@text{[shape=coordinate,name=#1]{}}%
+ \tikz@parse@child@node@rest}}%
+\def\tikz@p@c@n@c@at(#1)at#2({%
+ \def\tikz@child@node@text@pre{[shape=coordinate,name=#1]at}%
+ \tikz@scan@one@point\tikz@p@c@n@c@at@math(%
+}%
+\def\tikz@p@c@n@c@at@math#1{%
+ \pgf@process{#1}%
+ \edef\tikz@marshal{(\the\pgf@x,\the\pgf@y){}}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@child@node@text%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@child@node@text@pre\tikz@marshal}%
+ \tikz@parse@child@node@rest%
+}%
+\def\tikz@parse@child@node@n node{\tikz@resetexpandcount%
+ \let\tikz@child@node@text=\pgfutil@empty%
+ \tikz@p@c@s}%
+\def\tikz@p@c@s{%
+ \pgfutil@ifnextchar a{\tikz@p@c@s@at}
+ {\pgfutil@ifnextchar ({\tikz@p@c@s@paran}
+ {\pgfutil@ifnextchar [{\tikz@p@c@s@bra}
+ {\pgfutil@ifnextchar \bgroup{\tikz@p@c@s@group}
+ {\tikzerror{Cannot parse this node}}}}}}%}}%
+\def\tikz@p@c@s@at at#1({%
+ \tikz@scan@one@point\tikz@p@c@s@at@math(%
+}%
+\def\tikz@p@c@s@at@math#1{%
+ \pgf@process{#1}%
+ \edef\tikz@marshal{ at(\the\pgf@x,\the\pgf@y)}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\tikz@child@node@text%
+ \expandafter\expandafter\expandafter{\expandafter\tikz@child@node@text\tikz@marshal}
+ \tikz@p@c@s}%
+\def\tikz@p@c@s@paran(#1){%
+ \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text(#1)}
+ \tikz@p@c@s}%
+\def\tikz@p@c@s@bra[#1]{%
+ \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text[#1]}
+ \tikz@p@c@s}%
+\def\tikz@p@c@s@group#1{%
+ \iftikz@handle@active@nodes%
+ \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{\scantokens{#1}}}%
+ \else%
+ \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{#1}}
+ \fi%
+ \tikz@parse@child@node@rest%
+}%
+
+
+
+%
+% Syntax for decorated subpaths:
+%
+% decorate [option] { subpath }
+%
+\def\tikz@decoration ecorate{%
+ \pgfutil@ifnextchar[{\tikz@lib@decoration}{\tikz@lib@decoration[]}%]
+}%
+
+\def\tikz@lib@decoration[#1]#2{\tikzerror{You need to load a decoration library}}%
+
+% The decorate path command:
+\def\tikz@lib@dec@decorate@path{\tikzerror{You need to load a decoration library}}%
+
+
+
+%
+% Syntax for let :
+%
+% let \p1 = (coordinate), \p2 = (coordinate),... in
+%
+\def\tikz@let@command et#1in{%
+ \tikzerror{You need to say \string\usetikzlibrary{calc} to use the let command}%
+ \tikz@scan@next@command%
+}%
+
+
+%
+% Syntax for pictures:
+%
+% as for nodes, but with "pic" instead of "node"
+%
+\newif\iftikz@node@is@pic
+\def\tikz@subpicture ic{\tikz@node@is@pictrue\tikz@scan@next@command node}%
+\def\tikz@subpicture@handle#1{%
+ \pgfkeys@spdef\tikz@temp{#1}%
+ \expandafter\tikz@subpicture@handle@\expandafter{\tikz@temp}%
+}%
+\def\tikz@subpicture@handle@#1{
+ \pgfkeys{/tikz/pics/.cd,#1}%
+ \tikz@node@transformations%
+ \let\tikz@transform=\relax%
+ \let\tikz@picmode\tikz@mode%
+ \tikzset{name prefix ../.style/.expanded={/tikz/name prefix=\pgfkeysvalueof{/tikz/name prefix}}}%
+ \ifx\tikz@fig@name\pgfutil@empty\else%
+ \tikzset{name prefix/.expanded=\tikz@fig@name}%
+ \fi%
+ \pgfkeysvalueof{/tikz/pics/setup code}%
+ \pgfkeysgetvalue{/tikz/pics/code}{\tikz@pic@code}
+ \ifx\tikz@pic@code\pgfutil@empty\else%
+ \setbox\tikz@whichbox=\hbox\bgroup%
+ \unhbox\tikz@whichbox%
+ \hbox\bgroup
+ \bgroup%
+ \pgfinterruptpath%
+ \pgfscope%
+ \tikz@options%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \tikz@atbegin@scope%
+ \scope[every pic/.try]%
+ \tikz@pic@code%
+ \endscope%
+ \tikz@atend@scope%
+ \endpgfscope%
+ \endpgfinterruptpath%
+ \egroup
+ \egroup%
+ \egroup%
+ \fi%
+ \pgfkeysgetvalue{/tikz/pics/foreground code}{\tikz@pic@code}
+ \ifx\tikz@pic@code\pgfutil@empty\else%
+ \setbox\tikz@figbox=\hbox\bgroup%
+ \unhbox\tikz@figbox%
+ \hbox\bgroup
+ \bgroup%
+ \pgfinterruptpath%
+ \pgfscope%
+ \tikz@options%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \tikz@atbegin@scope%
+ \scope[every front pic/.try]%
+ \tikz@pic@code%
+ \endscope%
+ \tikz@atend@scope%
+ \endpgfscope%
+ \endpgfinterruptpath%
+ \egroup
+ \egroup%
+ \egroup%
+ \fi%
+ \pgfkeysgetvalue{/tikz/pics/background code}{\tikz@pic@code}
+ \ifx\tikz@pic@code\pgfutil@empty\else%
+ \setbox\tikz@figbox@bg=\hbox\bgroup%
+ \unhbox\tikz@figbox@bg%
+ \hbox\bgroup
+ \bgroup%
+ \pgfinterruptpath%
+ \pgfscope%
+ \tikz@options%
+ \setbox\tikz@figbox=\box\pgfutil@voidb@x%
+ \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x%
+ \tikz@atbegin@scope%
+ \scope[every behind pic/.try]%
+ \tikz@pic@code%
+ \endscope%
+ \tikz@atend@scope%
+ \endpgfscope%
+ \endpgfinterruptpath%
+ \egroup
+ \egroup%
+ \egroup%
+ \fi%
+ \tikz@node@finish%
+}%
+\tikzset{
+ pic actions/.code=\tikz@addmode{\tikz@picmode}
+}%
+
+% Setting up the picture codes:
+\tikzset{
+ pics/setup code/.initial=,
+ pics/code/.initial=,
+ pics/background code/.initial=,
+ pics/foreground code/.initial=
+}%
+
+% Defining pictures:
+
+\def\tikzdeclarepic#1#2{\pgfkeys{/tikz/#1/.cd,#2}}%
+
+\pgfkeysdef{/handlers/.pic}{%
+ \edef\pgf@temp{\pgfkeyscurrentpath}%
+ \edef\pgf@temp{\expandafter\tikz@smuggle@pics@in\pgf@temp\pgf@stop}%
+ \expandafter\pgfkeys\expandafter{\pgf@temp/.style={code={#1}}}%
+}%
+\def\tikz@smuggle@pics@in/tikz/#1\pgf@stop{/tikz/pics/#1}%
+
+%
+% Timers
+%
+
+\def\tikz@timer@line{%
+ \pgftransformlineattime{\tikz@time}{\tikz@timer@start}{\tikz@timer@end}%
+}%
+
+\def\tikz@timer@vhline{%
+ \ifdim\tikz@time pt<0.5pt% first half
+ \pgf@process{\tikz@timer@start}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\tikz@timer@end}%
+ \pgf@xb=\tikz@time pt%
+ \pgf@xb=2\pgf@xb%
+ \edef\tikz@marshal{\noexpand\pgftransformlineattime{\pgf@sys@tonumber{\pgf@xb}}{\noexpand\tikz@timer@start}{%
+ \noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@y}}}%
+ \tikz@marshal%
+ \else% second half
+ \pgf@process{\tikz@timer@start}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\tikz@timer@end}%
+ \pgf@xb=\tikz@time pt%
+ \pgf@xb=2\pgf@xb%
+ \advance\pgf@xb by-1pt%
+ \edef\tikz@marshal{\noexpand\pgftransformlineattime{\pgf@sys@tonumber{\pgf@xb}}%
+ {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@y}}{\noexpand\tikz@timer@end}}%
+ \tikz@marshal%
+ \fi%
+}%
+
+\def\tikz@timer@hvline{%
+ \ifdim\tikz@time pt<0.5pt% first half
+ \pgf@process{\tikz@timer@start}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\tikz@timer@end}%
+ \pgf@xb=\tikz@time pt%
+ \pgf@xb=2\pgf@xb%
+ \edef\tikz@marshal{\noexpand\pgftransformlineattime{\pgf@sys@tonumber{\pgf@xb}}{\noexpand\tikz@timer@start}{%
+ \noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@ya}}}%
+ \tikz@marshal%
+ \else% second half
+ \pgf@process{\tikz@timer@start}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\tikz@timer@end}%
+ \pgf@xb=\tikz@time pt%
+ \pgf@xb=2\pgf@xb%
+ \advance\pgf@xb by-1pt%
+ \edef\tikz@marshal{\noexpand\pgftransformlineattime{\pgf@sys@tonumber{\pgf@xb}}%
+ {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@ya}}{\noexpand\tikz@timer@end}}%
+ \tikz@marshal%
+ \fi%
+}%
+
+\def\tikz@timer@curve{%
+ \pgftransformcurveattime{\tikz@time}{\tikz@timer@start}{\tikz@timer@cont@one}{\tikz@timer@cont@two}{\tikz@timer@end}%
+}%
+
+
+\def\tikz@timer@arc{%
+ \pgfmathcos@{\tikz@timer@start@angle}%
+ \let\tikz@angle@cos\pgfmathresult%
+ \pgfmathsin@{\tikz@timer@start@angle}%
+ \let\tikz@angle@sin\pgfmathresult%
+ \pgftransformarcaxesattime{\tikz@time}{%
+ \pgfpointdiff{%
+ \pgfpointadd{%
+ \pgfpointscale{\tikz@angle@cos}{\tikz@timer@zero@axis}%
+ }{%
+ \pgfpointscale{\tikz@angle@sin}{\tikz@timer@ninety@axis}%
+ }%
+ }%
+ {\tikz@timer@start}%
+ }%
+ {\tikz@timer@zero@axis}%
+ {\tikz@timer@ninety@axis}%
+ {\tikz@timer@start@angle}{\tikz@timer@end@angle}%
+}%
+
+
+
+%
+% Coordinate systems
+%
+
+\def\tikzdeclarecoordinatesystem#1#2{%
+ \expandafter\def\csname tikz@parse@cs@#1\endcsname(##1){%
+ \pgf@process{%
+ #2%
+ \global\let\tikz@smubble@b=\tikz@shapeborder@name%
+ }%
+ \let\tikz@shapeborder@name=\tikz@smubble@b%
+ \edef\tikz@return@coordinate{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+}%
+\def\tikzaliascoordinatesystem#1#2{%
+ \edef\pgf@marshal{\noexpand\let\expandafter\noexpand\csname
+ tikz@parse@cs@#1\endcsname=\expandafter\noexpand\csname
+ tikz@parse@cs@#2\endcsname}%
+ \pgf@marshal%
+}%
+
+
+% Default coordinate systems:
+
+\tikzdeclarecoordinatesystem{canvas}
+{%
+ \tikzset{cs/.cd,x=0pt,y=0pt,#1}%
+ \pgfpoint{\tikz@cs@x}{\tikz@cs@y}%
+}%
+
+\tikzdeclarecoordinatesystem{canvas polar}
+{%
+ \tikzset{cs/.cd,angle=0,radius=0cm,#1}%
+ \pgfpointpolar{\tikz@cs@angle}{\tikz@cs@xradius and \tikz@cs@yradius}%
+}%
+
+\tikzdeclarecoordinatesystem{xyz}
+{%
+ \tikzset{cs/.cd,x=0,y=0,z=0,#1}%
+ \pgfpointxyz{\tikz@cs@x}{\tikz@cs@y}{\tikz@cs@z}%
+}%
+
+\tikzdeclarecoordinatesystem{xyz polar}
+{%
+ \tikzset{cs/.cd,angle=0,radius=0,#1}%
+ \pgfpointpolarxy{\tikz@cs@angle}{\tikz@cs@xradius and \tikz@cs@yradius}%
+}%
+\tikzaliascoordinatesystem{xy polar}{xyz polar}%
+
+
+\tikzdeclarecoordinatesystem{node}
+{%
+ \tikzset{cs/.cd,name=,anchor=none,angle=none,#1}%
+ \ifx\tikz@cs@anchor\tikz@nonetext%
+ \ifx\tikz@cs@angle\tikz@nonetext%
+ \expandafter\ifx\csname pgf@sh@ns@\tikz@cs@node\endcsname\tikz@coordinate@text%
+ \else
+ \aftergroup\tikz@shapebordertrue%
+ \edef\tikz@shapeborder@name{\tikz@pp@name{\tikz@cs@node}}%
+ \fi%
+ \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{center}%
+ \else%
+ \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{\tikz@cs@angle}%
+ \fi%
+ \else%
+ \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{\tikz@cs@anchor}%
+ \fi%
+}%
+
+% Intersection coordinates
+\tikzset{cs/first line/.code=\def\tikz@cs@line@a{#1}\def\tikz@cs@type@a{line}}%
+\tikzset{cs/second line/.code=\def\tikz@cs@line@b{#1}\def\tikz@cs@type@b{line}}%
+
+\tikzset{cs/first node/.code=\tikz@cs@unpack{\tikz@cs@node@a}{\tikz@cs@type@a}{#1}}%
+\tikzset{cs/second node/.code=\tikz@cs@unpack{\tikz@cs@node@b}{\tikz@cs@type@b}{#1}}%
+
+\def\tikz@cs@unpack#1#2#3{%
+ \expandafter\ifx\csname pgf@sh@ns@#3\endcsname\relax%
+ \tikzerror{Undefined node ``#3''}%
+ \else%
+ \def#1{#3}%
+ \edef#2{\csname pgf@sh@ns@#3\endcsname}%
+ \fi%
+}%
+
+\tikzset{cs/solution/.initial=1}%
+
+\tikzset{cs/horizontal line through/.store in=\tikz@cs@hori@line}%
+\tikzset{cs/vertical line through/.store in=\tikz@cs@vert@line}%
+
+\tikzdeclarecoordinatesystem{intersection}
+{%
+ \tikzset{cs/.cd,#1}%
+ \expandafter\ifx\csname tikz@intersect@\tikz@cs@type@a @and@\tikz@cs@type@b\endcsname\relax%
+ \tikzerror{I do not know how to compute the intersection
+ of a \tikz@cs@type@a and a \tikz@cs@type@b. Try saying
+ \string\usetikzlibrary{calc}}%
+ \pgfpointorigin%
+ \else%
+ \csname tikz@intersect@\tikz@cs@type@a @and@\tikz@cs@type@b\endcsname%
+ \fi%
+}%
+
+\def\tikz@intersect@line@and@line{%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@parse@line\tikz@cs@line@a%
+ \pgf@xa=\pgf@xc%
+ \pgf@ya=\pgf@yc%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@parse@line\tikz@cs@line@b%
+ \edef\pgf@marshal{%
+ {\noexpand\pgfpointintersectionoflines%
+ {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}%
+ {\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}}%
+ \pgf@marshal%
+}%
+
+\def\tikz@parse@line#1--{%
+ \pgf@process{#1}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \tikz@scan@one@point\pgf@process%
+}%
+
+
+\tikzdeclarecoordinatesystem{perpendicular}
+{%
+ \tikzset{cs/.cd,#1}%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@parse@intersection@a\tikz@cs@hori@line%
+ \expandafter\tikz@scan@one@point\expandafter\tikz@parse@intersection@b\tikz@cs@vert@line%
+ \pgfqpoint{\the\pgf@xb}{\the\pgf@ya}
+}%
+
+\tikzdeclarecoordinatesystem{barycentric}
+{%
+ {%
+ \pgf@xa=0pt% point
+ \pgf@ya=0pt%
+ \pgf@xb=0pt% sum
+ \tikz@bary@dolist#1,=,%
+ \pgfmathparse{1/\the\pgf@xb}%
+ \global\pgf@x=\pgfmathresult\pgf@xa%
+ \global\pgf@y=\pgfmathresult\pgf@ya%
+ }%
+}%
+
+\def\tikz@bary@dolist#1=#2,{%
+ \def\tikz@temp{#1}%
+ \ifx\tikz@temp\pgfutil@empty%
+ \else
+ \pgf@process{\pgfpointanchor{#1}{center}}%
+ \pgfmathparse{#2}%
+ \advance\pgf@xa by\pgfmathresult\pgf@x%
+ \advance\pgf@ya by\pgfmathresult\pgf@y%
+ \advance\pgf@xb by\pgfmathresult pt%
+ \expandafter\tikz@bary@dolist%
+ \fi%
+}%
+
+\tikzset{cs/x/.store in=\tikz@cs@x}%
+\tikzset{cs/y/.store in=\tikz@cs@y}%
+\tikzset{cs/z/.store in=\tikz@cs@z}%
+\tikzset{cs/angle/.store in=\tikz@cs@angle}%
+\tikzset{cs/x radius/.store in=\tikz@cs@xradius}%
+\tikzset{cs/y radius/.store in=\tikz@cs@yradius}%
+\tikzset{cs/radius/.style={/tikz/cs/x radius={#1},/tikz/cs/y radius={#1}}}%
+\tikzset{cs/name/.store in=\tikz@cs@node}%
+\tikzset{cs/anchor/.store in=\tikz@cs@anchor}%
+
+
+
+%
+% Coordinate management
+%
+
+
+% Last position visited
+\def\tikz@last@position{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}%
+\def\tikz@last@position@saved{\pgfqpoint{\tikz@lastxsaved}{\tikz@lastysaved}}%
+
+% Make given point the last position visited
+\def\tikz@make@last@position#1{%
+ \pgf@process{#1}%
+ \tikz@lastx=\pgf@x\relax%
+ \tikz@lasty=\pgf@y\relax%
+ \iftikz@updatecurrent%
+ \tikz@lastxsaved=\pgf@x\relax%
+ \tikz@lastysaved=\pgf@y\relax%
+ \fi%
+ \iftikz@updatenext
+ \tikz@updatecurrenttrue%
+ \fi
+}%
+
+\newif\iftikz@updatecurrent
+\tikz@updatecurrenttrue
+\newif\iftikz@updatenext
+\tikz@updatenexttrue
+
+
+
+% Scanner: Scans a point or a relative point.
+% It then calls the first parameter with the argument set to an
+% appropriate pgf command representing that point.
+
+\def\tikz@scan@one@point#1{%
+ \let\tikz@to@use@whom=\tikz@to@use@last@coordinate%
+ \tikz@shapeborderfalse%
+ \pgfutil@ifnextchar+{\tikz@scan@relative#1}{\tikz@scan@absolute#1}}%
+\def\tikz@scan@absolute#1{%
+ \pgfutil@ifnextchar({\tikz@scan@@absolute#1}%)
+ {%
+ \advance\tikz@expandcount by -1
+ \ifnum\tikz@expandcount<0\relax%
+ \let\pgfutil@next=\tikz@@scangiveup%
+ \else%
+ \let\pgfutil@next=\tikz@@scanexpand%
+ \fi%
+ \pgfutil@next{#1}%
+ }%
+}%
+\def\tikz@@scanexpand#1{\expandafter\tikz@scan@one@point\expandafter#1}%
+\def\tikz@@scangiveup#1{\tikzerror{Cannot parse this coordinate}#1{\pgfpointorigin}}%
+\def\tikz@scan@@absolute#1({%
+ \pgfutil@ifnextchar[% uhoh... options!
+ {\def\tikz@scan@point@recall{#1}\tikz@scan@options}%
+ {\tikz@@@scan@@absolute#1(}%
+}%
+
+\def\tikz@scan@options[#1]#2{%
+ \def\tikz@scan@point@options{#1}%
+ \tikz@@@scan@@absolute\tikz@scan@handle@options(#2%
+}%
+
+\def\tikz@scan@handle@options#1{%
+ {%
+ % Ok, compute point with options set and zero transformation
+ % matrix:
+ \pgftransformreset%
+ \let\tikz@transform=\pgfutil@empty%
+ \expandafter\tikzset\expandafter{\tikz@scan@point@options}%
+ \tikz@transform%
+ \pgf@process{\pgfpointtransformed{#1}}%
+ \xdef\tikz@marshal{\expandafter\noexpand\tikz@scan@point@recall{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ }%
+ \tikz@marshal%
+}%
+
+\def\tikz@@@scan@@absolute#1({%
+ \pgfutil@ifnextchar{$}%$
+ {\tikz@parse@calculator#1(}
+ {\tikz@scan@no@calculator#1(}%
+}%
+\def\tikz@scan@no@calculator#1(#2){%
+ \edef\tikz@scan@point@coordinate{(#2)}%
+ \expandafter\tikz@@scan@@no@calculator\expandafter#1\tikz@scan@point@coordinate%
+}%
+\def\tikz@@scan@@no@calculator#1(#2){%
+ \pgfutil@in@{cs:}{#2}%
+ \ifpgfutil@in@%
+ \let\pgfutil@next\tikz@parse@coordinatesystem%
+ \else%
+ \pgfutil@in@{intersection }{#2}%
+ \ifpgfutil@in@%
+ \let\pgfutil@next\tikz@parse@intersection%
+ \else%
+ \pgfutil@in@|{#2}%
+ \ifpgfutil@in@
+ \pgfutil@in@{-|}{#2}%
+ \ifpgfutil@in@
+ \let\pgfutil@next\tikz@parse@hv%
+ \else%
+ \let\pgfutil@next\tikz@parse@vh%
+ \fi%
+ \else%
+ \pgfutil@in@:{#2}%
+ \ifpgfutil@in@
+ \let\pgfutil@next\tikz@parse@polar%
+ \else%
+ \pgfutil@in@,{#2}%
+ \ifpgfutil@in@%
+ \let\pgfutil@next\tikz@parse@regular%
+ \else%
+ \let\pgfutil@next\tikz@parse@node%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgfutil@next#1(#2)%
+}%
+
+\def\tikz@parse@calculator#1($#2$){%
+ \tikzerror{You need to say \string\usetikzlibrary{calc} for coordinate calculation}%
+ #1{\pgfpointorigin}%
+}%
+
+\def\tikz@parse@coordinatesystem#1(#2 cs:#3){%
+ \let\tikz@return@coordinate=\pgfpointorigin%
+ \pgfutil@ifundefined{tikz@parse@cs@#2}
+ {\tikzerror{Unknown coordinate system '#2'}}
+ {\csname tikz@parse@cs@#2\endcsname(#3)}%
+ \expandafter#1\expandafter{\tikz@return@coordinate}%
+}%
+
+
+\newif\iftikz@isdimension
+\def\tikz@checkunit#1{%
+ \pgfmathparse{#1}%
+ \let\iftikz@isdimension=\ifpgfmathunitsdeclared%
+}%
+
+\def\tikz@parse@polar#1(#2:#3){%
+ \pgfutil@ifundefined{tikz@polar@dir@#2}
+ {\tikz@@parse@polar#1({#2}:{#3})}
+ {\tikz@@parse@polar#1(\csname tikz@polar@dir@#2\endcsname:{#3})}%
+}%
+\def\tikz@@parse@polar#1(#2:#3){%
+ \pgfutil@in@{ and }{#3}%
+ \ifpgfutil@in@%
+ \edef\tikz@args{({#2}:#3)}%
+ \else%
+ \edef\tikz@args{({#2}:{#3} and {#3})}%
+ \fi%
+ \expandafter\tikz@@@parse@polar\expandafter#1\tikz@args%
+}%
+\def\tikz@@@parse@polar#1(#2:#3 and #4){%
+ \tikz@checkunit{#3}%
+ \iftikz@isdimension%
+ \tikz@checkunit{#4}%
+ \iftikz@isdimension%
+ \def\tikz@next{#1{\pgfpointpolar{#2}{#3 and #4}}}%
+ \else%
+ \tikzerror{You cannot mix dimension and dimensionless values for polar coordinates}
+ \def\tikz@next{#1{\pgfpointorigin}}%
+ \fi%
+ \else%
+ \tikz@checkunit{#4}%
+ \iftikz@isdimension%
+ \tikzerror{You cannot mix dimension and dimensionless values for polar coordinates}
+ \def\tikz@next{#1{\pgfpointorigin}}%
+ \else%
+ \def\tikz@next{#1{\pgfpointpolarxy{#2}{#3 and #4}}}%
+ \fi%
+ \fi%
+ \tikz@next%
+}%
+\def\tikz@polar@dir@up{90}%
+\def\tikz@polar@dir@down{-90}%
+\def\tikz@polar@dir@left{180}%
+\def\tikz@polar@dir@right{0}%
+\def\tikz@polar@dir@north{90}%
+\def\tikz@polar@dir@south{-90}%
+\def\tikz@polar@dir@east{0}%
+\def\tikz@polar@dir@west{180}%
+\expandafter\def\csname tikz@polar@dir@north east\endcsname{45}%
+\expandafter\def\csname tikz@polar@dir@north west\endcsname{135}%
+\expandafter\def\csname tikz@polar@dir@south east\endcsname{-45}%
+\expandafter\def\csname tikz@polar@dir@south west\endcsname{-135}%
+
+
+% MW:
+% Check to see if the y-coordinate is inside {}. If it is, scan it and
+% reinsert it into the stream inside an extra group.
+%
+\def\tikz@parse@regular#1(#2,{%
+ \pgfutil@ifnextchar\bgroup{\tikz@@parse@regular#1{#2}}{\tikz@@@parse@regular#1{#2}}%
+}%
+\def\tikz@@parse@regular#1#2#3{%
+ \pgfutil@ifnextchar[{% Uh oh! An array index.
+ \tikz@@@parse@regular#1{#2}{#3}}%
+ {\tikz@@@parse@regular#1{#2}{{#3}}}}%
+
+% Originally \def\tikz@parse@regular#1(#2,#3){%
+%
+\def\tikz@@@parse@regular#1#2#3){%
+ \pgfutil@in@,{#3}%
+ \ifpgfutil@in@%
+ \tikz@parse@splitxyz{#1}{#2}#3,%
+ \else%
+ \tikz@checkunit{#2}%
+ \iftikz@isdimension%
+ \tikz@checkunit{#3}%
+ \iftikz@isdimension%
+ \def\pgfutil@next{#1{\pgfpoint{#2}{#3}}}%
+ \else%
+ \def\pgfutil@next{#1{\pgfpointadd{\pgfpoint{#2}{0pt}}{\pgfpointxy{0}{#3}}}}%
+ \fi%
+ \else%
+ \tikz@checkunit{#3}%
+ \iftikz@isdimension%
+ \def\pgfutil@next{#1{\pgfpointadd{\pgfpoint{0pt}{#3}}{\pgfpointxy{#2}{0}}}}%
+ \else%
+ \def\pgfutil@next{#1{\pgfpointxy{#2}{#3}}}%
+ \fi%
+ \fi%
+ \fi%
+ \pgfutil@next%
+}%
+
+\def\tikz@parse@splitxyz#1#2#3,#4,{%
+ \def\pgfutil@next{#1{\pgfpointxyz{#2}{#3}{#4}}}%
+}%
+
+\def\tikz@coordinate@text{coordinate}%
+
+\def\tikz@parse@node#1(#2){%
+ \pgfutil@in@.{#2}% Ok, flag this
+ \ifpgfutil@in@
+ \tikz@calc@anchor#2\tikz@stop%
+ \else%
+ \tikz@calc@anchor#2.center\tikz@stop% to be on the save side, in
+ % case iftikz@shapeborder is ignored...
+ \ifcsname pgf@sh@ns@\tikz@pp@name{#2}\endcsname
+ \expandafter\ifx\csname pgf@sh@ns@\tikz@pp@name{#2}\endcsname\tikz@coordinate@text%
+ \else
+ \tikz@shapebordertrue%
+ \def\tikz@shapeborder@name{\tikz@pp@name{#2}}%
+ \fi%
+ \else\ifcsname pgf@sh@ns@#2\endcsname
+ \expandafter\ifx\csname pgf@sh@ns@#2\endcsname\tikz@coordinate@text%
+ \else
+ \tikz@shapebordertrue%
+ \def\tikz@shapeborder@name{#2}%
+ \fi%
+ \fi\fi
+ \fi%
+ \edef\tikz@marshal{\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \tikz@marshal%
+}%
+
+\def\tikz@calc@anchor#1.#2\tikz@stop{%
+ % Check if a shape with name prefix exists, otherwise try the global name
+ % without prefix.
+ \ifcsname pgf@sh@ns@\tikz@pp@name{#1}\endcsname%
+ \pgfpointanchor{\tikz@pp@name{#1}}{#2}%
+ \else
+ \pgfpointanchor{#1}{#2}%
+ \fi
+}%
+
+
+\def\tikz@parse@hv#1(#2){%
+ \pgfutil@in@{ -| }{#2}%
+ \ifpgfutil@in@%
+ \let\tikz@next=\tikz@parse@hvboth%
+ \else%
+ \pgfutil@in@{ -|}{#2}%
+ \ifpgfutil@in@%
+ \let\tikz@next=\tikz@parse@hvleft%
+ \else%
+ \pgfutil@in@{-| }{#2}%
+ \ifpgfutil@in@%
+ \let\tikz@next=\tikz@parse@hvright%
+ \else%
+ \let\tikz@next=\tikz@parse@hvdone%
+ \fi%
+ \fi%
+ \fi%
+ \tikz@next#1(#2)}%
+\def\tikz@parse@hvboth#1(#2 -| #3){\tikz@parse@vhdone#1({#3}|-{#2})}%
+\def\tikz@parse@hvleft#1(#2 -|#3){\tikz@parse@vhdone#1({#3}|-{#2})}%
+\def\tikz@parse@hvright#1(#2-| #3){\tikz@parse@vhdone#1({#3}|-{#2})}%
+\def\tikz@parse@hvdone#1(#2-|#3){\tikz@parse@vhdone#1({#3}|-{#2})}%
+
+\def\tikz@parse@vh#1(#2){%
+ \pgfutil@in@{ |- }{#2}%
+ \ifpgfutil@in@%
+ \let\tikz@next=\tikz@parse@vhboth%
+ \else%
+ \pgfutil@in@{ |-}{#2}%
+ \ifpgfutil@in@%
+ \let\tikz@next=\tikz@parse@vhleft%
+ \else%
+ \pgfutil@in@{|- }{#2}%
+ \ifpgfutil@in@%
+ \let\tikz@next=\tikz@parse@vhright%
+ \else%
+ \let\tikz@next=\tikz@parse@vhdone%
+ \fi%
+ \fi%
+ \fi%
+ \tikz@next#1(#2)}%
+\def\tikz@parse@vhboth#1(#2 |- #3){\tikz@parse@vhdone#1({#2}|-{#3})}%
+\def\tikz@parse@vhleft#1(#2 |-#3){\tikz@parse@vhdone#1({#2}|-{#3})}%
+\def\tikz@parse@vhright#1(#2|- #3){\tikz@parse@vhdone#1({#2}|-{#3})}%
+\def\tikz@parse@vhdone#1(#2|-#3){%
+ {%
+ \tikz@@@scan@@absolute\tikz@parse@vh@mid(#2)%
+ \tikz@@@scan@@absolute\tikz@parse@vh@end(#3)%
+ \xdef\tikz@marshal{\noexpand#1{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}}%
+ }%
+ \tikz@marshal%
+}%
+\def\tikz@parse@vh@mid#1{\pgf@process{#1}\pgf@xa=\pgf@x}%
+\def\tikz@parse@vh@end#1{\pgf@process{#1}\pgf@ya=\pgf@y}%
+
+\def\tikz@parse@intersection#1(intersection{%
+ \pgfutil@ifnextchar o{%
+ \tikz@parse@main@intersection#1 1%
+ }{%
+ \tikz@parse@main@intersection#1%
+ }%
+}%
+\def\tikz@parse@main@intersection#1#2of #3 and #4){%
+ \tikzset{cs/solution={#2}}%
+ \pgfutil@in@{--}{#3}%
+ \ifpgfutil@in@%
+ \tikz@reparse@line{first}#3\pgf@stop%
+ \else%
+ \tikzset{cs/first node={#3}}%
+ \fi%
+ \pgfutil@in@{--}{#4}%
+ \ifpgfutil@in@%
+ \tikz@reparse@line{second}#4\pgf@stop%
+ \else%
+ \tikzset{cs/second node={#4}}%
+ \fi%
+ \tikz@parse@cs@intersection()% advanced hackery...
+ \edef\pgf@marshal{\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \pgf@marshal%
+}%
+\def\tikz@reparse@line#1#2--#3\pgf@stop{%
+ \tikzset{cs/#1 line={(#2)--(#3)}}%
+}%
+
+
+\def\tikz@parse@intersection@a#1{\pgf@process{#1}\pgf@xa=\pgf@x\pgf@ya=\pgf@y}%
+\def\tikz@parse@intersection@b#1{\pgf@process{#1}\pgf@xb=\pgf@x\pgf@yb=\pgf@y}%
+
+\def\tikz@scan@relative#1+{%
+ \pgfutil@ifnextchar+{\tikz@scan@plusplus#1}{\tikz@scan@oneplus#1}}%
+
+\def\tikz@scan@plusplus#1+{%
+ \def\tikz@doafter{#1}%
+ \tikz@scan@absolute\tikz@add%
+}%
+\def\tikz@add#1{%
+ \tikz@doafter{\pgfpointadd{#1}{\tikz@last@position@saved}}%
+}%
+\def\tikz@scan@oneplus#1{%
+ \def\tikz@doafter{#1}%
+ \tikz@updatecurrentfalse%
+ \tikz@scan@absolute\tikz@add%
+}%
+
+
+
+%
+% Quote handling
+%
+
+\let\tikz@enable@node@quotes\relax
+\let\tikz@enable@edge@quotes\relax
+\let\tikz@enable@pic@quotes\relax
+
+
+
+% Loading further libraries
+
+% Include a library file.
+%
+% #1 = List of names of library file.
+%
+% Description:
+%
+% This command includes a list of TikZ library files. For each file X in the
+% list, the file tikzlibraryX.code.tex is included, provided this has
+% not been done earlier.
+%
+% For the convenience of Context users, both round and square brackets
+% are possible for the argument.
+%
+% If no file tikzlibraryX.code.tex exists, the file
+% pgflibraryX.code.tex is tried instead. If this file, also, does not
+% exist, an error message is printed.
+%
+% Example:
+%
+% \usetikzlibrary{arrows}
+% \usetikzlibrary[patterns,topaths]
+
+\def\usetikzlibrary{\pgfutil@ifnextchar[{\use@tikzlibrary}{\use@@tikzlibrary}}%}%
+\def\use@tikzlibrary[#1]{\use@@tikzlibrary{#1}}%
+\def\use@@tikzlibrary#1{%
+ \edef\pgf@list{#1}%
+ \pgfutil@for\pgf@temp:=\pgf@list\do{%
+ \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}%
+ \ifx\pgf@temp\pgfutil@empty
+ \else
+ \expandafter\ifx\csname tikz@library@\pgf@temp @loaded\endcsname\relax%
+ \expandafter\global\expandafter\let\csname tikz@library@\pgf@temp @loaded\endcsname=\pgfutil@empty%
+ \expandafter\edef\csname tikz@library@#1@atcode\endcsname{\the\catcode`\@}
+ \expandafter\edef\csname tikz@library@#1@barcode\endcsname{\the\catcode`\|}
+ \expandafter\edef\csname tikz@library@#1@dollarcode\endcsname{\the\catcode`\$}
+ \catcode`\@=11
+ \catcode`\|=12
+ \catcode`\$=3
+ \pgfutil@InputIfFileExists{tikzlibrary\pgf@temp.code.tex}{}{
+ \pgfutil@IfFileExists{pgflibrary\pgf@temp.code.tex}{%
+ \expandafter\usepgflibrary\expandafter{\pgf@temp}%
+ }{%
+ \tikzerror{I did not find the tikz library
+ '\pgf@temp'. I looked for files named
+ tikzlibrary\pgf@temp.code.tex and
+ pgflibrary\pgf@temp.code.tex, but neither
+ could be found in the current texmf trees.}
+ }}%
+ \catcode`\@=\csname tikz@library@#1@atcode\endcsname
+ \catcode`\|=\csname tikz@library@#1@barcode\endcsname
+ \catcode`\$=\csname tikz@library@#1@dollarcode\endcsname
+ \fi%
+ \fi
+ }%
+}%
+
+
+% Always-present libraries:
+
+\usetikzlibrary{topaths}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/LUA_CODING_STYLE b/graphics/pgf/base/tex/generic/graphdrawing/lua/LUA_CODING_STYLE
new file mode 100644
index 0000000000..295a8b2ed1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/LUA_CODING_STYLE
@@ -0,0 +1,27 @@
+Lua coding style for the graphdrawing library
+=============================================
+
+General naming rules and indentation:
+
+ * 2 spaces indentation
+ * variable_names_with_underscores
+ * namespaced.low_level_functions_with_underscores(foo, bar)
+ * CamelCaseClassNames
+ * CamelCaseClassNames.nameOfStaticFunctionLikeNewOrClone(foo, bar)
+ * CamelCaseClass:functionNamesLikeThis(foo, bar)
+ * never use global variables
+ * Use . for static functions and : for member functions
+
+LuaDoc comments:
+
+ ---
+ -- A function to do this and that.
+ --
+ -- @param first Description of the first parameter.
+ -- @param second Description of the second parameter.
+ --
+ -- @return This function returns something.
+ --
+ function myClass:myFunction(first, second)
+ ...
+ end
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf.lua
new file mode 100644
index 0000000000..b0a3247616
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf.lua
@@ -0,0 +1,72 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- The |pgf| namespace lies in the global namespace. It is the only
+-- global table defined by \pgfname. The whole graph drawing system,
+-- in turn, lies in the table |pgf.gd|.
+
+pgf = {}
+
+
+
+-- Forward
+local tostring_table
+
+---
+-- Writes debug info on the \TeX\ output, separating the parameters
+-- by spaces. The debug information will include a complete traceback
+-- of the stack, allowing you to see ``where you are'' inside the Lua
+-- program.
+--
+-- Note that this function resides directly in the |pgf| table. The
+-- reason for this is that you can ``always use it'' since |pgf| is
+-- always available in the global name space.
+--
+-- @param ... List of parameters to write to the \TeX\ output.
+
+function pgf.debug(...)
+ local stacktrace = debug.traceback("",2)
+ texio.write_nl(" ")
+ texio.write_nl("Debug called for: ")
+ -- this is to even print out nil arguments in between
+ local args = {...}
+ for i = 1, #args do
+ if i ~= 1 then texio.write(", ") end
+ texio.write(tostring_table(args[i], "", 5))
+ end
+ texio.write_nl('')
+ for w in string.gmatch(stacktrace, "/.-:.-:.-%c") do
+ texio.write('by ', string.match(w,".*/(.*)"))
+ end
+end
+
+
+-- Helper function
+
+function tostring_table(t, prefix, depth)
+ if type(t) ~= "table" or (getmetatable(t) and getmetatable(t).__tostring) or depth <= 0 then
+ return type(t) == "string" and ('"' .. t .. '"') or tostring(t)
+ else
+ local r = "{\n"
+ for k,v in pairs(t) do
+ r = r .. prefix .. " " .. tostring(k) .. "=" ..
+ (v==t and "self" or tostring_table(v, prefix .. " ", depth-1)) .. ",\n"
+ end
+ return r .. prefix .. "}"
+ end
+end
+
+
+
+
+return pgf \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd.lua
new file mode 100644
index 0000000000..20d8acafa5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd.lua
@@ -0,0 +1,72 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+
+-- Declare the gd namespace
+
+local gd = {}
+require("pgf").gd = gd
+
+
+
+
+
+
+
+-- Deprecated:
+--
+--
+-- Helping function for creating new algorithm classes
+--
+-- This function creates a new algorithm class. This class will have a
+-- new method, that takes a graph and, optionally, a parent algorithm
+-- as inputs. They will be stored in the "graph" and "parent_algorithm"
+-- fields, respectively.
+--
+-- @param info This table is used to configure the new class. It has
+-- the following fields: First, there is the "properties" table. If
+-- this table is present, it will be used as the default table. Second,
+-- it can have a graph_parameters table. This table will be used in the
+-- constructor to preload graph parameters from the pgf layer. For
+-- this, each entry of the table should be of the form
+--
+-- key = 'string'
+--
+-- What happens is that upon the creation of a new algorithm object,
+-- for each key we lookup the graph option 'string' and
+-- store its value in the key of the new algorithm object.
+--
+-- @return A table that is a class with a new function setup.
+
+function gd.new_algorithm_class (class)
+ class.__index = class
+ class.new =
+ function (initial)
+
+ -- Create new object
+ local obj = {}
+ for k,v in pairs(initial) do
+ obj[k] = v
+ end
+ setmetatable(obj, class)
+
+ return obj
+ end
+ class.preconditions = {}
+ class.postconditions = {}
+
+ return class
+end
+
+
+return gd
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings.lua
new file mode 100644
index 0000000000..410da3af45
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings.lua
@@ -0,0 +1,26 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+-- Imports
+
+require "pgf"
+require "pgf.gd"
+
+
+-- Declare namespace
+pgf.gd.bindings = {}
+
+
+-- Done
+
+return pgf.gd.bindings \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/Binding.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/Binding.lua
new file mode 100644
index 0000000000..6ffb4168f5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/Binding.lua
@@ -0,0 +1,265 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local Storage = require "pgf.gd.lib.Storage"
+
+
+---
+-- This class provides a (non-functional) default implementation of a
+-- binding between a display layer and the algorithm layer. Subclasses
+-- must implement most of the member functions declared in this class.
+--
+-- A instance of a subclass of this class encapsulates the complete
+-- implementation of all specific code needed for the communication
+-- between the display layer and the graph drawing engine.
+--
+-- Note that you never call the methods of a |Binding| object
+-- directly, neither from the display layer nor from the algorithm
+-- layer. Instead, you use the more powerful and more easy to use
+-- functions from |InterfaceToDisplay| and
+-- |InterfaceToAlgorithms|. They call the appropriate |Binding|
+-- methods internally.
+--
+-- Because of the above, in order to use the graph drawing system
+-- inside a new display layer, you need to subclass |Binding| and
+-- implement all the functions. Then you need to write the display
+-- layer in such a way that it calls the appropriate functions from
+-- |InterfaceToDisplay|.
+--
+-- @field storage A |Storage| storing the information passed from the
+-- display layer. The interpretation of this left to the actual
+-- binding.
+
+local Binding = {
+ storage = Storage.newTableStorage ()
+}
+Binding.__index = Binding
+
+-- Namespace
+require("pgf.gd.bindings").Binding = Binding
+
+
+
+
+
+--
+-- This method gets called whenever the graph drawing coroutine should
+-- be resumed. First, the binding layer should ask the display layer
+-- to execute the |code|, then, after this is done, the function
+-- |InterfaceToDisplay.resumeGraphDrawingCoroutine| should be called
+-- by this function.
+--
+-- @param code Some code to be executed by the display layer.
+
+function Binding:resumeGraphDrawingCoroutine(code)
+ -- Does nothing by default
+end
+
+
+---
+-- Declare a new key. This callback is called by |declare|. It is the job
+-- of the display layer to make the parameter |t.key| available to the
+-- parsing process. Furthermore, if |t.initial| is not |nil|, the
+-- display layer must convert it into a value that is stored as the
+-- initial value and call |InterfaceToDisplay.setOptionInitial|.
+--
+-- @param t See |InterfaceToAlgorithms.declare| for details.
+
+function Binding:declareCallback(t)
+ -- Does nothing by default
+end
+
+
+
+
+-- Rendering
+
+---
+-- This function and, later on, |renderStop| are called whenever the
+-- rendering of a laid-out graph starts or stops. See
+-- |InterfaceToDisplay.render| for details.
+
+function Binding:renderStart()
+ -- Does nothing by default
+end
+
+---
+-- See |renderStart|.
+
+function Binding:renderStop()
+ -- Does nothing by default
+end
+
+
+
+
+
+---
+-- This function and the corresponding |...Stop...| functions are
+-- called whenever a collection kind should be rendered. See
+-- |InterfaceToDisplay.render_collections| for details.
+--
+-- @param kind The kind (a string).
+-- @param layer The kind's layer (a number).
+
+function Binding:renderCollectionStartKind(kind, layer)
+ -- Does nothing by default
+end
+
+
+---
+-- The counterpart to |renderCollectionStartKind|.
+--
+-- @param kind The kind.
+-- @param layer The kind's layer.
+
+function Binding:renderCollectionStopKind(kind, layer)
+ -- Does nothing by default
+end
+
+
+---
+-- Renders a single collection, see |renderCollectionStartKind| for
+-- details.
+--
+-- @param collection The collection object.
+
+function Binding:renderCollection(collection)
+ -- Does nothing by default
+end
+
+
+
+---
+-- This function and the corresponding |...Stop...| functions are
+-- called whenever a vertex should be rendered. See
+-- |InterfaceToDisplay.render_vertices| for details.
+--
+
+function Binding:renderVerticesStart()
+ -- Does nothing by default
+end
+
+
+---
+-- The counterpart to |renderVerticesStop|.
+--
+
+function Binding:renderVerticesStop()
+ -- Does nothing by default
+end
+
+
+---
+-- Renders a single vertex, see |renderVertexStartKind| for
+-- details.
+--
+-- @param vertex The |Vertex| object.
+
+function Binding:renderVertex(vertex)
+ -- Does nothing by default
+end
+
+
+
+---
+-- This method is called by the interface to the display layer after
+-- the display layer has called |createVertex| to create a new
+-- vertex. After having done its internal bookkeeping, the interface
+-- calls this function to allow the binding to perform further
+-- bookkeeping on the node. Typically, this will be done using the
+-- information stored in |Binding.infos|.
+--
+-- @param v The vertex.
+
+function Binding:everyVertexCreation(v)
+ -- Does nothing by default
+end
+
+
+
+
+
+---
+-- This function and the corresponding |...Stop...| functions are
+-- called whenever an edge should be rendered. See
+-- |InterfaceToDisplay.render_edges| for details.
+--
+
+function Binding:renderEdgesStart()
+ -- Does nothing by default
+end
+
+
+---
+-- The counterpart to |renderEdgesStop|.
+--
+
+function Binding:renderEdgesStop()
+ -- Does nothing by default
+end
+
+
+---
+-- Renders a single vertex, see |renderEdgeStartKind| for
+-- details.
+--
+-- @param edge The |Edge| object.
+
+function Binding:renderEdge(edge)
+ -- Does nothing by default
+end
+
+
+---
+-- Like |everyVertexCreation|, only for edges.
+--
+-- @param e The edge.
+
+function Binding:everyEdgeCreation(e)
+ -- Does nothing by default
+end
+
+
+---
+-- Generate a new vertex. This method will be called when the
+-- \emph{algorithm} layer wishes to trigger the creation of a new
+-- vertex. This call will be made while an algorithm is running. It is
+-- now the job of the binding to cause the display layer to create the
+-- node. This is done by calling the |yield| method of the scope's
+-- coroutine.
+--
+-- @param init A table of initial values for the node. The following
+-- fields will be used:
+-- %
+-- \begin{itemize}
+-- \item |name| If present, this name will be given to the
+-- node. If not present, an internal name is generated. Note that,
+-- unless the node is a subgraph node, this name may not be the name
+-- of an already present node of the graph; in this case an error
+-- results.
+-- \item |shape| If present, a shape of the node.
+-- \item |generated_options| A table that is passed back to the
+-- display layer as a list of key--value pairs.
+-- \item |text| The text of the node, to be passed back to the
+-- higher layer. This is what should be displayed as the node's text.
+-- \end{itemize}
+
+function Binding:createVertex(init)
+ -- Does nothing by default
+end
+
+
+
+
+return Binding \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua
new file mode 100644
index 0000000000..5324a1652e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua
@@ -0,0 +1,374 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+-- Imports
+local Storage = require "pgf.gd.lib.Storage"
+
+
+---
+-- This class, which is a subclass of |Binding|, binds the graph
+-- drawing system to the \pgfname\ display system by overriding (that
+-- is, implementing) the methods of the |Binding| class. As a typical
+-- example, consider the implementation of the function |renderVertex|:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--function BindingToPGF:renderVertex(v)
+-- local info = assert(self.infos[v], "thou shalt not modify the syntactic digraph")
+-- tex.print(
+-- string.format(
+-- "\\pgfgdcallbackrendernode{%s}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%s}",
+-- 'not yet positionedPGFINTERNAL' .. v.name,
+-- info.x_min,
+-- info.x_max,
+-- info.y_min,
+-- info.y_max,
+-- v.pos.x,
+-- v.pos.y,
+-- info.box_count))
+--end
+--\end{codeexample}
+--
+-- As can be seen, the main job of this function is to call a function
+-- on the \TeX\ layer that is called |\pgfgdcallbackrendernode|, which gets
+-- several parameters like the name of the to-be-rendered node or the
+-- (new) position for the node. For almost all methods of the
+-- |Binding| class there is a corresponding ``callback'' macro on the
+-- \TeX\ layer, all of which are implemented in the \pgfname\ library
+-- |graphdrawing|. For details on these callbacks,
+-- please consult the code of that file and of the class
+-- |BindingToPGF| (they are not documented here since they are local
+-- to the binding and should not be called by anyone other than the
+-- binding class).
+
+local BindingToPGF = {
+ storage = Storage.newTableStorage () -- overwrite default storage
+}
+BindingToPGF.__index = BindingToPGF
+setmetatable(BindingToPGF, require "pgf.gd.bindings.Binding") -- subclass of Binding
+
+
+-- Namespace
+require("pgf.gd.bindings").BindingToPGF = BindingToPGF
+
+-- Imports
+local lib = require "pgf.gd.lib"
+
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Path = require "pgf.gd.model.Path"
+
+-- The implementation
+
+-- Forward
+local table_in_pgf_syntax
+local animations_in_pgf_syntax
+local path_in_pgf_syntax
+local coordinate_in_pgf_syntax
+
+
+
+
+-- Scope handling
+
+function BindingToPGF:resumeGraphDrawingCoroutine(text)
+ tex.print(text)
+ tex.print("\\pgfgdresumecoroutinetrue")
+end
+
+
+-- Declarations
+
+function BindingToPGF:declareCallback(t)
+ tex.print("\\pgfgdcallbackdeclareparameter{" .. t.key .. "}{" .. (t.type or "nil") .. "}")
+end
+
+
+
+-- Rendering
+
+function BindingToPGF:renderStart()
+ tex.print("\\pgfgdcallbackbeginshipout")
+end
+
+function BindingToPGF:renderStop()
+ tex.print("\\pgfgdcallbackendshipout")
+end
+
+
+-- Rendering collections
+
+function BindingToPGF:renderCollection(collection)
+ tex.print("\\pgfgdcallbackrendercollection{".. collection.kind .. "}{"
+ .. table_in_pgf_syntax(collection.generated_options) .. "}")
+end
+
+function BindingToPGF:renderCollectionStartKind(kind, layer)
+ tex.print("\\pgfgdcallbackrendercollectionkindstart{" .. kind .. "}{" .. tostring(layer) .. "}")
+end
+
+function BindingToPGF:renderCollectionStopKind(kind, layer)
+ tex.print("\\pgfgdcallbackrendercollectionkindstop{" .. kind .. "}{" .. tostring(layer) .. "}")
+end
+
+-- Printing points
+
+local function to_pt(x)
+ return string.format("%.12fpt", x)
+end
+
+
+-- Managing vertices (pgf nodes)
+
+local boxes = {}
+local box_count = 0
+
+function BindingToPGF:everyVertexCreation(v)
+ local info = self.storage[v]
+
+ -- Save the box!
+ box_count = box_count + 1
+ boxes[box_count] = node.copy_list(tex.box[info.tex_box_number])
+
+ -- Special tex stuff, should not be considered by gd algorithm
+ info.box_count = box_count
+end
+
+function BindingToPGF:renderVertex(v)
+ local info = assert(self.storage[v], "thou shalt not modify the syntactic digraph")
+ tex.print(
+ string.format(
+ "\\pgfgdcallbackrendernode{%s}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%s}{%s}",
+ 'not yet positionedPGFINTERNAL' .. v.name,
+ info.x_min,
+ info.x_max,
+ info.y_min,
+ info.y_max,
+ v.pos.x,
+ v.pos.y,
+ info.box_count,
+ animations_in_pgf_syntax(v.animations)))
+end
+
+function BindingToPGF:retrieveBox(index, box_num)
+ tex.box[box_num] = assert(boxes[index], "no box stored at given index")
+ boxes[index] = nil -- remove from memory
+end
+
+function BindingToPGF:renderVerticesStart()
+ tex.print("\\pgfgdcallbackbeginnodeshipout")
+end
+
+function BindingToPGF:renderVerticesStop()
+ tex.print("\\pgfgdcallbackendnodeshipout")
+end
+
+
+local function rigid(x)
+ if type(x) == "function" then
+ return x()
+ else
+ return x
+ end
+end
+
+
+-- Managing edges
+
+function BindingToPGF:renderEdge(e)
+ local info = assert(self.storage[e], "thou shalt not modify the syntactic digraph")
+
+ local function get_anchor(e, anchor)
+ local a = e.options[anchor]
+ if a and a ~= "" then
+ return "." .. a
+ else
+ return ""
+ end
+ end
+
+ local callback = {
+ '\\pgfgdcallbackedge',
+ '{', e.tail.name .. get_anchor(e, "tail anchor"), '}',
+ '{', e.head.name .. get_anchor(e, "head anchor"), '}',
+ '{', e.direction, '}',
+ '{', info.pgf_options or "", '}',
+ '{', info.pgf_edge_nodes or "", '}',
+ '{', table_in_pgf_syntax(e.generated_options), '}',
+ '{'
+ }
+
+ local i = 1
+ while i <= #e.path do
+ local c = e.path[i]
+ assert (type(c) == "string", "illegal path operand")
+
+ if c == "lineto" then
+ i = i + 1
+ local d = rigid(e.path[i])
+ callback [#callback + 1] = '--(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')'
+ i = i + 1
+ elseif c == "moveto" then
+ i = i + 1
+ local d = rigid(e.path[i])
+ callback [#callback + 1] = '(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')'
+ i = i + 1
+ elseif c == "closepath" then
+ callback [#callback + 1] = '--cycle'
+ i = i + 1
+ elseif c == "curveto" then
+ local d1, d2, d3 = rigid(e.path[i+1]), rigid(e.path[i+2]), rigid(e.path[i+3])
+ i = i + 3
+ callback [#callback + 1] = '..controls(' .. to_pt(d1.x) .. ',' .. to_pt(d1.y) .. ')and('
+ .. to_pt(d2.x) .. ',' .. to_pt(d2.y) .. ')..'
+ callback [#callback + 1] = '(' .. to_pt(d3.x) .. ',' .. to_pt(d3.y) .. ')'
+ i = i + 1
+ else
+ error("illegal operation in edge path")
+ end
+ end
+
+ callback [#callback + 1] = '}'
+ callback [#callback + 1] = '{' .. animations_in_pgf_syntax(e.animations) .. '}'
+
+ -- hand TikZ code over to TeX
+ tex.print(table.concat(callback))
+end
+
+
+function BindingToPGF:renderEdgesStart()
+ tex.print("\\pgfgdcallbackbeginedgeshipout")
+end
+
+function BindingToPGF:renderEdgesStop()
+ tex.print("\\pgfgdcallbackendedgeshipout")
+end
+
+
+-- Vertex creation
+
+function BindingToPGF:createVertex(init)
+ -- Now, go back to TeX...
+ coroutine.yield(
+ table.concat({
+ "\\pgfgdcallbackcreatevertex{", init.name, "}",
+ "{", init.shape, "}",
+ "{", table_in_pgf_syntax(init.generated_options), ",", init.pgf_options or "", "}",
+ "{", (init.text or ""), "}"
+ }))
+ -- ... and come back with a new node!
+end
+
+
+
+-- Local helpers
+
+function table_in_pgf_syntax (t)
+ local prefix = "/graph drawing/"
+ local suffix = "/.try"
+ return table.concat( lib.imap( t, function(table)
+ if table.value then
+ return prefix .. table.key .. suffix .. "={" .. tostring(table.value) .. "}"
+ else
+ return prefix .. table.key .. suffix
+ end
+ end), ",")
+end
+
+
+function animations_in_pgf_syntax (a)
+ return
+ table.concat(
+ lib.imap(
+ a,
+ function(animation)
+ return "\\pgfanimateattribute{" .. animation.attribute .. "}{whom=pgf@gd," ..
+ table.concat(
+ lib.imap (
+ animation.entries,
+ function (entry)
+ return "entry={" .. entry.t .. "s}{" .. to_pgf(entry.value) .. "}"
+ end
+ ), ",") ..
+ "," ..
+ table.concat(
+ lib.imap(
+ animation.options or {},
+ function(table)
+ if table.value then
+ return table.key .. "={" .. to_pgf(table.value) .. "}"
+ else
+ return table.key
+ end
+ end), ",")
+ .. "}"
+ end)
+ )
+end
+
+
+function to_pgf(x)
+ if type (x) == "table" then
+ if getmetatable(x) == Coordinate then
+ return coordinate_in_pgf_syntax(x)
+ elseif getmetatable(x) == Path then
+ return path_in_pgf_syntax(x)
+ else
+ error("illegal table in value of a key to be passed back to pgf")
+ end
+ else
+ return tostring(x)
+ end
+end
+
+function path_in_pgf_syntax (p)
+
+ local s = {}
+
+ local i = 1
+ while i <= #p do
+ local c = p[i]
+ assert (type(c) == "string", "illegal path operand")
+
+ if c == "lineto" then
+ i = i + 1
+ local d = rigid(p[i])
+ s [#s + 1] = '\\pgfpathlineto{\\pgfqpoint{' .. to_pt(d.x) .. '}{' .. to_pt(d.y) .. '}}'
+ i = i + 1
+ elseif c == "moveto" then
+ i = i + 1
+ local d = rigid(p[i])
+ s [#s + 1] = '\\pgfpathmoveto{\\pgfqpoint{' .. to_pt(d.x) .. '}{' .. to_pt(d.y) .. '}}'
+ i = i + 1
+ elseif c == "closepath" then
+ s [#s + 1] = '\\pgfpathclose'
+ i = i + 1
+ elseif c == "curveto" then
+ local d1, d2, d3 = rigid(p[i+1]), rigid(p[i+2]), rigid(p[i+3])
+ i = i + 3
+ s [#s + 1] = '\\pgfpathcurveto{\\pgfqpoint{' .. to_pt(d1.x) .. '}{' .. to_pt(d1.y) .. '}}{\\pgfqpoint{'
+ .. to_pt(d2.x) .. '}{' .. to_pt(d2.y) .. '}}{\\pgfqpoint{'
+ .. to_pt(d3.x) .. '}{' .. to_pt(d3.y) .. '}}'
+ i = i + 1
+ else
+ error("illegal operation in edge path")
+ end
+ end
+
+ return table.concat(s)
+end
+
+function coordinate_in_pgf_syntax(c)
+ return '\\pgfqpoint{'..to_pt(c.x) .. '}{'.. to_pt(c.y) .. '}'
+end
+
+
+return BindingToPGF
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular.lua
new file mode 100644
index 0000000000..cddfd96dfd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular.lua
@@ -0,0 +1,22 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+local circular = {}
+
+-- Declare namespace
+require("pgf.gd").circular = circular
+
+
+-- Done
+
+return circular \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua
new file mode 100644
index 0000000000..bebb87ab3e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua
@@ -0,0 +1,153 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+local routing = require("pgf.gd.routing")
+
+-- The algorithm class
+local Tantau2012 = {}
+
+---
+declare {
+ key = "simple necklace layout",
+ algorithm = Tantau2012,
+
+ postconditions = {
+ upward_oriented = true
+ },
+
+ documentation_in = "pgf.gd.circular.doc"
+}
+
+
+
+-- Imports
+
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Hints = require "pgf.gd.routing.Hints"
+
+local lib = require "pgf.gd.lib"
+
+
+
+
+-- The implementation
+
+function Tantau2012:run()
+ local g = self.ugraph
+ local vertices = g.vertices
+ local n = #vertices
+
+ local sib_dists = self:computeNodeDistances ()
+ local radii = self:computeNodeRadii()
+ local diam, adjusted_radii = self:adjustNodeRadii(sib_dists, radii)
+
+ -- Compute total necessary length. For this, iterate over all
+ -- consecutive pairs and keep track of the necessary space for
+ -- this node. We imagine the nodes to be aligned from left to
+ -- right in a line.
+ local carry = 0
+ local positions = {}
+ local function wrap(i) return (i-1)%n + 1 end
+ local ideal_pos = 0
+ for i = 1,n do
+ positions[i] = ideal_pos + carry
+ ideal_pos = ideal_pos + sib_dists[i]
+ local node_sep =
+ lib.lookup_option('node post sep', vertices[i], g) +
+ lib.lookup_option('node pre sep', vertices[wrap(i+1)], g)
+ local arc = node_sep + adjusted_radii[i] + adjusted_radii[wrap(i+1)]
+ local needed = carry + arc
+ local dist = math.sin( arc/diam ) * diam
+ needed = needed + math.max ((radii[i] + radii[wrap(i+1)]+node_sep)-dist, 0)
+ carry = math.max(needed-sib_dists[i],0)
+ end
+ local length = ideal_pos + carry
+
+ local radius = length / (2 * math.pi)
+ for i,vertex in ipairs(vertices) do
+ vertex.pos.x = radius * math.cos(2 * math.pi * (positions[i] / length + 1/4))
+ vertex.pos.y = -radius * math.sin(2 * math.pi * (positions[i] / length + 1/4))
+ end
+
+ -- Add routing infos
+ local necklace = lib.icopy({g.vertices[1]}, lib.icopy(g.vertices))
+ Hints.addNecklaceCircleHint(g, necklace, nil, true)
+end
+
+
+function Tantau2012:computeNodeDistances()
+ local sib_dists = {}
+ local sum_length = 0
+ local vertices = self.digraph.vertices
+ for i=1,#vertices do
+ sib_dists[i] = lib.lookup_option('node distance', vertices[i], self.digraph)
+ sum_length = sum_length + sib_dists[i]
+ end
+
+ local missing_length = self.digraph.options['radius'] * 2 * math.pi - sum_length
+ if missing_length > 0 then
+ -- Ok, the sib_dists to not add up to the desired minimum value.
+ -- What should we do? Hmm... We increase all by the missing amount:
+ for i=1,#vertices do
+ sib_dists[i] = sib_dists[i] + missing_length/#vertices
+ end
+ end
+
+ sib_dists.total = math.max(self.digraph.options['radius'] * 2 * math.pi, sum_length)
+
+ return sib_dists
+end
+
+
+function Tantau2012:computeNodeRadii()
+ local radii = {}
+ for i,v in ipairs(self.digraph.vertices) do
+ local min_x, min_y, max_x, max_y = v:boundingBox()
+ local w, h = max_x-min_x, max_y-min_y
+ if v.shape == "circle" or v.shape == "ellipse" then
+ radii[i] = math.max(w,h)/2
+ else
+ radii[i] = math.sqrt(w*w + h*h)/2
+ end
+ end
+ return radii
+end
+
+
+function Tantau2012:adjustNodeRadii(sib_dists,radii)
+ local total = 0
+ local max_rad = 0
+ for i=1,#radii do
+ total = total + 2*radii[i]
+ + lib.lookup_option('node post sep', self.digraph.vertices[i], self.digraph)
+ + lib.lookup_option('node pre sep', self.digraph.vertices[i], self.digraph)
+ max_rad = math.max(max_rad, radii[i])
+ end
+ total = math.max(total, sib_dists.total, max_rad*math.pi)
+ local diam = total/(math.pi)
+
+ -- Now, adjust the radii:
+ local adjusted_radii = {}
+ for i=1,#radii do
+ adjusted_radii[i] = (math.pi - 2*math.acos(radii[i]/diam))*diam/2
+ end
+
+ return diam, adjusted_radii
+end
+
+
+-- done
+
+return Tantau2012
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/doc.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/doc.lua
new file mode 100644
index 0000000000..9198885965
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/doc.lua
@@ -0,0 +1,145 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+--------------------------------------------------------------------
+key "simple necklace layout"
+
+summary
+[[
+This simple layout arranges the nodes in a circle, which is
+especially useful for drawing, well, circles of nodes.
+]]
+
+documentation
+[[
+The name |simple necklace layout| is reminiscent of the more general
+``necklace layout'', a term coined by Speckmann and Verbeek in
+their paper
+%
+\begin{itemize}
+ \item
+ Bettina Speckmann and Kevin Verbeek,
+ \newblock Necklace Maps,
+ \newblock \emph{IEEE Transactions on Visualization and Computer
+ Graphics,} 16(6):881--889, 2010.
+\end{itemize}
+
+For a |simple necklace layout|, the centers of the nodes
+are placed on a counter-clockwise circle, starting with the first
+node at the |grow| direction (for |grow'|, the circle is
+clockwise). The order of the nodes is the order in which they appear
+in the graph, the edges are not taken into consideration, unless the
+|componentwise| option is given.
+%
+\begin{codeexample}[
+ preamble={\usetikzlibrary{arrows.meta,graphs,graphdrawing}
+ \usegdlibrary{circular}}]
+\tikz[>={Stealth[round,sep]}]
+ \graph [simple necklace layout, grow'=down, node sep=1em,
+ nodes={draw,circle}, math nodes]
+ {
+ x_1 -> x_2 -> x_3 -> x_4 ->
+ x_5 -> "\dots"[draw=none] -> "x_{n-1}" -> x_n -> x_1
+ };
+\end{codeexample}
+
+When you give the |componentwise| option, the graph will be
+decomposed into connected components, which are then laid out
+individually and packed using the usual component packing
+mechanisms:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{circular}}]
+\tikz \graph [simple necklace layout] {
+ a -- b -- c -- d -- a,
+ 1 -- 2 -- 3 -- 1
+};
+\end{codeexample}
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{circular}}]
+\tikz \graph [simple necklace layout, componentwise] {
+ a -- b -- c -- d -- a,
+ 1 -- 2 -- 3 -- 1
+};
+\end{codeexample}
+
+The nodes are placed in such a way that
+%
+\begin{enumerate}
+ \item The (angular) distance between the centers of consecutive
+ nodes is at least |node distance|,
+ \item the distance between the borders of consecutive nodes is at
+ least |node sep|, and
+ \item the radius is at least |radius|.
+\end{enumerate}
+%
+The radius of the circle is chosen near-minimal such that the above
+properties are satisfied. To be more precise, if all nodes are
+circles, the radius is chosen optimally while for, say, rectangular
+nodes there may be too much space between the nodes in order to
+satisfy the second condition.
+]]
+
+example
+[[
+\tikz \graph [simple necklace layout,
+ node sep=0pt, node distance=0pt,
+ nodes={draw,circle}]
+{ 1 -- 2 [minimum size=30pt] -- 3 --
+ 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 };
+]]
+
+example
+[[
+\begin{tikzpicture}[radius=1.25cm]
+ \graph [simple necklace layout,
+ node sep=0pt, node distance=0pt,
+ nodes={draw,circle}]
+ { 1 -- 2 [minimum size=30pt] -- 3 --
+ 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 };
+
+ \draw [red] (0,-1.25) circle [];
+\end{tikzpicture}
+]]
+
+example
+[[
+\tikz \graph [simple necklace layout,
+ node sep=0pt, node distance=1cm,
+ nodes={draw,circle}]
+{ 1 -- 2 [minimum size=30pt] -- 3 --
+ 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 };
+]]
+
+example
+[[
+\tikz \graph [simple necklace layout,
+ node sep=2pt, node distance=0pt,
+ nodes={draw,circle}]
+{ 1 -- 2 [minimum size=30pt] -- 3 --
+ 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 };
+]]
+
+example
+[[
+\tikz \graph [simple necklace layout,
+ node sep=0pt, node distance=0pt,
+ nodes={rectangle,draw}]
+{ 1 -- 2 [minimum size=30pt] -- 3 --
+ 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 };
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/library.lua
new file mode 100644
index 0000000000..016cfe483f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/circular/library.lua
@@ -0,0 +1,30 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+---
+-- ``Circular'' graph drawing algorithms arrange the nodes of a graph
+-- on one of more circles.
+--
+-- @library
+
+local circular -- Library name
+
+-- Load declarations from:
+
+-- Load algorithms from:
+require "pgf.gd.circular.Tantau2012"
+
+
+-- General declarations
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control.lua
new file mode 100644
index 0000000000..a3bec1fef3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control.lua
@@ -0,0 +1,26 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+-- Imports
+
+require "pgf"
+require "pgf.gd"
+
+
+-- Declare namespace
+pgf.gd.control = {}
+
+
+-- Done
+
+return pgf.gd.control \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Anchoring.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Anchoring.lua
new file mode 100644
index 0000000000..03a05ee627
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Anchoring.lua
@@ -0,0 +1,104 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Anchoring a Graph}
+--
+-- \label{subsection-library-graphdrawing-anchoring}
+--
+-- A graph drawing algorithm must compute positions of the nodes of a
+-- graph, but the computed positions are only \emph{relative} (``this
+-- node is left of this node, but above that other node''). It is not
+-- immediately obvious where the ``the whole graph'' should be placed
+-- \emph{absolutely} once all relative positions have been computed. In
+-- case that the graph consists of several unconnected components, the
+-- situation is even more complicated.
+--
+-- The order in which the algorithm layer determines the node at which
+-- the graph should be anchored:
+-- %
+-- \begin{enumerate}
+-- \item If the |anchor node=|\meta{node name} option given to the graph
+-- as a whole, the graph is anchored at \meta{node name}, provided
+-- there is a node of this name in the graph. (If there is no node of
+-- this name or if it is misspelled, the effect is the same as if this
+-- option had not been given at all.)
+-- \item Otherwise, if there is a node where the |anchor here| option is
+-- specified, the first node with this option set is used.
+-- \item Otherwise, if there is a node where the |desired at| option is
+-- set (perhaps implicitly through keys like |x|), the first such node
+-- is used.
+-- \item Finally, in all other cases, the first node is used.
+-- \end{enumerate}
+--
+-- In the above description, the ``first'' node refers to the node first
+-- encountered in the specification of the graph.
+--
+-- Once the node has been determined, the graph is shifted so that
+-- this node lies at the position specified by |anchor at|.
+--
+-- @end
+
+
+
+local Anchoring = {}
+
+
+-- Namespace
+require("pgf.gd.control").Anchoring = Anchoring
+
+
+-- Imports
+local Coordinate = require("pgf.gd.model.Coordinate")
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+
+---
+declare {
+ key = "desired at",
+ type = "coordinate",
+ documentation_in = "pgf.gd.control.doc"
+}
+
+---
+declare {
+ key = "anchor node",
+ type = "string",
+ documentation_in = "pgf.gd.control.doc"
+}
+
+
+---
+declare {
+ key = "anchor at",
+ type = "canvas coordinate",
+ initial = "(0pt,0pt)",
+ documentation_in = "pgf.gd.control.doc"
+}
+
+
+---
+declare {
+ key = "anchor here",
+ type = "boolean",
+ documentation_in = "pgf.gd.control.doc"
+}
+
+
+
+
+
+-- Done
+
+return Anchoring \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua
new file mode 100644
index 0000000000..72a82be978
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua
@@ -0,0 +1,540 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+---
+-- @section subsubsection {Aligning Components}
+--
+-- When components are placed next to each from left to right, it
+-- is not immediately clear how the components should be aligned
+-- vertically. What happens is that in each component a horizontal line is
+-- determined and then all components are shifted vertically so that the
+-- lines are aligned. There are different strategies for choosing these
+-- ``lines'', see the description of the options described later on.
+-- When the |component direction| option is used to change the direction
+-- in which components are placed, it certainly make no longer sense to
+-- talk about ``horizontal'' and ``vertical'' lines. Instead, what
+-- actually happens is that the alignment does not consider
+-- ``horizontal'' lines, but lines that go in the direction specified by
+-- |component direction| and aligns them by moving components along a
+-- line that is perpendicular to the line. For these reasons, let us call
+-- the line in the component direction the \emph{alignment line} and a
+-- line that is perpendicular to it the \emph{shift line}.
+--
+-- The first way of specifying through which point of a component the
+-- alignment line should get is to use the option |align here|.
+-- In many cases, however, you will not wish to specify an alignment node
+-- manually in each component. Instead, you will use the
+-- |component align| key to specify a \emph{strategy} that should be used to
+-- automatically determine such a node.
+--
+-- Using a combination of |component direction| and |component align|,
+-- numerous different packing strategies can be configured. However,
+-- since names like |counterclockwise| are a bit hard to remember and to
+-- apply in practice, a number of easier-to-remember keys are predefined
+-- that combine an alignment and a direction.
+--
+-- @end
+
+---
+
+declare {
+ key = "align here",
+ type = "boolean",
+
+ summary = [["
+ When this option is given to a node, this alignment line will go
+ through the origin of this node. If this option is passed to more
+ than one node of a component, the node encountered first in the
+ component is used.
+ "]],
+ examples = [["
+ \tikz \graph [binary tree layout, nodes={draw}]
+ { a, b -- c[align here], d -- e[second, align here] -- f };
+ "]]
+}
+
+---
+
+declare {
+ key = "component align",
+ type = "string",
+ initial = "first node",
+
+ summary = [["
+ Specifies a ``strategy'' for the alignment of components.
+ "]],
+ documentation = [["
+ The following values are permissible:
+ %
+ \begin{itemize}
+ \item \declare{|first node|}
+
+ In each component, the alignment line goes through the center of
+ the first node of the component encountered during specification
+ of the component.
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [binary tree layout, nodes={draw},
+ component align=first node]
+ { a, b -- c, d -- e[second] -- f };
+\end{codeexample}
+ %
+ \item \declare{|center|}
+
+ The nodes of the component are projected onto the shift line. The
+ alignment line is now chosen so that it is exactly in the middle
+ between the maximum and minimum value that the projected nodes
+ have on the shift line.
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [binary tree layout, nodes={draw},
+ component align=center]
+ { a, b -- c, d -- e[second] -- f };
+\end{codeexample}
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [binary tree layout, nodes={draw},
+ component direction=90,
+ component align=center]
+ { a, b -- c, d -- e[second] -- f };
+\end{codeexample}
+ %
+ \item \declare{|counterclockwise|}
+
+ As for |center|, we project the nodes of the component onto the
+ shift line. The alignment line is now chosen so that it goes
+ through the center of the node whose center has the highest
+ projected value.
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [binary tree layout, nodes={draw},
+ component align=counterclockwise]
+ { a, b -- c, d -- e[second] -- f };
+\end{codeexample}
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [binary tree layout, nodes={draw},
+ component direction=90,
+ component align=counterclockwise]
+ { a, b -- c, d -- e[second] -- f };
+\end{codeexample}
+ The name |counterclockwise| is intended to indicate that the align
+ line goes through the node that comes last if we go from the
+ alignment direction in a counter-clockwise direction.
+ \item \declare{|clockwise|}
+
+ Works like |counterclockwise|, only in the other direction:
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [binary tree layout, nodes={draw},
+ component align=clockwise]
+ { a, b -- c, d -- e[second] -- f };
+\end{codeexample}
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [binary tree layout, nodes={draw},
+ component direction=90,
+ component align=clockwise]
+ { a, b -- c, d -- e[second] -- f };
+\end{codeexample}
+ %
+ \item \declare{|counterclockwise bounding box|}
+
+ This method is quite similar to |counterclockwise|, only the
+ alignment line does not go through the center of the node with a
+ maximum projected value on the shift line, but through the maximum
+ value of the projected bounding boxes. For a left-to-right
+ packing, this means that the components are aligned so that the
+ bounding boxes of the components are aligned at the top.
+ %
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [tree layout, nodes={draw, align=center},
+ component sep=0pt,
+ component align=counterclockwise]
+ { a, "high\\node" -- b};\quad
+\tikz \graph [tree layout, nodes={draw, align=center},
+ component sep=0pt,
+ component align=counterclockwise bounding box]
+ { a, "high\\node" -- b};
+\end{codeexample}
+ %
+ \item \declare{|clockwise bounding box|}
+
+ Works like |counterclockwise bounding box|.
+ \end{itemize}
+ "]]
+}
+
+---
+
+declare {
+ key = "components go right top aligned",
+ use = {
+ { key = "component direction", value = 0},
+ { key = "component align", value = "counterclockwise"},
+ },
+
+ summary = [["
+ Shorthand for |component direction=right| and
+ |component align=counterclockwise|. This means that, as the name
+ suggest, the components will be placed left-to-right and they are
+ aligned such that their top nodes are in a line.
+ "]],
+ examples = [["
+ \tikz \graph [tree layout, nodes={draw, align=center},
+ components go right top aligned]
+ { a, "high\\node" -- b};
+ "]]
+}
+
+---
+
+declare {
+ key = "components go right absolute top aligned",
+ use = {
+ { key = "component direction", value=0},
+ { key = "component align", value = "counterclockwise bounding box"},
+ },
+
+ summary = [["
+ Like |components go right top aligned|, but with
+ |component align| set to |counterclockwise| |bounding box|.
+ This means that the components will be aligned with their bounding
+ boxed being top-aligned.
+ "]],
+ examples = [["
+ \tikz \graph [tree layout, nodes={draw, align=center},
+ components go right absolute top aligned]
+ { a, "high\\node" -- b};
+ "]]
+}
+
+---
+
+declare {
+ key = "components go right bottom aligned",
+ use = {
+ { key = "component direction", value=0},
+ { key = "component align", value = "clockwise"},
+ },
+
+ summary = "See the other |components go ...| keys."
+}
+
+---
+--
+
+declare {
+ key = "components go right absolute bottom aligned",
+ use = {
+ { key = "component direction", value=0},
+ { key = "component align", value = "clockwise bounding box"},
+ },
+
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+
+declare {
+ key = "components go right center aligned",
+ use = {
+ { key = "component direction", value=0},
+ { key = "component align", value = "center"},
+ },
+
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+
+declare {
+ key = "components go right",
+ use = {
+ { key = "component direction", value=0},
+ { key = "component align", value = "first node"},
+ },
+
+ summary = [["
+ Shorthand for |component direction=right| and
+ |component align=first node|.
+ "]]
+ }
+
+
+---
+
+declare {
+ key = "components go left top aligned",
+ use = {
+ { key = "component direction", value=180},
+ { key = "component align", value = "clockwise"},
+ },
+
+ summary = "See the other |components go ...| keys.",
+
+ examples = [["
+ \tikz \graph [tree layout, nodes={draw, align=center},
+ components go left top aligned]
+ { a, "high\\node" -- b};
+ "]]
+}
+
+---
+--
+
+declare {
+ key = "components go left absolute top aligned",
+ use = {
+ { key = "component direction", value=180},
+ { key = "component align", value = "clockwise bounding box"},
+ },
+
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go left bottom aligned",
+ use = {
+ { key = "component direction", value=180},
+ { key = "component align", value = "counterclockwise"},
+ },
+
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go left absolute bottom aligned",
+ use = {
+ { key = "component direction", value=180},
+ { key = "component align", value = "counterclockwise bounding box"},
+ },
+
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go left center aligned",
+ use = {
+ { key = "component direction", value=180},
+ { key = "component align", value = "center"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go left",
+ use = {
+ { key = "component direction", value=180},
+ { key = "component align", value = "first node"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+
+---
+
+declare {
+ key = "components go down right aligned",
+ use = {
+ { key = "component direction", value=270},
+ { key = "component align", value = "counterclockwise"},
+ },
+ summary = "See the other |components go ...| keys.",
+
+ examples = {[["
+ \tikz \graph [tree layout, nodes={draw, align=center},
+ components go down left aligned]
+ { a, hello -- {world,s} };
+ "]],[["
+ \tikz \graph [tree layout, nodes={draw, align=center},
+ components go up absolute left aligned]
+ { a, hello -- {world,s}};
+ "]]
+ }
+}
+
+---
+--
+
+declare {
+ key = "components go down absolute right aligned",
+ use = {
+ { key = "component direction", value=270},
+ { key = "component align", value = "counterclockwise bounding box"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go down left aligned",
+ use = {
+ { key = "component direction", value=270},
+ { key = "component align", value = "clockwise"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go down absolute left aligned",
+ use = {
+ { key = "component direction", value=270},
+ { key = "component align", value = "clockwise bounding box"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go down center aligned",
+ use = {
+ { key = "component direction", value=270},
+ { key = "component align", value = "center"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go down",
+ use = {
+ { key = "component direction", value=270},
+ { key = "component align", value = "first node"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+---
+--
+
+declare {
+ key = "components go up right aligned",
+ use = {
+ { key = "component direction", value=90},
+ { key = "component align", value = "clockwise"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go up absolute right aligned",
+ use = {
+ { key = "component direction", value=90},
+ { key = "component align", value = "clockwise bounding box"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go up left aligned",
+ use = {
+ { key = "component direction", value=90},
+ { key = "component align", value = "counterclockwise"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go up absolute left aligned",
+ use = {
+ { key = "component direction", value=90},
+ { key = "component align", value = "counterclockwise bounding box"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go up center aligned",
+ use = {
+ { key = "component direction", value=90},
+ { key = "component align", value = "center"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+---
+--
+
+declare {
+ key = "components go up",
+ use = {
+ { key = "component direction", value=90},
+ { key = "component align", value = "first node"},
+ },
+ summary = "See the other |components go ...| keys."
+}
+
+
+
+
+return Components
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua
new file mode 100644
index 0000000000..f941ff226e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua
@@ -0,0 +1,58 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+---
+-- @section subsubsection {Arranging Components in a Certain Direction}
+--
+-- @end
+
+---
+
+declare {
+ key = "component direction",
+ type = "direction",
+ initial = "0",
+
+ summary = [["
+ The \meta{angle} is used to determine the relative position of each
+ component relative to the previous one. The direction need not be a
+ multiple of |90|. As usual, you can use texts like |up| or
+ |right| instead of a number.
+ "]],
+ documentation = [["
+ As the examples show, the direction only has an influence on the
+ relative positions of the components, not on the direction of growth
+ inside the components. In particular, the components are not rotated
+ by this option in any way. You can use the |grow| option or |orient|
+ options to orient individual components.
+ "]],
+ examples = {[["
+ \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle},
+ component direction=left]
+ { a, b, c -- d -- e, f -- g };
+ "]],[["
+ \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle},
+ component direction=10]
+ { a, b, c -- d -- e, f -- g };
+ "]],[["
+ \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle},
+ component direction=up]
+ { a, b, c [grow=right] -- d -- e, f[grow=45] -- g };
+ "]]
+ }
+}
+
+
+return Components \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua
new file mode 100644
index 0000000000..a2d04a178f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua
@@ -0,0 +1,108 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+---
+-- @section subsubsection {The Distance Between Components}
+--
+-- Once the components of a graph have been oriented, sorted, aligned,
+-- and a direction has been chosen, it remains to determine the distance
+-- between adjacent components. Two methods are available for computing
+-- this distance, as specified by the following option:
+--
+-- @end
+
+---
+
+declare {
+ key = "component packing",
+ type = "string",
+ initial = "skyline",
+
+ documentation = [["
+ Given two components, their distance is computed as follows in
+ dependence of \meta{method}:
+ %
+ \begin{itemize}
+ \item \declare{|rectangular|}
+
+ Imagine a bounding box to be drawn around both components. They
+ are then shifted such that the padding (separating distance)
+ between the two boxes is the current value of |component sep|.
+ %
+ \begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+ \tikz \graph [tree layout, nodes={draw}, component sep=0pt,
+ component packing=rectangular]
+ { a -- long text, longer text -- b};
+ \end{codeexample}
+ %
+ \item \declare{|skyline|}
+
+ The ``skyline method'' is used to compute the distance. It works
+ as follows: For simplicity, assume that the component direction is
+ right (other case work similarly, only everything is
+ rotated). Imaging the second component to be placed far right
+ beyond the first component. Now start moving the second component
+ back to the left until one of the nodes of the second component
+ touches a node of the first component, and stop. Again, the
+ padding |component sep| can be used to avoid the nodes actually
+ touching each other.
+ %
+ \begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+ \tikz \graph [tree layout, nodes={draw}, component sep=0pt,
+ level distance=1.5cm,
+ component packing=skyline]
+ { a -- long text, longer text -- b};
+ \end{codeexample}
+
+ In order to avoid nodes of the second component ``passing through
+ a hole in the first component'', the actual algorithm is a bit
+ more complicated: For both components, a ``skyline'' is
+ computed. For the first component, consider an arbitrary
+ horizontal line. If there are one or more nodes on this line, the
+ rightmost point on any of the bounding boxes of these nodes will
+ be the point on the skyline of the first component for this
+ line. Similarly, for the second component, for each horizontal
+ level the skyline is given by the leftmost point on any of the
+ bounding boxes intersecting the line.
+
+ Now, the interesting case are horizontal lines that do not
+ intersect any of the nodes of the first and/or second
+ component. Such lines represent ``holes'' in the skyline. For
+ them, the following rule is used: Move the horizontal line upward
+ and downward as little as possible until a height is reached where
+ there is a skyline defined. Then the skyline position on the
+ original horizontal line is the skyline position at the reached
+ line, minus (or, for the second component, plus) the distance by
+ which the line was moved. This means that the holes are ``filled
+ up by slanted roofs''.
+ %
+ \begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+ \begin{tikzpicture}
+ \graph [tree layout, nodes={draw}, component sep=0pt,
+ component packing=skyline]
+ { a -- long text, longer text -- b};
+ \draw[red] (long text.north east) -- ++(north west:1cm);
+ \end{tikzpicture}
+ \end{codeexample}
+
+ \end{itemize}
+ "]]
+}
+
+
+return Components
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua
new file mode 100644
index 0000000000..78537b614c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua
@@ -0,0 +1,105 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+
+
+---
+-- @section subsubsection {Ordering the Components}
+--
+-- The different connected components of the graph are collected in a
+-- list. The ordering of the nodes in this list can be configured using
+-- the following key.
+--
+-- @end
+
+
+---
+
+declare {
+ key = "component order",
+ type = "string",
+ initial = "by first specified node",
+
+ summary = [["
+ Selects a ``strategy'' for ordering the components. By default,
+ they are ordered in the way they appear in the input.
+ "]],
+ documentation = [["
+ The following values are permissible for \meta{strategy}
+ %
+ \begin{itemize}
+ \item \declare{|by first specified node|}
+
+ The components are ordered ``in the way they appear in the input
+ specification of the graph''. More precisely, for each component
+ consider the node that is first encountered in the description
+ of the graph. Order the components in the same way as these nodes
+ appear in the graph description.
+ \item \declare{|increasing node number|}
+
+ The components are ordered by increasing number of nodes. For
+ components with the same number of nodes, the first node in each
+ component is considered and they are ordered according to the
+ sequence in which these nodes appear in the input.
+
+ \item \declare{|decreasing node number|}
+ As above, but in decreasing order.
+ \end{itemize}
+ "]],
+ examples = {[["
+ \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle},
+ component order=by first specified node]
+ { a, b, c, f -- g, c -- d -- e };
+ "]],[["
+ \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle},
+ component order=increasing node number]
+ { a, b, c -- d -- e, f -- g };
+ "]]
+ }
+}
+
+
+---
+
+declare {
+ key = "small components first",
+ use = {
+ { key = "component order", value = "increasing node number" }
+ },
+
+ summary = [["
+ A shorthand for |component order=increasing node number|.
+ "]]
+ }
+
+---
+
+declare {
+ key = "large components first",
+ use = {
+ { key = "component order", value = "decreasing node number" },
+ },
+ summary = [["
+ A shorthand for |component order=decreasing node number|.
+ "]],
+ examples = [["
+ \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle},
+ large components first]
+ { a, b, c -- d -- e, f -- g };
+ "]]
+}
+
+
+return Components \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Components.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Components.lua
new file mode 100644
index 0000000000..c5019a56e2
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Components.lua
@@ -0,0 +1,127 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+---
+-- @section subsection {Packing of Connected Components}
+--
+-- \label{subsection-gd-component-packing}
+-- \label{section-gd-packing}
+--
+-- Graphs may be composed of subgraphs or \emph{components} that are not
+-- connected to each other. In order to draw these nicely, most graph
+-- drawing algorithms split them into separate graphs, compute
+-- their layouts with the same graph drawing algorithm independently and,
+-- in a postprocessing step, arrange them next to each other. Note,
+-- however, that some graph drawing algorithms can also arrange the nodes
+-- of the graph in a uniform way even for unconnected components (the
+-- |simple necklace layout| is a case in point); for such algorithms you can
+-- choose whether they should be applied to each component individually
+-- or not (if not, the following options do not apply). To configure
+-- which is the case, use the |componentwise| key.
+--
+-- The default method for placing the different components works as
+-- follows:
+-- %
+-- \begin{enumerate}
+-- \item For each component, a layout is determined and the component is
+-- oriented as described
+-- Section~\ref{subsection-library-graphdrawing-standard-orientation}
+-- on the orientation of graphs.
+-- \item The components are sorted as prescribed by the
+-- |component order| key.
+-- \item The first component is now placed (conceptually) at the
+-- origin. (The final position of this and all other components will be
+-- determined later, namely in the anchoring phase, but let us imagine
+-- that the first component lies at the origin at this point.)
+-- \item The second component is now positioned relative to the first
+-- component. The ``direction'' in which the next component is placed
+-- relative to the first one is determined by the |component direction|
+-- key, so components can be placed from left to right or up to down or
+-- in any other direction (even something like $30^\circ$). However,
+-- both internally and in the following description, we assume that the
+-- components are placed from left to right; other directions are
+-- achieved by doing some (clever) rotating of the arrangement achieved
+-- in this way.
+--
+-- So, we now wish to place the second component to the right of the
+-- first component. The component is first shifted vertically according
+-- to some alignment strategy. For instance, it can be shifted so that
+-- the topmost node of the first component and the topmost node of the
+-- second component have the same vertical position. Alternatively, we
+-- might require that certain ``alignment nodes'' in both components
+-- have the same vertical position. There are several other strategies,
+-- which can be configured using the |component align| key.
+--
+-- One the vertical position has been fixed, the horizontal position is
+-- computed. Here, two different strategies are available: First, image
+-- rectangular bounding boxed to be drawn around both components. Then
+-- we shift the second component such that the right border of the
+-- bounding box of the first component touches the left border of the
+-- bounding box of the second component. Instead of having the bounding
+-- boxes ``touch'', we can also have a padding of |component sep|
+-- between them. The second strategy is more involved and also known as
+-- a ``skyline'' strategy, where (roughly) the components are
+-- ``moved together as near as possible so that nodes do not touch''.
+-- \item
+-- After the second component has been placed, the third component is
+-- considered and positioned relative to the second one, and so on.
+-- \item
+-- At the end, as hinted at earlier, the whole arrangement is rotate so
+-- that instead of ``going right'' the component go in the direction of
+-- |component direction|. Note, however, that this rotation applies only
+-- to the ``shift'' of the components; the components themselves are
+-- not rotated. Fortunately, this whole rotation process happens in the
+-- background and the result is normally exactly what you would expect.
+-- \end{enumerate}
+--
+-- In the following, we go over the different keys that can be used to
+-- configure the component packing.
+--
+-- @end
+
+
+---
+
+declare {
+ key = "componentwise",
+ type = "boolean",
+
+ summary = [["
+ For algorithms that also support drawing unconnected graphs, use
+ this key to enforce that the components of the graph are,
+ nevertheless, laid out individually. For algorithms that do not
+ support laying out unconnected graphs, this option has no effect;
+ rather it works as if this option were always set.
+ "]],
+ examples = {[["
+ \tikz \graph [simple necklace layout]
+ {
+ a -- b -- c -- d -- a,
+ 1 -- 2 -- 3 -- 1
+ };
+ "]],[[",
+ \tikz \graph [simple necklace layout, componentwise]
+ {
+ a -- b -- c -- d -- a,
+ 1 -- 2 -- 3 -- 1
+ };
+ "]]
+ }
+}
+
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Distances.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Distances.lua
new file mode 100644
index 0000000000..6dc5a13018
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Distances.lua
@@ -0,0 +1,454 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local lib = require "pgf.gd.lib"
+
+---
+-- @section subsection {Padding and Node Distances}
+--
+-- \label{subsection-gd-dist-pad}
+--
+-- In many drawings, you may wish to specify how ``near'' two nodes should
+-- be placed by a graph drawing algorithm. Naturally, this depends
+-- strongly on the specifics of the algorithm, but there are a number of
+-- general keys that will be used by many algorithms.
+--
+-- There are different kinds of objects for which you can specify
+-- distances and paddings:
+-- %
+-- \begin{itemize}
+-- \item You specify the ``natural'' distance between nodes
+-- connected by an edge using |node distance|, which is also available in
+-- normal \tikzname\ albeit for a slightly different purpose. However,
+-- not every algorithm will (or can) honor the key; see the description
+-- of each algorithm what it will ``make of this option''.
+-- \item A number of graph drawing algorithms arrange nodes in layers
+-- (or levels); we refer
+-- to the nodes on the same layer as siblings (although, in a tree,
+-- siblings are only nodes with the same parent; nevertheless we use
+-- ``sibling'' loosely also for nodes that are more like ``cousins'').
+-- \item When a graph consists of several connected component, many graph
+-- drawing algorithms will layout these components individually. The
+-- different components will then be arranged next to each other, see
+-- Section~\ref{section-gd-packing} for the details, such that between
+-- the nodes of any two components a padding is available.
+-- \end{itemize}
+--
+-- @end
+
+
+
+
+---
+
+declare {
+ key = "node distance",
+ type = "length",
+ initial = "1cm",
+
+ summary = [["
+ This is minimum distance that the centers of nodes connected by an
+ edge should have. It will not always be possible to satisfy this
+ desired distance, for instance in case the nodes are too big. In
+ this case, the \meta{length} is just considered as a lower bound.
+ "]],
+ examples = [["
+ \begin{tikzpicture}
+ \graph [simple necklace layout, node distance=1cm, node sep=0pt,
+ nodes={draw,circle,as=.}]
+ {
+ 1 -- 2 [minimum size=2cm] -- 3 --
+ 4 -- 5 -- 6 -- 7 --[orient=up] 8
+ };
+ \draw [red,|-|] (1.center) -- ++(0:1cm);
+ \draw [red,|-|] (5.center) -- ++(180:1cm);
+ \end{tikzpicture}
+ "]]
+}
+
+
+---
+
+declare {
+ key = "node pre sep",
+ type = "length",
+ initial = ".333em",
+
+ summary = [["
+ This is a minimum ``padding'' or ``separation'' between the border
+ of nodes connected by an edge. Thus, if nodes are so big that nodes
+ with a distance of |node distance| would overlap (or
+ just come with \meta{dimension} distance of one another), their
+ distance is enlarged so that this distance is still satisfied.
+ The |pre| means that the padding is added to the node ``at the
+ front''. This make sense only for some algorithms, like for a
+ simple necklace layout.
+ "]],
+ examples = {[["
+ \tikz \graph [simple necklace layout, node distance=0cm, nodes={circle,draw}]
+ { 1--2--3--4--5--1 };
+ "]],[["
+ \tikz \graph [simple necklace layout, node distance=0cm, node sep=0mm,
+ nodes={circle,draw}]
+ { 1--2--3[node pre sep=5mm]--4--5[node pre sep=1mm]--1 };
+ "]]
+ }
+}
+
+---
+
+declare {
+ key = "node post sep",
+ type = "length",
+ initial = ".333em",
+
+ summary = [["
+ Works like |node pre sep|.
+ "]]
+}
+
+
+
+---
+-- @param length A length.
+
+declare {
+ key = "node sep",
+ type = "length",
+ use = {
+ { key = "node pre sep", value = function(v) return v/2 end },
+ { key = "node post sep", value = function(v) return v/2 end },
+ },
+ summary = [["
+ A shorthand for setting both |node pre sep| and |node post sep| to
+ $\meta{length}/2$.
+ "]]
+}
+
+
+---
+
+declare {
+ key = "level distance",
+ type = "length",
+ initial = "1cm",
+
+ summary = [["
+ This is minimum distance that the centers of nodes on one
+ level should have from the centers of nodes on the next level. It
+ will not always be possible to satisfy this desired distance, for
+ instance in case the nodes are too big. In this case, the
+ \meta{length} is just considered as a lower bound.
+ "]],
+ examples = [["
+ \begin{tikzpicture}[inner sep=2pt]
+ \draw [help lines] (0,0) grid (3.5,2);
+ \graph [layered layout, level distance=1cm, level sep=0]
+ { 1 [x=1,y=2] -- 2 -- 3 -- 1 };
+ \graph [layered layout, level distance=5mm, level sep=0]
+ { 1 [x=3,y=2] -- 2 -- 3 -- 1, 3 -- {4,5} -- 6 -- 3 };
+ \end{tikzpicture}
+ "]]
+}
+
+---
+declare {
+ key = "layer distance",
+ type = "length",
+ use = {
+ { key = "level distance", value = lib.id },
+ },
+ summary = "An alias for |level distance|"
+}
+
+---
+declare {
+ key = "level pre sep",
+ type = "length",
+ initial = ".333em",
+
+ summary = [["
+ This is a minimum ``padding'' or ``separation'' between the border
+ of the nodes on a level to any nodes on the previous level. Thus, if
+ nodes are so big that nodes on consecutive levels would overlap (or
+ just come with \meta{length} distance of one another), their
+ distance is enlarged so that this distance is still satisfied.
+ If a node on the previous level also has a |level post sep|, this
+ post padding and the \meta{dimension} add up. Thus, these keys
+ behave like the ``padding'' keys rather
+ than the ``margin'' key of cascading style sheets.
+ "]],
+ examples = [["
+ \begin{tikzpicture}[inner sep=2pt, level sep=0pt, sibling distance=0pt]
+ \draw [help lines] (0,0) grid (3.5,2);
+ \graph [layered layout, level distance=0cm, nodes=draw]
+ { 1 [x=1,y=2] -- {2,3[level pre sep=1mm],4[level pre sep=5mm]} -- 5 };
+ \graph [layered layout, level distance=0cm, nodes=draw]
+ { 1 [x=3,y=2] -- {2,3,4} -- 5[level pre sep=5mm] };
+ \end{tikzpicture}
+ "]]
+}
+
+---
+
+declare {
+ key = "level post sep",
+ type = "length",
+ initial = ".333em",
+
+ summary = [["
+ Works like |level pre sep|.
+ "]]
+}
+
+---
+declare {
+ key = "layer pre sep",
+ type = "length",
+ use = {
+ { key = "level pre sep", value = lib.id },
+ },
+ summary = "An alias for |level pre sep|."
+}
+
+---
+declare {
+ key = "layer post sep",
+ type = "length",
+ use = {
+ { key = "level post sep", value = lib.id },
+ },
+ summary = "An alias for |level post sep|."
+}
+
+
+
+
+---
+-- @param length A length
+
+declare {
+ key = "level sep",
+ type = "length",
+ use = {
+ { key = "level pre sep", value = function (v) return v/2 end },
+ { key = "level post sep", value = function (v) return v/2 end },
+ },
+
+ summary = [["
+ A shorthand for setting both |level pre sep| and |level post sep| to
+ $\meta{length}/2$. Note that if you set |level distance=0| and
+ |level sep=1em|, you get a layout where any two consecutive layers
+ are ``spaced apart'' by |1em|.
+ "]]
+}
+
+
+---
+declare {
+ key = "layer sep",
+ type = "number",
+ use = {
+ { key = "level sep", value = lib.id },
+ },
+ summary = "An alias for |level sep|."
+}
+
+
+---
+declare {
+ key = "sibling distance",
+ type = "length",
+ initial = "1cm",
+
+ summary = [["
+ This is minimum distance that the centers of node should have to the
+ center of the next node on the same level. As for levels, this is
+ just a lower bound.
+ For some layouts, like a simple necklace layout, the \meta{length} is
+ measured as the distance on the circle.
+ "]],
+ examples = {[["
+ \tikz \graph [tree layout, sibling distance=1cm, nodes={circle,draw}]
+ { 1--{2,3,4,5} };
+ "]],[["
+ \tikz \graph [tree layout, sibling distance=0cm, sibling sep=0pt,
+ nodes={circle,draw}]
+ { 1--{2,3,4,5} };
+ "]],[["
+ \tikz \graph [tree layout, sibling distance=0cm, sibling sep=0pt,
+ nodes={circle,draw}]
+ { 1--{2,3[sibling distance=1cm],4,5} };
+ "]]
+ }
+}
+
+
+---
+
+declare {
+ key = "sibling pre sep",
+ type = "length",
+ initial = ".333em",
+
+ summary = [["
+ Works like |level pre sep|, only for siblings.
+ "]],
+ examples = [["
+ \tikz \graph [tree layout, sibling distance=0cm, nodes={circle,draw},
+ sibling sep=0pt]
+ { 1--{2,3[sibling pre sep=1cm],4,5} };
+ "]]
+}
+
+---
+
+declare {
+ key = "sibling post sep",
+ type = "length",
+ initial = ".333em",
+
+ summary = [["
+ Works like |sibling pre sep|.
+ "]]
+ }
+
+
+
+---
+-- @param length A length
+
+declare {
+ key = "sibling sep",
+ type = "length",
+ use = {
+ { key = "sibling pre sep", value = function(v) return v/2 end },
+ { key = "sibling post sep", value = function(v) return v/2 end },
+ },
+
+ summary = [["
+ A shorthand for setting both |sibling pre sep| and |sibling post sep| to
+ $\meta{length}/2$.
+ "]]
+}
+
+
+
+
+
+
+---
+declare {
+ key = "part distance",
+ type = "length",
+ initial = "1.5cm",
+
+ summary = [["
+ This is minimum distance between the centers of ``parts'' of a
+ graph. What a ``part'' is depends on the algorithm.
+ "]]
+}
+
+
+---
+
+declare {
+ key = "part pre sep",
+ type = "length",
+ initial = "1em",
+ summary = "A pre-padding for parts."
+}
+
+---
+
+declare {
+ key = "part post sep",
+ type = "length",
+ initial = "1em",
+ summary = "A post-padding for pars."
+ }
+
+
+
+---
+-- @param length A length
+
+declare {
+ key = "part sep",
+ type = "length",
+ use = {
+ { key = "part pre sep", value = function(v) return v/2 end },
+ { key = "part post sep", value = function(v) return v/2 end },
+ },
+
+ summary = [["
+ A shorthand for setting both |part pre sep| and |part post sep| to
+ $\meta{length}/2$.
+ "]]
+}
+
+
+
+
+---
+
+declare {
+ key = "component sep",
+ type = "length",
+ initial = "1.5em",
+
+ summary = [["
+ This is padding between the bounding boxes that nodes of different
+ connected components will have when they are placed next to each
+ other.
+ "]],
+ examples = {[["
+ \tikz \graph [binary tree layout, sibling distance=4mm, level distance=8mm,
+ components go right top aligned,
+ component sep=1pt, nodes=draw]
+ {
+ 1 -> 2 -> {3->4[second]->5,6,7};
+ a -> b[second] -> c[second] -> d -> e;
+ x -> y[second] -> z -> u[second] -> v;
+ };
+ "]],[["
+ \tikz \graph [binary tree layout, sibling distance=4mm, level distance=8mm,
+ components go right top aligned,
+ component sep=1em, nodes=draw]
+ {
+ 1 -> 2 -> {3->4[second]->5,6,7};
+ a -> b[second] -> c[second] -> d -> e;
+ x -> y[second] -> z -> u[second] -> v;
+ };
+ "]]
+ }
+}
+
+
+
+---
+
+declare {
+ key = "component distance",
+ type = "length",
+ initial = "2cm",
+
+ summary = [["
+ This is the minimum distance between the centers of bounding
+ boxes of connected components when they are placed next to each
+ other. (Not used, currently.)
+ "]]
+}
+
+
+return Distances
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/FineTune.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/FineTune.lua
new file mode 100644
index 0000000000..87d67b5b56
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/FineTune.lua
@@ -0,0 +1,164 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+local Coordinate = require "pgf.gd.model.Coordinate"
+local lib = require "pgf.gd.lib"
+
+---
+-- @section subsection {Fine-Tuning Positions of Nodes}
+--
+-- @end
+
+
+
+---
+declare {
+ key = "nudge",
+ type = "canvas coordinate",
+
+ summary = [["
+ This option allows you to slightly ``nudge'' (move) nodes after
+ they have been positioned by the given offset. The idea is that
+ this nudging is done after the position of the node has been
+ computed, so nudging has no influence on the actual graph
+ drawing algorithms. This, in turn, means that you can use
+ nudging to ``correct'' or ``optimize'' the positioning of nodes
+ after the algorithm has computed something.
+ "]],
+
+ examples = [["
+ \tikz \graph [edges=rounded corners, nodes=draw,
+ layered layout, sibling distance=0] {
+ a -- {b, c, d[nudge=(up:2mm)]} -- e -- a;
+ };
+ "]]
+}
+
+
+---
+-- @param distance A distance by which the node is nudges.
+
+declare {
+ key = "nudge up",
+ type = "length",
+ use = {
+ { key = "nudge", value = function (v) return Coordinate.new(0,v) end }
+ },
+
+ summary = "A shorthand for nudging a node upwards.",
+ examples = [["
+ \tikz \graph [edges=rounded corners, nodes=draw,
+ layered layout, sibling distance=0] {
+ a -- {b, c, d[nudge up=2mm]} -- e -- a;
+ };
+ "]]
+}
+
+
+---
+-- @param distance A distance by which the node is nudges.
+
+declare {
+ key = "nudge down",
+ type = "length",
+ use = {
+ { key = "nudge", value = function (v) return Coordinate.new(0,-v) end }
+ },
+
+ summary = "Like |nudge up|, but downwards."
+}
+
+---
+-- @param distance A distance by which the node is nudges.
+
+declare {
+ key = "nudge left",
+ type = "length",
+ use = {
+ { key = "nudge", value = function (v) return Coordinate.new(-v,0) end }
+ },
+
+ summary = "Like |nudge up|, but left.",
+ examples = [["
+ \tikz \graph [edges=rounded corners, nodes=draw,
+ layered layout, sibling distance=0] {
+ a -- {b, c, d[nudge left=2mm]} -- e -- a;
+ };
+ "]]
+}
+
+---
+-- @param distance A distance by which the node is nudges.
+
+declare {
+ key = "nudge right",
+ type = "length",
+ use = {
+ { key = "nudge", value = function (v) return Coordinate.new(v,0) end }
+ },
+
+ summary = "Like |nudge left|, but right."
+}
+
+
+---
+declare {
+ key = "regardless at",
+ type = "canvas coordinate",
+
+ summary = [["
+ Using this option you can provide a position for a node to wish
+ it will be forced after the graph algorithms have run. So, the node
+ is positioned normally and the graph drawing algorithm does not know
+ about the position specified using |regardless at|. However,
+ afterwards, the node is placed there, regardless of what the
+ algorithm has computed (all other nodes are unaffected).
+ "]],
+ examples = [["
+ \tikz \graph [edges=rounded corners, nodes=draw,
+ layered layout, sibling distance=0] {
+ a -- {b,c,d[regardless at={(1,0)}]} -- e -- a;
+ };
+ "]]
+}
+
+
+
+
+---
+-- @param pos A canvas position (a coordinate).
+
+declare {
+ key = "nail at",
+ type = "canvas coordinate",
+ use = {
+ { key = "desired at", value = lib.id },
+ { key = "regardless at", value = lib.id },
+ },
+
+ summary = [["
+ This option combines |desired at| and |regardless at|. Thus, the
+ algorithm is ``told'' about the desired position. If it fails to place
+ the node at the desired position, it will be put there
+ regardless. The name of the key is intended to remind one of a node
+ being ``nailed'' to the canvas.
+ "]],
+ examples = [["
+ \tikz \graph [edges=rounded corners, nodes=draw,
+ layered layout, sibling distance=0] {
+ a -- {b,c,d[nail at={(1,0)}]} -- e[nail at={(1.5,-1)}] -- a;
+ };
+ "]]
+}
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua
new file mode 100644
index 0000000000..1c5e48b4c7
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua
@@ -0,0 +1,1347 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- This class controls the running of graph drawing algorithms on
+-- graphs. In particular, it performs pre- and posttransformations and
+-- also invokes the collapsing of sublayouts.
+--
+-- You do not call any of the methods of this class directly, the
+-- whole class is included only for documentation purposes.
+--
+-- Before an algorithm is applied, a number of transformations will
+-- have been applied, depending on the algorithm's |preconditions|
+-- field:
+-- %
+-- \begin{itemize}
+-- \item |connected|
+--
+-- If this property is set for an algorithm (that is, in the
+-- |declare| statement for the algorithm the |predconditions| field
+-- has the entry |connected=true| set), then the graph will be
+-- decomposed into connected components. The algorithm is run on each
+-- component individually.
+-- \item |tree|
+--
+-- When set, the field |spanning_tree| of the algorithm will be set
+-- to a spanning tree of the graph. This option implies |connected|.
+-- \item |loop_free|
+--
+-- When set, all loops (arcs from a vertex to itself) will have been
+-- removed when the algorithm runs.
+--
+-- \item |at_least_two_nodes|
+--
+-- When explicitly set to |false| (this precondition is |true| by
+-- default), the algorithm will even be run if there is only a
+-- single vertex in the graph.
+-- \end{itemize}
+--
+-- Once the algorithm has run, the algorithm's |postconditions| will
+-- be processed:
+-- %
+-- \begin{itemize}
+-- \item |upward_oriented|
+--
+-- When set, the algorithm tells the layout pipeline that the graph
+-- has been laid out in a layered manner with each layer going from
+-- left to right and layers at a whole going upwards (positive
+-- $y$-coordinates). The graph will then be rotated and possibly
+-- swapped in accordance with the |grow| key set by the user.
+-- \item |fixed|
+--
+-- When set, no rotational postprocessing will be done after the
+-- algorithm has run. Usually, a graph is rotated to meet a user's
+-- |orient| settings. However, when the algorithm has already
+-- ``ideally'' rotated the graph, set this postcondition.
+-- \end{itemize}
+--
+--
+-- In addition to the above-described always-present and automatic
+-- transformations, users may also specify additional pre- and
+-- posttransformations. This happens when users install additional
+-- algorithms in appropriate phases. In detail, the following happens
+-- in order:
+-- %
+-- \begin{enumerate}
+-- \item If specified, the graph is decomposed into connected
+-- components and the following steps are applied to each component
+-- individually.
+-- \item All algorithms in the phase stack for the phase
+-- |preprocessing| are applied to the component. These algorithms are
+-- run one after the other in the order they appear in the phase stack.
+-- \item If necessary, the spanning tree is now computed and
+-- rotational information is gathered.
+-- \item The single algorithm in phase |main| is called.
+-- \item All algorithms in the phase stack for the phase
+-- |edge routing| are run.
+-- \item All algorithms in the phase stack for phase |postprocessing|
+-- are run.
+-- \item Edge syncing, orientation, and anchoring are applied.
+-- \end{enumerate}
+--
+-- If sublayouts are used, all of the above (except for anchoring)
+-- happens for each sublayout.
+
+local LayoutPipeline = {}
+
+
+-- Namespace
+require("pgf.gd.control").LayoutPipeline = LayoutPipeline
+
+
+-- Imports
+local Direct = require "pgf.gd.lib.Direct"
+local Storage = require "pgf.gd.lib.Storage"
+local Simplifiers = require "pgf.gd.lib.Simplifiers"
+local LookupTable = require "pgf.gd.lib.LookupTable"
+local Transform = require "pgf.gd.lib.Transform"
+
+local Arc = require "pgf.gd.model.Arc"
+local Vertex = require "pgf.gd.model.Vertex"
+local Digraph = require "pgf.gd.model.Digraph"
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Path = require "pgf.gd.model.Path"
+
+local Sublayouts = require "pgf.gd.control.Sublayouts"
+
+local lib = require "pgf.gd.lib"
+
+local InterfaceCore = require "pgf.gd.interface.InterfaceCore"
+
+
+
+
+-- Forward definitions
+
+local prepare_events
+
+
+
+-- The main ``graph drawing pipeline'' that handles the pre- and
+-- postprocessing for a graph. This method is called by the display
+-- interface.
+--
+-- @param scope A graph drawing scope.
+
+function LayoutPipeline.run(scope)
+
+ -- The pipeline...
+
+ -- Step 1: Preparations
+
+ -- Prepare events
+ prepare_events(scope.events)
+
+ -- Step 2: Recursively layout the graph, starting with the root layout
+ local root_layout = assert(scope.collections[InterfaceCore.sublayout_kind][1], "no layout in scope")
+
+ scope.syntactic_digraph =
+ Sublayouts.layoutRecursively (scope,
+ root_layout,
+ LayoutPipeline.runOnLayout,
+ { root_layout })
+
+ -- Step 3: Anchor the graph
+ LayoutPipeline.anchor(scope.syntactic_digraph, scope)
+
+ -- Step 4: Apply regardless transforms
+ Sublayouts.regardless(scope.syntactic_digraph)
+
+ -- Step 5: Cut edges
+ LayoutPipeline.cutEdges(scope.syntactic_digraph)
+
+end
+
+
+
+--
+-- This method is called by the sublayout rendering pipeline when the
+-- algorithm should be invoked for an individual graph. At this point,
+-- the sublayouts will already have been collapsed.
+--
+-- @param scope The graph drawing scope.
+-- @param algorithm_class The to-be-applied algorithm class.
+-- @param layout_graph A subgraph of the syntactic digraph which is
+-- restricted to the current layout and in which sublayouts have
+-- been contracted to single nodes.
+-- @param layout The layout to which the graph belongs.
+--
+function LayoutPipeline.runOnLayout(scope, algorithm_class, layout_graph, layout)
+
+ if #layout_graph.vertices < 1 then
+ return
+ end
+
+ -- The involved main graphs:
+ local layout_copy = Digraph.new (layout_graph) --Direct.digraphFromSyntacticDigraph(layout_graph)
+ for _,a in ipairs(layout_graph.arcs) do
+ local new_a = layout_copy:connect(a.tail,a.head)
+ new_a.syntactic_edges = a.syntactic_edges
+ end
+
+ -- Step 1: Decompose the graph into connected components, if necessary:
+ local syntactic_components
+ if algorithm_class.preconditions.tree or algorithm_class.preconditions.connected or layout_graph.options.componentwise then
+ syntactic_components = LayoutPipeline.decompose(layout_copy)
+ LayoutPipeline.sortComponents(layout_graph.options['component order'], syntactic_components)
+ else
+ -- Only one component: The graph itself...
+ syntactic_components = { layout_copy }
+ end
+
+ -- Step 2: For all components do:
+ for i,syntactic_component in ipairs(syntactic_components) do
+
+ -- Step 2.1: Reset random number generator to make sure that the
+ -- same graph is always typeset in the same way.
+ lib.randomseed(layout_graph.options['random seed'])
+
+ local digraph = Direct.digraphFromSyntacticDigraph(syntactic_component)
+
+ -- Step 2.3: If requested, remove loops
+ if algorithm_class.preconditions.loop_free then
+ for _,v in ipairs(digraph.vertices) do
+ digraph:disconnect(v,v)
+ end
+ end
+
+ -- Step 2.4: Precompute the underlying undirected graph
+ local ugraph = Direct.ugraphFromDigraph(digraph)
+
+ -- Step 2.4a: Run preprocessor
+ for _,class in ipairs(layout_graph.options.algorithm_phases["preprocessing stack"]) do
+ class.new{
+ digraph = digraph,
+ ugraph = ugraph,
+ scope = scope,
+ layout = layout,
+ layout_graph = layout_graph,
+ syntactic_component = syntactic_component,
+ }:run()
+ end
+
+ -- Step 2.5: Create an algorithm object
+ local algorithm = algorithm_class.new{
+ digraph = digraph,
+ ugraph = ugraph,
+ scope = scope,
+ layout = layout,
+ layout_graph = layout_graph,
+ syntactic_component = syntactic_component,
+ }
+
+ -- Step 2.7: Compute a spanning tree, if necessary
+ if algorithm_class.preconditions.tree then
+ local spanning_algorithm_class = syntactic_component.options.algorithm_phases["spanning tree computation"]
+ algorithm.spanning_tree =
+ spanning_algorithm_class.new{
+ ugraph = ugraph,
+ events = scope.events
+ }:run()
+ end
+
+ -- Step 2.8: Compute growth-adjusted sizes
+ algorithm.rotation_info = LayoutPipeline.prepareRotateAround(algorithm.postconditions, syntactic_component)
+ algorithm.adjusted_bb = Storage.newTableStorage()
+ LayoutPipeline.prepareBoundingBoxes(algorithm.rotation_info, algorithm.adjusted_bb, syntactic_component, syntactic_component.vertices)
+
+ -- Step 2.9: Finally, run algorithm on this component!
+ if #digraph.vertices > 1 or algorithm_class.run_also_for_single_node
+ or algorithm_class.preconditions.at_least_two_nodes == false then
+ -- Main run of the algorithm:
+ if algorithm_class.old_graph_model then
+ LayoutPipeline.runOldGraphModel(scope, digraph, algorithm_class, algorithm)
+ else
+ algorithm:run ()
+ end
+ end
+
+ -- Step 2.9a: Run edge routers
+ for _,class in ipairs(layout_graph.options.algorithm_phases["edge routing stack"]) do
+ class.new{
+ digraph = digraph,
+ ugraph = ugraph,
+ scope = scope,
+ layout = layout,
+ layout_graph = layout_graph,
+ syntactic_component = syntactic_component,
+ }:run()
+ end
+
+ -- Step 2.9b: Run postprocessor
+ for _,class in ipairs(layout_graph.options.algorithm_phases["postprocessing stack"]) do
+ class.new{
+ digraph = digraph,
+ ugraph = ugraph,
+ scope = scope,
+ layout = layout,
+ layout_graph = layout_graph,
+ syntactic_component = syntactic_component,
+ }:run()
+ end
+
+ -- Step 2.10: Sync the graphs
+ digraph:sync()
+ ugraph:sync()
+ if algorithm.spanning_tree then
+ algorithm.spanning_tree:sync()
+ end
+
+ -- Step 2.11: Orient the graph
+ LayoutPipeline.orient(algorithm.rotation_info, algorithm.postconditions, syntactic_component, scope)
+ end
+
+ -- Step 3: Packing:
+ LayoutPipeline.packComponents(layout_graph, syntactic_components)
+
+end
+
+
+
+
+
+
+---
+-- This function is called internally to perform the graph anchoring
+-- procedure described in
+-- Section~\ref{subsection-library-graphdrawing-anchoring}. These
+-- transformations are always performed.
+--
+-- @param graph A graph
+-- @param scope The scope
+
+function LayoutPipeline.anchor(graph, scope)
+
+ -- Step 1: Find anchor node:
+ local anchor_node
+
+ local anchor_node_name = graph.options['anchor node']
+ if anchor_node_name then
+ anchor_node = scope.node_names[anchor_node_name]
+ end
+
+ if not graph:contains(anchor_node) then
+ anchor_node =
+ lib.find (graph.vertices, function (v) return v.options['anchor here'] end) or
+ lib.find (graph.vertices, function (v) return v.options['desired at'] end) or
+ graph.vertices[1]
+ end
+
+ -- Sanity check
+ assert(graph:contains(anchor_node), "anchor node is not in graph!")
+
+ local desired = anchor_node.options['desired at'] or graph.options['anchor at']
+ local delta = desired - anchor_node.pos
+
+ -- Step 3: Shift nodes
+ for _,v in ipairs(graph.vertices) do
+ v.pos:shiftByCoordinate(delta)
+ end
+ for _,a in ipairs(graph.arcs) do
+ if a.path then a.path:shiftByCoordinate(delta) end
+ for _,e in ipairs(a.syntactic_edges) do
+ e.path:shiftByCoordinate(delta)
+ end
+ end
+end
+
+
+
+---
+-- This method tries to determine in which direction the graph is supposed to
+-- grow and in which direction the algorithm will grow the graph. These two
+-- pieces of information together produce a necessary rotation around some node.
+-- This rotation is returned in a table.
+--
+-- Note that this method does not actually cause a rotation to happen; this is
+-- left to other method.
+--
+-- @param postconditions The algorithm's postconditions.
+-- @param graph An undirected graph
+-- @return A table containing the computed information.
+
+function LayoutPipeline.prepareRotateAround(postconditions, graph)
+
+ -- Find the vertex from which we orient
+ local swap = true
+
+ local v,_,grow = lib.find (graph.vertices, function (v) return v.options["grow"] end)
+
+ if not v and graph.options["grow"] then
+ v,grow,swap = graph.vertices[1], graph.options["grow"], true
+ end
+
+ if not v then
+ v,_,grow = lib.find (graph.vertices, function (v) return v.options["grow'"] end)
+ swap = false
+ end
+
+ if not v and graph.options["grow'"] then
+ v,grow,swap = graph.vertices[1], graph.options["grow'"], false
+ end
+
+ if not v then
+ v, grow, swap = graph.vertices[1], -90, true
+ end
+
+ -- Now compute the rotation
+ local info = {}
+ local growth_direction = (postconditions.upward_oriented and 90) or (postconditions.upward_oriented_swapped and 90)
+
+ if postconditions.upward_oriented_swapped then
+ swap = not swap
+ end
+
+ if growth_direction == "fixed" then
+ info.angle = 0 -- no rotation
+ elseif growth_direction then
+ info.from_node = v
+ info.from_angle = growth_direction/360*2*math.pi
+ info.to_angle = grow/360*2*math.pi
+ info.swap = swap
+ info.angle = info.to_angle - info.from_angle
+ else
+ info.from_node = v
+ local other = lib.find_min(
+ graph:outgoing(v),
+ function (a)
+ if a.head ~= v and a:eventIndex() then
+ return a, a:eventIndex()
+ end
+ end)
+ info.to_node = (other and other.head) or
+ (graph.vertices[1] == v and graph.vertices[2] or graph.vertices[1])
+ info.to_angle = grow/360*2*math.pi
+ info.swap = swap
+ info.angle = info.to_angle - math.atan2(info.to_node.pos.y - v.pos.y, info.to_node.pos.x - v.pos.x)
+ end
+
+ return info
+end
+
+
+
+---
+-- Compute growth-adjusted node sizes.
+--
+-- For each node of the graph, compute bounding box of the node that
+-- results when the node is rotated so that it is in the correct
+-- orientation for what the algorithm assumes.
+--
+-- The ``bounding box'' actually consists of the fields
+-- %
+-- \begin{itemize}
+-- \item |sibling_pre|,
+-- \item |sibling_post|,
+-- \item |layer_pre|, and
+-- \item |layer_post|,
+-- \end{itemize}
+-- %
+-- which correspond to ``min x'', ``min y'', ``min y'', and ``max y''
+-- for a tree growing up.
+--
+-- The computation of the ``bounding box'' treats a centered circle in
+-- a special way, all other shapes are currently treated like a
+-- rectangle.
+--
+-- @param rotation_info The table computed by the function prepareRotateAround
+-- @param packing_storage A storage in which the computed distances are stored.
+-- @param graph An graph
+-- @param vertices An array of to-be-prepared vertices inside graph
+
+function LayoutPipeline.prepareBoundingBoxes(rotation_info, adjusted_bb, graph, vertices)
+
+ local angle = assert(rotation_info.angle, "angle field missing")
+ local swap = rotation_info.swap
+
+ for _,v in ipairs(vertices) do
+ local bb = adjusted_bb[v]
+ local a = angle
+
+ if v.shape == "circle" then
+ a = 0 -- no rotation for circles.
+ end
+
+ -- Fill the bounding box field,
+ bb.sibling_pre = math.huge
+ bb.sibling_post = -math.huge
+ bb.layer_pre = math.huge
+ bb.layer_post = -math.huge
+
+ local c = math.cos(angle)
+ local s = math.sin(angle)
+ for _,p in ipairs(v.path:coordinates()) do
+ local x = p.x*c + p.y*s
+ local y = -p.x*s + p.y*c
+
+ bb.sibling_pre = math.min (bb.sibling_pre, x)
+ bb.sibling_post = math.max (bb.sibling_post, x)
+ bb.layer_pre = math.min (bb.layer_pre, y)
+ bb.layer_post = math.max (bb.layer_post, y)
+ end
+
+ -- Flip sibling per and post if flag:
+ if swap then
+ bb.sibling_pre, bb.sibling_post = -bb.sibling_post, -bb.sibling_pre
+ end
+ end
+end
+
+
+
+
+
+--
+-- Rotate the whole graph around a point
+--
+-- Causes the graph to be rotated around \meta{around} so that what
+-- used to be the |from_angle| becomes the |to_angle|. If the flag |swap|
+-- is set, the graph is additionally swapped along the |to_angle|.
+--
+-- @param graph The to-be-rotated (undirected) graph
+-- @param around_x The $x$-coordinate of the point around which the graph should be rotated
+-- @param around_y The $y$-coordinate
+-- @param from An ``old'' angle
+-- @param to A ``new'' angle
+-- @param swap A boolean that, when true, requests that the graph is
+-- swapped (flipped) along the new angle
+
+function LayoutPipeline.rotateGraphAround(graph, around_x, around_y, from, to, swap)
+
+ -- Translate to origin
+ local t = Transform.new_shift(-around_x, -around_y)
+
+ -- Rotate to zero degrees:
+ t = Transform.concat(Transform.new_rotation(-from), t)
+
+ -- Swap
+ if swap then
+ t = Transform.concat(Transform.new_scaling(1,-1), t)
+ end
+
+ -- Rotate to from degrees:
+ t = Transform.concat(Transform.new_rotation(to), t)
+
+ -- Translate back
+ t = Transform.concat(Transform.new_shift(around_x, around_y), t)
+
+ for _,v in ipairs(graph.vertices) do
+ v.pos:apply(t)
+ end
+ for _,a in ipairs(graph.arcs) do
+ for _,p in ipairs(a:pointCloud()) do
+ p:apply(t)
+ end
+ end
+end
+
+
+
+--
+-- Orient the whole graph using two nodes
+--
+-- The whole graph is rotated so that the line from the first node to
+-- the second node has the given angle. If swap is set to true, the
+-- graph is also flipped along this line.
+--
+-- @param graph
+-- @param first_node
+-- @param seond_node
+-- @param target_angle
+-- @param swap
+
+function LayoutPipeline.orientTwoNodes(graph, first_node, second_node, target_angle, swap)
+ if first_node and second_node then
+ -- Compute angle between first_node and second_node:
+ local x = second_node.pos.x - first_node.pos.x
+ local y = second_node.pos.y - first_node.pos.y
+
+ local angle = math.atan2(y,x)
+ LayoutPipeline.rotateGraphAround(graph, first_node.pos.x,
+ first_node.pos.y, angle, target_angle, swap)
+ end
+end
+
+
+
+---
+-- Performs a post-layout orientation of the graph by performing the
+-- steps documented in Section~\ref{subsection-library-graphdrawing-standard-orientation}.
+--
+-- @param rotation_info The info record computed by the function |prepareRotateAround|.
+-- @param postconditions The algorithm's postconditions.
+-- @param graph A to-be-oriented graph.
+-- @param scope The graph drawing scope.
+
+function LayoutPipeline.orient(rotation_info, postconditions, graph, scope)
+
+ -- Sanity check
+ if #graph.vertices < 2 then return end
+
+ -- Step 1: Search for global graph orient options:
+ local function f (orient, tail, head, flag)
+ if orient and head and tail then
+ local n1 = scope.node_names[tail]
+ local n2 = scope.node_names[head]
+ if graph:contains(n1) and graph:contains(n2) then
+ LayoutPipeline.orientTwoNodes(graph, n1, n2, orient/360*2*math.pi, flag)
+ return true
+ end
+ end
+ end
+ if f(graph.options["orient"], graph.options["orient tail"],graph.options["orient head"], false) then return end
+ if f(graph.options["orient'"], graph.options["orient tail"],graph.options["orient head"], true) then return end
+ local tail, head = string.match(graph.options["horizontal"] or "", "^(.*) to (.*)$")
+ if f(0, tail, head, false) then return end
+ local tail, head = string.match(graph.options["horizontal'"] or "", "^(.*) to (.*)$")
+ if f(0, tail, head, true) then return end
+ local tail, head = string.match(graph.options["vertical"] or "", "^(.*) to (.*)$")
+ if f(-90, tail, head, false) then return end
+ local tail, head = string.match(graph.options["vertical'"] or "", "^(.*) to (.*)$")
+ if f(-90, tail, head, true) then return end
+
+ -- Step 2: Search for a node with the orient option:
+ for _, v in ipairs(graph.vertices) do
+ local function f (key, flag)
+ local orient = v.options[key]
+ local head = v.options["orient head"]
+ local tail = v.options["orient tail"]
+
+ if orient and head then
+ local n2 = scope.node_names[head]
+ if graph:contains(n2) then
+ LayoutPipeline.orientTwoNodes(graph, v, n2, orient/360*2*math.pi, flag)
+ return true
+ end
+ elseif orient and tail then
+ local n1 = scope.node_names[tail]
+ if graph:contains(n1) then
+ LayoutPipeline.orientTwoNodes(graph, n1, v, orient/360*2*math.pi, flag)
+ return true
+ end
+ end
+ end
+ if f("orient", false) then return end
+ if f("orient'", true) then return end
+ end
+
+ -- Step 3: Search for an edge with the orient option:
+ for _, a in ipairs(graph.arcs) do
+ if a:options("orient",true) then
+ return LayoutPipeline.orientTwoNodes(graph, a.tail, a.head, a:options("orient")/360*2*math.pi, false)
+ end
+ if a:options("orient'",true) then
+ return LayoutPipeline.orientTwoNodes(graph, a.tail, a.head, a:options("orient'")/360*2*math.pi, true)
+ end
+ end
+
+ -- Step 4: Search two nodes with a desired at option:
+ local first, second, third
+
+ for _, v in ipairs(graph.vertices) do
+ if v.options['desired at'] then
+ if first then
+ if second then
+ third = v
+ break
+ else
+ second = v
+ end
+ else
+ first = v
+ end
+ end
+ end
+
+ if second then
+ local a = first.options['desired at']
+ local b = second.options['desired at']
+ return LayoutPipeline.orientTwoNodes(graph, first, second, math.atan2(b.y-a.y,b.x-a.x), false)
+ end
+
+ -- Computed during preprocessing:
+ if rotation_info.from_node and postconditions.fixed ~= true then
+ local x = rotation_info.from_node.pos.x
+ local y = rotation_info.from_node.pos.y
+ local from_angle = rotation_info.from_angle or math.atan2(rotation_info.to_node.pos.y - y, rotation_info.to_node.pos.x - x)
+
+ LayoutPipeline.rotateGraphAround(graph, x, y, from_angle, rotation_info.to_angle, rotation_info.swap)
+ end
+end
+
+
+
+
+---
+-- This internal function is called to decompose a graph into its
+-- components. Whether or not this function is called depends on
+-- whether the precondition |connected| is set for the algorithm class
+-- and whether the |componentwise| key is used.
+--
+-- @param graph A to-be-decomposed graph
+--
+-- @return An array of graph objects that represent the connected components of the graph.
+
+function LayoutPipeline.decompose (digraph)
+
+ -- The list of connected components (node sets)
+ local components = {}
+
+ -- Remember, which graphs have already been visited
+ local visited = {}
+
+ for _,v in ipairs(digraph.vertices) do
+ if not visited[v] then
+ -- Start a depth-first-search of the graph, starting at node n:
+ local stack = { v }
+ local component = Digraph.new {
+ syntactic_digraph = digraph.syntactic_digraph,
+ options = digraph.options
+ }
+
+ while #stack >= 1 do
+ local tos = stack[#stack]
+ stack[#stack] = nil -- pop
+
+ if not visited[tos] then
+
+ -- Visit pos:
+ component:add { tos }
+ visited[tos] = true
+
+ -- Push all unvisited neighbors:
+ for _,a in ipairs(digraph:incoming(tos)) do
+ local neighbor = a.tail
+ if not visited[neighbor] then
+ stack[#stack+1] = neighbor -- push
+ end
+ end
+ for _,a in ipairs(digraph:outgoing(tos)) do
+ local neighbor = a.head
+ if not visited[neighbor] then
+ stack[#stack+1] = neighbor -- push
+ end
+ end
+ end
+ end
+
+ -- Ok, vertices will now contain all vertices reachable from n.
+ components[#components+1] = component
+ end
+ end
+
+ if #components < 2 then
+ return { digraph }
+ end
+
+ for _,c in ipairs(components) do
+ table.sort (c.vertices, function (u,v) return u.event.index < v.event.index end)
+ for _,v in ipairs(c.vertices) do
+ for _,a in ipairs(digraph:outgoing(v)) do
+ local new_a = c:connect(a.tail, a.head)
+ new_a.syntactic_edges = a.syntactic_edges
+ end
+ for _,a in ipairs(digraph:incoming(v)) do
+ local new_a = c:connect(a.tail, a.head)
+ new_a.syntactic_edges = a.syntactic_edges
+ end
+ end
+ end
+
+ return components
+end
+
+
+
+
+-- Handling of component order
+--
+-- LayoutPipeline are ordered according to a function that is stored in
+-- a key of the |LayoutPipeline.component_ordering_functions| table
+-- whose name is the graph option |component order|.
+--
+-- @param component_order An ordering method
+-- @param subgraphs A list of to-be-sorted subgraphs
+
+function LayoutPipeline.sortComponents(component_order, subgraphs)
+ if component_order then
+ local f = LayoutPipeline.component_ordering_functions[component_order]
+ if f then
+ table.sort (subgraphs, f)
+ end
+ end
+end
+
+
+-- Right now, we hardcode the functions here. Perhaps make this
+-- dynamic in the future. Could easily be done on the tikzlayer,
+-- actually.
+
+LayoutPipeline.component_ordering_functions = {
+ ["increasing node number"] =
+ function (g,h)
+ if #g.vertices == #h.vertices then
+ return g.vertices[1].event.index < h.vertices[1].event.index
+ else
+ return #g.vertices < #h.vertices
+ end
+ end,
+ ["decreasing node number"] =
+ function (g,h)
+ if #g.vertices == #h.vertices then
+ return g.vertices[1].event.index < h.vertices[1].event.index
+ else
+ return #g.vertices > #h.vertices
+ end
+ end,
+ ["by first specified node"] = nil,
+}
+
+
+
+
+local function compute_rotated_bb(vertices, angle, sep, bb)
+
+ local r = Transform.new_rotation(-angle)
+
+ for _,v in ipairs(vertices) do
+ -- Find the rotated bounding box field,
+ local t = Transform.concat(r,Transform.new_shift(v.pos.x, v.pos.y))
+
+ local min_x = math.huge
+ local max_x = -math.huge
+ local min_y = math.huge
+ local max_y = -math.huge
+
+ for _,e in ipairs(v.path) do
+ if type(e) == "table" then
+ local c = e:clone()
+ c:apply(t)
+
+ min_x = math.min (min_x, c.x)
+ max_x = math.max (max_x, c.x)
+ min_y = math.min (min_y, c.y)
+ max_y = math.max (max_y, c.y)
+ end
+ end
+
+ -- Enlarge by sep:
+ min_x = min_x - sep
+ max_x = max_x + sep
+ min_y = min_y - sep
+ max_y = max_y + sep
+
+ local _,_,_,_,c_x,c_y = v:boundingBox()
+ local center = Coordinate.new(c_x,c_y)
+
+ center:apply(t)
+
+ bb[v].min_x = min_x
+ bb[v].max_x = max_x
+ bb[v].min_y = min_y
+ bb[v].max_y = max_y
+ bb[v].c_y = center.y
+ end
+end
+
+
+
+---
+-- This internal function packs the components of a graph. See
+-- Section~\ref{subsection-gd-component-packing} for details.
+--
+-- @param graph The graph
+-- @param components A list of components
+
+function LayoutPipeline.packComponents(syntactic_digraph, components)
+
+ local vertices = Storage.newTableStorage()
+ local bb = Storage.newTableStorage()
+
+ -- Step 1: Preparation, rotation to target direction
+ local sep = syntactic_digraph.options['component sep']
+ local angle = syntactic_digraph.options['component direction']/180*math.pi
+
+ local mark = {}
+ for _,c in ipairs(components) do
+
+ -- Setup the lists of to-be-considered nodes
+ local vs = {}
+ for _,v in ipairs(c.vertices) do
+ vs [#vs + 1] = v
+ end
+
+ for _,a in ipairs(c.arcs) do
+ for _,p in ipairs(a:pointCloud()) do
+ vs [#vs + 1] = Vertex.new { pos = p }
+ end
+ end
+ vertices[c] = vs
+
+ compute_rotated_bb(vs, angle, sep/2, bb)
+ end
+
+ local x_shifts = { 0 }
+ local y_shifts = {}
+
+ -- Step 2: Vertical alignment
+ for i,c in ipairs(components) do
+ local max_max_y = -math.huge
+ local max_center_y = -math.huge
+ local min_min_y = math.huge
+ local min_center_y = math.huge
+
+ for _,v in ipairs(c.vertices) do
+ local info = bb[v]
+ max_max_y = math.max(info.max_y, max_max_y)
+ max_center_y = math.max(info.c_y, max_center_y)
+ min_min_y = math.min(info.min_y, min_min_y)
+ min_center_y = math.min(info.c_y, min_center_y)
+ end
+
+ -- Compute alignment line
+ local valign = syntactic_digraph.options['component align']
+ local line
+ if valign == "counterclockwise bounding box" then
+ line = max_max_y
+ elseif valign == "counterclockwise" then
+ line = max_center_y
+ elseif valign == "center" then
+ line = (max_max_y + min_min_y) / 2
+ elseif valign == "clockwise" then
+ line = min_center_y
+ elseif valign == "first node" then
+ line = bb[c.vertices[1]].c_y
+ else
+ line = min_min_y
+ end
+
+ -- Overruled?
+ for _,v in ipairs(c.vertices) do
+ if v.options['align here'] then
+ line = bb[v].c_y
+ break
+ end
+ end
+
+ -- Ok, go!
+ y_shifts[i] = -line
+
+ -- Adjust nodes:
+ for _,v in ipairs(vertices[c]) do
+ local info = bb[v]
+ info.min_y = info.min_y - line
+ info.max_y = info.max_y - line
+ info.c_y = info.c_y - line
+ end
+ end
+
+ -- Step 3: Horizontal alignment
+ local y_values = {}
+
+ for _,c in ipairs(components) do
+ for _,v in ipairs(vertices[c]) do
+ local info = bb[v]
+ y_values[#y_values+1] = info.min_y
+ y_values[#y_values+1] = info.max_y
+ y_values[#y_values+1] = info.c_y
+ end
+ end
+
+ table.sort(y_values)
+
+ local y_ranks = {}
+ local right_face = {}
+ for i=1,#y_values do
+ y_ranks[y_values[i]] = i
+ right_face[i] = -math.huge
+ end
+
+
+
+ for i=1,#components-1 do
+ -- First, update right_face:
+ local touched = {}
+
+ for _,v in ipairs(vertices[components[i]]) do
+ local info = bb[v]
+ local border = info.max_x
+
+ for i=y_ranks[info.min_y],y_ranks[info.max_y] do
+ touched[i] = true
+ right_face[i] = math.max(right_face[i], border)
+ end
+ end
+
+ -- Fill up the untouched entries:
+ local right_max = -math.huge
+ for i=1,#y_values do
+ if not touched[i] then
+ -- Search for next and previous touched
+ local interpolate = -math.huge
+ for j=i+1,#y_values do
+ if touched[j] then
+ interpolate = math.max(interpolate,right_face[j] - (y_values[j] - y_values[i]))
+ break
+ end
+ end
+ for j=i-1,1,-1 do
+ if touched[j] then
+ interpolate = math.max(interpolate,right_face[j] - (y_values[i] - y_values[j]))
+ break
+ end
+ end
+ right_face[i] = math.max(interpolate,right_face[i])
+ end
+ right_max = math.max(right_max, right_face[i])
+ end
+
+ -- Second, compute the left face
+ local touched = {}
+ local left_face = {}
+ for i=1,#y_values do
+ left_face[i] = math.huge
+ end
+ for _,v in ipairs(vertices[components[i+1]]) do
+ local info = bb[v]
+ local border = info.min_x
+
+ for i=y_ranks[info.min_y],y_ranks[info.max_y] do
+ touched[i] = true
+ left_face[i] = math.min(left_face[i], border)
+ end
+ end
+
+ -- Fill up the untouched entries:
+ local left_min = math.huge
+ for i=1,#y_values do
+ if not touched[i] then
+ -- Search for next and previous touched
+ local interpolate = math.huge
+ for j=i+1,#y_values do
+ if touched[j] then
+ interpolate = math.min(interpolate,left_face[j] + (y_values[j] - y_values[i]))
+ break
+ end
+ end
+ for j=i-1,1,-1 do
+ if touched[j] then
+ interpolate = math.min(interpolate,left_face[j] + (y_values[i] - y_values[j]))
+ break
+ end
+ end
+ left_face[i] = interpolate
+ end
+ left_min = math.min(left_min, left_face[i])
+ end
+
+ -- Now, compute the shift.
+ local shift = -math.huge
+
+ if syntactic_digraph.options['component packing'] == "rectangular" then
+ shift = right_max - left_min
+ else
+ for i=1,#y_values do
+ shift = math.max(shift, right_face[i] - left_face[i])
+ end
+ end
+
+ -- Adjust nodes:
+ x_shifts[i+1] = shift
+ for _,v in ipairs(vertices[components[i+1]]) do
+ local info = bb[v]
+ info.min_x = info.min_x + shift
+ info.max_x = info.max_x + shift
+ end
+ end
+
+ -- Now, rotate shifts
+ for i,c in ipairs(components) do
+ local x = x_shifts[i]*math.cos(angle) - y_shifts[i]*math.sin(angle)
+ local y = x_shifts[i]*math.sin(angle) + y_shifts[i]*math.cos(angle)
+
+ for _,v in ipairs(vertices[c]) do
+ v.pos.x = v.pos.x + x
+ v.pos.y = v.pos.y + y
+ end
+ end
+end
+
+
+
+
+
+
+
+--
+-- Store for each begin/end event the index of
+-- its corresponding end/begin event
+--
+-- @param events An event list
+
+prepare_events =
+ function (events)
+ local stack = {}
+
+ for i=1,#events do
+ if events[i].kind == "begin" then
+ stack[#stack + 1] = i
+ elseif events[i].kind == "end" then
+ local tos = stack[#stack]
+ stack[#stack] = nil -- pop
+
+ events[tos].end_index = i
+ events[i].begin_index = tos
+ end
+ end
+ end
+
+
+
+---
+-- Cut the edges. This function handles the ``cutting'' of edges. The
+-- idea is that every edge is a path going from the center of the from
+-- node to the center of the target node. Now, we intersect this path
+-- with the path of the start node and cut away everything before this
+-- intersection. Likewise, we intersect the path with the head node
+-- and, again, cut away everything following the intersection.
+--
+-- These cuttings are not done if appropriate options are set.
+
+function LayoutPipeline.cutEdges(graph)
+
+ for _,a in ipairs(graph.arcs) do
+ for _,e in ipairs(a.syntactic_edges) do
+ local p = e.path
+ p:makeRigid()
+ local orig = p:clone()
+
+ if e.options['tail cut'] and e.tail.options['cut policy'] == "as edge requests"
+ or e.tail.options['cut policy'] == "all" then
+
+ local vpath = e.tail.path:clone()
+ vpath:shiftByCoordinate(e.tail.pos)
+
+ local x = p:intersectionsWith (vpath)
+
+ if #x > 0 then
+ p:cutAtBeginning(x[1].index, x[1].time)
+ end
+ end
+
+ if e.options['head cut'] and e.head.options['cut policy'] == "as edge requests"
+ or e.head.options['cut policy'] == "all" then
+
+ local vpath = e.head.path:clone()
+ vpath:shiftByCoordinate(e.head.pos)
+ x = p:intersectionsWith (vpath)
+ if #x > 0 then
+ p:cutAtEnd(x[#x].index, x[#x].time)
+ else
+ -- Check whether there was an intersection with the original
+ --path:
+ local x2 = orig:intersectionsWith (vpath)
+ if #x2 > 0 then
+ -- Ok, after cutting the tail vertex, there is no longer
+ -- an intersection with the head vertex, but there used to
+ -- be one. This means that the vertices overlap and the
+ -- path should be ``inside'' them. Hmm...
+ if e.options['allow inside edges'] and #p > 1 then
+ local from = p[2]
+ local to = x2[1].point
+ p:clear()
+ p:appendMoveto(from)
+ p:appendLineto(to)
+ else
+ p:clear()
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+
+
+
+
+
+-- Deprecated stuff
+
+local Node = require "pgf.gd.deprecated.Node"
+local Graph = require "pgf.gd.deprecated.Graph"
+local Edge = require "pgf.gd.deprecated.Edge"
+local Cluster = require "pgf.gd.deprecated.Cluster"
+
+
+
+
+
+local unique_count = 0
+
+local function compatibility_digraph_to_graph(scope, g)
+ local graph = Graph.new()
+
+ -- Graph options
+ graph.options = g.options
+ graph.orig_digraph = g
+
+ -- Events
+ for i,e in ipairs(scope.events) do
+ graph.events[i] = e
+ end
+
+ -- Nodes
+ for _,v in ipairs(g.vertices) do
+ if not v.name then
+ -- compat needs unique name
+ v.name = "auto generated node nameINTERNAL" .. unique_count
+ unique_count = unique_count + 1
+ end
+ local minX, minY, maxX, maxY = v:boundingBox()
+ local node = Node.new{
+ name = v.name,
+ tex = {
+ tex_node = v.tex and v.tex.stored_tex_box_number,
+ shape = v.shape,
+ minX = minX,
+ maxX = maxX,
+ minY = minY,
+ maxY = maxY,
+ },
+ options = v.options,
+ event_index = v.event.index,
+ index = v.event.index,
+ orig_vertex = v,
+ }
+ graph:addNode(node)
+ graph.events[v.event.index or (#graph.events+1)] = { kind = 'node', parameters = node }
+ end
+
+ -- Edges
+ local mark = Storage.new()
+ for _,a in ipairs(g.arcs) do
+ local da = g.syntactic_digraph:arc(a.tail, a.head)
+ if da then
+ for _,m in ipairs(da.syntactic_edges) do
+ if not mark[m] then
+ mark[m] = true
+ local from_node = graph:findNode(da.tail.name)
+ local to_node = graph:findNode(da.head.name)
+ local edge = graph:createEdge(from_node, to_node, m.direction, nil, m.options, nil)
+ edge.event_index = m.event.index
+ edge.orig_m = m
+ graph.events[m.event.index] = { kind = 'edge', parameters = edge }
+ end
+ end
+ end
+ local da = g.syntactic_digraph:arc(a.head, a.tail)
+ if da then
+ for _,m in ipairs(da.syntactic_edges) do
+ if not mark[m] then
+ mark[m] = true
+ local from_node = graph:findNode(da.tail.name)
+ local to_node = graph:findNode(da.head.name)
+ local edge = graph:createEdge(from_node, to_node, m.direction, nil, m.options, nil)
+ edge.event_index = m.event.index
+ edge.orig_m = m
+ graph.events[m.event.index] = { kind = 'edge', parameters = edge }
+ end
+ end
+ end
+ end
+
+ table.sort(graph.edges, function(e1,e2) return e1.event_index < e2.event_index end)
+ for _,n in ipairs (graph.nodes) do
+ table.sort(n.edges, function(e1,e2) return e1.event_index < e2.event_index end)
+ end
+
+
+ -- Clusters
+ for _, c in ipairs(scope.collections['same layer'] or {}) do
+ cluster = Cluster.new("cluster" .. unique_count)
+ unique_count = unique_count+1
+ graph:addCluster(cluster)
+ for _,v in ipairs(c.vertices) do
+ if g:contains(v) then
+ cluster:addNode(graph:findNode(v.name))
+ end
+ end
+ end
+
+ return graph
+end
+
+
+local function compatibility_graph_to_digraph(graph)
+ for _,n in ipairs(graph.nodes) do
+ n.orig_vertex.pos.x = n.pos.x
+ n.orig_vertex.pos.y = n.pos.y
+ end
+ for _,e in ipairs(graph.edges) do
+ if #e.bend_points > 0 then
+ local c = {}
+ for _,x in ipairs(e.bend_points) do
+ c[#c+1] = Coordinate.new (x.x, x.y)
+ end
+ e.orig_m:setPolylinePath(c)
+ end
+ end
+end
+
+
+
+
+
+function LayoutPipeline.runOldGraphModel(scope, digraph, algorithm_class, algorithm)
+
+ local graph = compatibility_digraph_to_graph(scope, digraph)
+
+ algorithm.graph = graph
+ graph:registerAlgorithm(algorithm)
+
+ -- If requested, remove loops
+ if algorithm_class.preconditions.loop_free then
+ Simplifiers:removeLoopsOldModel(algorithm)
+ end
+
+ -- If requested, collapse multiedges
+ if algorithm_class.preconditions.simple then
+ Simplifiers:collapseMultiedgesOldModel(algorithm)
+ end
+
+ if #graph.nodes > 1 then
+ -- Main run of the algorithm:
+ algorithm:run ()
+ end
+
+ -- If requested, expand multiedges
+ if algorithm_class.preconditions.simple then
+ Simplifiers:expandMultiedgesOldModel(algorithm)
+ end
+
+ -- If requested, restore loops
+ if algorithm_class.preconditions.loop_free then
+ Simplifiers:restoreLoopsOldModel(algorithm)
+ end
+
+ compatibility_graph_to_digraph(graph)
+end
+
+
+
+
+-- Done
+
+return LayoutPipeline
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua
new file mode 100644
index 0000000000..80aa7ef420
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua
@@ -0,0 +1,175 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+
+---
+-- @section subsection {Anchoring Edges}
+--
+-- \label{section-gd-anchors}
+--
+-- When a graph has been laid out completely, the edges between the
+-- nodes must be drawn. Conceptually, an edge is ``between two
+-- nodes'', but when we actually draw the node, we do not really want
+-- the edge's path to start ``in the middle'' of the node; rather, we
+-- want it to start ``on the border'' and also end there.
+--
+-- Normally, computing such border positions for nodes is something we
+-- would leave to the so-called display layer (which is typically
+-- \tikzname\ and \tikzname\ is reasonably good at computing border
+-- positions). However, different display layers may behave
+-- differently here and even \tikzname\ fails when the node shapes are
+-- very involved and the paths also.
+--
+-- For these reasons, computing the anchor positions where edges start
+-- and end is done inside the graph drawing system. As a user, you
+-- specify a |tail anchor| and a |head anchor|, which are points
+-- inside the tail and head nodes, respectively. The edge path will
+-- then start and end at these points, however, they will usually be
+-- shortened so that they actually start and end on the intersection
+-- of the edge's path with the nodes' paths.
+
+
+---
+
+declare {
+ key = "tail anchor",
+ type = "string",
+ initial = "",
+
+ summary = [["
+ Specifies where in the tail vertex the edge should start.
+ "]],
+
+ documentation = [["
+ This is either a string or a number, interpreted as an angle
+ (with 90 meaning ``up''). If it is a string, when the start of
+ the edge is computed, we try to look up the anchor in the tail
+ vertex's table of anchors (some anchors get installed in this
+ table by the display system). If it is not found, we test
+ whether it is one of the special ``direction anchors'' like
+ |north| or |south east|. If so, we convert them into points on
+ the border of the node that lie in the direction of a line
+ starting at the center to a point on the bounding box of the
+ node in the designated direction. Finally, if the anchor is a
+ number, we use a point on the border of the node that is on a
+ line from the center in the specified direction.
+
+ If the anchor is set to the empty string (which is the default),
+ the anchor is interpreted as the |center| anchor inside the
+ graph drawing system. However, a display system may choose to
+ make a difference between the |center| anchor and an empty
+ anchor (\tikzname\ does: for options like |bend left| if the
+ anchor is empty, the bend line starts at the border of the node,
+ while for the anchor set explicitly to |center| it starts at the
+ center).
+
+ Note that graph drawing algorithms need not take the
+ setting of this option into consideration. However, the final
+ rendering of the edge will always take it into consideration
+ (only, the setting may not be very sensible if the algorithm
+ ignored it).
+ "]]
+}
+
+---
+
+declare {
+ key = "head anchor",
+ type = "string",
+ initial = "",
+
+ summary = "See |tail anchor|"
+}
+
+
+---
+
+declare {
+ key = "tail cut",
+ type = "boolean",
+ initial = true,
+
+ summary = [["
+ Decides whether the tail of an edge is ``cut'', meaning
+ that the edge's path will be shortened at the beginning so that
+ it starts only of the node's border rather than at the exact
+ position of the |tail anchor|, which may be inside the node.
+ "]]
+}
+
+
+---
+
+declare {
+ key = "head cut",
+ type = "boolean",
+ initial = true,
+
+ summary = "See |tail cut|."
+}
+
+
+---
+
+declare {
+ key = "cut policy",
+ type = "string",
+ initial = "as edge requests",
+
+ summary = "The policy for cutting edges entering or leaving a node.",
+
+ documentation = [["
+ This option is important for nodes only. It can have three
+ possible values:
+ %
+ \begin{itemize}
+ \item |as edge requests| Whether or not an edge entering or
+ leaving the node is cut depends on the setting of the edge's
+ |tail cut| and |head cut| options. This is the default.
+ \item |all| All edges entering or leaving the node are cut,
+ regardless of the edges' cut values.
+ \item |none| No edge entering or leaving the node is cut,
+ regardless of the edges' cut values.
+ \end{itemize}
+ "]]
+}
+
+
+---
+declare {
+ key = "allow inside edges",
+ type = "boolean",
+ initial = "true",
+
+ summary = "Decides whether an edge between overlapping nodes should be drawn.",
+
+ documentation = [["
+ If two vertices overlap, it may happen that when you draw an
+ edge between them, this edges would be completely inside the two
+ vertices. In this case, one could either not draw them or one
+ could draw a sort of ``inside edge''.
+ "]],
+
+ examples = { [["
+ \tikz \graph [no layout, nodes={draw, minimum size=20pt}] {
+ a [x=0, y=0] -- b [x=15pt, y=10pt] -- c[x=40pt]
+ };
+ "]],[["
+ \tikz \graph [no layout, nodes={draw, minimum size=20pt},
+ allow inside edges=false] {
+ a [x=0, y=0] -- b [x=15pt, y=10pt] -- c[x=40pt]
+ };
+ "]]
+ }
+} \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Orientation.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Orientation.lua
new file mode 100644
index 0000000000..1890fa4f39
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Orientation.lua
@@ -0,0 +1,303 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+---
+-- @section subsection {Orienting a Graph}
+--
+-- \label{subsection-library-graphdrawing-standard-orientation}
+--
+-- Just as a graph drawing algorithm cannot know \emph{where} a graph
+-- should be placed on a page, it is also often unclear which
+-- \emph{orientation} it should have. Some graphs, like trees, have a
+-- natural direction in which they ``grow'', but for an ``arbitrary''
+-- graph the ``natural orientation'' is, well, arbitrary.
+--
+-- There are two ways in which you can specify an orientation: First,
+-- you can specify that the line from a certain vertex to another
+-- vertex should have a certain slope. How these vertices and slopes
+-- are specified in explained momentarily. Second, you can specify a
+-- so-called ``growth direction'' for trees.
+--
+-- @end
+
+
+-- Namespace
+require("pgf.gd.control").Orientation = Orientation
+
+
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+---
+
+declare {
+ key = "orient",
+ type = "direction",
+ default = 0,
+
+ summary = [["
+ This key specifies that the straight line from the |orient tail| to
+ the |orient head| should be at an angle of \meta{direction} relative to
+ the right-going $x$-axis. Which vertices are used as tail an head
+ depends on where the |orient| option is encountered: When used with
+ an edge, the tail is the edge's tail and the head is the edge's
+ head. When used with a node, the tail or the head must be specified
+ explicitly and the node is used as the node missing in the
+ specification. When used with a graph as a whole, both the head and
+ tail nodes must be specified explicitly.
+ "]],
+ documentation = [["
+ Note that the \meta{direction} is independent of the actual to-path
+ of an edge, which might define a bend or more complicated shapes. For
+ instance, a \meta{angle} of |45| requests that the end node is ``up
+ and right'' relative to the start node.
+
+ You can also specify the standard direction texts |north| or |south east|
+ and so forth as \meta{direction} and also |up|, |down|, |left|, and
+ |right|. Also, you can specify |-| for ``right'' and \verb!|! for ``down''.
+ "]],
+ examples = {[["
+ \tikz \graph [spring layout]
+ {
+ a -- { b, c, d, e -- {f, g, h} };
+ h -- [orient=30] a;
+ };
+ "]],[["
+ \tikz \graph [spring layout]
+ {
+ a -- { b, c, d[> orient=right], e -- {f, g, h} };
+ h -- a;
+ };
+ "]]
+ }
+}
+
+
+---
+
+declare {
+ key = "orient'",
+ type = "direction",
+ default = 0,
+
+ summary = [["
+ Same as |orient|, only the rest of the graph should be
+ flipped relative to the connection line.
+ "]],
+ examples = [["
+ \tikz \graph [spring layout]
+ {
+ a -- { b, c, d[> orient'=right], e -- {f, g, h} };
+ h -- a;
+ };
+ "]]
+}
+
+---
+
+declare {
+ key = "orient tail",
+ type = "string",
+
+ summary = [["
+ Specifies the tail vertex for the orientation of a graph. See
+ |orient| for details.
+ "]],
+ examples = {[["
+ \tikz \graph [spring layout] {
+ a [orient=|, orient tail=f] -- { b, c, d, e -- {f, g, h} };
+ { h, g } -- a;
+ };
+ "]],[["
+ \tikz \graph [spring layout] {
+ a [orient=down, orient tail=h] -- { b, c, d, e -- {f, g, h} };
+ { h, g } -- a;
+ };
+ "]]
+ }
+}
+
+
+
+
+
+---
+
+declare {
+ key = "orient head",
+ type = "string",
+
+ summary = [["
+ Specifies the head vertex for the orientation of a graph. See
+ |orient| for details.
+ "]],
+ examples = {[["
+ \tikz \graph [spring layout]
+ {
+ a [orient=|, orient head=f] -- { b, c, d, e -- {f, g, h} };
+ { h, g } -- a;
+ };
+ "]],[["
+ \tikz \graph [spring layout] { a -- b -- c -- a };
+ \tikz \graph [spring layout, orient=10,
+ orient tail=a, orient head=b] { a -- b -- c -- a };
+ "]]
+ }
+}
+
+---
+
+declare {
+ key = "horizontal",
+ type = "string",
+
+ summary = [["
+ A shorthand for specifying |orient tail|, |orient head| and
+ |orient=0|. The tail will be everything before the part ``| to |''
+ and the head will be everything following it.
+ "]],
+ examples = [["
+ \tikz \graph [spring layout] { a -- b -- c -- a };
+ \tikz \graph [spring layout, horizontal=a to b] { a -- b -- c -- a };
+ "]]
+}
+
+
+
+
+---
+
+declare {
+ key = "horizontal'",
+ type = "string",
+
+ summary = [["
+ Like |horizontal|, but with a flip.
+ "]]
+}
+
+
+
+
+
+
+
+---
+
+declare {
+ key = "vertical",
+ type = "string",
+
+ summary = [["
+ A shorthand for specifying |orient tail|, |orient head| and |orient=-90|.
+ "]],
+ examples = [["
+ \tikz \graph [spring layout] { a -- b -- c -- a };
+ \tikz \graph [spring layout, vertical=a to b] { a -- b -- c -- a };
+ "]]
+}
+
+
+
+
+
+---
+
+declare {
+ key = "vertical'",
+ type = "string",
+
+ summary = [["
+ Like |vertical|, but with a flip.
+ "]]
+}
+
+
+
+---
+
+declare {
+ key = "grow",
+ type = "direction",
+
+ summary = [["
+ This key specifies in which direction the neighbors of a node
+ ``should grow''. For some graph drawing algorithms, especially for
+ those that layout trees, but also for those that produce layered
+ layouts, there is a natural direction in which the ``children'' of
+ a node should be placed. For instance, saying |grow=down| will cause
+ the children of a node in a tree to be placed in a left-to-right
+ line below the node (as always, you can replace the \meta{angle}
+ by direction texts). The children are requested to be placed in a
+ counter-clockwise fashion, the |grow'| key will place them in a
+ clockwise fashion.
+ "]],
+ documentation = [["
+ Note that when you say |grow=down|, it is not necessarily the case
+ that any particular node is actually directly below the current
+ node; the key just requests that the direction of growth is downward.
+
+ In principle, you can specify the direction of growth for each node
+ individually, but do not count on graph drawing algorithms to
+ honor these wishes.
+
+ When you give the |grow=right| key to the graph as a whole, it will
+ be applied to all nodes. This happens to be exactly what you want:
+ "]],
+ examples = {[["
+ \tikz \graph [layered layout, sibling distance=5mm]
+ {
+ a [grow=right] -- { b, c, d, e -- {f, g, h} };
+ { h, g } -- a;
+ };
+ "]],[["
+ \tikz \graph [layered layout, grow=right, sibling distance=5mm]
+ {
+ a -- { b, c, d, e -- {f, g, h} };
+ { h, g } -- a;
+ };
+ "]],[["
+ \tikz
+ \graph [layered layout, grow=-80]
+ {
+ {a,b,c} --[complete bipartite] {e,d,f}
+ --[complete bipartite] {g,h,i};
+ };
+ "]]
+ }
+}
+
+
+---
+
+declare {
+ key = "grow'",
+ type = "direction",
+
+ summary = "Same as |grow|, only with the children in clockwise order.",
+ examples = [["
+ \tikz \graph [layered layout, sibling distance=5mm]
+ {
+ a [grow'=right] -- { b, c, d, e -- {f, g, h} };
+ { h, g } -- a;
+ };
+ "]]
+}
+
+
+-- Done
+
+return Orientation \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Sublayouts.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Sublayouts.lua
new file mode 100644
index 0000000000..970483193f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/Sublayouts.lua
@@ -0,0 +1,536 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+local function full_print(g, pref)
+ local s = ""
+
+ for _,v in ipairs(g.vertices) do
+ s = s .. tostring(v) .. "[" .. tostring(v.pos) .. "]\n "
+ end
+
+ s = s .. "\n"
+
+ for _,a in ipairs(g.arcs) do
+ for _,e in ipairs(a.syntactic_edges) do
+ s = s .. tostring(e) .. "(" .. tostring(e.path) .. ")\n"
+ end
+ end
+
+ pgf.debug((pref or "") .. s)
+end
+
+
+---
+-- The |Sublayouts| module handles graphs for which multiple layouts are defined.
+--
+-- Please see Section~\ref{section-gd-sublayouts} for an overview of
+-- sublayouts.
+--
+
+local Sublayouts = {}
+
+-- Namespace
+require("pgf.gd.control").Sublayouts = Sublayouts
+
+
+-- Includes
+
+local Digraph = require "pgf.gd.model.Digraph"
+local Vertex = require "pgf.gd.model.Vertex"
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Path = require "pgf.gd.model.Path"
+
+local lib = require "pgf.gd.lib"
+
+local InterfaceCore = require "pgf.gd.interface.InterfaceCore"
+
+local Storage = require "pgf.gd.lib.Storage"
+
+
+
+-- Storages
+
+local subs = Storage.newTableStorage()
+local already_nudged = Storage.new()
+local positions = Storage.newTableStorage()
+
+
+
+
+-- Offset a node by an offset. This will \emph{also} offset all
+-- subnodes, which arise from sublayouts.
+--
+-- @param vertex A vertex
+-- @param pos A offset
+--
+local function offset_vertex(v, delta)
+ v.pos:shiftByCoordinate(delta)
+ for _,sub in ipairs(subs[v]) do
+ offset_vertex(sub, delta)
+ end
+end
+
+
+-- Nudge positioning. You can call this function several times on the
+-- same graph; nudging will be done only once.
+--
+-- @param graph A graph
+--
+local function nudge(graph)
+ for _,v in ipairs(graph.vertices) do
+ local nudge = v.options['nudge']
+ if nudge and not already_nudged[v] then
+ offset_vertex(v, nudge)
+ already_nudged[v] = true
+ end
+ end
+end
+
+
+
+-- Create subgraph nodes
+--
+-- @param scope A scope
+-- @param syntactic_digraph The syntactic digraph.
+-- @param test Only for vertices whose subgraph collection passes this test will we create subgraph nodes
+local function create_subgraph_node(scope, syntactic_digraph, vertex)
+
+ local subgraph_collection = vertex.subgraph_collection
+ local binding = InterfaceCore.binding
+
+ local cloud = {}
+ -- Add all points of n's collection, except for v itself, to the cloud:
+ for _,v in ipairs(subgraph_collection.vertices) do
+ if vertex ~= v then
+ assert(syntactic_digraph:contains(v), "the layout must contain all nodes of the subgraph")
+ for _,p in ipairs(v.path) do
+ if type(p) == "table" then
+ cloud[#cloud+1] = p + v.pos
+ end
+ end
+ end
+ end
+ for _,e in ipairs(subgraph_collection.edges) do
+ for _,p in ipairs(e.path) do
+ if type(p) == "table" then
+ cloud[#cloud+1] = p:clone()
+ end
+ end
+ end
+ local x_min, y_min, x_max, y_max, c_x, c_y = Coordinate.boundingBox(cloud)
+
+ -- Shift the graph so that it is centered on the origin:
+ for _,p in ipairs(cloud) do
+ p:unshift(c_x,c_y)
+ end
+
+ local o = vertex.subgraph_info.generated_options
+
+ o[#o+1] = { key = "subgraph point cloud", value = table.concat(lib.imap(cloud, tostring)) }
+ o[#o+1] = { key = "subgraph bounding box height", value = tostring(y_max-y_min) .. "pt" }
+ o[#o+1] = { key = "subgraph bounding box width", value = tostring(x_max-x_min) .. "pt" }
+
+ -- And now, the "grand call":
+ binding:createVertex(vertex.subgraph_info)
+
+ -- Shift it were it belongs
+ vertex.pos:shift(c_x,c_y)
+
+ -- Remember all the subnodes for nudging and regardless
+ -- positioning
+ local s = {}
+ for _,v in ipairs(subgraph_collection.vertices) do
+ if v ~= vertex then
+ s[#s+1] = v
+ end
+ end
+
+ subs[vertex] = s
+end
+
+
+-- Tests whether two graphs have a vertex in common
+local function intersection(g1, g2)
+ for _,v in ipairs(g1.vertices) do
+ if g2:contains(v) then
+ return v
+ end
+ end
+end
+
+-- Tests whether a graph is a set is a subset of another
+local function special_vertex_subset(vertices, graph)
+ for _,v in ipairs(vertices) do
+ if not graph:contains(v) and not (v.kind == "subgraph node") then
+ return false
+ end
+ end
+ return true
+end
+
+
+
+---
+-- The layout recursion. See \ref{section-gd-sublayouts} for details.
+--
+-- @param scope The graph drawing scope
+-- @param layout The to-be-laid-out collection
+-- @param fun The to-be-called function for laying out the graph.
+-- processed. This stack is important when a new syntactic vertex is
+-- added by the algorithm: In this case, this vertex is added to all
+-- layouts on this stack.
+--
+-- @return A laid out graph.
+
+function Sublayouts.layoutRecursively(scope, layout, fun)
+
+ -- Step 1: Iterate over all sublayouts of the current layout:
+ local resulting_graphs = {}
+ local loc = Storage.new()
+
+ -- Now, iterate over all sublayouts
+ for i,child in ipairs(layout:childrenOfKind(InterfaceCore.sublayout_kind)) do
+ resulting_graphs[i] = Sublayouts.layoutRecursively(scope, child, fun)
+ loc[resulting_graphs[i]] = child
+ end
+
+ -- Step 2: Run the merge process:
+ local merged_graphs = {}
+
+ while #resulting_graphs > 0 do
+
+ local n = #resulting_graphs
+
+ -- Setup marked array:
+ local marked = {}
+ for i=1,n do
+ marked[i] = false
+ end
+
+ -- Mark first graph and copy everything from there
+ marked[1] = true
+ local touched = Storage.new()
+ for _,v in ipairs(resulting_graphs[1].vertices) do
+ v.pos = positions[v][resulting_graphs[1]]
+ touched[v] = true
+ end
+
+ -- Repeatedly find a node that is connected to a marked node:
+ local i = 1
+ while i <= n do
+ if not marked[i] then
+ for j=1,n do
+ if marked[j] then
+ local v = intersection(resulting_graphs[i], resulting_graphs[j])
+ if v then
+ -- Aha, they intersect at vertex v
+
+ -- Mark the i-th graph:
+ marked[i] = true
+ connected_some_graph = true
+
+ -- Shift the i-th graph:
+ local x_offset = v.pos.x - positions[v][resulting_graphs[i]].x
+ local y_offset = v.pos.y - positions[v][resulting_graphs[i]].y
+
+ for _,u in ipairs(resulting_graphs[i].vertices) do
+ if not touched[u] then
+ touched[u] = true
+ u.pos = positions[u][resulting_graphs[i]]:clone()
+ u.pos:shift(x_offset, y_offset)
+
+ for _,a in ipairs(resulting_graphs[i]:outgoing(u)) do
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,p in ipairs(e.path) do
+ if type(p) == "table" then
+ p:shift(x_offset, y_offset)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- Restart
+ i = 0
+ break
+ end
+ end
+ end
+ end
+ i = i + 1
+ end
+
+ -- Now, we can collapse all marked graphs into one graph:
+ local merge = Digraph.new {}
+ merge.syntactic_digraph = merge
+ local remaining = {}
+
+ -- Add all vertices and edges:
+ for i=1,n do
+ if marked[i] then
+ merge:add (resulting_graphs[i].vertices)
+ for _,a in ipairs(resulting_graphs[i].arcs) do
+ local ma = merge:connect(a.tail,a.head)
+ for _,e in ipairs(a.syntactic_edges) do
+ ma.syntactic_edges[#ma.syntactic_edges+1] = e
+ end
+ end
+ else
+ remaining[#remaining + 1] = resulting_graphs[i]
+ end
+ end
+
+ -- Remember the first layout this came from:
+ loc[merge] = loc[resulting_graphs[1]]
+
+ -- Restart with rest:
+ merged_graphs[#merged_graphs+1] = merge
+
+ resulting_graphs = remaining
+ end
+
+ -- Step 3: Run the algorithm on the layout:
+
+ local class = layout.options.algorithm_phases.main
+ assert (type(class) == "table", "algorithm selection failed")
+
+ local algorithm = class
+ local uncollapsed_subgraph_nodes = lib.imap(
+ scope.collections[InterfaceCore.subgraph_node_kind] or {},
+ function (c)
+ if c.parent_layout == layout then
+ return c.subgraph_node
+ end
+ end)
+
+
+ -- Create a new syntactic digraph:
+ local syntactic_digraph = Digraph.new {
+ options = layout.options
+ }
+
+ syntactic_digraph.syntactic_digraph = syntactic_digraph
+
+ -- Copy all vertices and edges from the collection...
+ syntactic_digraph:add (layout.vertices)
+ for _,e in ipairs(layout.edges) do
+ syntactic_digraph:add {e.head, e.tail}
+ local arc = syntactic_digraph:connect(e.tail, e.head)
+ arc.syntactic_edges[#arc.syntactic_edges+1] = e
+ end
+
+ -- Find out which subgraph nodes can be created now and make them part of the merged graphs
+ for i=#uncollapsed_subgraph_nodes,1,-1 do
+ local v = uncollapsed_subgraph_nodes[i]
+ local vertices = v.subgraph_collection.vertices
+ -- Test, if all vertices of the subgraph are in one of the merged graphs.
+ for _,g in ipairs(merged_graphs) do
+ if special_vertex_subset(vertices, g) then
+ -- Ok, we can create a subgraph now
+ create_subgraph_node(scope, syntactic_digraph, v)
+ -- Make it part of the collapse!
+ g:add{v}
+ -- Do not consider again
+ uncollapsed_subgraph_nodes[i] = false
+ break
+ end
+ end
+ end
+
+ -- Collapse the nodes that are part of a merged_graph
+ local collapsed_vertices = {}
+ for _,g in ipairs(merged_graphs) do
+
+ local intersection = {}
+ for _,v in ipairs(g.vertices) do
+ if syntactic_digraph:contains(v) then
+ intersection[#intersection+1] = v
+ end
+ end
+ if #intersection > 0 then
+ -- Compute bounding box of g (this should actually be the convex
+ -- hull) Hmm...:
+ local array = {}
+ for _,v in ipairs(g.vertices) do
+ local min_x, min_y, max_x, max_y = v:boundingBox()
+ array[#array+1] = Coordinate.new(min_x + v.pos.x, min_y + v.pos.y)
+ array[#array+1] = Coordinate.new(max_x + v.pos.x, max_y + v.pos.y)
+ end
+ for _,a in ipairs(g.arcs) do
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,p in ipairs(e.path) do
+ if type(p) == "table" then
+ array[#array+1] = p
+ end
+ end
+ end
+ end
+ local x_min, y_min, x_max, y_max, c_x, c_y = Coordinate.boundingBox(array)
+
+ -- Shift the graph so that it is centered on the origin:
+ for _,v in ipairs(g.vertices) do
+ v.pos:unshift(c_x,c_y)
+ end
+ for _,a in ipairs(g.arcs) do
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,p in ipairs(e.path) do
+ if type(p) == "table" then
+ p:unshift(c_x,c_y)
+ end
+ end
+ end
+ end
+
+ x_min = x_min - c_x
+ x_max = x_max - c_x
+ y_min = y_min - c_y
+ y_max = y_max - c_y
+
+ local index = loc[g].event.index
+
+ local v = Vertex.new {
+ -- Standard stuff
+ shape = "none",
+ kind = "node",
+ path = Path.new {
+ "moveto",
+ x_min, y_min,
+ x_min, y_max,
+ x_max, y_max,
+ x_max, y_min,
+ "closepath"
+ },
+ options = {},
+ event = scope.events[index]
+ }
+
+ -- Update node_event
+ scope.events[index].parameters = v
+
+ local collapse_vertex = syntactic_digraph:collapse(
+ intersection,
+ v,
+ nil,
+ function (new_arc, arc)
+ for _,e in ipairs(arc.syntactic_edges) do
+ new_arc.syntactic_edges[#new_arc.syntactic_edges+1] = e
+ end
+ end)
+
+ syntactic_digraph:remove(intersection)
+ collapsed_vertices[#collapsed_vertices+1] = collapse_vertex
+ end
+ end
+
+ -- Sort the vertices
+ table.sort(syntactic_digraph.vertices, function(u,v) return u.event.index < v.event.index end)
+
+ -- Should we "hide" the subgraph nodes?
+ local hidden_node
+ if not algorithm.include_subgraph_nodes then
+ local subgraph_nodes = lib.imap (syntactic_digraph.vertices,
+ function (v) if v.kind == "subgraph node" then return v end end)
+
+ if #subgraph_nodes > 0 then
+ hidden_node = Vertex.new {}
+ syntactic_digraph:collapse(subgraph_nodes, hidden_node)
+ syntactic_digraph:remove (subgraph_nodes)
+ syntactic_digraph:remove {hidden_node}
+ end
+ end
+
+ -- Now, we want to call the actual algorithm. This call may modify
+ -- the layout's vertices and edges fields, namely when new vertices
+ -- and edges are created. We then need to add these to our local
+ -- syntactic digraph. So, we remember the length of these fields
+ -- prior to the call and then add everything ``behind'' these
+ -- positions later on.
+
+ -- Ok, everything setup! Run the algorithm...
+ fun(scope, algorithm, syntactic_digraph, layout)
+
+ if hidden_node then
+ syntactic_digraph:expand(hidden_node)
+ end
+
+ -- Now, we need to expand the collapsed vertices once more:
+ for i=#collapsed_vertices,1,-1 do
+ syntactic_digraph:expand(
+ collapsed_vertices[i],
+ function (c, v)
+ v.pos:shiftByCoordinate(c.pos)
+ end,
+ function (a, v)
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,p in ipairs(e.path) do
+ if type(p) == "table" then
+ p:shiftByCoordinate(v.pos)
+ end
+ end
+ end
+ end
+ )
+ for _,a in ipairs(syntactic_digraph:outgoing(collapsed_vertices[i])) do
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,p in ipairs(e.path) do
+ if type(p) == "table" then
+ p:shiftByCoordinate(a.tail.pos)
+ p:unshiftByCoordinate(e.tail.pos)
+ end
+ end
+ end
+ end
+ end
+ syntactic_digraph:remove(collapsed_vertices)
+
+ -- Step 4: Create the layout node if necessary
+ for i=#uncollapsed_subgraph_nodes,1,-1 do
+ if uncollapsed_subgraph_nodes[i] then
+ create_subgraph_node(scope, syntactic_digraph, uncollapsed_subgraph_nodes[i])
+ end
+ end
+
+ -- Now seems like a good time to nudge and do regardless positioning
+ nudge(syntactic_digraph)
+
+ -- Step 5: Cleanup
+ -- Push the computed position into the storage:
+ for _,v in ipairs(syntactic_digraph.vertices) do
+ positions[v][syntactic_digraph] = v.pos:clone()
+ end
+
+ return syntactic_digraph
+end
+
+
+
+
+
+---
+-- Regardless positioning.
+--
+-- @param graph A graph
+--
+function Sublayouts.regardless(graph)
+ for _,v in ipairs(graph.vertices) do
+ local regardless = v.options['regardless at']
+ if regardless then
+ offset_vertex(v, regardless - v.pos)
+ end
+ end
+end
+
+
+
+-- Done
+
+return Sublayouts
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/doc.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/doc.lua
new file mode 100644
index 0000000000..19bfd52fdf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/doc.lua
@@ -0,0 +1,245 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "desired at"
+
+summary
+[[
+When you add this key to a node in a graph, you ``desire''
+that the node should be placed at the \meta{coordinate} by the graph
+drawing algorithm.
+]]
+
+documentation
+[[
+Now, when you set this key for a single node of a graph,
+then, by shifting the graph around, this ``wish'' can obviously
+always be fulfill:
+%
+\begin{codeexample}[preamble={ \usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{force}}]
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \graph [spring layout]
+ {
+ a [desired at={(1,2)}] -- b -- c -- a;
+ };
+\end{tikzpicture}
+\end{codeexample}
+%
+\begin{codeexample}[preamble={ \usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{force}}]
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \graph [spring layout]
+ {
+ a -- b[desired at={(2,1)}] -- c -- a;
+ };
+\end{tikzpicture}
+\end{codeexample}
+%
+Since the key's name is a bit long and since the many braces and
+parentheses are a bit cumbersome, there is a special support for
+this key inside a |graph|: The standard |/tikz/at| key is redefined
+inside a |graph| so that it points to |/graph drawing/desired at|
+instead. (Which is more logical anyway, since it makes no sense to
+specify an |at| position for a node whose position it to be computed
+by a graph drawing algorithm.) A nice side effect of this is that
+you can use the |x| and |y| keys (see
+Section~\ref{section-graphs-xy}) to specify desired positions:
+%
+\begin{codeexample}[preamble={ \usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{force}}]
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \graph [spring layout]
+ {
+ a -- b[x=2,y=0] -- c -- a;
+ };
+\end{tikzpicture}
+\end{codeexample}
+%
+\begin{codeexample}[preamble={ \usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{layered}}]
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \graph [layered layout]
+ {
+ a [x=1,y=2] -- { b, c } -- {e, f} -- a
+ };
+\end{tikzpicture}
+\end{codeexample}
+
+A problem arises when two or more nodes have this key set, because
+then your ``desires'' for placement and the positions computed by
+the graph drawing algorithm may clash. Graph drawing algorithms are
+``told'' about the desired positions. Most algorithms will simply
+ignore these desired positions since they will be taken care of in
+the so-called post-anchoring phase, see below. However, for some
+algorithms it makes a lot of sense to fix the positions of some
+nodes and only compute the positions of the other nodes relative
+to these nodes. For instance, for a |spring layout| it makes perfect
+sense that some nodes are ``nailed to the canvas'' while other
+nodes can ``move freely''.
+]]
+
+--[[
+% TODOsp: codeexamples: the following 3 examples need these libraries
+% \usetikzlibrary{graphs,graphdrawing}
+% \usegdlibrary{force}
+--]]
+example
+[[
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \graph [spring layout]
+ {
+ a[x=1] -- { b, c, d, e -- {f,g,h} };
+ { h, g } -- a;
+ };
+\end{tikzpicture}
+]]
+
+example
+[[
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \graph [spring layout]
+ {
+ a -- { b, c, d[x=0], e -- {f[x=2], g, h[x=1]} };
+ { h, g } -- a;
+ };
+\end{tikzpicture}
+]]
+
+example
+[[
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+ \graph [spring layout]
+ {
+ a -- { b, c, d[x=0], e -- {f[x=2,y=1], g, h[x=1]} };
+ { h, g } -- a;
+ };
+\end{tikzpicture}
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "anchor node"
+
+summary
+[[
+This option can be used with a graph to specify a node that
+should be used for anchoring the whole graph.
+]]
+
+documentation
+[[
+When this option is specified, after the layout has been computed, the
+whole graph will be shifted in such a way that the \meta{node name} is
+either
+%
+\begin{itemize}
+ \item at the current value of |anchor at| or
+ \item at the position that is specified in the form of a
+ |desired at| for the \meta{node name}.
+\end{itemize}
+%
+Note how in the last example |c| is placed at |(1,1)| rather than
+|b| as would happen by default.
+]]
+
+--[[
+% TODOsp: codeexamples: the following 4 examples need these libraries
+% \usetikzlibrary{graphs,graphdrawing}
+% \usegdlibrary{layered}
+--]]
+example
+[[
+\tikz \draw (0,0)
+ -- (1,0.5) graph [edges=red, layered layout, anchor node=a] { a -> {b,c} }
+ -- (1.5,0) graph [edges=blue, layered layout,
+ anchor node=y, anchor at={(2,0)}] { x -> {y,z} };
+]]
+
+example
+[[
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (3,2);
+
+ \graph [layered layout, anchor node=c, edges=rounded corners]
+ { a -- {b [x=1,y=1], c [x=1,y=1] } -- d -- a};
+\end{tikzpicture}
+]]
+--------------------------------------------------------------------
+
+
+
+
+--------------------------------------------------------------------
+key "anchor at"
+
+summary
+[[
+The coordinate at which the graph should be anchored when no
+explicit anchor is given for any node. The initial value is the origin.
+]]
+
+example
+[[
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (2,2);
+
+ \graph [layered layout, edges=rounded corners, anchor at={(1,2)}]
+ { a -- {b, c [anchor here] } -- d -- a};
+\end{tikzpicture}
+]]
+--------------------------------------------------------------------
+
+
+
+
+--------------------------------------------------------------------
+key "anchor here"
+
+summary
+[[
+This option can be passed to a single node (rather than the
+graph as a whole) in order to specify that this node should be used
+for the anchoring process.
+]]
+
+documentation
+[[
+In the example, |c| is placed at the origin since this is the
+default |anchor at| position.
+]]
+
+example
+[[
+\begin{tikzpicture}
+ \draw [help lines] (0,0) grid (2,2);
+
+ \graph [layered layout, edges=rounded corners]
+ { a -- {b, c [anchor here] } -- d -- a};
+\end{tikzpicture}
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/library.lua
new file mode 100644
index 0000000000..df7ce68dd9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/control/library.lua
@@ -0,0 +1,196 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Load declarations from:
+
+require "pgf.gd.control.FineTune"
+require "pgf.gd.control.Anchoring"
+require "pgf.gd.control.Sublayouts"
+require "pgf.gd.control.Orientation"
+require "pgf.gd.control.Distances"
+require "pgf.gd.control.Components"
+require "pgf.gd.control.ComponentAlign"
+require "pgf.gd.control.ComponentDirection"
+require "pgf.gd.control.ComponentDistance"
+require "pgf.gd.control.ComponentOrder"
+require "pgf.gd.control.NodeAnchors"
+
+
+local InterfaceCore = require "pgf.gd.interface.InterfaceCore"
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local lib = require "pgf.gd.lib"
+
+
+
+---
+
+declare {
+ key = "nodes behind edges",
+ type = "boolean",
+
+ summary = "Specifies, that nodes should be drawn behind the edges",
+ documentation = [["
+ Once a graph drawing algorithm has determined positions for the nodes,
+ they are drawn \emph{before} the edges are drawn; after
+ all, it is hard to draw an edge between nodes when their positions
+ are not yet known. However, we typically want the nodes to be
+ rendered \emph{after} or rather \emph{on top} of the edges. For
+ this reason, the default behavior is that the nodes at their
+ final positions are collected in a box that is inserted into the
+ output stream only after the edges have been drawn -- which has
+ the effect that the nodes will be placed ``on top'' of the
+ edges.
+
+ This behavior can be changed using this option. When the key is
+ invoked, nodes are placed \emph{behind} the edges.
+ "]],
+ examples = [["
+ \tikz \graph [simple necklace layout, nodes={draw,fill=white},
+ nodes behind edges]
+ { subgraph K_n [n=7], 1 [regardless at={(0,-1)}] };
+ "]]
+}
+
+
+---
+
+declare {
+ key = "edges behind nodes",
+ use = {
+ { key = "nodes behind edges", value = "false" },
+ },
+
+ summary = [["
+ This is the default placement of edges: Behind the nodes.
+ "]],
+ examples = [["
+ \tikz \graph [simple necklace layout, nodes={draw,fill=white},
+ edges behind nodes]
+ { subgraph K_n [n=7], 1 [regardless at={(0,-1)}] };
+ "]]
+}
+
+---
+declare {
+ key = "random seed",
+ type = "number",
+ initial = "42",
+
+ summary = [["
+ To ensure that the same is always shown in the same way when the
+ same algorithm is applied, the random is seed is reset on each call
+ of the graph drawing engine. To (possibly) get different results on
+ different runs, change this value.
+ "]]
+}
+
+
+---
+declare {
+ key = "variation",
+ type = "number",
+ use = {
+ { key = "random seed", value = lib.id },
+ },
+ summary = "An alias for |random seed|."
+}
+
+
+---
+declare {
+ key = "weight",
+ type = "number",
+ initial = 1,
+
+ summary = [["
+ Sets the ``weight'' of an edge or a node. For many algorithms, this
+ number tells the algorithm how ``important'' the edge or node is.
+ For instance, in a |layered layout|, an edge with a large |weight|
+ will be as short as possible.
+ "]],
+ examples = {[["
+ \tikz \graph [layered layout] {
+ a -- {b,c,d} -- e -- a;
+ };
+ "]],[["
+ \tikz \graph [layered layout] {
+ a -- {b,c,d} -- e --[weight=3] a;
+ };
+ "]]
+ }
+}
+
+
+
+---
+declare {
+ key = "length",
+ type = "length",
+ initial = 1,
+
+ summary = [["
+ Sets the ``length'' of an edge. Algorithms may take this value
+ into account when drawing a graph.
+ "]],
+ examples = {[["
+ \tikz \graph [phylogenetic tree layout] {
+ a --[length=2] b --[length=1] {c,d};
+ a --[length=3] e
+ };
+ "]],
+ }
+}
+
+
+---
+
+declare {
+ key = "radius",
+ type = "number",
+ initial = "0",
+
+ summary = [["
+ The radius of a circular object used in graph drawing.
+ "]]
+}
+
+---
+
+declare {
+ key = "no layout",
+ algorithm = {
+ run =
+ function (self)
+ for _,v in ipairs(self.digraph.vertices) do
+ if v.options['desired at'] then
+ v.pos.x = v.options['desired at'].x
+ v.pos.y = v.options['desired at'].y
+ end
+ end
+ end },
+ summary = "This layout does nothing.",
+}
+
+
+
+-- The following collection kinds are internal
+
+declare {
+ key = InterfaceCore.sublayout_kind,
+ layer = 0
+}
+
+declare {
+ key = InterfaceCore.subgraph_node_kind,
+ layer = 0
+}
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua
new file mode 100644
index 0000000000..d7baed45da
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua
@@ -0,0 +1,65 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+--- The Cluster class defines a model of a cluster inside a graph.
+--
+--
+
+local Cluster = {}
+Cluster.__index = Cluster
+
+
+-- Namespace
+
+
+
+--- TODO Jannis: Add documentation for this class.
+--
+function Cluster.new(name)
+ local cluster = {
+ name = name,
+ nodes = {},
+ contains_node = {},
+ }
+ setmetatable(cluster, Cluster)
+ return cluster
+end
+
+
+
+function Cluster:getName()
+ return self.name
+end
+
+
+
+function Cluster:addNode(node)
+ if not self:findNode(node) then
+ self.contains_node[node] = true
+ self.nodes[#self.nodes + 1] = node
+ end
+end
+
+
+
+function Cluster:findNode(node)
+ return self.contains_node[node]
+end
+
+
+
+
+-- Done
+
+return Cluster \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Edge.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Edge.lua
new file mode 100644
index 0000000000..7355597955
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Edge.lua
@@ -0,0 +1,358 @@
+-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+--- The Edge class
+--
+--
+
+local Edge = {}
+Edge.__index = Edge
+
+
+-- Namespace
+
+local lib = require "pgf.gd.lib"
+
+
+-- Definitions
+
+Edge.UNDIRECTED = "--"
+Edge.LEFT = "<-"
+Edge.RIGHT = "->"
+Edge.BOTH = "<->"
+Edge.NONE = "-!-"
+
+
+--- Creates an edge between nodes of a graph.
+--
+-- @param values Values to override default edge settings.
+-- The following parameters can be set:\par
+-- |nodes|: TODO \par
+-- |edge_nodes|: TODO \par
+-- |options|: TODO \par
+-- |tikz_options|: TODO \par
+-- |direction|: TODO \par
+-- |bend_points|: TODO \par
+-- |bend_nodes|: TODO \par
+-- |reversed|: TODO \par
+--
+-- @return A newly-allocated edge.
+--
+function Edge.new(values)
+ local defaults = {
+ nodes = {},
+ edge_nodes = '',
+ options = {},
+ tikz_options = {},
+ direction = Edge.DIRECTED,
+ bend_points = {},
+ bend_nodes = {},
+ reversed = false,
+ algorithmically_generated_options = {},
+ index = nil,
+ event_index = nil,
+ }
+ setmetatable(defaults, Edge)
+ if values then
+ for k,v in pairs(values) do
+ defaults[k] = v
+ end
+ end
+ return defaults
+end
+
+
+
+--- Sets the edge option \meta{name} to \meta{value}.
+--
+-- @param name Name of the option to be changed.
+-- @param value New value for the edge option \meta{name}.
+--
+function Edge:setOption(name, value)
+ self.options[name] = value
+end
+
+
+
+--- Returns the value of the edge option \meta{name}.
+--
+-- @param name Name of the option.
+-- @param graph If this optional argument is given,
+-- in case the option is not set as a node parameter,
+-- we try to look it up as a graph parameter.
+--
+-- @return The value of the edge option \meta{name} or |nil|.
+--
+function Edge:getOption(name, graph)
+ return lib.lookup_option(name, self, graph)
+end
+
+
+
+--- Checks whether or not the edge is a loop edge.
+--
+-- An edge is a loop if it one node multiple times and no other node.
+--
+-- @return |true| if the edge is a loop, |false| otherwise.
+--
+function Edge:isLoop()
+ local nodes = self.nodes
+ for i=1,#nodes do
+ if nodes[i] ~= nodes[1] then
+ return false
+ end
+ end
+ return true
+end
+
+
+
+--- Returns whether or not the edge is a hyperedge.
+--
+-- A hyperedge is an edge with more than two adjacent nodes.
+--
+-- @return |true| if the edge is a hyperedge. |false| otherwise.
+--
+function Edge:isHyperedge()
+ return self:getDegree() > 2
+end
+
+
+
+--- Returns all nodes of the edge.
+--
+-- Instead of calling |edge:getNodes()| the nodes can alternatively be
+-- accessed directly with |edge.nodes|.
+--
+-- @return All edges of the node.
+--
+function Edge:getNodes()
+ return self.nodes
+end
+
+
+
+--- Returns whether or not a node is adjacent to the edge.
+--
+-- @param node The node to check.
+--
+-- @return |true| if the node is adjacent to the edge. |false| otherwise.
+--
+function Edge:containsNode(node)
+ return lib.find(self.nodes, function (other) return other == node end) ~= nil
+end
+
+
+
+--- If possible, adds a node to the edge.
+--
+-- @param node The node to be added to the edge.
+--
+function Edge:addNode(node)
+ table.insert(self.nodes, node)
+ node:addEdge(self)
+end
+
+
+
+--- Gets first neighbor of the node (disregarding hyperedges).
+--
+-- @param node The node which first neighbor should be returned.
+--
+-- @return The first neighbor of the node.
+--
+function Edge:getNeighbour(node)
+ if node == self.nodes[1] then
+ return self.nodes[#self.nodes]
+ else
+ return self.nodes[1]
+ end
+end
+
+
+
+--- Counts the nodes on this edge.
+--
+-- @return The number of nodes on the edge.
+--
+function Edge:getDegree()
+ return #self.nodes
+end
+
+
+
+function Edge:getHead()
+ -- by default, the head of -> edges is the last node and the head
+ -- of <- edges is the first node
+ local head_index = (self.direction == Edge.LEFT) and 1 or #self.nodes
+
+ -- if the edge should be assumed reversed, we simply switch head and
+ -- tail positions
+ if self.reversed then
+ head_index = (head_index == 1) and #self.nodes or 1
+ end
+
+ return self.nodes[head_index]
+end
+
+
+
+function Edge:getTail()
+ -- by default, the tail of -> edges is the first node and the tail
+ -- of <- edges is the last node
+ local tail_index = (self.direction == Edge.LEFT) and #self.nodes or 1
+
+ -- if the edge should be assumed reversed, we simply switch head
+ -- and tail positions
+ if self.reversed then
+ tail_index = (tail_index == 1) and #self.nodes or 1
+ end
+
+ return self.nodes[tail_index]
+end
+
+
+
+--- Checks whether a node is the head of the edge. Does not work for hyperedges.
+--
+-- This method only works for edges with two adjacent nodes.
+--
+-- Edges may be reversed internally, so their head and tail might be switched.
+-- Whether or not this internal reversal is handled by this method
+-- can be specified with the optional second \meta{ignore\_reversed} parameter
+-- which is |false| by default.
+--
+-- @param node The node to check.
+--
+-- @return True if the node is the head of the edge.
+--
+function Edge:isHead(node)
+ local result = false
+
+ -- by default, the head of -> edges is the last node and the head
+ -- of <- edges is the first node
+ local head_index = (self.direction == Edge.LEFT) and 1 or #self.nodes
+
+ -- if the edge should be assumed reversed, we simply switch head and
+ -- tail positions
+ if self.reversed then
+ head_index = (head_index == 1) and #self.nodes or 1
+ end
+
+ -- check if the head node equals the input node
+ if self.nodes[head_index].name == node.name then
+ result = true
+ end
+
+ return result
+end
+
+
+
+--- Checks whether a node is the tail of the edge. Does not work for hyperedges.
+--
+-- This method only works for edges with two adjacent nodes.
+--
+-- Edges may be reversed internally, so their head and tail might be switched.
+-- Whether or not this internal reversal is handled by this method
+-- can be specified with the optional second \meta{ignore\_reversed} parameter
+-- which is |false| by default.
+--
+-- @param node The node to check.
+-- @param ignore_reversed Optional parameter. Set this to true if reversed edges
+-- should not be considered reversed for this method call.
+--
+-- @return True if the node is the tail of the edge.
+--
+function Edge:isTail(node, ignore_reversed)
+ local result = false
+
+ -- by default, the tail of -> edges is the first node and the tail
+ -- of <- edges is the last node
+ local tail_index = (self.direction == Edge.LEFT) and #self.nodes or 1
+
+ -- if the edge should be assumed reversed, we simply switch head
+ -- and tail positions
+ if self.reversed then
+ tail_index = (tail_index == 1) and #self.nodes or 1
+ end
+
+ -- check if the tail node equals the input node
+ if self.nodes[tail_index].name == node.name then
+ result = true
+ end
+
+ return result
+end
+
+
+
+--- Copies an edge (preventing accidental use).
+--
+-- The nodes of the edge are not preserved and have to be added
+-- to the copy manually if necessary.
+--
+-- @return Shallow copy of the edge.
+--
+function Edge:copy()
+ local result = lib.copy(self, Edge.new())
+ result.nodes = {}
+ return result
+ end
+
+
+
+
+local function reverse_values(source)
+ local copy = {}
+ for i = 1,#source do
+ copy[i] = source[#source-i+1]
+ end
+ return copy
+end
+
+
+--- Returns a readable string representation of the edge.
+--
+-- @ignore This should not appear in the documentation.
+--
+-- @return String representation of the edge.
+--
+function Edge:__tostring()
+ local result = "Edge(" .. self.direction .. ", reversed = " .. tostring(self.reversed) .. ", "
+ if #self.nodes > 0 then
+ local node_strings = lib.imap(self.nodes, function (node) return node.name end)
+ result = result .. table.concat(node_strings, ', ')
+ end
+ --return result .. ")"
+
+ -- Note: the following lines generate a shorter string representation
+ -- of the edge that is more readable and can be used for debugging.
+ -- So please don't remove this:
+ --
+ local node_strings = lib.imap(self.nodes, function (node) return node.name end)
+ if self.reversed then
+ return table.concat(reverse_values(node_strings), ' ' .. self.direction .. ' ')
+ else
+ return table.concat(node_strings, ' ' .. self.direction .. ' ')
+ end
+end
+
+
+
+-- Done
+
+return Edge \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Graph.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Graph.lua
new file mode 100644
index 0000000000..161b89fd15
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Graph.lua
@@ -0,0 +1,396 @@
+-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+--- The Graph class
+--
+--
+
+local Graph = {}
+Graph.__index = Graph
+
+
+-- Namespace
+
+-- Imports
+local Edge = require "pgf.gd.deprecated.Edge"
+
+local lib = require "pgf.gd.lib"
+
+
+--- Creates a new graph.
+--
+-- @param values Values to override default graph settings.
+-- The following parameters can be set:\par
+-- |nodes|: The nodes of the graph.\par
+-- |edges|: The edges of the graph.\par
+-- |clusters|: The node clusters of the graph.\par
+-- |options|: A table of node options passed over from \tikzname.
+-- |events|: A sequence of events signaled during the graph specification.
+--
+-- @return A newly-allocated graph.
+--
+function Graph.new(values)
+ local defaults = {
+ nodes = {},
+ edges = {},
+ clusters = {},
+ options = {},
+ events = {},
+ }
+ setmetatable(defaults, Graph)
+ if values then
+ for k,v in pairs(values) do
+ defaults[k] = v
+ end
+ end
+ return defaults
+end
+
+
+
+--- Prepares a graph for an algorithm.
+--
+-- This method causes self, all its nodes, and all its edges to get
+-- a new empty table for the key algorithm. This allows an algorithm to
+-- store stuff with nodes and edges without them interfering with information
+-- stored by other algorithms.
+--
+-- @param An algorithm object.
+
+function Graph:registerAlgorithm(algorithm)
+ self[algorithm] = self[algorithm] or {}
+
+ -- Add an algorithm field to all nodes, all edges, and the graph:
+ for _,n in pairs(self.nodes) do
+ n[algorithm] = n[algorithm] or {}
+ end
+ for _,e in pairs(self.edges) do
+ e[algorithm] = e[algorithm] or {}
+ end
+end
+
+
+--- Sets the graph option \meta{name} to \meta{value}.
+--
+-- @param name Name of the option to be changed.
+-- @param value New value for the graph option \meta{name}.
+--
+function Graph:setOption(name, value)
+ self.options[name] = value
+end
+
+
+
+--- Returns the value of the graph option \meta{name}.
+--
+-- @param name Name of the option.
+--
+-- @return The value of the graph option \meta{name} or |nil|.
+--
+function Graph:getOption(name)
+ return self.options[name]
+end
+
+
+
+
+--- Creates a shallow copy of a graph.
+--
+-- The nodes and edges of the original graph are not preserved in the copy.
+--
+-- @return A shallow copy of the graph.
+--
+function Graph:copy ()
+ return Graph.new({options = self.options, events = self.events})
+end
+
+
+--- Adds a node to the graph.
+--
+-- @param node The node to be added.
+--
+function Graph:addNode(node)
+ -- only add the node if it's not included in the graph yet
+ if not self:findNode(node.name) then
+ -- Does the node have an index, yet?
+ if not node.index then
+ node.index = #self.nodes + 1
+ end
+
+ table.insert(self.nodes, node)
+ end
+end
+
+
+
+--- If possible, removes a node from the graph and returns it.
+--
+-- @param node The node to remove.
+--
+-- @return The removed node or |nil| if it was not found in the graph.
+--
+function Graph:removeNode(node)
+ local _, index = lib.find(self.nodes, function (other)
+ return other.name == node.name
+ end)
+ if index then
+ table.remove(self.nodes, index)
+ return node
+ else
+ return nil
+ end
+end
+
+
+
+--- If possible, looks up the node with the given name in the graph.
+--
+-- @param name Name of the node to look up.
+--
+-- @return The node with the given name or |nil| if it was not found in the graph.
+--
+function Graph:findNode(name)
+ return self:findNodeIf(function (node) return node.name == name end)
+end
+
+
+
+--- Looks up the first node for which the function \meta{test} returns |true|.
+--
+-- @param test A function that takes one parameter (a |Node|) and returns
+-- |true| or |false|.
+--
+-- @return The first node for which \meta{test} returns |true|.
+--
+function Graph:findNodeIf(test)
+ return lib.find(self.nodes, test)
+end
+
+
+
+--- Like removeNode, but also deletes all adjacent edges of the removed node.
+--
+-- This function also removes the deleted adjacent edges from all neighbors
+-- of the removed node.
+--
+-- @param node The node to be deleted together with its adjacent edges.
+--
+-- @return The removed node or |nil| if the node was not found in the graph.
+--
+function Graph:deleteNode(node)
+ local node = self:removeNode(node)
+ if node then
+ for _,edge in ipairs(node.edges) do
+ self:removeEdge(edge)
+ for _,other_node in ipairs(edge.nodes) do
+ if other_node.name ~= node.name then
+ other_node:removeEdge(edge)
+ end
+ end
+ end
+ node.edges = {}
+ end
+ return node
+end
+
+
+
+-- Checks whether the edge already exists in the graph and returns it if possible.
+--
+-- @param edge Edge to search for.
+--
+-- @return The edge if it was found in the graph, |nil| otherwise.
+--
+function Graph:findEdge(edge)
+ return lib.find(self.edges, function (other) return other == edge end)
+end
+
+
+
+--- Adds an edge to the graph.
+--
+-- @param edge The edge to be added.
+--
+function Graph:addEdge(edge)
+ if not edge.index then
+ edge.index = #self.edges + 1
+ end
+
+ table.insert(self.edges, edge)
+end
+
+
+
+--- If possible, removes an edge from the graph and returns it.
+--
+-- @param edge The edge to be removed.
+--
+-- @return The removed edge or |nil| if it was not found in the graph.
+--
+function Graph:removeEdge(edge)
+ local _, index = lib.find(self.edges, function (other) return other == edge end)
+ if index then
+ table.remove(self.edges, index)
+ return edge
+ else
+ return nil
+ end
+end
+
+
+
+--- Like removeEdge, but also removes the edge from its adjacent nodes.
+--
+-- @param edge The edge to be deleted.
+--
+-- @return The removed edge or |nil| if it was not found in the graph.
+--
+function Graph:deleteEdge(edge)
+ local edge = self:removeEdge(edge)
+ if edge then
+ for _,node in ipairs(edge.nodes) do
+ node:removeEdge(edge)
+ end
+ end
+ return edge
+end
+
+
+
+--- Removes an edge between two nodes and also removes it from these nodes.
+--
+-- @param from Start node of the edge.
+-- @param to End node of the edge.
+--
+-- @return The deleted edge.
+--
+function Graph:deleteEdgeBetweenNodes(from, to)
+ -- try to find the edge
+ local edge = lib.find(self.edges, function (edge)
+ return edge.nodes[1] == from and edge.nodes[2] == to
+ end)
+
+ -- delete and return the edge
+ if edge then
+ return self:deleteEdge(edge)
+ else
+ return nil
+ end
+end
+
+
+
+--- Creates and adds a new edge to the graph.
+--
+-- @param first_node The first node of the new edge.
+-- @param second_node The second node of the new edge.
+-- @param direction The direction of the new edge. Possible values are
+-- \begin{itemize}
+-- \item |Edge.UNDIRECTED|,
+-- \item |Edge.LEFT|,
+-- \item |Edge.RIGHT|,
+-- \item |Edge.BOTH| and
+-- \item |Edge.NONE| (for invisible edges).
+-- \end{itemize}
+-- @param edge_nodes A string of \tikzname\ edge nodes that needs to be passed
+-- back to the \TeX layer unmodified.
+-- @param options The options of the new edge.
+-- @param tikz_options A table of \tikzname\ options to be used by graph drawing
+-- algorithms to treat the edge in special ways.
+--
+-- @return The newly created edge.
+--
+function Graph:createEdge(first_node, second_node, direction, edge_nodes, options, tikz_options)
+ local edge = Edge.new{
+ direction = direction,
+ edge_nodes = edge_nodes,
+ options = options,
+ tikz_options = tikz_options
+ }
+ edge:addNode(first_node)
+ edge:addNode(second_node)
+ self:addEdge(edge)
+ return edge
+end
+
+
+
+--- Returns the cluster with the given name or |nil| if no such cluster exists.
+--
+-- @param name Name of the node cluster to look up.
+--
+-- @return The cluster with the given name or |nil| if no such cluster is defined.
+--
+function Graph:findClusterByName(name)
+ return lib.find(self.clusters, function (cluster)
+ return cluster.name == name
+ end)
+end
+
+
+
+--- Tries to add a cluster to the graph. Returns whether or not this was successful.
+--
+-- Clusters are supposed to have unique names. This function will add the given
+-- cluster only if there is no cluster with this name already. It returns |true|
+-- if the cluster was added and |false| otherwise.
+--
+-- @param cluster Cluster to add to the graph.
+--
+-- @return |true| if the cluster was added successfully, |false| otherwise.
+--
+function Graph:addCluster(cluster)
+ if not self:findClusterByName(cluster.name) then
+ table.insert(self.clusters, cluster)
+ end
+end
+
+
+
+
+
+--- Returns a string representation of this graph including all nodes and edges.
+--
+-- @ignore This should not appear in the documentation.
+--
+-- @return Graph as string.
+--
+function Graph:__tostring()
+ local tmp = Graph.__tostring
+ Graph.__tostring = nil
+ local result = "Graph<" .. tostring(self) .. ">(("
+ Graph.__tostring = tmp
+
+ local first = true
+ for _,node in ipairs(self.nodes) do
+ if first then first = false else result = result .. ", " end
+ result = result .. tostring(node)
+ end
+ result = result .. "), ("
+ first = true
+ for _,edge in ipairs(self.edges) do
+ if first then first = false else result = result .. ", " end
+ result = result .. tostring(edge)
+ end
+
+ return result .. "))"
+end
+
+
+
+-- Done
+
+return Graph
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua
new file mode 100644
index 0000000000..903291a892
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua
@@ -0,0 +1,91 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+--- The Iterators class is a singleton object.
+--
+-- It provides advanced iterators.
+
+local Iterators = {}
+
+-- Namespace
+
+local lib = require("pgf.gd.lib")
+
+
+
+--- Iterator for traversing a \meta{dag} using a topological sorting.
+--
+-- A topological sorting of a directed graph is a linear ordering of its
+-- nodes such that, for every edge |(u,v)|, |u| comes before |v|.
+--
+-- Important note: if performed on a graph with at least one cycle a
+-- topological sorting is impossible. Thus, the nodes returned from the
+-- iterator are not guaranteed to satisfy the ``|u| comes before |v|''
+-- criterion. The iterator may even terminate early or loop forever.
+--
+-- @param graph A directed acyclic graph.
+--
+-- @return An iterator for traversing \meta{graph} in a topological order.
+--
+function Iterators.topologicallySorted(dag)
+ -- track visited edges
+ local deleted_edges = {}
+
+ -- collect all sources (nodes with no incoming edges) of the dag
+ local sources = lib.imap(dag.nodes, function (node) if node:getInDegree() == 0 then return node end end)
+
+ -- return the iterator function
+ return function ()
+ while #sources > 0 do
+ -- fetch the next sink from the queue
+ local source = table.remove(sources, 1)
+
+ -- get its outgoing edges
+ local out_edges = source:getOutgoingEdges()
+
+ -- iterate over all outgoing edges we haven't visited yet
+ for _,edge in ipairs(out_edges) do
+ if not deleted_edges[edge] then
+ -- mark the edge as visited
+ deleted_edges[edge] = true
+
+ -- get the node at the other end of the edge
+ local neighbour = edge:getNeighbour(source)
+
+ -- get a list of all incoming edges of the neighbor that have
+ -- not been visited yet
+ local in_edges = lib.imap(neighbour:getIncomingEdges(),
+ function (edge) if not deleted_edges[edge] then return edge end end)
+
+ -- if there are no such edges then we have a new source
+ if #in_edges == 0 then
+ sources[#sources+1] = neighbour
+ end
+ end
+ end
+
+ -- return the current source
+ return source
+ end
+
+ -- the iterator terminates if there are no sources left
+ return nil
+ end
+end
+
+
+
+-- Done
+
+return Iterators
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Node.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Node.lua
new file mode 100644
index 0000000000..379a65fafd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Node.lua
@@ -0,0 +1,280 @@
+-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+--- The Node class
+--
+--
+
+local Node = {}
+Node.__index = Node
+
+
+-- Namespace
+
+local lib = require "pgf.gd.lib"
+
+
+-- Imports
+
+local Vector = require "pgf.gd.deprecated.Vector"
+
+
+
+--- Creates a new node.
+--
+-- @param values Values to override default node settings.
+-- The following parameters can be set:\par
+-- |name|: The name of the node. It is obligatory to define this.\par
+-- |tex|: Information about the corresponding \TeX\ node.\par
+-- |edges|: Edges adjacent to the node.\par
+-- |pos|: Initial position of the node.\par
+-- |options|: A table of node options passed over from \tikzname.
+--
+-- @return A newly allocated node.
+--
+function Node.new(values)
+ local new = {
+ class = Node,
+ name = nil,
+ tex = {
+ -- texNode = nil,
+ -- maxX = nil,
+ -- minX = nil,
+ -- maxY = nil,
+ -- minY = nil
+ },
+ edges = {},
+ -- pos = nil,
+ options = {},
+ -- growth_direction = nil,
+ -- index = nil,
+ -- event_index = nil,
+ kind = "node",
+ }
+ setmetatable(new, Node)
+ if values then
+ for k,v in pairs(values) do
+ new [k] = v
+ end
+ end
+ if not new.pos then
+ new.pos = Vector.new(2)
+ end
+ return new
+end
+
+
+
+--- Sets the node option \meta{name} to \meta{value}.
+--
+-- @param name Name of the node option to be changed.
+-- @param value New value for the node option \meta{name}.
+--
+function Node:setOption(name, value)
+ self.options[name] = value
+end
+
+
+
+--- Returns the value of the node option \meta{name}.
+--
+-- @param name Name of the node option.
+-- @param graph If this optional argument is given,
+-- in case the option is not set as a node parameter,
+-- we try to look it up as a graph parameter.
+--
+-- @return The value of the node option \meta{name} or |nil|.
+--
+function Node:getOption(name, graph)
+ return lib.lookup_option(name, self, graph)
+end
+
+
+
+--- Computes the width of the node.
+--
+-- @return Width of the node.
+--
+function Node:getTexWidth()
+ return math.abs(self.tex.maxX - self.tex.minX)
+end
+
+
+
+--- Computes the height of the node.
+--
+-- @return Height of the node.
+--
+function Node:getTexHeight()
+ return math.abs(self.tex.maxY - self.tex.minY)
+end
+
+
+
+--- Adds new edge to the node.
+--
+-- @param edge The edge to be added.
+--
+function Node:addEdge(edge)
+ table.insert(self.edges, edge)
+end
+
+
+
+--- Removes an edge from the node.
+--
+-- @param edge The edge to remove.
+--
+function Node:removeEdge(edge)
+ self.edges = lib.imap (self.edges, function(other) if other ~= edge then return other end end)
+end
+
+
+
+--- Counts the adjacent edges of the node.
+--
+-- @return The number of adjacent edges of the node.
+--
+function Node:getDegree()
+ return #self.edges
+end
+
+
+
+--- Returns all edges of the node.
+--
+-- Instead of calling |node:getEdges()| the edges can alternatively be
+-- accessed directly with |node.edges|.
+--
+-- @return All edges of the node.
+--
+function Node:getEdges()
+ return self.edges
+end
+
+
+
+--- Returns the incoming edges of the node. Undefined result for hyperedges.
+--
+-- @param ignore_reversed Optional parameter to consider reversed edges not
+-- reversed for this method call. Defaults to |false|.
+--
+-- @return Incoming edges of the node. This includes undirected edges
+-- and directed edges pointing to the node.
+--
+function Node:getIncomingEdges(ignore_reversed)
+ return lib.imap(self.edges,
+ function (edge)
+ if edge:isHead(self, ignore_reversed) then return edge end
+ end)
+end
+
+
+
+--- Returns the outgoing edges of the node. Undefined result for hyperedges.
+--
+-- @param ignore_reversed Optional parameter to consider reversed edges not
+-- reversed for this method call. Defaults to |false|.
+--
+-- @return Outgoing edges of the node. This includes undirected edges
+-- and directed edges leaving the node.
+--
+function Node:getOutgoingEdges(ignore_reversed)
+ return lib.imap(self.edges,
+ function (edge)
+ if edge:isTail(self, ignore_reversed) then return edge end
+ end)
+end
+
+
+
+--- Returns the number of incoming edges of the node.
+--
+-- @see Node:getIncomingEdges(reversed)
+--
+-- @param ignore_reversed Optional parameter to consider reversed edges not
+-- reversed for this method call. Defaults to |false|.
+--
+-- @return The number of incoming edges of the node.
+--
+function Node:getInDegree(ignore_reversed)
+ return #self:getIncomingEdges(ignore_reversed)
+end
+
+
+
+--- Returns the number of edges starting at the node.
+--
+-- @see Node:getOutgoingEdges()
+--
+-- @param ignore_reversed Optional parameter to consider reversed edges not
+-- reversed for this method call. Defaults to |false|.
+--
+-- @return The number of outgoing edges of the node.
+--
+function Node:getOutDegree(ignore_reversed)
+ return #self:getOutgoingEdges(ignore_reversed)
+end
+
+
+
+--- Creates a shallow copy of the node.
+--
+-- Most notably, the edges adjacent are not preserved in the copy.
+--
+-- @return Copy of the node.
+--
+function Node:copy()
+ local result = lib.copy(self, Node.new())
+ result.edges = {}
+ return result
+end
+
+
+
+--- Compares two nodes by their name.
+--
+-- @ignore This should not appear in the documentation.
+--
+-- @param other Another node to compare with.
+--
+-- @return |true| if both nodes have the same name. |false| otherwise.
+--
+function Node:__eq(object)
+ return self.name == object.name
+end
+
+
+
+--- Returns a formated string representation of the node.
+--
+-- @ignore This should not appear in the documentation.
+--
+-- @return String representation of the node.
+--
+function Node:__tostring()
+ local tmp = Node.__tostring
+ Node.__tostring = nil
+ local result = "Node<" .. tostring(self) .. ">(" .. self.name .. ")"
+ Node.__tostring = tmp
+ return result
+end
+
+
+
+
+-- Done
+
+return Node
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Vector.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Vector.lua
new file mode 100644
index 0000000000..8af7378154
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/deprecated/Vector.lua
@@ -0,0 +1,256 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+--- Vector class
+--
+-- This class augments a normal array so that:
+--
+-- 1) Several functions like "plus" or "normalize" become available.
+-- 2) You can access the ".x" and ".y" fields to get the fields [1] and [2].
+
+local Vector = {}
+
+
+-- Namespace:
+local lib = require "pgf.gd.lib"
+lib.Vector = Vector
+
+
+-- Class setup
+Vector.__index =
+ function (t, k)
+ if k == "x" then
+ return rawget(t,1)
+ elseif k == "y" then
+ return rawget(t,2)
+ else
+ return rawget(Vector,k)
+ end
+ end
+Vector.__newindex =
+ function (t, k, v)
+ if k == "x" then
+ rawset(t,1,v)
+ elseif k == "y" then
+ rawset(t,2,v)
+ else
+ rawset(t,k,v)
+ end
+ end
+
+
+
+--- Creates a new vector with \meta{n} values using an optional \meta{fill\_function}.
+--
+-- @param n The number of elements of the vector. (If omitted, then 2.)
+-- @param fill_function Optional function that takes a number between 1 and \meta{n}
+-- and is expected to return a value for the corresponding element
+-- of the vector. If omitted, all elements of the vector will
+-- be initialized with 0.
+--
+-- @return A newly-allocated vector with \meta{n} elements.
+--
+function Vector.new(n, fill_function)
+ -- create vector
+ local vector = { }
+ setmetatable(vector, Vector)
+
+ local n = n or 2
+
+ if type(n) == 'table' then
+ for k,v in pairs(n) do
+ vector[k] = v
+ end
+ else
+ -- fill vector elements with values
+ if not fill_function then
+ for i = 1,n do
+ rawset(vector,i,0)
+ end
+ else
+ for i = 1,n do
+ rawset(vector,i,fill_function(i))
+ end
+ end
+ end
+
+ return vector
+end
+
+
+
+--- Creates a copy of the vector that holds the same elements as the original.
+--
+-- @return A newly-allocated copy of the vector holding exactly the same elements.
+--
+function Vector:copy()
+ return Vector.new(#self, function (n) return self[n] end)
+end
+
+
+
+--- Performs a vector addition and returns the result in a new vector.
+--
+-- @param other The vector to add.
+--
+-- @return A new vector with the result of the addition.
+--
+function Vector:plus(other)
+ assert(#self == #other)
+
+ return Vector.new(#self, function (n) return self[n] + other[n] end)
+end
+
+
+
+--- Subtracts two vectors and returns the result in a new vector.
+--
+-- @param other Vector to subtract.
+--
+-- @return A new vector with the result of the subtraction.
+--
+function Vector:minus(other)
+ assert(#self == #other)
+
+ return Vector.new(#self, function (n) return self[n] - other[n] end)
+end
+
+
+
+--- Divides a vector by a scalar value and returns the result in a new vector.
+--
+-- @param scalar Scalar value to divide the vector by.
+--
+-- @return A new vector with the result of the division.
+--
+function Vector:dividedByScalar(scalar)
+ return Vector.new(#self, function (n) return self[n] / scalar end)
+end
+
+
+
+--- Multiplies a vector by a scalar value and returns the result in a new vector.
+--
+-- @param scalar Scalar value to multiply the vector with.
+--
+-- @return A new vector with the result of the multiplication.
+--
+function Vector:timesScalar(scalar)
+ return Vector.new(#self, function (n) return self[n] * scalar end)
+end
+
+
+
+--- Performs the dot product of two vectors and returns the result in a new vector.
+--
+-- @param other Vector to perform the dot product with.
+--
+-- @return A new vector with the result of the dot product.
+--
+function Vector:dotProduct(other)
+ assert(#self == #other)
+
+ local product = 0
+ for n = 1,#self do
+ product = product + self[n] * other[n]
+ end
+ return product
+end
+
+
+
+--- Computes the Euclidean norm of the vector.
+--
+-- @return The Euclidean norm of the vector.
+--
+function Vector:norm()
+ return math.sqrt(self:dotProduct(self))
+end
+
+
+
+--- Normalizes the vector and returns the result in a new vector.
+--
+-- @return Normalized version of the original vector.
+--
+function Vector:normalized()
+ local norm = self:norm()
+ if norm == 0 then
+ return Vector.new(#self)
+ else
+ return self:dividedByScalar(self:norm())
+ end
+end
+
+
+
+--- Updates the values of the vector in-place.
+--
+-- @param update_function A function that is called for each element of the
+-- vector. The elements are replaced by the values
+-- returned from this function.
+--
+function Vector:update(update_function)
+ for i=1,#self do
+ self[i] = update_function(self[i])
+ end
+end
+
+
+
+--- Limits all elements of the vector in-place.
+--
+-- @param limit_function A function that is called for each index/element
+-- pair. It is supposed to return minimum and maximum
+-- values for the element. The element is then clamped
+-- to these values.
+--
+function Vector:limit(limit_function)
+ for i=1,#self do
+ local min, max = limit_function(i, self[i])
+ self[i] = math.max(min, math.min(max, value))
+ end
+end
+
+
+--- Tests whether all elements of two vectors are the same
+--
+-- @param other The other vector
+--
+-- @return true or false
+--
+function Vector:equals(other)
+ if #self ~= #other then
+ return false
+ end
+
+ for n = 1, #self do
+ if self[n] ~= other[n] then
+ return false
+ end
+ end
+
+ return true
+end
+
+
+function Vector:__tostring()
+ return '(' .. table.concat(self, ', ') .. ')'
+end
+
+
+
+
+
+-- Done
+
+return Vector
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc.lua
new file mode 100644
index 0000000000..78b68bbcb1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc.lua
@@ -0,0 +1,124 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- The table doc is used for documentation purposes. It is used to
+-- provide lazy documentation for keys, that is, to install
+-- documentation for keys only when this information is requested and
+-- when the documentation is kept in a separate file.
+--
+-- Using the doc facility is easy:
+-- %
+-- \begin{enumerate}
+-- \item In the |declare| statement of the key, you do not provide
+-- fields like |documentation| or |summary|. Rather, you provide the
+-- field |documentation_in|, which gets the name of a Lua file the
+-- will be read whenever one of the fields |documentation|, |summary|,
+-- or |examples| is requested for the key.
+-- \item When the key is requested, |require| will be applied to the
+-- filename given in the |documentation_in| field.
+-- \item In this file, you start with the following code:
+-- %
+--\begin{codeexample}[code only]
+--local doc = require 'pgf.gd.doc'
+--local key = doc.key
+--local documentation = doc.documentation
+--local summary = doc.summary
+--local example = doc.example
+--\end{codeexample}
+-- %
+-- This will setup nice shortcuts for the commands you are going to
+-- use in your file.
+-- \item Next, for each to-be-lazily-documented key, add a block to
+-- the file like the following:
+-- %
+--\begin{codeexample}[code only]
+-- ---
+-- key "my radius"
+-- summary "This key specifies a radius."
+-- documentation
+-- [[
+-- This key is used, whenever...
+-- ]]
+-- example "\tikz \graph [foo layout, my radius=5] { a--b };"
+-- example "\tikz \graph [foo layout, my radius=3] { c--d };"
+--\end{codeexample}
+--
+-- Note that |[[| and |]]| are used in Lua for raw multi-line strings.
+--
+-- The effect of the above code will be that for the key |my radius|
+-- the different field like |summary| or |documentation| get
+-- updated. The |key| function simple ``selects'' a key and subsequent
+-- commands like |summary| will update this key until a different key
+-- is selected through another use of |key|.
+-- \end{enumerate}
+
+local doc = {}
+
+local current_key
+
+
+-- Namespace
+require "pgf.gd".doc = doc
+
+
+-- Imports
+local keys = require "pgf.gd.interface.InterfaceCore".keys
+
+---
+-- Selects the key which will be subsequently updated by the other
+-- functions of this class.
+--
+-- @param key A key.
+
+function doc.key (key)
+ current_key = assert(keys[key], "trying to document not-yet-declared key")
+end
+
+
+---
+-- Updates (replaces) the summary field of the last key selected
+-- through the |key| command.
+--
+-- @param string A (new) summary string.
+
+function doc.summary (string)
+ current_key.summary = string
+end
+
+
+---
+-- Updates (replaces) the documentation field of the last key selected
+-- through the |key| command.
+--
+-- @param string A (new) documentation string. Typically, the |[[|
+-- syntax will be used to specify this string.
+
+function doc.documentation (string)
+ current_key.documentation = string
+end
+
+
+---
+-- Adds an example to the |examples| field of the last key selected
+-- through the |key| command.
+--
+-- @param string An additional example string.
+
+function doc.example (string)
+ local examples = rawget(current_key, "examples") or {}
+ examples[#examples + 1] = string
+ current_key.examples = examples
+end
+
+
+return doc
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua
new file mode 100644
index 0000000000..552dd00dc8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua
@@ -0,0 +1,19 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Force-Based Algorithms}
+--
+--
+
+local _ \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua
new file mode 100644
index 0000000000..fcd5b26fb0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua
@@ -0,0 +1,129 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "FMMMLayout"
+summary "The fast multipole multilevel layout algorithm."
+
+documentation
+[[
+|FMMMLayout| implements a force-directed graph drawing
+method suited also for very large graphs. It is based on a
+combination of an efficient multilevel scheme and a strategy for
+approximating the repulsive forces in the system by rapidly
+evaluating potential fields.
+
+The implementation is based on the following publication:
+%
+\begin{itemize}
+ \item Stefan Hachul, Michael J\"unger: Drawing Large Graphs with
+ a Potential-Field-Based Multilevel Algorithm. \emph{12th
+ International Symposium on Graph Drawing 1998 (GD '04)},
+ New York, LNCS 3383, pp. 285--295, 2004.
+\end{itemize}
+]]
+
+example
+[[
+\tikz \graph [FMMMLayout] { a -- {b,c,d} -- e -- a };
+]]
+
+
+example
+[[
+\tikz [nodes={text height=.7em, text depth=.2em,
+ draw=black!20, thick, fill=white, font=\footnotesize},
+ >={Stealth[round,sep]}, rounded corners, semithick]
+ \graph [FMMMLayout, node sep=1mm, variation=2] {
+ "5th Edition" -> { "6th Edition", "PWB 1.0" };
+ "6th Edition" -> { "LSX", "1 BSD", "Mini Unix", "Wollongong", "Interdata" };
+ "Interdata" ->[orient=down] "Unix/TS 3.0",
+ "Interdata" -> { "PWB 2.0", "7th Edition" };
+ "7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" };
+ "V7M" -> "Ultrix-11";
+ "8th Edition" -> "9th Edition";
+ "1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" };
+ "32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" };
+ "4.2 BSD" -> { "4.3 BSD", "Ultrix-32" };
+ "PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }};
+ "CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" };
+ { "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0";
+ { "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } ->
+ "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3";
+ };
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "FMMMLayout.randSeed"
+summary "Sets the random seed for the |FMMMLayout|."
+documentation
+[[
+By changing this number, you can vary the appearance of the generated
+graph drawing. This key is an alias for |random seed|, which in turn
+can be set by using the |variation| key.
+]]
+
+example
+[[
+\tikz \graph [FMMMLayout, variation=1] { a -- {b,c,d} -- e -- a };
+]]
+example
+[[
+\tikz \graph [FMMMLayout, variation=2] { a -- {b,c,d} -- e -- a };
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "FMMMLayout.unitEdgeLength"
+summary "The ``ideal'' padding between two nodes."
+
+documentation
+[[
+The algorithm will try to make the padding between any two vertices
+this distance. Naturally, this is not always possible, so, normally,
+distance will actually be different. This key is an alias for the more
+natural |node sep|.
+]]
+
+example
+[[
+\tikz {
+ \graph [FMMMLayout, node sep=1cm] { subgraph C_n[n=6]; };
+
+ \draw [red, ultra thick, |-|] (1.south) -- ++(down:1cm);
+}
+]]
+example
+[[
+\tikz {
+ \graph [FMMMLayout, node sep=5mm] { subgraph C_n[n=6]; };
+
+ \draw [red, ultra thick, |-|] (1.south) -- ++(down:5mm);
+}
+]]
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua
new file mode 100644
index 0000000000..453078b130
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua
@@ -0,0 +1,51 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "FastMultipoleEmbedder"
+summary "Implementation of a fast multipole embedder by Martin Gronemann."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "FastMultipoleEmbedder.numIterations"
+summary "sets the maximum number of iterations"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "FastMultipoleEmbedder.multipolePrec"
+summary "sets the number of coefficients for the expansions. default = 4"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "FastMultipoleEmbedder.defaultEdgeLength"
+summary ""
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "FastMultipoleEmbedder.defaultNodeSize"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua
new file mode 100644
index 0000000000..d0b94c2bb7
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua
@@ -0,0 +1,103 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout"
+summary "The energy-based GEM layout algorithm."
+
+documentation [[
+ The implementation used in |GEMLayout| is based on the following publication:
+ %
+ \begin{itemize}
+ \item Arne Frick, Andreas Ludwig, Heiko Mehldau: \emph{A Fast Adaptive Layout
+ Algorithm for Undirected Graphs.} Proc. Graph Drawing 1994,
+ LNCS 894, pp. 388-403, 1995.
+ \end{itemize}
+]]
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.numberOfRounds"
+summary "Sets the maximal number of round per node."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.minimalTemperature"
+summary "Sets the minimal temperature."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.initialTemperature"
+summary "Sets the initial temperature; must be $\\ge$ |minimalTemperature|."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.gravitationalConstant"
+summary "Sets the gravitational constant; must be $\\ge 0$."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.desiredLength"
+summary "Sets the desired edge length; must be $\\ge 0$."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.maximalDisturbance"
+summary "Sets the maximal disturbance; must be $\\ge 0$."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.rotationAngle"
+summary "Sets the opening angle for rotations ($0 \\le x \\le \\pi / 2$)."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.oscillationAngle"
+summary "Sets the opening angle for oscillations ($0 \\le x \\le \\pi / 2$)."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.rotationSensitivity"
+summary "Sets the rotation sensitivity ($0 \\le x \\le 1$)."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.oscillationSensitivity"
+summary "Sets the oscillation sensitivity ($0 \\le x \\le 1$)."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "GEMLayout.attractionFormula"
+summary "sets the formula for attraction (1 = Fruchterman / Reingold, 2 = GEM)."
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua
new file mode 100644
index 0000000000..6210c93941
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "MultilevelLayout"
+summary "A wrapper for the multilevel layout computation using the modular multi-level mixer."
+
+example [[
+\tikz \graph [MultilevelLayout] {
+ a -- b -- c -- a -- d -- e -- f -- a
+};
+]]
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua
new file mode 100644
index 0000000000..ae3cf9c8ef
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua
@@ -0,0 +1,53 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFR"
+summary "The spring-embedder layout algorithm by Fruchterman and Reingold."
+
+documentation [[
+ The implementation used in SpringEmbedderFR is based on the following
+ publication:
+
+ Thomas M. J. Fruchterman, Edward M. Reingold: \emph{Graph Drawing by Force-directed
+ Placement}. Software - Practice and Experience 21(11), pp. 1129--1164, 1991.
+]]
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFR.iterations"
+summary "Sets the number of iterations."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFR.noise"
+summary "Sets the parameter noise."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFR.scaleFunctionFactor"
+summary "Sets the scale function factor."
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua
new file mode 100644
index 0000000000..6286e9f395
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua
@@ -0,0 +1,57 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFRExact"
+summary "Declaration of Spring-Embedder (Fruchterman,Reingold) algorithm with exact force computations."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFRExact.iterations"
+summary "Sets the number of iterations."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFRExact.noise"
+summary "Sets the parameter noise."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFRExact.coolingFunction"
+summary "Sets the parameter coolingFunction to |factor| or to |logarithmic|."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFRExact.idealEdgeLength"
+summary "Sets the ideal edge length to a length."
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderFRExact.convTolerance"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua
new file mode 100644
index 0000000000..a4fd46aa77
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua
@@ -0,0 +1,62 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderKK"
+summary "The spring embedder of Kamada and Kawai"
+
+documentation [[
+ The implementation used in |SpringEmbedderKK| is based on
+ the following publication:
+
+ Tomihisa Kamada, Satoru Kawai: \emph{An Algorithm for Drawing
+ General Undirected Graphs.} Information Processing Letters 31, pp. 7--15, 1989.
+
+ There are some parameters that can be tuned to optimize the
+ algorithm's behavior regarding runtime and layout quality.
+ First of all note that the algorithm uses all pairs shortest path
+ to compute the graph theoretic distance. This can be done either
+ with BFS (ignoring node sizes) in quadratic time or by using
+ e.g. Floyd's algorithm in cubic time with given edge lengths
+ that may reflect the node sizes. Also |m_computeMaxIt| decides
+ if the computation is stopped after a fixed maximum number of
+ iterations. The desirable edge length can either be set or computed
+ from the graph and the given layout.
+]]
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderKK.stopTolerance"
+summary "Sets the value for the stop tolerance."
+documentation [[
+ Below this value, the system is regarded stable (balanced) and the
+ optimization stopped.
+]]
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SpringEmbedderKK.desLength"
+summary "Sets desirable edge length directly"
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua
new file mode 100644
index 0000000000..e658a896bd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "BarycenterPlacer"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "BarycenterPlacer.weightedPositionPriority"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua
new file mode 100644
index 0000000000..e6f06add57
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua
@@ -0,0 +1,45 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "CirclePlacer"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "CirclePlacer.circleSize"
+summary ""
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "CirclePlacer.radiusFixed"
+summary ""
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "CirclePlacer.nodeSelection"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua
new file mode 100644
index 0000000000..e8723272ee
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "EdgeCoverMerger"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "EdgeCoverMerger.factor"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua
new file mode 100644
index 0000000000..81e2f37db0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "IndependentSetMerger"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "IndependentSetMerger.searchDepthBase"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua
new file mode 100644
index 0000000000..7fbca25e81
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "LocalBiconnectedMerger"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "LocalBiconnectedMerger.factor"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua
new file mode 100644
index 0000000000..e966b49056
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "MatchingMerger"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "MatchingMerger.selectByNodeMass"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua
new file mode 100644
index 0000000000..0b9d967db9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua
@@ -0,0 +1,27 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "MedianPlacer"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua
new file mode 100644
index 0000000000..71bdbc7340
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "RandomMerger"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "RandomMerger.factor"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua
new file mode 100644
index 0000000000..c26946d4e1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "RandomPlacer"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "RandomPlacer.circleSize"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua
new file mode 100644
index 0000000000..76b084fa67
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua
@@ -0,0 +1,39 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "SolarMerger"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SolarMerger.simple"
+summary ""
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "SolarMerger.massAsNodeRadius"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua
new file mode 100644
index 0000000000..530ddbc0d8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua
@@ -0,0 +1,27 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "SolarPlacer"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua
new file mode 100644
index 0000000000..6f579d0a45
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua
@@ -0,0 +1,33 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "ZeroPlacer"
+summary "?"
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "ZeroPlacer.randomRange"
+summary ""
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua
new file mode 100644
index 0000000000..ffd3ea844d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua
@@ -0,0 +1,19 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Algorithms for Drawing Layered Graphs}
+--
+--
+
+local _ \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua
new file mode 100644
index 0000000000..5e4138eece
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua
@@ -0,0 +1,23 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+
+--------------------------------------------------------------------
+key "BarycenterHeuristic"
+summary "The barycenter heuristic for 2-layer crossing minimization."
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua
new file mode 100644
index 0000000000..fd13e9bd4b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua
@@ -0,0 +1,35 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "CoffmanGrahamRanking"
+summary "The ranking algorithm due to Coffman and Graham."
+documentation
+[[
+|CoffmanGrahamRanking| implements a node ranking algorithm based on
+the Coffman--Graham scheduling algorithm, which can be used as first
+phase in |SugiyamaLayout|. The aim of the algorithm is to ensure that
+the height of the ranking (the number of layers) is kept small.
+]]
+--------------------------------------------------------------------
+
+
+--------------------------------------------------------------------
+key "CoffmanGrahamRanking.width"
+summary "A mysterious width parameter..."
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua
new file mode 100644
index 0000000000..eced60b2ed
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua
@@ -0,0 +1,27 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+
+--------------------------------------------------------------------
+key "DfsAcyclicSubgraph"
+summary "DFS-based algorithm for computing a maximal acyclic subgraph."
+documentation
+[[
+The algorithm simply removes all DFS-backedges and works in linear-time.
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua
new file mode 100644
index 0000000000..a7baad7e10
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua
@@ -0,0 +1,99 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "FastHierarchyLayout"
+summary "Coordinate assignment phase for the Sugiyama algorithm by Buchheim et al."
+documentation
+[[
+This class implements a hierarchy layout algorithm, that is, it
+layouts hierarchies with a given order of nodes on each
+layer. It is used as a third phase of the Sugiyama algorithm.
+
+All edges of the layout will have at most two
+bends. Additionally, for each edge having exactly two bends, the
+segment between them is drawn vertically. This applies in
+particular to the long edges arising in the first phase of the
+Sugiyama algorithm.
+
+The implementation is based on:
+%
+\begin{itemize}
+ \item
+ Christoph Buchheim, Michael Jünger, Sebastian Leipert: A Fast
+ Layout Algorithm for k-Level Graphs. \emph{Proc. Graph
+ Drawing 2000}, volume 1984 of LNCS, pages 229--240, 2001.
+\end{itemize}
+]]
+
+example
+[[
+\tikz \graph [SugiyamaLayout, FastHierarchyLayout] {
+ a -- {b,c,d} -- e -- a;
+};
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "FastHierarchyLayout.fixedLayerDistance"
+summary "If true, the distance between neighbored layers is fixed, otherwise variable."
+--------------------------------------------------------------------
+
+
+
+
+--------------------------------------------------------------------
+key "FastHierarchyLayout.layerDistance"
+summary "Separation distance (padding) between two consecutive layers."
+
+documentation
+[[
+Sets the (minimum?) padding between nodes on two consecutive
+layers. It defaults to the sum of the keys
+|level pre sep| and |level post sep|.
+]]
+
+example
+[[
+\tikz \graph [SugiyamaLayout, FastHierarchyLayout,
+ level sep=1cm] {
+ a -- {b,c,d} -- e -- a;
+};
+]]
+--------------------------------------------------------------------
+
+--------------------------------------------------------------------
+key "FastHierarchyLayout.nodeDistance"
+summary "Separation distance (padding) between two consecutive nodes on the same layer."
+
+documentation
+[[
+Sets the (minimum?) padding between sibling nodes. It defaults to the
+sum of the keys |sibling pre sep| and |sibling post sep|.
+]]
+
+example
+[[
+\tikz \graph [SugiyamaLayout, FastHierarchyLayout,
+ sibling sep=5mm] {
+ a -- {b,c,d} -- e -- a;
+};
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua
new file mode 100644
index 0000000000..4af6daa620
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua
@@ -0,0 +1,99 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "FastSimpleHierarchyLayout"
+summary "Coordinate assignment phase for the Sugiyama algorithm by Ulrik Brandes and Boris Köpf."
+
+documentation
+[[
+This class implements a hierarchy layout algorithm, that is, it
+layouts hierarchies with a given order of nodes on each
+layer. It is used as a third phase of the Sugiyama algorithm.
+
+The algorithm runs in three phases:
+%
+\begin{enumerate}
+ \item Alignment (4x)
+ \item Horizontal Compactation (4x)
+ \item Balancing
+\end{enumerate}
+%
+The alignment and horizontal compactification phases are calculated
+downward, upward, left-to-right and right-to-left. The four
+resulting layouts are combined in a balancing step.
+
+Warning: The implementation is known to not always produce a
+correct layout. Therefore this Algorithm is for testing purpose
+only.
+
+The implementation is based on:
+%
+\begin{itemize}
+ \item
+ Ulrik Brandes, Boris Köpf: Fast and Simple Horizontal
+ Coordinate Assignment. \emph{LNCS} 2002, Volume 2265/2002,
+ pp. 33--36
+\end{itemize}
+]]
+
+example
+[[
+\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout] {
+ a -- {b,c,d} -- e -- a;
+};
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "FastSimpleHierarchyLayout.layerDistance"
+summary "Distance between the centers of nodes of two consecutive layers."
+
+documentation
+[[
+Sets the (minimum?) distance between nodes on two consecutive
+layers. It defaults to the key |level distance|.
+]]
+example
+[[
+\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout,
+ level distance=2cm] {
+ a -- {b,c,d} -- e -- a;
+};
+]]
+--------------------------------------------------------------------
+
+--------------------------------------------------------------------
+key "FastSimpleHierarchyLayout.siblingDistance"
+summary "Distance between the centers of nodes of sibling nodes."
+
+documentation
+[[
+Sets the (minimum?) padding between sibling nodes. It defaults to
+|sibling distance|.
+]]
+example
+[[
+\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout,
+ sibling distance=5mm] {
+ a -- {b,c,d} -- e -- a;
+};
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua
new file mode 100644
index 0000000000..d2f1d8eeea
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua
@@ -0,0 +1,27 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "GreedyCycleRemoval"
+summary "Greedy algorithm for computing a maximal acyclic subgraph."
+documentation
+[[
+ The algorithm applies a greedy heuristic to compute a maximal
+ acyclic subgraph and works in linear-time.
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua
new file mode 100644
index 0000000000..a8cd94ef19
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua
@@ -0,0 +1,23 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+
+--------------------------------------------------------------------
+key "GreedyInsertHeuristic"
+summary "The greedy-insert heuristic for 2-layer crossing minimization."
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua
new file mode 100644
index 0000000000..3d98fbe9c6
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua
@@ -0,0 +1,57 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "LongestPathRanking"
+summary "The longest-path ranking algorithm."
+documentation
+[[
+ |LongestPathRanking| implements the well-known longest-path ranking
+ algorithm, which can be used as first phase in |SugiyamaLayout|. The
+ implementation contains a special optimization for reducing edge
+ lengths, as well as special treatment of mixed-upward graphs (for
+ instance, \textsc{uml} class diagrams).
+]]
+--------------------------------------------------------------------
+
+
+--------------------------------------------------------------------
+key "LongestPathRanking.separateDeg0Layer"
+summary "If set to true, isolated nodes are placed on a separate layer."
+--------------------------------------------------------------------
+
+
+--------------------------------------------------------------------
+key "LongestPathRanking.separateMultiEdges"
+summary "If set to true, multi-edges will span at least two layers."
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "LongestPathRanking.optimizeEdgeLength"
+summary
+[[
+ If set to true the ranking algorithm tries to reduce edge
+ length even if this might increase the height of the layout. Choose
+ false, if the longest-path ranking known from the literature should be
+ used.
+]]
+--------------------------------------------------------------------
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua
new file mode 100644
index 0000000000..b37480ac78
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua
@@ -0,0 +1,24 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+
+--------------------------------------------------------------------
+key "MedianHeuristic"
+summary "The median heuristic for 2-layer crossing minimization."
+--------------------------------------------------------------------
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua
new file mode 100644
index 0000000000..25a8dd5262
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua
@@ -0,0 +1,35 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "OptimalRanking"
+summary "The optimal ranking algorithm."
+documentation
+[[
+ The |OptimalRanking| implements the LP-based algorithm for
+ computing a node ranking with minimal edge lengths, which can
+ be used as first phase in |SugiyamaLayout|.
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "OptimalRanking.separateMultiEdges"
+summary "If set to true, multi-edges will span at least two layers."
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua
new file mode 100644
index 0000000000..d0815a5b76
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua
@@ -0,0 +1,34 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+
+--------------------------------------------------------------------
+key "SiftingHeuristic"
+summary "The sifting heuristic for 2-layer crossing minimization."
+--------------------------------------------------------------------
+
+
+--------------------------------------------------------------------
+key "SiftingHeuristic.strategy"
+summary "Sets a so-called ``sifting strategy''."
+documentation
+[[
+ The following values are permissible: |left_to_right|, |desc_degree|,
+ and |random|.
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua
new file mode 100644
index 0000000000..1579c7153d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua
@@ -0,0 +1,24 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+
+--------------------------------------------------------------------
+key "SplitHeuristic"
+summary "The split heuristic for 2-layer crossing minimization."
+--------------------------------------------------------------------
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua
new file mode 100644
index 0000000000..ec75fa7e6e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua
@@ -0,0 +1,113 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "SugiyamaLayout"
+summary "The OGDF implementation of the Sugiyama algorithm."
+
+documentation [[
+ This layout represents a customizable implementation of Sugiyama's
+ layout algorithm. The implementation used in |SugiyamaLayout| is based
+ on the following publications:
+
+ \begin{itemize}
+ \item Emden R. Gansner, Eleftherios Koutsofios, Stephen
+ C. North, Kiem-Phong Vo: A technique for drawing directed
+ graphs. \emph{IEEE Trans. Software Eng.} 19(3):214--230, 1993.
+ \item Georg Sander: \emph{Layout of compound directed graphs.}
+ Technical Report, Universität des Saarlandes, 1996.
+ \end{itemize}
+]]
+
+example
+[[
+\tikz \graph [SugiyamaLayout] { a -- {b,c,d} -- e -- a };
+]]
+
+example
+[[
+\tikz \graph [SugiyamaLayout, grow=right] {
+ a -- {b,c,d} -- e -- a
+};
+]]
+
+example
+[[
+\tikz [nodes={text height=.7em, text depth=.2em,
+ draw=black!20, thick, fill=white, font=\footnotesize},
+ >={Stealth[round,sep]}, rounded corners, semithick]
+ \graph [SugiyamaLayout, FastSimpleHierarchyLayout, grow=-80,
+ level distance=1.5cm, sibling distance=7mm] {
+ "5th Edition" -> { "6th Edition", "PWB 1.0" };
+ "6th Edition" -> { "LSX", "1 BSD", "Mini Unix", "Wollongong", "Interdata" };
+ "Interdata" -> { "Unix/TS 3.0", "PWB 2.0", "7th Edition" };
+ "7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" };
+ "V7M" -> "Ultrix-11";
+ "8th Edition" -> "9th Edition";
+ "1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" };
+ "32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" };
+ "4.2 BSD" -> { "4.3 BSD", "Ultrix-32" };
+ "PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }};
+ "CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" };
+ { "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0";
+ { "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } ->
+ "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3";
+ };
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "SugiyamaLayout.runs"
+summary "Determines, how many times the crossing minimization is repeated."
+documentation
+[[
+Each repetition (except for the first) starts with
+randomly permuted nodes on each layer. Deterministic behavior can
+be achieved by setting |SugiyamaLayout.runs| to 1.
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "SugiyamaLayout.transpose"
+documentation [[
+ Determines whether the transpose step is performed
+ after each 2-layer crossing minimization; this step tries to
+ reduce the number of crossings by switching neighbored nodes on
+ a layer.
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "SugiyamaLayout.fails"
+documentation [[
+ The number of times that the number of crossings may
+ not decrease after a complete top-down bottom-up traversal,
+ before a run is terminated.
+]]
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End:
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua
new file mode 100644
index 0000000000..9f5f291461
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua
@@ -0,0 +1,19 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Miscellaneous Algorithms for Graph Drawing}
+--
+--
+
+local _ \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua
new file mode 100644
index 0000000000..2a250ecece
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua
@@ -0,0 +1,48 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "BalloonLayout"
+summary "A ``balloon layout''."
+
+documentation
+[[
+This algorithm computes a radial (balloon) layout based on a
+spanning tree. The algorithm is partially based on the paper
+\emph{On Balloon Drawings of Rooted Trees} by Lin and Yen and on
+\emph{Interacting with Huge Hierarchies: Beyond Cone Trees} by
+Carriere and Kazman.
+]]
+
+example
+[[
+\tikz \graph [BalloonLayout] { a -- {b,c,d -- {e,f,h,h,i}, j -- k -- {l,m,n}} };
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "BalloonLayout.evenAngles"
+summary "Subtrees may be assigned even angles or angles depending on their size."
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End: \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua
new file mode 100644
index 0000000000..c5e2cf7a6c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua
@@ -0,0 +1,95 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "CircularLayout"
+summary "The circular layout algorithm."
+
+documentation
+[[
+The implementation used in CircularLayout is based on the following publication:
+%
+\begin{itemize}
+ \item Ugur Dogrus\"oz, Brendan Madden, Patrick Madden: Circular
+ Layout in the Graph Layout Toolkit. \emph{Proc. Graph Drawing 1996,}
+ LNCS 1190, pp. 92--100, 1997.
+\end{itemize}
+]]
+
+example
+[[
+\tikz \graph [CircularLayout] {
+ a -- b -- c -- a -- d -- e -- f -- g -- d;
+ b -- {x,y,z};
+};
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "CircularLayout.minDistCircle"
+summary "The minimal padding between nodes on a circle."
+
+documentation "This is an alias for |part sep|."
+
+example
+[[
+\tikz \graph [CircularLayout, part sep=1cm] {
+ a -- b -- c -- a -- d -- e -- f -- g -- d;
+ b -- {x,y,z};
+};
+]]
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "CircularLayout.minDistLevel"
+summary "The minimal padding between nodes on different levels."
+
+documentation "This is an alias for |layer sep| and |level sep|."
+
+example
+[[
+\tikz \graph [CircularLayout, layer sep=1cm] {
+ a -- b -- c -- a -- d -- e -- f -- g -- d;
+ b -- {x,y,z};
+};
+]]
+--------------------------------------------------------------------------------
+
+
+--------------------------------------------------------------------------------
+key "CircularLayout.minDistSibling"
+summary "The minimal padding between sibling nodes."
+
+documentation "This is an alias for |sibling sep|."
+
+example
+[[
+\tikz \graph [CircularLayout, sibling sep=1cm] {
+ a -- b -- c -- a -- d -- e -- f -- g -- d;
+ b -- {x,y,z};
+};
+]]
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End: \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua
new file mode 100644
index 0000000000..b2bb7e1d24
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua
@@ -0,0 +1,18 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {Computing Acyclic Subgraphs Module}
+--
+
+local _
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua
new file mode 100644
index 0000000000..a0292530cd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua
@@ -0,0 +1,17 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {The Hierarchy Layout Module}
+--
+
+local _
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua
new file mode 100644
index 0000000000..328a2806db
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua
@@ -0,0 +1,17 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {The Initial Placer Module}
+--
+
+local _
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua
new file mode 100644
index 0000000000..9604c98640
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua
@@ -0,0 +1,17 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {The Multilevel Builder Module}
+--
+
+local _
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua
new file mode 100644
index 0000000000..8dce27a335
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua
@@ -0,0 +1,17 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {The Ranking Module}
+--
+
+local _
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua
new file mode 100644
index 0000000000..877cba47f6
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua
@@ -0,0 +1,17 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {The Two Layer Crossing Minimization Module}
+--
+
+local _
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua
new file mode 100644
index 0000000000..fb1abb5ccd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua
@@ -0,0 +1,19 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Algorithms for Drawing Planar Graphs}
+--
+--
+
+local _ \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua
new file mode 100644
index 0000000000..e61f9281b9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua
@@ -0,0 +1,66 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------------------
+key "PlanarizationLayout"
+summary "The planarization layout algorithm."
+
+documentation
+[[
+ A |PlanarizationLayout| represents a customizable implementation
+ of the planarization approach for drawing graphs. The implementation
+ used in PlanarizationLayout is based on the following publication:
+ %
+ \begin{itemize}
+ \item C. Gutwenger, P. Mutzel: \emph{An Experimental Study of Crossing
+ Minimization Heuristics.} 11th International Symposium on Graph
+ Drawing 2003, Perugia (GD '03), LNCS 2912, pp. 13--24, 2004.
+ \end{itemize}
+]]
+
+example
+[[
+\tikz \graph [PlanarizationLayout] { a -- {b,c,d,e,f} -- g -- a };
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "PlanarizationLayout.preprocessCliques"
+summary "Configures, whether cliques are collapsed in a preprocessing step."
+documentation
+[[
+ If set to true, a preprocessing for cliques (complete subgraphs)
+ is performed and cliques will be laid out in a special form (straight-line,
+ not orthogonal). The preprocessing may reduce running time and improve
+ layout quality if the input graphs contains dense subgraphs.
+]]
+--------------------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------------------
+key "PlanarizationLayout.minCliqueSize"
+summary "The minimum size of cliques collapsed in preprocessing."
+--------------------------------------------------------------------------------
+
+
+-- Local Variables:
+-- mode:latex
+-- End: \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples.lua
new file mode 100644
index 0000000000..de33c0ed37
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples.lua
@@ -0,0 +1,26 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+-- Imports
+
+require "pgf"
+require "pgf.gd"
+
+
+-- Declare namespace
+pgf.gd.examples = {}
+
+
+-- Done
+
+return pgf.gd.examples \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua
new file mode 100644
index 0000000000..5acc28396b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua
@@ -0,0 +1,32 @@
+local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay"
+
+InterfaceToDisplay.bind(require "pgf.gd.examples.BindingToASCII")
+require "pgf.gd.layered.library"
+require "pgf.gd.force.library"
+
+local algorithm = io.read():match("%s*graph%s*%[(.-)%]")
+
+InterfaceToDisplay.pushPhase(algorithm, "main", 1)
+InterfaceToDisplay.pushOption("level distance", 6, 2)
+InterfaceToDisplay.pushOption("sibling distance", 8, 3)
+InterfaceToDisplay.beginGraphDrawingScope(3)
+InterfaceToDisplay.pushLayout(4)
+
+for line in io.lines() do
+ if line:match("}") then
+ break
+ elseif line:find("-") then
+ local n1, dir, n2 = string.match(line, "^%s*(.-)%s*(-.)%s*(.-)%s*;")
+ InterfaceToDisplay.createEdge(n1, n2, dir, 4)
+ else
+ local n1 = string.match(line, "^%s*(.-)%s*;")
+ InterfaceToDisplay.createVertex(n1, "rectangle", nil, 4)
+ end
+end
+
+InterfaceToDisplay.runGraphDrawingAlgorithm()
+InterfaceToDisplay.renderGraph()
+InterfaceToDisplay.endGraphDrawingScope()
+
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua
new file mode 100644
index 0000000000..2b5c9cc0b6
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua
@@ -0,0 +1,87 @@
+local lib = require "pgf.gd.lib"
+
+-- Create a binding to ourselves
+local BindingToASCII = lib.class { base_class = require "pgf.gd.bindings.Binding" }
+
+local canvas
+
+function BindingToASCII:renderStart()
+ canvas = {}
+ -- Clear the canvas
+ for x=-30,30 do
+ canvas [x] = {}
+ for y=-30,30 do
+ canvas[x][y] = ' '
+ end
+ end
+end
+
+function BindingToASCII:renderStop()
+ for y=10,-30,-1 do
+ local t = {}
+ for x=-30,30 do
+ local s = canvas[x][y]
+ for i=1,#s do
+ pos = x+30+i-math.floor(#s/2)
+ if not t[pos] or t[pos] == " " or t[pos] == "." then
+ t[pos] = string.sub(s,i,i)
+ end
+ end
+ end
+ print(table.concat(t))
+ end
+end
+
+function BindingToASCII:renderVertex(v)
+ canvas [math.floor(v.pos.x)][math.floor(v.pos.y)] = v.name
+end
+
+function BindingToASCII:renderEdge(e)
+
+ local function connect (p,q)
+
+ local x1, y1, x2, y2 = math.floor(p.x+0.5), math.floor(p.y+0.5), math.floor(q.x+0.5), math.floor(q.y+0.5)
+
+ -- Go upward with respect to x
+ if x2 < x1 then
+ x1, y1, x2, y2 = x2, y2, x1, y1
+ end
+
+ local delta_x = x2-x1
+ local delta_y = y2-y1
+
+ if math.abs(delta_x) > math.abs(delta_y) then
+ local slope = delta_y/delta_x
+ for i=x1,x2 do
+ local x,y = i, math.floor(y1 + (i-x1)*slope + 0.5)
+
+ if canvas[x][y] == " " then
+ canvas[x][y] = '.'
+ end
+ end
+ elseif math.abs(delta_y) > 0 then
+ local slope = delta_x/delta_y
+ for i=y1,y2,(y1<y2 and 1) or -1 do
+ local x,y = math.floor(x1 + (i-y1)*slope + 0.5), i
+
+ if canvas[x][y] == " " then
+ canvas[x][y] = '.'
+ end
+ end
+ end
+ end
+
+
+ local p = e.tail.pos
+
+ for i=1,#e.path do
+ if type(e.path[i]) == "table" then
+ connect(p, e.path[i])
+ p = e.path[i]
+ end
+ end
+
+ connect(p, e.head.pos)
+end
+
+return BindingToASCII
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua
new file mode 100644
index 0000000000..46eb4eff38
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua
@@ -0,0 +1,82 @@
+-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {The ``Hello World'' of Graph Drawing}
+--
+-- @end
+
+
+-- Inputs
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+---
+
+declare {
+ key = "simple demo layout",
+ algorithm = {
+ run =
+ function (self)
+ local g = self.digraph
+ local alpha = (2 * math.pi) / #g.vertices
+
+ for i,vertex in ipairs(g.vertices) do
+ local radius = vertex.options['radius'] or g.options['radius']
+ vertex.pos.x = radius * math.cos(i * alpha)
+ vertex.pos.y = radius * math.sin(i * alpha)
+ end
+ end
+ },
+
+ summary = [["
+ This algorithm is the ``Hello World'' of graph drawing.
+ "]],
+ documentation = [=["
+ The algorithm arranges nodes in a circle (without paying heed to the
+ sizes of the nodes or to the edges). In order to ``really'' layout
+ nodes in a circle, use |simple necklace layout|; the present layout
+ is only intended to demonstrate how much (or little) is needed to
+ implement a graph drawing algorithm.
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+-- File pgf.gd.examples.SimpleDemo
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+declare {
+ key = "simple demo layout",
+ algorithm = {
+ run =
+ function (self)
+ local g = self.digraph
+ local alpha = (2 * math.pi) / #g.vertices
+
+ for i,vertex in ipairs(g.vertices) do
+ local radius = vertex.options['radius'] or g.options['radius']
+ vertex.pos.x = radius * math.cos(i * alpha)
+ vertex.pos.y = radius * math.sin(i * alpha)
+ end
+ end
+ },
+ summary = "This algorithm is the 'Hello World' of graph drawing.",
+ documentation = [["
+ This algorithm arranges nodes in a circle ...
+ "]]
+}
+\end{codeexample}
+
+ On the display layer (\tikzname, that is) the algorithm can now
+ immediately be employed; you just need to say
+ |\usegdlibrary{examples.SimpleDemo}| at the beginning
+ somewhere.
+ "]=]
+} \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua
new file mode 100644
index 0000000000..3ff5f4ea23
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua
@@ -0,0 +1,144 @@
+-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {How To Generate Edges Inside an Algorithm}
+--
+-- @end
+
+
+-- Imports
+local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms"
+local declare = InterfaceToAlgorithms.declare
+
+-- The class object
+local SimpleEdgeDemo = {}
+
+
+---
+declare {
+ key = "simple edge demo layout",
+ algorithm = SimpleEdgeDemo,
+
+ summary = "This algorithm shows how edges can be created by an algorithm.",
+ documentation = [["
+ For its job, the algorithm uses the function |createEdge|, which can be
+ called during the run of the algorithm to create edges in the
+ syntactic graph. The algorithm first does exactly the same as the
+ simple demo layout, then it creates an edge for every node where the
+ |new edge to| option is set. You will see in the code how this
+ option is declared and how we use it to look up a vertex in the
+ graph by its name.
+ %
+\begin{codeexample}[preamble={ \usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{examples}}]
+\tikz [simple edge demo layout]
+\graph [radius=2cm] {
+ a, b, c, d, e, f;
+
+ e -> [red] f; % normal edge
+
+ % Edges generated by the algorithm:
+ a[new edge to=b];
+ b[new edge to=d];
+ c[new edge to=f];
+};
+\end{codeexample}
+
+ And the algorithm:
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+ -- File pgf.gd.examples.SimpleEdgeDemo
+
+ -- Imports
+ local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms"
+ local declare = InterfaceToAlgorithms.declare
+
+ -- The class object
+ local SimpleEdgeDemo = {}
+
+declare {
+ key = "simple edge demo layout",
+ algorithm = SimpleEdgeDemo,
+ summary = "This algorithm shows...",
+}
+\end{codeexample}
+
+ Next comes the declaration of the new option |new edge to|:
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+declare {
+ key = "new edge to",
+ type = "string",
+ summary = "This option takes the name of a vertex..."
+}
+\end{codeexample}
+
+ Finally, the algorithm's code:
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+function SimpleEdgeDemo:run()
+ -- As in a SimpleDemo:
+ ...
+ -- Now add some edges:
+ for _,tail in ipairs(g.vertices) do
+ local name = tail.options['new edge to']
+ if name then
+ local node = InterfaceToAlgorithms.findVertexByName(name)
+ if node and self.digraph:contains(node) then
+ InterfaceToAlgorithms.createEdge (self, tail, node)
+ end
+ end
+ end
+end
+\end{codeexample}
+ "]]
+}
+
+---
+declare {
+ key = "new edge to",
+ type = "string",
+
+ summary = [["
+ This option takes the name of a vertex. An edge leading to this
+ vertex is added to the syntactic digraph.
+ "]]
+}
+
+
+function SimpleEdgeDemo:run()
+
+ -- As in a SimpleDemo:
+ local g = self.digraph
+ local alpha = (2 * math.pi) / #g.vertices
+
+ for i,vertex in ipairs(g.vertices) do
+ local radius = vertex.options['radius'] or g.options['radius']
+ vertex.pos.x = radius * math.cos(i * alpha)
+ vertex.pos.y = radius * math.sin(i * alpha)
+ end
+
+ -- Now add some edges:
+ for _,tail in ipairs(g.vertices) do
+ local name = tail.options['new edge to']
+ if name then
+ local node = InterfaceToAlgorithms.findVertexByName(name)
+ if node and self.digraph:contains(node) then
+ InterfaceToAlgorithms.createEdge (self, tail, node)
+ end
+ end
+ end
+end
+
+return SimpleEdgeDemo
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua
new file mode 100644
index 0000000000..6aa9bffb72
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua
@@ -0,0 +1,287 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- @section subsubsection {How To Generate Nodes Inside an Algorithm}
+--
+-- @end
+
+
+
+-- Imports
+local layered = require "pgf.gd.layered"
+local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms"
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+-- The class
+local SimpleHuffman = {}
+
+
+---
+
+declare {
+ key = "simple Huffman layout",
+ algorithm = SimpleHuffman,
+
+ postconditions = {
+ upward_oriented = true
+ },
+
+ summary = [["
+ This algorithm demonstrates how an algorithm can generate new nodes.
+ "]],
+ documentation = [["
+ The input graph should just consist of some nodes (without
+ edges) and each node should have a |probability| key set. The nodes
+ will then be arranged in a line (as siblings) and a Huffman tree
+ will be constructed ``above'' these nodes. For the construction of
+ the Huffman tree, new nodes are created and connected.
+
+ \pgfgdset{
+ HuffmanLabel/.style={/tikz/edge node={node[fill=white,font=\footnotesize,inner sep=1pt]{#1}}},
+ HuffmanNode/.style={/tikz/.cd,circle,inner sep=0pt,outer sep=0pt,draw,minimum size=3pt}
+ }
+
+\begin{codeexample}[preamble={ \usetikzlibrary{graphs,graphdrawing,quotes}
+ \usegdlibrary{examples}}]
+\tikz \graph [simple Huffman layout,
+ level distance=7mm, sibling distance=8mm, grow'=up]
+{
+ a ["0.5", probability=0.5],
+ b ["0.12", probability=0.12],
+ c ["0.2", probability=0.2],
+ d ["0.1", probability=0.1],
+ e ["0.11", probability=0.11]
+};
+\end{codeexample}
+ %
+ The file starts with some setups and declarations:
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+-- File pgf.gd.examples.SimpleHuffman
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+-- The class
+local SimpleHuffman = {}
+
+declare {
+ key = "simple Huffman layout",
+ algorithm = SimpleHuffman,
+ postconditions = { upward_oriented = true }
+ summary = "..."
+}
+
+declare {
+ key = "probability",
+ type = "number",
+ initial = "1",
+ summary = "..."
+}
+
+-- Import
+local layered = require "pgf.gd.layered"
+local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms"
+local Storage = require "pgf.gd.lib.Storage"
+
+local probability = Storage.new()
+local layer = Storage.new()
+
+function SimpleHuffman:run()
+ -- Construct a Huffman tree on top of the vertices...
+\end{codeexample}
+
+ Next comes a setup, where we create the working list of vertices
+ that changes as the Huffman coding method proceeds:
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+ -- Shorthand
+ local function prop (v)
+ return probability[v] or v.options['probability']
+ end
+
+ -- Copy the vertex table, since we are going to modify it:
+ local vertices = {}
+ for i,v in ipairs(self.ugraph.vertices) do
+ vertices[i] = v
+ end
+\end{codeexample}
+
+ The initial vertices are arranged in a line on the last layer. The
+ function |ideal_sibling_distance| takes care of the rather
+ complicated handling of the (possibly rotated) bounding boxes and
+ separations. The |props| and |layer| are tables used by
+ algorithms to ``store stuff'' at a vertex or at an arc. The
+ table will be accessed by |arrange_layers_by_baselines| to
+ determine the ideal vertical placements.
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+ -- Now, arrange the nodes in a line:
+ vertices [1].pos.x = 0
+ layer[ vertices [1] ] = #vertices
+ for i=2,#vertices do
+ local d = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, vertices[i-1], vertices[i])
+ vertices [i].pos.x = vertices[i-1].pos.x + d
+ layer[ vertices [i] ] = #vertices
+ end
+\end{codeexample}
+
+ Now comes the actual Huffman algorithm: Always find the vertices
+ with a minimal probability\dots
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+ -- Now, do the Huffman thing...
+ while #vertices > 1 do
+ -- Find two minimum probabilities
+ local min1, min2
+
+ for i=1,#vertices do
+ if not min1 or prop(vertices[i]) < prop(vertices[min1]) then
+ min2 = min1
+ min1 = i
+ elseif not min2 or prop(vertices[i]) < prop(vertices[min2]) then
+ min2 = i
+ end
+ end
+\end{codeexample}
+ %
+ \dots and connect them with a new node. This new node gets the
+ option |HuffmanNode|. It is now the job of the higher layers to map
+ this option to something ``nice''.
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+ -- Create new node:
+ local p = prop(vertices[min1]) + prop(vertices[min2])
+ local v = InterfaceToAlgorithms.createVertex(self, { generated_options = {{key="HuffmanNode"}}})
+ probability[v] = p
+ layer[v] = #vertices-1
+ v.pos.x = (vertices[min1].pos.x + vertices[min2].pos.x)/2
+ vertices[#vertices + 1] = v
+
+ InterfaceToAlgorithms.createEdge (self, v, vertices[min1],
+ {generated_options = {{key="HuffmanLabel", value = "0"}}})
+ InterfaceToAlgorithms.createEdge (self, v, vertices[min2],
+ {generated_options = {{key="HuffmanLabel", value = "1"}}})
+
+ table.remove(vertices, math.max(min1, min2))
+ table.remove(vertices, math.min(min1, min2))
+ end
+\end{codeexample}
+ %
+ Ok, we are mainly done now. Finish by computing vertical placements
+ and do formal cleanup.
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+ layered.arrange_layers_by_baselines(layers, self.adjusted_bb, self.ugraph)
+end
+\end{codeexample}
+
+ In order to use the class, we have to make sure that, on the
+ display layer, the options |HuffmanLabel| and |HuffmanNode| are
+ defined. This is done by adding, for instance, the following to
+ \tikzname:
+ %
+\begin{codeexample}[code only]
+\pgfkeys{
+ /graph drawing/HuffmanLabel/.style={
+ /tikz/edge node={node[fill=white,font=\footnotesize,inner sep=1pt]{#1}}
+ },
+ /graph drawing/HuffmanNode/.style={
+ /tikz/.cd,circle,inner sep=0pt,outer sep=0pt,draw,minimum size=3pt
+ }
+}
+\end{codeexample}
+ "]]
+}
+
+
+---
+
+declare {
+ key = "probability",
+ type = "number",
+ initial = "1",
+
+ summary = [["
+ The probability parameter. It is used by the Huffman algorithm to
+ group nodes.
+ "]]
+}
+
+-- Imports
+
+local Storage = require 'pgf.gd.lib.Storage'
+
+-- Storages
+
+local probability = Storage.new()
+local layer = Storage.new()
+
+
+function SimpleHuffman:run()
+ -- Construct a Huffman tree on top of the vertices...
+
+ -- Shorthand
+ local function prop (v)
+ return probability[v] or v.options['probability']
+ end
+
+ -- Copy the vertex table, since we are going to modify it:
+ local vertices = {}
+ for i,v in ipairs(self.ugraph.vertices) do
+ vertices[i] = v
+ end
+
+ -- Now, arrange the nodes in a line:
+ vertices [1].pos.x = 0
+ layer[vertices [1]] = #vertices
+ for i=2,#vertices do
+ local d = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, vertices[i-1], vertices[i])
+ vertices [i].pos.x = vertices[i-1].pos.x + d
+ layer[vertices [i]] = #vertices
+ end
+
+ -- Now, do the Huffman thing...
+ while #vertices > 1 do
+ -- Find two minimum probabilities
+ local min1, min2
+
+ for i=1,#vertices do
+ if not min1 or prop(vertices[i]) < prop(vertices[min1]) then
+ min2 = min1
+ min1 = i
+ elseif not min2 or prop(vertices[i]) < prop(vertices[min2]) then
+ min2 = i
+ end
+ end
+
+ -- Create new node:
+ local p = prop(vertices[min1]) + prop(vertices[min2])
+ local v = InterfaceToAlgorithms.createVertex(self, { generated_options = {{key="HuffmanNode"}}})
+ probability[v] = p
+ layer[v] = #vertices-1
+ v.pos.x = (vertices[min1].pos.x + vertices[min2].pos.x)/2
+ vertices[#vertices + 1] = v
+
+ InterfaceToAlgorithms.createEdge (self, v, vertices[min1],
+ {generated_options = {{key="HuffmanLabel", value = "0"}}})
+ InterfaceToAlgorithms.createEdge (self, v, vertices[min2],
+ {generated_options = {{key="HuffmanLabel", value = "1"}}})
+
+ table.remove(vertices, math.max(min1, min2))
+ table.remove(vertices, math.min(min1, min2))
+ end
+
+ layered.arrange_layers_by_baselines(layer, self.adjusted_bb, self.ugraph)
+end
+
+return SimpleHuffman
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt
new file mode 100644
index 0000000000..052ebdcdb8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt
@@ -0,0 +1,20 @@
+graph [layered layout] {
+ Alice;
+ Bob;
+ Charly;
+ Dave;
+ Eve;
+ Fritz;
+ George;
+ Alice -> Bob;
+ Alice -> Charly;
+ Charly -> Dave;
+ Bob -> Dave;
+ Dave -> Eve;
+ Eve -> Fritz;
+ Fritz -> Alice;
+ George -> Eve;
+ George -> Fritz;
+ Alice -> George;
+}
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/library.lua
new file mode 100644
index 0000000000..0c977600a7
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/examples/library.lua
@@ -0,0 +1,30 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This package presents some examples of how different aspects of the
+-- graph drawing engine can be used. In particular, the algorithms of
+-- this package are not really meant to be used to layout graphs
+-- (although they can be used, in principle); rather you are invited
+-- to have a look at their implementation and to adapt them to your needs.
+--
+-- @library
+
+local examples
+
+
+-- Load algorithms from:
+require "pgf.gd.examples.SimpleDemo"
+require "pgf.gd.examples.SimpleEdgeDemo"
+require "pgf.gd.examples.SimpleHuffman"
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GraphAnimationCoordination.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GraphAnimationCoordination.lua
new file mode 100644
index 0000000000..31f8f27431
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GraphAnimationCoordination.lua
@@ -0,0 +1,638 @@
+-- Copyright 2015 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--
+--
+-- @field.visible_objects An array which stores for each supernode a mapping
+-- of snapshots to the related visible snapshot nodes.
+-- Note that these mappings may differ from the supergraph
+-- because if there are two snapshot nodes in consecutive snapshots
+-- then the first can be shown for a longer time period to
+-- put aside some fade animations.
+-- @field is_first A table storing for each snapshot node or snapshot arc if it
+-- appears in its snapshot. This means that in the previous snapshot
+-- there is no corresponding arc or node.
+-- @field is_last A table storing for each snapshot node or arc if there
+-- is no representative in the next snapshot.
+-- @field move_on_enter A table which stores for each snapshot object if it is in
+-- motion while it appears in its snapshot.
+-- @field move_on_leave A table which stores for each snapshot object if it is in
+-- motion while switching to the next snapshot
+-- @field last_rep
+-- A table which stores for every snapshot node if the representing (visible) node
+-- disappears with the next snapshot.
+--
+-- @field previous_node The same as |next_node| just for the previous node
+-- @field next_node A Storage to map each snapshot node to the next node in the
+-- following snapshot related to the same supernode.
+-- If in the next snapshot there is node following snapshot node
+-- then the value is nil.
+--
+local GraphAnimationCoordination = {}
+
+-- Imports
+local lib = require "pgf.gd.lib"
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+local Storage = require "pgf.gd.lib.Storage"
+local Coordinate = require "pgf.gd.model.Coordinate"
+
+
+declare {
+ key = "modified",
+ type = "boolean",
+ Initial = false,
+ documentation = [["
+ This key specifies, if a supernode changed its
+ visual properties since the last snapshot.
+ The default value is |false| and prevent the algorithm
+ to produce a lot of unnecessary animations.
+ "]]
+}
+
+declare {
+ key = "unmodified",
+ use = {
+ { key = "modified", boolean = false},
+ },
+}
+
+
+---
+declare {
+ key = "minimum rest time",
+ type = "number",
+ initial = 0.5,
+ documentation = [["
+ This key specifies a minimum time in which a single node
+ has to be prohibited to be animated.
+ For a node with minimum rest time of 1s that exists in a snapshot
+ at time $t$ this means that all animations including movements and fadings
+ are only allowed before $t$-0.5s and after $t$+0.5s.
+ "]],
+}
+
+declare {
+ key = "maximum motion time",
+ type = "number",
+ initial = math.huge,
+ documentation = [["
+ Use this key if you want to limit the time during nodes are allowed to move
+ when they changing their positions.
+ "]],
+}
+
+declare {
+ key = "overlapping transition",
+ type = "boolean",
+ initial = true,
+ documentation = [["
+ Use this key if you want to allow that the fade animations for or
+ disappearing nodes may occurs while the mid time between two snapshots.
+ If false then the appearing ends on the midtime and the disappearing
+ starts in this moment.
+ "]]
+}
+
+---
+declare {
+ key = "default evolving graph animation",
+ algorithm = GraphAnimationCoordination,
+ phase = "evolving graph animation",
+ phase_default = true,
+ summary = [["
+ This phase animates all vertices including movements and
+ fade in or fade out animations given an evolving graph as sequence
+ of single snapshot graphs.
+ "]],
+ documentation = [["
+ This phase animates all vertices including movements and
+ fade in or fade out animations given an evolving graph as sequence
+ of single snapshot graphs.
+
+ Your algorithm needs to work on evolving graphs and has to use
+ the |evolving graph animation| phase. You do not need to use
+ this key by yourself then because this key starts the default
+ algorithm algorithm of the phase.
+ %
+ \begin{codeexample}[]
+ local ga_class = self.digraph.options.algorithm_phases['evolving graph animation']
+ -- animate graph
+ ga_class.new {
+ main_algorithm = self,
+ supergraph = supergraph,
+ digraph = self.digraph,
+ ugraph = self.ugraph
+ }:run()
+ \end{codeexample}
+
+ This algorithm and phase require a supergraph instance and the original
+ digraph and ugraph. Note that you have to set the layout of the snapshot
+ nodes before running algorithms of this is useful.
+ "]],
+}
+
+-- Help functions
+
+--
+-- Appends a move animation to a given snapshot object such that the
+-- object moves from one point to another on a straight line. Note
+-- that the coordinates of the two points are given as relative
+-- coordinates to the current origin of the object.
+--
+-- This means if we want to move a node 1cm to the right the value of
+-- |c_from| has to be (0,0) while |c_to| must be (1,0). The argument
+-- |c_from| is useful for a node which has a position but its
+-- previous node related to the same supervertex is at a different
+-- position. Then we can use this argument to move the new node to
+-- its origin position for smooth transitions.
+--
+-- @field object The snapshot object which should be moved
+--
+-- @field c_from The coordinate where the animation starts
+--
+-- @field c_to The coordinate where the animation should end
+--
+-- @field t_start The time when the movement starts.
+--
+-- @field t_end The time when the animation stops.
+local function append_move_animation(object, c_from, c_to, t_start, t_end)
+ if not object then return end
+ assert(object, "no object to animate")
+ if ((c_from.x~=c_to.x) or (c_from.y~=c_to.y))then
+ local animations = object.animations or {}
+ local c1 = Coordinate.new((2*c_from.x+c_to.x)/3,(2*c_from.y+c_to.y)/3)
+ local c2 = Coordinate.new((c_from.x+2*c_to.x)/3,(c_from.y+2*c_to.y)/3)
+ local t1 = (7*t_start + 5*t_end)/12
+ local t2 = (5*t_start + 7*t_end)/12
+ table.insert(animations, {
+ attribute = "translate",
+ entries = {
+ { t = t_start, value = c_from},
+-- { t = t1, value = c1 },
+-- { t = t2, value = c2 },
+ { t = t_end, value = c_to }
+ },
+ options = { { key = "freeze at end", },
+-- {key = "entry control", value="0}{1",}
+ }
+ })
+ object.animations = animations
+ end
+end
+
+local function append_fade_animation(object, v_start, v_end, t_start, t_end)
+ local animations = object.animations or {}
+
+ if v_start == 0 then
+ table.insert(animations, {
+ attribute = "stage",
+ entries = { { t = t_start, value = "true"}, },
+ options = { { key = "freeze at end" } }
+ })
+ elseif v_end == 0 and nil then
+ table.insert(animations, {
+ attribute = "stage",
+ entries = { { t = t_end, value = "false"}, },
+ options = { --{ key = "freeze at end" }
+ }
+ })
+ end
+
+ table.insert(animations, {
+ attribute = "opacity",
+ entries = {
+ { t = t_start, value = v_start },
+ { t = t_end, value = v_end } },
+ options = { { key = "freeze at end" } }
+ })
+ object.animations = animations
+end
+
+--
+-- check if the difference/vector between two pairs (a1,a2),(b1,b2) of points
+-- is the same.
+local function eq_offset(a1, a2, b1, b2)
+ local dx = ((a1.x-a2.x) - (b1.x-b2.x))
+ local dy = ((a1.y-a2.y) - (b1.y-b2.y))
+ if dx<0 then dx = -dx end
+ if dy<0 then dy = -dy end
+ return dx<0.001 and dy<0.001
+end
+
+--
+-- Check if two arcs connect a pair of nodes at the same position.
+-- This can be used as an indicator that two consecutive arcs
+-- can be represented by the same arc object.
+--
+local function eq_arc(arc1, arc2)
+ if not arc1 or not arc2 then
+ return false
+ end
+ return eq_offset(arc1.tail.pos, arc1.head.pos, arc2.tail.pos, arc2.head.pos)
+end
+
+
+-- Implementation
+
+function GraphAnimationCoordination:run()
+ assert(self.supergraph, "no supergraph defined")
+
+ self.is_first = Storage.new()
+ self.is_last = Storage.new()
+ self.last_rep = Storage.new()
+ self.move_on_enter = Storage.new()
+ self.move_on_leave = Storage.new()
+ self.previous_node = Storage.new()
+ self.next_node = Storage.new()
+ self.visible_objects = Storage.new()
+
+
+ self:precomputeNodes()
+ self:precomputeEdges()
+ self:animateNodeAppearing()
+ self:animateEdgeAppearing()
+ self:generateNodeMotions()
+ self:generateEdgeMotions()
+end
+
+function GraphAnimationCoordination:generateNodeMotions(node_types)
+ local supergraph = self.supergraph
+ local graph = self.digraph
+
+ for _, supervertex in ipairs(self.supergraph.vertices) do
+ local lj = -1
+ local last_v = nil
+ local last_time = nil
+ for j, s in ipairs(supergraph.snapshots) do
+ local vertex = supergraph:getSnapshotVertex(supervertex, s)
+
+ if lj == j-1 and vertex and last_v then
+ local mrt1 = last_v.options["minimum rest time"]/2
+ local mrt2 = vertex.options["minimum rest time"]/2
+
+ local s1 = Coordinate.new(0,0)
+ local e1 = Coordinate.new(vertex.pos.x-last_v.pos.x,-vertex.pos.y+last_v.pos.y)
+
+ local s2 = Coordinate.new(-vertex.pos.x+last_v.pos.x,vertex.pos.y-last_v.pos.y)
+ local e2 = Coordinate.new(0,0)
+
+ local t_end = s.timestamp - math.max(0, mrt2)
+ local t_start = last_time + math.max(0,mrt1)
+
+ local representative = self.visible_objects[supervertex][s]
+ if representative == vertex then
+ append_move_animation(vertex, s2, e2, t_start, t_end)
+ append_move_animation(last_v, s1, e1, t_start, t_end)
+ else
+ append_move_animation(representative,s1,e1,t_start,t_end)
+ end
+ end
+ last_time = s.timestamp
+ lj = j
+ last_v = vertex
+ end
+ end
+end
+
+
+
+
+
+function GraphAnimationCoordination:generateEdgeMotions()
+ local supergraph = self.supergraph
+ local graph = self.digraph
+
+ for i, arc in ipairs(supergraph.arcs) do
+ local head = arc.head
+ local tail = arc.tail
+
+ local last_arc = nil
+ local last_time = nil
+ local last_v = nil
+ local last_w = nil
+
+ for j, s in ipairs(supergraph.snapshots) do
+ local v = supergraph:getSnapshotVertex(tail,s)
+ local w = supergraph:getSnapshotVertex(head,s)
+
+ if v and w then
+ local this_arc = graph:arc(v,w) --or graph:arc(w,v)
+ if this_arc then
+ if this_arc and last_arc then
+ local mrt1 = last_v.options["minimum rest time"]/2
+ local mrt2 = v.options["minimum rest time"]/2
+
+ local s1 = Coordinate.new(0,0)--lv.pos
+ local e1 = Coordinate.new(v.pos.x-last_v.pos.x,-v.pos.y+last_v.pos.y)
+
+ local s2 = Coordinate.new(-v.pos.x+last_v.pos.x,v.pos.y-last_v.pos.y)
+ local e2 = Coordinate.new(0,0)
+
+ local t_end = s.timestamp - math.max(0,mrt2)
+ local t_start = last_time + math.max(0,mrt1)
+
+ local representative = self.visible_objects[arc][s]
+ if representative == this_arc then
+ append_move_animation(last_arc, s1, e1, t_start,t_end)
+ append_move_animation(this_arc, s2, e2, t_start,t_end)
+ else
+ append_move_animation(representative,s1,e1,t_start,t_end)
+ end
+ this_arc = representative
+ end
+ last_arc = this_arc
+ last_v = v
+ last_time = s.timestamp
+ else
+ last_arc = nil
+ end
+ else
+ last_arc = nil
+ end
+ end
+ end
+end
+
+--
+--
+-- @field t_transition The mid time between two snapshot times.
+-- @field fade_duration The duration of the fade animation
+-- @field overlapping A boolean defining if the animation occurs
+-- before and after the mid time (true) or if it
+-- starts/end only in one interval (false)
+-- @field closing A boolean specifying if this is an outfading time
+local function compute_fade_times(t_transition, fade_duration, overlapping, closing)
+
+ if overlapping then
+ t_start = t_transition - fade_duration / 2
+ t_end = t_transition + fade_duration / 2
+ else
+ if closing then
+ t_start = t_transition - fade_duration
+ t_end = t_transition
+ else
+ t_start = t_transition
+ t_end = t_transition + fade_duration
+ end
+ end
+ return {t_start = t_start, t_end = t_end}
+end
+
+function GraphAnimationCoordination:animateNodeAppearing()
+ local supergraph = self.supergraph
+ for i,vertex in ipairs(self.ugraph.vertices) do
+ local snapshot = supergraph:getSnapshot(vertex)
+ local interval = snapshot.interval
+ local supernode = supergraph:getSupervertex(vertex)
+ local representative = self.visible_objects[supernode][snapshot]
+ local overlapping_in = true -- init true for crossfading
+ local overlapping_out= true
+ local minimum_rest_time = math.max(0,vertex.options["minimum rest time"])
+ local allow_overlapping = vertex.options["overlapping transition"]
+ local fadein_duration = 0.01
+ local fadeout_duration = 0.01
+
+ if self.is_first[vertex] then
+ fadein_duration = self.ugraph.options["fadein time"]
+ overlapping_in = false or allow_overlapping
+ end
+ if self.is_last[vertex] then
+ fadeout_duration = self.ugraph.options["fadeout time"]
+ overlapping_out = false or allow_overlapping
+ end
+
+ if fadein_duration == math.huge or fadein_duration<0 then
+ fadein_duration = (interval.to-interval.from-minimum_rest_time)/2
+ if overlapping then fadein_duration = fadein_duration * 2 end
+ end
+ if fadeout_duration == math.huge or fadeout_duration<0 then
+ fadeout_duration = (interval.to-interval.from-minimum_rest_time)/2
+ if overlapping then fadeout_duration = fadeout_duration*2 end
+ end
+
+ local fin = compute_fade_times(interval.from, fadein_duration, overlapping_in, false)
+ local fout = compute_fade_times(interval.to, fadeout_duration, overlapping_out, true)
+
+ vertex.animations = vertex.animations or {}
+
+ if representative~= vertex then
+ table.insert(vertex.animations,{
+ attribute = "stage",
+ entries = { { t = 0, value = "false"}, },
+ options = {}
+ })
+ end
+
+ if interval.from > -math.huge and (vertex == representative or self.is_first[vertex]) then
+ -- only appears if the snapshot node is its own repr. or if in the prev snapshot is
+ -- no representative.
+ append_fade_animation(representative, 0, 1, fin.t_start, fin.t_end)
+ end
+ if interval.to < math.huge and (self.is_last[vertex] or self.last_rep[vertex]) then
+ -- The snapshot node only disappears when the node is not visible
+ -- in the next or (this=)last snapshot:
+ append_fade_animation(representative, 1, 0, fout.t_start, fout.t_end)
+ end
+ end
+end
+
+
+
+function GraphAnimationCoordination:animateEdgeAppearing()
+ local supergraph = self.supergraph
+ local graph = self.digraph
+ for _,edge in ipairs(graph.arcs) do
+ local snapshot = supergraph:getSnapshot(edge.head)
+ local int = snapshot.interval
+ local superarc = supergraph:getSuperarc(edge)
+ local representative = self.visible_objects[superarc][snapshot] or edge
+
+ local minimum_rest_time = math.max(0,edge.head.options["minimum rest time"]/2,
+ edge.tail.options["minimum rest time"]/2)
+
+ local appears = math.max(int.from, int.from)
+ local disappears = math.min(int.to, int.to)
+
+ local overlapping_in = true -- init true for crossfading
+ local overlapping_out= true
+ local fadein_duration = 0.01
+ local fadeout_duration = 0.01
+ local allow_overlapping = (edge.tail.options["overlapping transition"] and edge.head.options["overlapping transition"])
+
+ if self.is_first[edge] and not self.move_on_enter[edge] and not self.move_on_enter[edge.head] then
+ fadein_duration = self.ugraph.options["fadein time"]
+ overlapping_in = false or allow_overlapping
+ end
+
+ if self.is_last[edge] and not self.move_on_leave[edge] then
+ fadeout_duration = self.ugraph.options["fadeout time"]
+ overlapping_out = false or allow_overlapping
+ end
+
+
+ if self.is_first[edge]
+ and (self.move_on_enter[edge.head]
+ or self.move_on_enter[edge.tail] )
+ then
+ appears = snapshot.timestamp - minimum_rest_time
+ end
+ if self.is_last[edge] and
+ (self.move_on_leave[edge.head]
+ or self.move_on_leave[edge.tail]
+ ) then
+ disappears = snapshot.timestamp + minimum_rest_time
+ end
+
+ local fin = compute_fade_times(appears, fadein_duration, overlapping_in,false)
+ local fout = compute_fade_times(disappears,fadeout_duration,overlapping_out,true)
+
+ edge.animations = edge.animations or {}
+
+ if representative~=edge then
+ table.insert(edge.animations,{
+ attribute = "stage",
+ entries = { { t = 0, value = "false"}, },
+ options = {}})
+ end
+
+ -- Fade in:
+ if appears > -math.huge and (edge == representative or self.is_first[edge]) then
+ append_fade_animation(representative, 0, 1, fin.t_start, fin.t_end )
+ end
+
+ -- Fade out:
+ if disappears < math.huge and (self.is_last[edge] or self.last_rep[edge])then
+ append_fade_animation(representative, 1, 0, fout.t_start,fout.t_end )
+ end
+ end
+end
+
+function GraphAnimationCoordination:precomputeNodes()
+ local supergraph = self.supergraph
+
+ for _, supernode in ipairs(supergraph.vertices) do
+
+ local vis_nodes = {}
+ self.visible_objects[supernode] = vis_nodes
+
+ local any_previous_node = nil
+ local previous_representant = nil
+ local node_before = nil
+
+ for i, s in ipairs(supergraph.snapshots) do
+ local node = supergraph:getSnapshotVertex(supernode, s)
+
+ if node then
+ -- assume the node is the last node
+ self.is_last[node] = true
+
+ if node.options["modified"] then
+ -- modified
+ vis_nodes[s] = node
+ previous_representant = node
+ if any_previous_node then
+ self.last_rep[any_previous_node] = true
+ end
+ else
+ -- unmodified
+ previous_representant = previous_representant or node
+ vis_nodes[s] = previous_representant
+ end
+ any_previous_node = node
+
+ if node_before then
+ self.is_last[node_before] = false
+ self.previous_node[node] = node_before
+ self.next_node[node_before] = node
+
+ local do_move = (( node.pos.x ~= node_before.pos.x )
+ or (node.pos.y ~= node_before.pos.y))
+ self.move_on_enter[node] = do_move
+ self.move_on_leave[node_before] = do_move
+ else
+ self.is_first[node] = true
+ end
+ node_before = node
+ else
+ node_before = nil
+ end
+ end
+ end
+end
+
+function GraphAnimationCoordination:precomputeEdges()
+ -- 1. classify arcs (appearing, disappearing)
+ for _, arc in ipairs(self.digraph.arcs) do
+ local head = arc.head
+ local tail = arc.tail
+ if not ( self.is_first[head] or self.is_first[tail]) then
+ if not self.digraph:arc(self.previous_node[tail], self.previous_node[head]) then
+ -- new arc connects existing nodes
+ self.is_first[arc] = true
+ end
+ else
+ -- arc and at least one node is new.
+ self.is_first[arc] = true
+ end
+ if not ( self.is_last[head] or self.is_last[tail]) then
+ if not self.digraph:arc(self.next_node[tail],self.next_node[head]) then
+ -- arc disappears while nodes are still in the next snapshot
+ self.is_last[arc] = true
+ end
+ else
+ -- arc and at least one node disappears in the next snapshot
+ self.is_last[arc] = true
+ end
+ self.move_on_enter[arc] = self.move_on_enter[head] or self.move_on_enter[tail]
+ self.move_on_leave[arc] = self.move_on_leave[head] or self.move_on_leave[tail]
+ end
+
+ -- 2. precompute the unmodified edges
+ local supergraph = self.supergraph
+
+ for _, superarc in ipairs(supergraph.arcs) do
+ local vis_objects = {}
+ self.visible_objects[superarc] = vis_objects
+
+ local previous_arc
+ local previous_representant
+
+ for _, s in ipairs(supergraph.arc_snapshots[superarc]) do
+ local head = supergraph:getSnapshotVertex(superarc.head, s)
+ local tail = supergraph:getSnapshotVertex(superarc.tail, s)
+ -- use the digraph because the snapshot arc is not synced
+ local arc = self.digraph:arc(tail, head)
+
+ local modified = false
+ local opt_array = arc:optionsArray('modified')
+ for i = 1,#opt_array.aligned do
+ modified = modified or opt_array[i]
+ end
+
+ if modified or
+ not eq_arc(arc, previous_arc) or self.is_first[arc] then
+ --modified
+ previous_representant = arc
+ vis_objects[s] = arc
+ if previous_arc then
+ self.last_rep[previous_arc] = true
+ end
+ else
+ -- unmodified
+ previous_representant = previous_representant or arc
+ vis_objects[s] = previous_representant
+ end
+ previous_arc = arc
+ end
+ end
+end
+-- Done
+
+return GraphAnimationCoordination
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GreedyTemporalCycleRemoval.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GreedyTemporalCycleRemoval.lua
new file mode 100644
index 0000000000..0c348bcc8f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/GreedyTemporalCycleRemoval.lua
@@ -0,0 +1,177 @@
+-- Copyright 2015 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+local GreedyTemporalCycleRemoval = {}
+
+-- Imports
+local lib = require "pgf.gd.lib"
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+local Vertex = require "pgf.gd.model.Vertex"
+local Digraph = require "pgf.gd.model.Digraph"
+local Coordinate = require "pgf.gd.model.Coordinate"
+
+local PriorityQueue = require "pgf.gd.lib.PriorityQueue"
+
+-- Keys
+
+---
+
+declare {
+ key = "split critical arc head",
+ type = "boolean",
+ initial = true,
+ summary = "Specifies, that for a critical the tail node is separated"
+}
+
+---
+
+declare {
+ key = "split critical arc tail",
+ type = "boolean",
+ initial = true,
+ summary = "Specifies, that for a critical the tail node is separated"
+}
+
+---
+
+declare {
+ key = "greedy temporal cycle removal",
+ algorithm = GreedyTemporalCycleRemoval,
+ phase = "temporal cycle removal",
+ phase_default = true,
+ summary = [["
+ A temporal dependency cycle is a cyclic path in the supergraph of
+ an evolving graph. Use this key if you want remove all temporal
+ dependency cycles by a greedy strategy which incrementally inserts
+ edge checks if this edge creates a cycle and splits at least one node
+ into two supernode at a given time.
+ "]],
+ documentation = [["
+ See ToDo
+ "]]
+}
+
+-- Help functions
+local function reachable(graph, v, w)
+ local visited = {}
+ local queue = PriorityQueue.new()
+ queue:enqueue(v,1)
+ while not queue:isEmpty() do
+ local vertex = queue:dequeue()
+ if vertex==w then
+ return true
+ end
+ local outgoings = graph:outgoing(vertex)
+ for _, e in ipairs(outgoings) do
+ local head = e.head
+ if not visited[head] then
+ visited[head] = true
+ if head == w then
+ return true
+ else
+ queue:enqueue(head,1)
+ end
+ end
+ end
+ end
+ return false
+end
+
+-- Implementation
+
+function GreedyTemporalCycleRemoval:run()
+ local supergraph = assert(self.supergraph, "no supergraph passed")
+ local digraph = assert(self.digraph, "no digraph passed to the phase")
+ local split_tail = digraph.options["split critical arc tail"]
+ local split_head = digraph.options["split critical arc head"]
+ assert(split_tail or split_head, "without splitting nodes dependency cycles cannot be removed.")
+
+ self:iterativeCycleRemoval(supergraph, split_tail, split_head)
+end
+
+--
+-- Resolves all dependencies by splitting supernodes into multiple supernodes.
+-- To resolve a cycle each edge will be inserted into a dependency graph
+-- successively. Each time such edge closes a cycle the head and tail will
+-- be split at the related snapshot.
+--
+-- @param supergraph
+--
+function GreedyTemporalCycleRemoval:iterativeCycleRemoval(supergraph, split_tail, split_head)
+ -- Build up the global dependency graph
+ -- A supernode v directly depends on another supernode w if
+ -- there is a snapshot in which w is a child of w
+ local dependency_graph = Digraph.new(supergraph)
+ local stable_arcs = {}
+ for i, snapshot in ipairs(supergraph.snapshots) do
+ --local tree = snapshot.spanning_tree
+ for _,tree in ipairs(snapshot.spanning_trees) do
+ local new_arcs = {}
+
+ for _, e in ipairs(tree.arcs) do
+ if e.head.kind ~= "dummy" and e.tail.kind~="dummy" then
+ table.insert(new_arcs, e)
+
+ local sv = supergraph:getSupervertex(e.tail)
+ local sw = supergraph:getSupervertex(e.head)
+ local dep_arc = dependency_graph:arc(sv, sw)
+
+
+ if (not dep_arc) then
+ -- check if the edge v->w closes a cycle in the dependency graph
+ --pgf.debug{dependency_graph}
+ local cycle_arc = reachable(dependency_graph, sw, sv)
+ dep_arc = dependency_graph:connect(sv,sw)
+-- texio.write("\ncheck ".. sv.name.."->" .. sw.name)
+ if cycle_arc then
+ if split_tail then
+ supergraph:splitSupervertex(sv, { [1]=snapshot })
+ end
+ if split_head then
+ supergraph:splitSupervertex(sw, { [1]=snapshot })
+ end
+
+ -- rebuild dependency graph
+ dependency_graph = Digraph.new(supergraph)
+
+ for _, arc in ipairs(stable_arcs) do
+ dependency_graph:connect(arc.tail, arc.head)
+ end
+
+ for _, arc in ipairs(new_arcs) do
+ local sv = supergraph:getSupervertex(arc.tail)
+ local sw = supergraph:getSupervertex(arc.head)
+ dependency_graph:connect(sv, sw)
+ end
+ end -- end of resolve cycle_arc
+ end
+ end
+ end
+ -- Stable Arcs:
+ for _, arc in ipairs(new_arcs) do
+
+ local sv = supergraph:getSupervertex(arc.tail)
+ local sw = supergraph:getSupervertex(arc.head)
+ local deparc = dependency_graph:arc(sv, sw)
+-- if not deparc or not stable_arcs[deparc] then
+-- stable_arcs[deparc] = true
+ table.insert(stable_arcs, deparc)
+-- end
+
+ end
+ end -- end for spanning_tree
+ end -- end for snapshot
+end
+
+
+-- Done
+
+return GreedyTemporalCycleRemoval
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Skambath2016.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Skambath2016.lua
new file mode 100644
index 0000000000..2beec1e216
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Skambath2016.lua
@@ -0,0 +1,875 @@
+-- Copyright 2015 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+--
+
+-- Imports
+require "pgf.gd.trees.ChildSpec"
+
+local Digraph = require "pgf.gd.model.Digraph"
+local Vertex = require "pgf.gd.model.Vertex"
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+local layered = require "pgf.gd.layered"
+local tlayered = require "pgf.gd.experimental.evolving.layered"
+local SpanningTreeComputation = require "pgf.gd.trees.SpanningTreeComputation"
+local lib = require "pgf.gd.lib"
+
+local Storage = require "pgf.gd.lib.Storage"
+local PriorityQueue = require "pgf.gd.lib.PriorityQueue"
+
+local Supergraph = require "pgf.gd.experimental.evolving.Supergraph"
+
+local LayoutPipeline = require "pgf.gd.control.LayoutPipeline"
+local Direct = require "pgf.gd.lib.Direct"
+
+--
+--
+local Skambath2016 = {}
+
+
+---
+declare {
+ key = "animated tree layout",
+ algorithm = Skambath2016,
+ postconditions = {
+ upward_oriented = true
+ },
+ documentation_in = "pgf.gd.evolving.doc"
+}
+
+---
+declare {
+ key = "animated binary tree layout",
+ use = {
+ { key = "animated tree layout" },
+ { key = "minimum number of children", value = 2 },
+ { key = "significant sep", value = 0 },
+ },
+
+ documentation_in = "pgf.gd.evolving.doc"
+}
+
+---
+declare {
+ key = "extended animated binary tree layout",
+ use = {
+ { key = "animated tree layout" },
+ { key = "minimum number of children", value=2 },
+ { key = "missing nodes get space" },
+ { key = "significant sep", value = 0 }
+ },
+ documentation_in = "pgf.gd.evolving.doc"
+}
+
+
+
+
+
+-- Help functions
+
+---
+-- Borders models the borderlines / the line of border vertices
+-- of a tree or subtree structure which can change over time.
+-- Each ordered and rooted tree or subtree has vertices per layer for which they
+-- are on the outer places. On the left or respectively on the right.
+-- The field |left| and |right| stores the both borderlines.
+-- A \emph{borderline} is an array. This array contains for each layer of the tree
+-- a table mapping a given snapshot to the related border-vertex of the layer
+-- in the snapshot.
+--
+-- @field left
+-- @field right
+--
+local Borders = {}
+Borders.__index = Borders
+
+
+-- Namespace
+
+--require("pgf.gd.experimental.evolving").Borders = Borders
+
+
+--- Create a new tree border description.
+--
+--
+function Borders.new()
+ return setmetatable( {left = {}, right = {}}, Borders )
+end
+
+function Borders:addBoth(layer, snapshot, vertex)
+ local lleft = self.left[layer] or {}
+ local lright = self.right[layer] or {}
+ assert(not lleft[snapshot] and not lright[snapshot], "borders already defined for given layer and snapshot")
+ lleft[snapshot] = vertex
+ lright[snapshot] = vertex
+ self.left[layer] = lleft
+ self.right[layer] = lright
+end
+
+function Borders:appendBelow(level, borders)
+ assert(borders, "invalid argument for borders. Value must not be 'nil'.")
+ assert((#self.left == #self.right) and (#self.left == level), "cannot be appended")
+ local new_level = borders:getLevel()
+ for i = 1, new_level do
+ self.left[i + level] = borders.left[i]
+ self.right[i + level] = borders.right[i]
+ end
+end
+
+---
+--
+-- @return the number of levels in which bordervertices exists.
+function Borders:getLevel()
+ assert(#self.left == #self.right, "different levels")
+ return #self.left
+end
+
+function Borders.copyBordersAtSnapshot(source, target, snapshot)
+ local source_level = source:getLevel()
+ for i = 1, source_level do
+ level_border_left = target.left[i] or {}
+ level_border_right = target.right[i] or {}
+ assert(not level_border_left[snapshot] and not level_border_right[snapshot],
+ "border for a given snapshot already defined")
+ level_border_left[snapshot] = source.left[i][snapshot]
+ level_border_right[snapshot] = source.right[i][snapshot]
+ target.left[i] = level_border_left
+ target.right[i] = level_border_right
+ end
+end
+
+--
+-- Adapt existing borders with the borders of a group which will be
+-- placed on the right next to the existing borders. For each level
+-- and time in which the group has a border the borders on the right
+-- will be replaced with this border. If it is not existing in the old
+-- borders then also the left border will be adapted
+--
+-- @param borders The existing borders. These will be modified with
+-- the borders of
+--
+-- @param group_borders The borders of the group
+--
+-- @param snapshots All snapshots in which checking for distances is necessary.
+--
+local function adapt_borders(borders, group_borders, snapshots, ignore_dummies)
+ for level = 1, group_borders:getLevel() do
+ local l = borders.left[level] or {}
+ local r = borders.right[level] or {}
+ for _, s in pairs(snapshots) do
+ if ignore_dummies then
+ local gls,grs = group_borders.left[level][s], group_borders.right[level][s]
+ if gls~=nil then
+ if gls.kind~="dummy" then
+ l[s] = l[s] or gls
+ end
+ end
+ if grs~=nil then
+ if grs.kind~="dummy" then
+ r[s] = grs or r[s]
+ end
+ end
+ else
+ l[s] = l[s] or group_borders.left[level][s]
+ r[s] = group_borders.right[level][s] or r[s]
+ end
+
+ end
+ borders.left[level] = l
+ borders.right[level] = r
+ end
+
+end
+
+--
+-- Shift all vertices of a group and their descendants
+-- for a certain length into horizontal direction.
+--
+-- @param shift the length all involved vertices
+-- should be shifted in horizontal direction
+--
+--
+-- @param group A group of the spanning trees that should be shifted.
+-- A group entry has to map snapshots to root nodes
+--
+-- @param snapshots An array of at least all snapshots in which the group
+-- has a vertex
+--
+-- @param descendants A table or Storage storing the list of descendants
+-- for each vertex
+--
+-- @return the highest x-coordinate of vertices in the group after the shift.
+-- If there is no vertex which was shifted then -math.huge
+-- will be returned
+--
+local function shift_group(shift, group, snapshots, descendants)
+ assert(group,"no group passed")
+ assert(shift~=math.huge and shift ~=-math.huge,
+ "shift must be a valid finite length")
+ local shifted = {} -- remember which vertex was shifted during this run
+ local anchor = -math.huge
+ for _, s in ipairs(snapshots) do
+ local v = group[s]
+ if not shifted[v] and v then
+ v.pos.x = v.pos.x + shift
+ shifted[v] = true
+
+ -- also shift all descendants of the group vertex
+ for _, d in ipairs(descendants[v]) do
+ if not shifted[d] then
+ d.pos.x = d.pos.x + shift
+ shifted[d] = true
+ end
+ end
+ anchor = math.max(anchor, v.pos.x )
+ end
+ end
+ return anchor
+end
+
+--
+-- Traverse through the spanning tree |tree| of a snapshot and sort
+-- the child nodes into groups. A group summarizes for a given parent
+-- node all children node over time that are at the same child
+-- position. The k-th child group groups[i] maps each snapshot to the
+-- k-th node in the related snapshot.
+--
+--
+-- @field supergraph the supergraph
+--
+-- @field tree the tree or spanning tree to decide the indices of the
+-- child nodes
+--
+-- @field childgroups a Storage which contains the list of childgroups
+-- for each supernode
+--
+-- @field snapshot
+--
+local function precompute_childgroups(supergraph, tree, node, childgroups, snapshot)
+ local outgoings = tree:outgoing(node)
+ if #outgoings > 0 then
+ local supervertex = supergraph:getSupervertex(node)
+ local groups = childgroups[supervertex] or {}
+ for i, e in ipairs(outgoings) do
+
+ group = groups[i] or {}
+ assert(e.head, "no edge")
+ group[snapshot] = e.head
+ groups[i] = group
+ precompute_childgroups(supergraph, tree, e.head, childgroups, snapshot)
+ end
+ assert(supervertex, "no mv")
+ childgroups[supervertex] = groups
+ end
+end
+
+--
+-- Use this function to compute the horizontal positions of all
+-- vertices in a tree by accumulation of the relative shifts on the
+-- path from the root to the vertex recursively.
+--
+-- @param tree the tree in which the vertex's position should be
+-- computed.
+--
+-- @param vertex the next vertex that gets its absolute coordinate.
+--
+-- @param shifts a Storage, which stores for each node the relative
+-- shift between the vertex and its parent.
+--
+-- @param abs_shift the sum of all relative shifts on the path from
+-- the root to the vertex.
+--
+local function accumulate_hpos(tree, vertex, shifts, abs_shift)
+ local new_shift = abs_shift + shifts[vertex]
+ local test = vertex.pos.x
+ vertex.pos.x = new_shift
+-- if vertex.pos.x - test > 0.0001 then texio.write("X")end
+ local outgoings = tree:outgoing(vertex)
+ for _, e in ipairs(outgoings) do
+ accumulate_hpos(tree, e.head, shifts, new_shift)
+ end
+end
+
+
+local function get_next(border_pair, next)
+ local nl = next.left[border_pair.left]
+ local nr = next.right[border_pair.right]
+ assert ((nl and nr) or (not nl and not nr))
+ return {left = nl, right = nr,
+ }
+end
+
+local function add_shift(abs_shift, border_pair, next)
+ abs_shift.left = abs_shift.left + next.left_shift[border_pair.left]
+ abs_shift.right = abs_shift.right + next.right_shift[border_pair.right]
+end
+
+--
+-- Given a tree, computes the required distance between the i-th and the (i+1)-th subtree
+-- of the vertex |snapshot_vertex|.
+--
+-- @param shifts a Storage, which contains for each vertex the relative horizontal shift
+-- to its parent vertex.
+--
+function Skambath2016:computeRequiredDistance(tree, vertex, i, shifts, next)
+ local outgoings = tree:outgoing(vertex)
+-- texio.write("\n::"..vertex.name.. " "..i.."|"..(i+1))
+ if #outgoings > 0 then
+ local clumb = {left = outgoings[1].head,right = outgoings[i].head}
+ if clumb.right.kind=="dummy" then shifts[clumb.right] = 0 end
+ local v0 = outgoings[i].head
+ local v1 = outgoings[i+1].head
+ local shift = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, v0, v1) + shifts[clumb.right]
+ local last0 = {left = clumb.left, right = clumb.right}
+ local last1 = {left = v1, right = v1}
+ local next0 = get_next(last0, next)
+ local next1 = get_next(last1, next)
+ local abs_shift0 = {left = shifts[clumb.left], right = shifts[clumb.right]}
+ local abs_shift1 = {left = 0, right = 0}
+
+ while (next0.left and next1.left) do
+ add_shift(abs_shift0, last0, next)
+ add_shift(abs_shift1, last1, next)
+
+ shift = math.max(shift,
+ layered.ideal_sibling_distance(self.adjusted_bb,
+ self.ugraph,
+ next0.right,
+ next1.left)
+ + abs_shift0.right - abs_shift1.left)
+-- texio.write("\n | "..(next0.right.name or "dummy").."<->"..(next1.left.name or "dummy").." :\t"..shift)
+ last0, last1 = next0, next1
+ next0 = get_next(next0, next)
+ next1 = get_next(next1, next)
+ end
+ return shift, {l0 = last0, l1 = last1, n0 = next0, n1 = next1,abs_shift1 = abs_shift1,abs_shift0=abs_shift0}
+ -- end
+ else
+ return 0
+ end
+end
+
+local function apply_shift(tree, vertex, i, shifts, next, border_ptr, shift)
+ local outgoings = tree:outgoing(vertex)
+-- texio.write("\n" .. (vertex.name or "dummy")..": ".. shift )
+ if #outgoings >= (i+1) then
+ assert(border_ptr, "unexpected error")
+ local last0 = border_ptr.l0
+ local last1 = border_ptr.l1
+ local next0 = border_ptr.n0
+ local next1 = border_ptr.n1
+ local abs0 = border_ptr.abs_shift0
+ local abs1 = border_ptr.abs_shift1
+ local vbase = outgoings[1].head -- before centering the 1st vertex is at x=0
+ local v0 = outgoings[i].head
+ local v1 = outgoings[i+1].head
+ if v0.kind=="dummy" then shifts[v0] = 0 end
+ shifts[v1] = shifts[vbase] + shift
+ if next0.left then
+ assert(next0.right and next0.left, "failA")
+ -- pointer from T_i to T_{i+0}
+ next.right[last1.right] = next0.right
+ next.right_shift[last1.right] = - shift - abs1.right + (abs0.right + next.right_shift[last0.right])
+ elseif next1.right then
+ assert(next1.right and next1.left, "")
+ -- pointer from T_{i+0} to T_i
+ -- texio.write(last0.left .." -> " ..next1.left)
+ next.left[last0.left] = next1.left
+-- pgf.debug{last0,abs0,abs1,last1}
+ next.left_shift[last0.left] = shift - abs0.left + (abs1.left + next.left_shift[last1.left] )
+
+ else
+ -- both trees have the same height
+ end
+ end
+end
+
+-- Implementation
+
+function Skambath2016:run()
+ local layers = Storage.new()
+ local descendants = Storage.new()
+ local childgroups = Storage.new()
+
+ local phases = self.digraph.options.algorithm_phases
+
+ local so_class = phases['supergraph optimization']
+ local ga_class = phases['evolving graph animation']
+ local cr_class = phases['temporal cycle removal']
+
+ self.extended_version = self.digraph.options['missing nodes get space']
+ self.supergraph = Supergraph.generateSupergraph(self.digraph)
+ local supergraph_original = Supergraph.generateSupergraph(self.digraph)
+
+ -- optimize graph by splitting nodes by trivial criteria
+ so_class.new {
+ main_algorithm = self,
+ supergraph = self.supergraph,
+ digraph = self.digraph,
+ ugraph = self.ugraph
+ }:run()
+
+
+ self:precomputeSpanningTrees()
+
+ -- Resolve cyclic dependencies if exists.
+ cr_class.new {
+ main_algorithm = self,
+ supergraph = self.supergraph,
+ digraph = self.digraph,
+ }:run()
+
+
+
+ self:precomputeDescendants(layers, descendants)
+ self:precomputeChildgroups(childgroups)
+
+ self:computeHorizontalLayout(childgroups, descendants)
+-- self:computeHorizontalLayoutFast()
+
+ -- vertical positions
+ tlayered.arrange_layers_by_baselines(layers,
+ self.adjusted_bb,
+ self.ugraph,
+ self.supergraph.snapshots,
+ self.supergraph.vertex_snapshots)
+
+ -- animate graph
+ ga_class.new {
+ main_algorithm = self,
+ supergraph = supergraph_original,
+ digraph = self.digraph,
+ ugraph = self.ugraph
+ }:run()
+end
+
+--
+-- Compute the required shift value for a second tree to guarantee
+-- a required node distance.
+-- @field right_borders The Border data structure for the right border of
+-- the left tree
+-- @field left_borders The Border data structure for the left border of
+-- the right tree
+-- @field selected_snapshots if you set this value with an array of snapshots
+-- only the predefined snapshots are used in the border
+-- computation.
+--
+function Skambath2016:computeMinShift(right_borders, left_borders, selected_snapshots)
+ local shift = -math.huge
+ local max_level = math.min(#right_borders, #left_borders)
+ local first_shift = 0
+ local snapshots = selected_snapshots or self.supergraph.snapshots
+
+ for layer = 1, max_level do
+ local rb, lb = right_borders[layer], left_borders[layer]
+ for _,s in ipairs(snapshots) do
+
+ local v1,v2 = rb[s],lb[s]
+ if v1 and v2 then
+ local local_shift = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, v1, v2) + v1.pos.x - v2.pos.x
+ shift = math.max(shift, local_shift)
+ end
+ end
+ if layer == 1 then
+ first_shift = shift
+ end
+ end
+
+ local is_significant = false
+
+ if max_level > 1 and shift<=first_shift then
+ -- if the necessary shift of the subtrees
+ -- is the minimum required shift between two
+ -- nodes than a node is significant
+ is_significant = true
+ end
+
+ if shift <= -math.huge then
+ shift = 0
+ end
+
+ if is_significant then
+ shift = shift + self.ugraph.options['significant sep']
+ end
+
+ return shift
+end
+
+
+--
+-- The main algorithm: This method computes the layout for each vertex.
+-- For this all supervertices are visited in a topological order to their dependency.
+-- If a . This requires the supergraph to be acyclic. If this is not the case
+-- the calling process has to remove all cycles otherwise the x-coordinate will
+-- not be computed for every vertex.
+--
+function Skambath2016:computeHorizontalLayout(groups, descendants)
+ local subtree_borders = Storage.new()
+ local dep_counter = {}
+ local visited = {}
+ local queue = PriorityQueue.new()
+ local dependency_graph = Digraph.new()
+ for _, vertex in ipairs(self.supergraph.vertices) do
+ dep_counter[vertex] = 0
+ dependency_graph:add {vertex}
+ end
+
+ -- 1. Initialize Dependencies
+
+ for _, snapshot in ipairs(self.supergraph.snapshots) do
+ for _, spanning_tree in ipairs(snapshot.spanning_trees) do
+ for _, arc in ipairs(spanning_tree.arcs) do
+
+ local head = self.supergraph:getSupervertex(arc.head)
+ local tail = self.supergraph:getSupervertex(arc.tail)
+
+ if(head and tail) then
+ if not dependency_graph:arc(tail, head) then
+ dependency_graph:connect(tail, head)
+ dep_counter[tail] = dep_counter[tail] + 1
+ end
+ end
+ end
+ end
+ end
+
+ -- 2. Find independent vertices
+ for _, vertex in ipairs(dependency_graph.vertices) do
+ local outgoings = dependency_graph:outgoing(vertex)
+ if #outgoings == 0 then
+ queue:enqueue(vertex, 1)
+ end
+ end
+
+ -- 2.
+ while not queue:isEmpty() do
+ local vertex = queue:dequeue()
+ local vertex_snapshots = self.supergraph:getSnapshots(vertex)
+
+ -- a. Resolve dependencies on this vertex:
+ local incomings = dependency_graph:incoming(vertex)
+ for _, e in ipairs(incomings) do
+ dep_counter[e.tail] = dep_counter[e.tail] - 1
+ if dep_counter[e.tail] == 0 then
+ queue:enqueue(e.tail, 1)
+ end
+ end
+
+ -- b. Compute borders of this supervertex:
+ local vertex_borders = Borders.new()
+ for _, s in ipairs(vertex_snapshots) do
+ local snapshot_vertex = self.supergraph:getSnapshotVertex(vertex, s)
+ vertex_borders:addBoth(1, s, snapshot_vertex)
+ snapshot_vertex.pos.x = 0
+ snapshot_vertex.pos.y = 0
+ end
+
+ local vertex_groups = groups[vertex]
+ local last_pos_x = 0
+ if vertex_groups then
+ -- c. Compute borders of groups:
+ local all_group_borders = {}
+ for i, group in ipairs(vertex_groups) do
+ local group_boders = Borders.new()
+ for _,s in ipairs(vertex_snapshots) do
+ local child = group[s]
+ if child then
+ local child_borders
+ if not (child.kind == "dummy") then
+ local superchild = self.supergraph:getSupervertex(child)
+ child_borders = subtree_borders[superchild] or Borders.new()
+ else
+ child_borders = Borders.new()
+ child_borders:addBoth(1, s, child)
+ end
+ assert(child.pos~=math.huge, "invalid child pos")
+ shift_group(-child.pos.x,{[s]=child},{[1]=s}, descendants)
+ Borders.copyBordersAtSnapshot(child_borders, group_boders, s)
+ end
+ end
+ all_group_borders[i] = group_boders
+ end
+
+ -- d. Place groups and merge borders of groups:
+ local last_group = nil
+ last_pos_x = 0
+ local merged_borders = Borders.new()
+ local final_borders = Borders.new()
+ for i, group in ipairs(vertex_groups) do
+ local group_borders = all_group_borders[i]
+ if last_group_borders then
+ -- i. compute minimal shift
+
+ local shift
+ shift = self:computeMinShift(merged_borders.right, group_borders.left)
+
+
+ assert(shift ~= math.huge and shift~=-math.huge, "invalid shift")
+
+ -- ii. shift group
+ local anchor = shift_group(shift, group,vertex_snapshots, descendants)
+ last_pos_x = anchor
+ end
+ last_group_borders = group_borders
+
+ -- iii. adapt borders
+ adapt_borders(merged_borders,
+ group_borders,
+ self.supergraph.snapshots)
+ adapt_borders(final_borders,
+ group_borders,
+ self.supergraph.snapshots,
+ not self.extended_version)
+ end -- for (group)
+ vertex_borders:appendBelow(1, final_borders)
+ end
+ -- e. store borders:
+ assert(last_pos_x~=math.huge and last_pos_x~=-math.huge, "invalid position")
+ local x = ((last_pos_x) - 0)/2 + 0
+ assert(x~=math.huge and x~=-math.huge, "invalid position")
+ for _,s in ipairs(vertex_snapshots) do
+ local snapshot_vertex = self.supergraph:getSnapshotVertex(vertex, s)
+ snapshot_vertex.pos.x = x
+ end
+
+ subtree_borders[vertex] = vertex_borders
+ end
+
+ -- align roots
+ for _, s in ipairs(self.supergraph.snapshots) do
+ local lastroot
+ local rborder
+ for i, spanning_tree in ipairs(s.spanning_trees) do
+ local root = spanning_tree.root
+ local rootborders = subtree_borders[self.supergraph:getSupervertex(root)]
+ shift_group(-root.pos.x,{[s]=root},{[1]=s}, descendants)
+ if i>1 then
+ local l = subtree_borders[self.supergraph:getSupervertex(lastroot)]
+ local r = rootborders
+ shift = math.max(self:computeMinShift(l.right, r.left, {[1]=s}),
+ self:computeMinShift(rborder.right,r.left, {[1]=s}))
+ shift_group(shift,{[s]=root},{[1]=s}, descendants)
+ else
+ rborder = Borders.new()
+ end
+ adapt_borders(rborder,rootborders,self.supergraph.snapshots,false)
+ lastroot = root
+ end
+ end
+end
+
+--
+-- The main algorithm: This method computes the layout for each vertex.
+-- For this all supervertices are visited in a topological order to their dependency.
+-- If a . This requires the supergraph to be acyclic. If this is not the case
+-- the calling process has to remove all cycles otherwise the x-coordinate will
+-- not be computed for every vertex.
+--
+function Skambath2016:computeHorizontalLayoutFast()
+ local all_trees = Storage.new()
+ local dep_counter = {}
+ local visited = {}
+ local queue = PriorityQueue.new()
+ local dependency_graph = Digraph.new()
+ local shifts = Storage.new()
+ local next = Storage.new()
+ for _, vertex in ipairs(self.supergraph.vertices) do
+ dep_counter[vertex] = 0
+ dependency_graph:add {vertex}
+ end
+
+
+ -- I. Initialize Dependencies (Build Dependency Graph)
+ for _, snapshot in ipairs(self.supergraph.snapshots) do
+ for _, spanning_tree in ipairs(snapshot.spanning_trees) do
+ table.insert(all_trees, spanning_tree)
+ shifts[spanning_tree] = Storage.new()
+ next[spanning_tree] = {left= Storage.new(),
+ right= Storage.new(),
+ left_shift = Storage.new(),
+ right_shift = Storage.new()
+ }
+
+ for _, arc in ipairs(spanning_tree.arcs) do
+ local head = self.supergraph:getSupervertex(arc.head)
+ local tail = self.supergraph:getSupervertex(arc.tail)
+
+ if(head and tail) then
+ if not dependency_graph:arc(tail, head) then
+ dependency_graph:connect(tail, head)
+ dep_counter[tail] = dep_counter[tail] + 1
+ end
+ end
+ end
+ end
+ end
+
+ -- II. Visit vertices in topological ordering
+ -- Find independent vertices
+ for _, vertex in ipairs(dependency_graph.vertices) do
+ local outgoings = dependency_graph:outgoing(vertex)
+ if #outgoings == 0 then
+ queue:enqueue(vertex, 1)
+ end
+ end
+
+ while not queue:isEmpty() do
+ -- Next node in topological order
+ local vertex = queue:dequeue()
+-- texio.write("\n\n --- "..vertex.name .. " ---")
+ --pgf.debug{next}
+ local vertex_snapshots = self.supergraph:getSnapshots(vertex)
+
+ -- a. Resolve dependencies on this vertex:
+ local incomings = dependency_graph:incoming(vertex)
+ for _, e in ipairs(incomings) do
+ dep_counter[e.tail] = dep_counter[e.tail] - 1
+ if dep_counter[e.tail] == 0 then
+ queue:enqueue(e.tail, 1)
+ end
+ end
+
+ -- b. Compute maximum number of children over time:
+ local num_children = 0
+ for _, s in ipairs(vertex_snapshots) do
+ local v = self.supergraph:getSnapshotVertex(vertex, s)
+ local tree = s.spanning_trees[1]
+ num_children = math.max(num_children, #(tree:outgoing(v)))
+ shifts[tree][v] = 0
+ end
+
+ -- c. Shift all subtrees in all snapshots:
+ local hlp_ptr = Storage.new()
+ local max_shift = 0
+ for i = 1, (num_children - 1) do
+ -- i) Compute the necessary shift between the i-th and (i+1)-th subtrees (per snapshot):
+ local min_shift = 0
+ for t, s in ipairs(vertex_snapshots) do
+ local snapshot_vertex = self.supergraph:getSnapshotVertex(vertex, s)
+ local tree = s.spanning_trees[1]
+ local req_shift, hptr
+ req_shift, hptr = self:computeRequiredDistance(tree,
+ snapshot_vertex,
+ i,
+ shifts[tree],
+ next[tree]
+ )
+ hlp_ptr[t] = hptr
+-- texio.write(" -> \t"..req_shift)
+ min_shift = math.max(min_shift, req_shift)
+ end
+
+-- texio.write("\n \t\t".. min_shift )
+
+ -- ii) Synchronize distance between neighbored subtrees and apply shifts
+ for t, s in ipairs(vertex_snapshots) do
+ local snapshot_vertex = self.supergraph:getSnapshotVertex(vertex, s)
+ local tree = s.spanning_trees[1]
+ apply_shift(tree, snapshot_vertex, i, shifts[tree], next[tree], hlp_ptr[t], min_shift)
+ end
+
+ max_shift = min_shift
+ end
+
+ for t, s in ipairs(vertex_snapshots) do
+ local snapshot_vertex = self.supergraph:getSnapshotVertex(vertex, s)
+ local tree = s.spanning_trees[1]
+ local outgoings = tree:outgoing(snapshot_vertex)
+
+-- next[tree].left[snapshot_vertex] = outgoings[1].head
+
+
+ for i = 1,#outgoings do
+ if i==1 then
+ next[tree].left_shift[snapshot_vertex] = - max_shift / 2
+ next[tree].left[snapshot_vertex]= outgoings[i].head
+ end
+ shifts[tree][outgoings[i].head] = shifts[tree][outgoings[i].head] - max_shift / 2
+ next[tree].right[snapshot_vertex] = outgoings[i].head
+ next[tree].right_shift[snapshot_vertex] = shifts[tree][outgoings[i].head]
+ end
+
+ end
+
+ end -- end while (all vertices have been processed)
+
+ -- III. Accumulate absolute horizontal coordinates
+ for _, tree in ipairs(all_trees) do
+ accumulate_hpos(tree, tree.root, shifts[tree], 0)
+ end
+end
+
+
+
+
+function Skambath2016:precomputeTreeDescendants(tree, node, depth, layers, descendants)
+ local my_descendants = { node }
+
+ for _,arc in ipairs(tree:outgoing(node)) do
+ local head = arc.head
+ self:precomputeTreeDescendants(tree, head, depth+1, layers, descendants)
+ for _,d in ipairs(descendants[head]) do
+ my_descendants[#my_descendants + 1] = d
+ end
+ end
+ layers[node] = depth
+ descendants[node] = my_descendants
+end
+
+function Skambath2016:precomputeDescendants(layers, descendants)
+ for _,snapshot in ipairs(self.supergraph.snapshots) do
+ for _, spanning_tree in ipairs(snapshot.spanning_trees) do
+ self:precomputeTreeDescendants(spanning_tree, spanning_tree.root, 1, layers, descendants)
+ end
+ end
+end
+
+
+--
+--
+--
+function Skambath2016:precomputeChildgroups(childgroups)
+ for _,s in ipairs(self.supergraph.snapshots) do
+ for _,spanning_tree in ipairs(s.spanning_trees) do
+ precompute_childgroups(self.supergraph, spanning_tree, spanning_tree.root, childgroups, s)
+ end
+ end
+end
+
+--
+-- Compute a for each connected component of each
+-- snapshot and appends the result for a snapshot s to
+-- the array s.spanning_trees.
+--
+function Skambath2016:precomputeSpanningTrees()
+ local events = assert(self.scope.events,
+ "no events found for the spanning tree computation")
+
+ for i, s in ipairs(self.supergraph.snapshots) do
+ -- The involved snapshot graph:
+ local s_copy = Digraph.new(s)
+ for _,a in ipairs(s.arcs) do
+ local new_a = s_copy:connect(a.tail,a.head)
+ new_a.syntactic_edges = a.syntactic_edges
+ end
+ s.spanning_trees = s.spanning_trees or {}
+ -- Step 1: Decompose the snapshot into its connected components
+ local syntactic_components = LayoutPipeline.decompose(s_copy)
+ for i, syntactic_component in ipairs (syntactic_components) do
+ local tree = SpanningTreeComputation.computeSpanningTree(syntactic_component, true, events)
+ s.spanning_trees[i] = tree
+ end
+ end
+end
+
+return Skambath2016
+
+
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Supergraph.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Supergraph.lua
new file mode 100644
index 0000000000..99e79919b5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/Supergraph.lua
@@ -0,0 +1,571 @@
+-- Copyright 2015 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+
+-- Imports
+local lib = require "pgf.gd.lib"
+
+local Vertex = require "pgf.gd.model.Vertex"
+local Digraph = require "pgf.gd.model.Digraph"
+local Storage = require "pgf.gd.lib.Storage"
+
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+---
+-- Each |Supergraph| instance is a |Digraph| instance which represents
+-- the graph by union operation on all graphs G_i of an evolving graph
+-- $G=(G_1, G_2, \dots, G_n)$. Additional to that all references to
+-- the snapshot-graphs are shared such that is possible to get access
+-- to all vertices for each snapshot graph in a sequence. A vertex of
+-- an evolving graph may exists at different times, thus in in
+-- different snapshots. Each vertex will be a vertex in the supergraph
+-- and if there is a single snapshot in which two vertices are
+-- connected by an edge they are connected in the supergraph.
+--
+-- Note that in \tikzname\ a \emph{node} is more than a single dot. A node
+-- has a content and different properties like background-color or a
+-- shape. Formally this can be modeled by function mapping vertices
+-- to their properties. For evolving graphs this could be done in the
+-- same way. As this is difficult to be realized in PGF because there
+-- is no basic support for time dependent properties on nodes, each
+-- vertex will be displayed over time by different single
+-- (snapshot-)nodes which can have different visual properties. This
+-- means for a vertex which we call |supervertex| in the following we
+-- will have a (snapshot-)node for each time stamp.
+--
+-- \medskip
+-- \noindent\emph{Snapshots.}
+-- Since an evolving graph is a sequence of different snapshot-graphs
+-- $G_i$ each snapshot is assigned to a time
+--
+--
+-- @field vertex_snapshots This storage maps each pgf-node to the snapshots
+-- in which they are visible.
+--
+-- @field supervertices This storage maps each pgf-node to its supervertex
+-- which represents all pgf-vertices assigned to the same node
+--
+-- @field supervertices_by_id This storage maps a node identifier to the
+-- related supervertex such that PGF-nodes which belonging to
+-- the same superverticex can be identified
+--
+-- @field snapshots An array of all snapshots. Sorted in ascending order
+-- over the timestamps of the snapshots.
+--
+-- @field arc_snapshots A table storing all snapshots of a supervertex in which
+-- the related nodes are connected. Using a snapshot as key you can check
+-- if a given snapshot is in the array.
+--
+-- Assume we want to iterate over all snapshots
+-- for a certain pair of supernodes in which they are connected
+-- by an arc. The arc_snapshots storage helps in this case:
+-- %
+-- \begin{codeexample}[code only, tikz syntax=false]
+-- local supergraph = Supergraph.generateSupergraph(self.digraph)
+-- local u = supergraph.vertices[1]
+-- local v = supergraph.vertices[2]
+--
+-- local snapshots = supergraph.arc_snapshots[supergraph:arc(u, v)]
+-- for _, snapshot in ipairs(snapshots) do
+-- do_something(snapshot)
+-- end
+-- \end{codeexample}
+--
+local Supergraph = lib.class { base_class = Digraph }
+
+-- Namespace
+--require("pgf.gd.experimental.evolving").Supergraph = Supergraph
+
+Supergraph.__index =
+ function (t, k)
+ if k == "arcs" then
+ return Digraph.__index(t,k)
+ else
+ return rawget(Supergraph, k) or rawget(Digraph, k)
+ end
+ end
+
+function Supergraph.new(initial)
+ local supergraph = Digraph.new(initial)
+ setmetatable(supergraph, Supergraph)
+
+ supergraph.vertex_snapshots = Storage.new()
+ supergraph.supervertices = Storage.new()
+ supergraph.supervertices_by_id = {}
+ supergraph.arc_snapshots = Storage.newTableStorage()
+
+ return supergraph
+
+end
+
+
+local get_snapshot
+
+---
+-- Generate or extract a snapshot instance for a given snapshot time.
+--
+-- @param snapshots An array of all existing snapshots
+-- @param timestamps A table which maps known timestamps to their
+-- related snapshots
+-- @param ugraph The ugraph of the underlying graph structure
+-- @param snapshot_time
+--
+-- @return The snapshot instance found in the snapshots array for the
+-- wanted timestamp snapshot_time if it doesn't exists a new snapshot
+-- will be generated and added to the arrays
+--
+function get_snapshot(snapshots, timestamps, ugraph, snapshot_time)
+ local snapshot
+ local snapshot_idx = timestamps[snapshot_time]
+
+ if not snapshot_idx then
+ -- store snapshot if it doesn't exists
+ snapshot_idx = timestamps.n + 1
+ timestamps[snapshot_time] = snapshot_idx
+ timestamps.n = timestamps.n + 1
+ snapshot = Digraph.new {
+ syntactic_digraph = ugraph.syntactic_digraph,
+ options = ugraph.options
+ }
+ snapshot.timestamp = snapshot_time
+ snapshots[snapshot_idx] = snapshot
+ else
+ snapshot = snapshots[snapshot_idx]
+ end
+ assert(snapshot~=nil, "an unexpected error occurred")
+ return snapshot
+end
+
+
+---
+-- Generate a new supergraph to describe the whole evolving graph by
+-- collecting all temporal information from the digraph and the node
+-- options. All nodes in the |digraph| require a |snapshot| and
+-- a |supernode| option. To identify a (snapshot-)node with its
+-- supernode and snapshot.
+--
+-- @param digraph
+--
+-- @return The supergraph which is a |Digraph| that has a supervertex
+-- for each set of snapshot-vertices with the same |supernode|
+-- attribute.
+--
+function Supergraph.generateSupergraph(digraph)
+ local new_supergraph
+ new_supergraph = Supergraph.new {
+ syntactic_digraph = digraph.syntactic_digraph,
+ options = digraph.options,
+ digraph = digraph,
+ }
+
+ -- array to store the supervertices for a given vertex name
+ local local_snapshots = {} -- array to store each snapshot graphs
+
+ local timestamps = { n = 0 } -- set of snapshot times
+
+ -- separate and assign vertices to their snapshots and supervertices
+ for i,vertex in ipairs(digraph.vertices) do
+ local snapshot_time = assert(vertex.options["snapshot"], "Missing option 'snapshot' for vertex ".. vertex.name ..". ")
+ local supernode_name = assert(vertex.options["supernode"], "Missing option 'supernode' for vertex"..vertex.name..". ")
+
+ local snapshot = get_snapshot(local_snapshots, timestamps, digraph, snapshot_time)
+ local supervertex = new_supergraph.supervertices_by_id[supernode_name]
+
+ if not supervertex then
+ -- first appearance of the supernode id
+ supervertex = Vertex.new {
+ kind = "super",
+ name = supernode_name
+ }
+ supervertex.snapshots = {}
+ supervertex.subvertex = {}
+ new_supergraph.supervertices_by_id[supernode_name] = supervertex
+ new_supergraph:add{supervertex}
+
+ supervertex.options = {}
+ supervertex.options = vertex.options
+ end
+
+ snapshot:add{vertex}
+
+ new_supergraph.supervertices[vertex] = supervertex
+ new_supergraph.vertex_snapshots[vertex] = snapshot
+ new_supergraph:addSnapshotVertex(supervertex, snapshot, vertex)
+ end
+
+ -- Create edges
+ for i, e in ipairs(digraph.arcs) do
+ local u,v = e.tail, e.head
+ local snapshot_tail = new_supergraph.vertex_snapshots[e.tail]
+ local snapshot_head = new_supergraph.vertex_snapshots[e.head]
+
+ assert(snapshot_head == snapshot_tail, "Arcs must connect nodes that exist at the same time.")
+
+ -- connect in the snapshot graph
+ local arc = snapshot_tail:connect(u,v)
+
+ -- connect in the supergraph:
+ local super_tail = new_supergraph.supervertices[u]
+ local super_head = new_supergraph.supervertices[v]
+
+ new_supergraph:assignToSuperarc(super_tail, super_head, snapshot_tail)
+ end
+
+ -- snapshots in temporal order
+ table.sort(local_snapshots,
+ function(s1,s2)
+ return s1.timestamp < s2.timestamp
+ end )
+
+ local previous_snapshot
+
+ for i,s in ipairs(local_snapshots) do
+ local start = -math.huge
+ if previous_snapshot then
+ start = (s.timestamp - previous_snapshot.timestamp) / 2 + previous_snapshot.timestamp
+ previous_snapshot.interval.to = start
+ end
+ s.interval = { from = start , to = math.huge }
+ previous_snapshot = s
+ end
+
+ new_supergraph.snapshots = local_snapshots
+ new_supergraph.snapshots_indices = Storage.new()
+
+ for i, s in ipairs(new_supergraph.snapshots) do
+ new_supergraph.snapshots_indices[s] = i
+ end
+
+ return new_supergraph
+end
+
+
+function Supergraph:getSnapshotStaticDuration(snapshot)
+ assert(snapshot, "a snapshot as parameter expected, but got nil")
+ local idur = snapshot.interval.to - snapshot.interval.from
+ assert(idur, "unexpected nil-value")
+ local d1 = snapshot.interval.to - snapshot.timestamp
+ local d2 = snapshot.timestamp - snapshot.interval.from
+ local dm = math.min(d1,d2)
+ if (idur >= math.huge and dm < math.huge) then
+ return dm -- [-\infty,t] or [t,\infty]
+ elseif idur >= math.huge then
+ return 0 -- only one snapshot [-\infty,\infty]
+ else
+ return d1 + d2 -- [t_1, t_2]
+ end
+end
+
+---
+-- Get the durations of the graph in which snapshots are given which is exactly
+-- the time between the first and the last defined snapshot
+--
+-- @return The time between the last and first snapshot in seconds
+function Supergraph:getDuration()
+ local first_snapshot = self.snapshots[1]
+ local last_snapshot = self.snapshots[#self.snapshots]
+ return last_snapshot.timestamp - first_snapshot.timestamp
+end
+
+---
+--
+-- @return The ratio of the time of a snapshot related to the global duration of the whole
+-- evolving trees. (The time between the last and first snapshot)
+function Supergraph:getSnapshotRelativeDuration(snapshot)
+ if self:getDuration() == 0 then
+ return 1
+ else
+ return self:getSnapshotStaticDuration(snapshot) / self:getDuration()
+ end
+end
+
+---
+-- Give the supervertex for a certain pgf-vertex (vertex of a snapshot)
+--
+-- @param vertex A vertex of a snapshot.
+--
+-- @return A supervertex in the supergraph for the given vertex, nil if no
+-- supervertex was assigned before.
+--
+function Supergraph:getSupervertex(vertex)
+ assert(vertex, "vertex required")
+ assert(self.supervertices, "supervertex table is not defined")
+ return self.supervertices[vertex]
+end
+
+function Supergraph:getSuperarc(arc)
+ local superhead = self:getSupervertex(arc.head)
+ local supertail = self:getSupervertex(arc.tail)
+ local arc = assert(self:arc(supertail, superhead),"unexpected problem")
+ return arc
+end
+
+function Supergraph:getSnapshots(supervertex)
+ return supervertex.snapshots
+end
+
+---
+-- Find the snapshot-instance for a given pgf-vertex
+-- (which is a vertex for one certain snapshot)
+--
+-- @param vertex A vertex for which you want to get the related snapshot
+--
+-- @return The snapshot which contains the given vertex as vertex.
+function Supergraph:getSnapshot(vertex)
+ return self.vertex_snapshots[vertex]
+end
+
+---
+-- For a given supervertex get the related vertex for a snapshot
+--
+-- @param supervertex
+--
+-- @param snapshot
+--
+-- @return The vertex of the supervertex at the specified snapshot
+--
+function Supergraph:getSnapshotVertex(supervertex, snapshot)
+ assert(supervertex, "supervertex must not be nil")
+ assert(snapshot, "snapshot must not be nil")
+ return supervertex.subvertex[snapshot]
+end
+
+
+function Supergraph:consecutiveSnapshots(snapshot1, snapshot2, n)
+ assert(snapshot1 and snapshot2, "no snapshot passed")
+ local idx1 = self.snapshots_indices[snapshot1] --or -1
+ local idx2 = self.snapshots_indices[snapshot2] --or -1
+ local d = n or 1
+
+ return (idx2-idx1 <= d) or (idx1-idx2 <= d)
+end
+
+function Supergraph:consecutive(vertex1, vertex2, n)
+ local s1 = self:getSnapshot(vertex1)
+ local s2 = self:getSnapshot(vertex2)
+ return self:consecutiveSnapshots(s1, s2, n)
+end
+
+---
+-- Write pack all position information to the nodes of each snapshot
+-- such that all nodes with the same supervertex have the same position
+--
+-- @param ugraph An undirected graph for which the vertices should get
+-- their positions from the supergraph.
+--
+function Supergraph:sharePositions(ugraph, ignore)
+
+ for _,vertex in ipairs(ugraph.vertices) do
+ if not ignore then
+ vertex.pos.x = self.supervertices[vertex].pos.x
+ vertex.pos.y = self.supervertices[vertex].pos.y
+ else
+ if not ignore.x then
+ vertex.pos.x = self.supervertices[vertex].pos.x
+ end
+ if not ignore.y then
+ vertex.pos.y = self.supervertices[vertex].pos.y
+ end
+ end
+
+
+ end
+end
+
+function Supergraph:onAllSnapshotvertices(f, ugraph)
+ for _,vertex in ipairs(ugraph.vertices) do
+ local snapshot_vertex = self.supertvertices[vertex]
+ if snapshot_vertex then
+ f(vertex, snapshot_vertex)
+ end
+ end
+end
+
+---
+-- Split a supervertex into new supervertices such that
+-- for a given snapshot there is a new pseudo-supervertex.
+-- This pseudo-supervertex will be assigned to all snapshots
+-- after the given snapshot.
+-- All snapshots of a new pseudo-supervertex are removed from
+-- the original vertex.
+-- If a supervertex has no subvertices then it will not be added to the graph.
+--
+-- @param supervertex The supervertex which should be split.
+--
+-- @param snapshots An array of snapshots at which the supervertex
+-- should be split into a new one with the corresponding pgf-vertices.
+-- If there are more than one snapshots passed to the function
+-- for each snapshot there will be a new pseudo-vertex
+--
+function Supergraph:splitSupervertex(supervertex, snapshots)
+ assert(supervertex, "no supervertex defined")
+ -- snapshots in temporal order
+ table.sort(snapshots,
+ function(s1,s2)
+ return s1.timestamp < s2.timestamp
+ end )
+
+ assert(#snapshots~=0)
+
+ local edit_snapshots = supervertex.snapshots
+ local first_removed = math.huge
+ local rem_arcs = {}
+ for i = 1, #snapshots do
+ local s_first = self.snapshots_indices[snapshots[i]]
+ first_removed = math.min(s_first,first_removed)
+ local s_last
+ if i==#snapshots then
+ s_last = #self.snapshots
+ else
+ s_last = self.snapshots_indices[snapshots[i+1]]-1
+ end
+
+ local pseudovertex = Vertex.new {
+ kind = "super",
+ name = supervertex.name.."*"..i,
+ subvertex = {},
+ snapshots = {}
+ }
+
+ local has_subvertices = false
+
+ for j = s_first, s_last do
+ local s = self.snapshots[j]
+ local vertex = self:getSnapshotVertex(supervertex, s)
+ if vertex then
+ self.supervertices[vertex] = pseudovertex
+ self:addSnapshotVertex(pseudovertex, s, vertex)
+ self:removeSnapshotVertex(supervertex, s)
+
+ if not has_subvertices then
+ has_subvertices = true
+ self:add{pseudovertex}
+ end
+
+ -- update edges:
+ local incoming = self.digraph:incoming(vertex)
+ local outgoing = self.digraph:outgoing(vertex)
+
+ for _, arc in ipairs(incoming) do
+ local tail = self.supervertices[arc.tail]
+ local head = self.supervertices[arc.head]
+ self:assignToSuperarc(tail, pseudovertex, s)
+
+ local super_arc = self:arc(tail, supervertex)
+ if not rem_arcs[super_arc] then
+ table.insert(rem_arcs, {arc = super_arc, snapshot = s})
+ rem_arcs[super_arc] = true
+ end
+ end
+
+ for _, arc in ipairs(outgoing) do
+ local tail = self.supervertices[arc.tail]
+ local head = self.supervertices[arc.head]
+ self:assignToSuperarc(pseudovertex, head, s)
+
+ local super_arc = self:arc(supervertex, head)
+ if not rem_arcs[super_arc] then
+ table.insert(rem_arcs, {arc = super_arc, snapshot = s})
+ rem_arcs[super_arc] = true
+ end
+ end
+ end
+ end
+ end
+
+ if first_removed ~= math.huge then
+ for _, removed_arc in ipairs(rem_arcs) do
+ local snapshots = self.arc_snapshots[removed_arc.arc]
+ for i=#snapshots,1,-1 do
+ local s = snapshots[i]
+ if s.timestamp >= removed_arc.snapshot.timestamp then
+ table.remove(snapshots, i)
+ end
+ end
+
+ if #snapshots==0 then
+ self:disconnect(removed_arc.arc.tail, removed_arc.arc.head)
+ end
+ end
+ end
+end
+
+-- function Supergraph:reloadArcSnapshots()
+-- for _, arc in ipairs(self.digraph.arcs) do
+-- local snapshot = self:getSnapshot(arc.head)
+-- local superarc = self:getSuperarc(arc)
+-- texio.write("\n"..arc.tail.name..">"..arc.head.name)
+-- self.arc_snapshots[superarc] = snapshot
+-- end
+-- end
+
+---
+-- Remove the binding of a vertex at a certain snapshot from its assigned
+-- supervertex.
+-- This requires time $O(n)$ where $n$ is the number of nodes actually
+-- assigned to the supervertex.
+function Supergraph:removeSnapshotVertex(supervertex, snapshot)
+ assert(supervertex and snapshot,"missing argument: the supervertex and snapshot must not be nil")
+
+ -- remove reference to snapshot
+ for i = #supervertex.snapshots,1,-1 do
+ if supervertex.snapshots[i] == snapshot then
+ table.remove(supervertex.snapshots, i)
+ end
+ end
+ -- remove vertex at snapshot
+ supervertex.subvertex[snapshot] = nil
+end
+
+---
+-- Assign a vertex to a snapshot vertex of this supergraph.
+-- This requires time $O(1)$
+-- @param supervertex
+--
+-- @param snapshot
+--
+-- @param vertex The vertex which should be assigned to the supervertex
+-- for the given snapshot.
+--
+function Supergraph:addSnapshotVertex(supervertex, snapshot, vertex)
+ supervertex.subvertex[snapshot] = vertex
+ table.insert(supervertex.snapshots, snapshot)
+end
+
+---
+-- Assign a given snapshot to the superarc between two supernodes.
+-- If still no arc between those nodes exists a new edges will
+-- be created.
+-- This requires time $O(n)$ where $n$ is the number of snapshots already
+-- assigned to the given arc.
+--
+-- @param super_tail The tail of the directed arc in the supergraph.
+--
+-- @param super_head The head of the directed arc in the supergraph.
+--
+-- @param snapshot A snapshot in which both nodes are connected.
+--
+-- @return The arc which was created or updated.
+--
+function Supergraph:assignToSuperarc(super_tail, super_head, snapshot)
+ assert(self:contains(super_tail) and self:contains(super_head),
+ "tried to connect supernodes not in the supergraph")
+
+ local super_arc = self:arc(super_tail, super_head)
+ if not super_arc then
+ super_arc = self:connect(super_tail, super_head)
+ end
+
+ table.insert(self.arc_snapshots[super_arc], snapshot)
+ self.arc_snapshots[super_arc][snapshot] = true
+
+ return super_arc
+end
+
+return Supergraph
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/SupergraphVertexSplitOptimization.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/SupergraphVertexSplitOptimization.lua
new file mode 100644
index 0000000000..b5a4ea22c9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/SupergraphVertexSplitOptimization.lua
@@ -0,0 +1,196 @@
+-- Copyright 2015 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+local SupergraphVertexSplitOptimization = {}
+
+-- Imports
+local lib = require "pgf.gd.lib"
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+local Vertex = require "pgf.gd.model.Vertex"
+local Digraph = require "pgf.gd.model.Digraph"
+local Coordinate = require "pgf.gd.model.Coordinate"
+
+declare {
+ key = "split me",
+ type = "boolean",
+ initial = false
+}
+
+declare {
+ key = "split on disappearing",
+ type = "boolean",
+ initial = true
+}
+
+declare {
+ key = "split on disjoint neighbors",
+ type = "boolean",
+ initial = false
+}
+
+declare {
+ key = "split on disjoint children",
+ type = "boolean",
+ initial = false
+}
+
+declare {
+ key = "split on disjoint parents",
+ type = "boolean",
+ initial = false
+}
+
+declare {
+ key = "split all supervertices",
+ type = "boolean",
+ initial = false
+}
+
+declare {
+ key = "unbound vertex splitting",
+ algorithm = SupergraphVertexSplitOptimization,
+ phase = "supergraph optimization",
+ phase_default = true,
+ summary = [["
+ Use this key if you want to disable animations.
+ Instead of producing animations the evolving graph animation phasephase animates all vertices including movements and
+ fade in or fade out animations.
+ "]],
+ documentation = [["
+ See ToDo
+ "]]
+}
+
+
+
+-- Help functions
+
+
+-- Implementation
+
+function SupergraphVertexSplitOptimization:run()
+ local supergraph = assert(self.supergraph, "no supergraph passed")
+
+ local split_on_dissapearing = self.digraph.options["split on disappearing"]
+ local split_on_no_common_neighbor = self.digraph.options["split on disjoint neighbors"]
+ local split_on_no_common_child = self.digraph.options["split on disjoint children"]
+ local split_on_no_common_parent = self.digraph.options["split on disjoint parents"]
+ local split_all = self.digraph.options["split all supervertices"]
+
+ for _, supernode in ipairs(supergraph.vertices) do
+ -- follow trace of the supernode
+ local snapshots = supergraph:getSnapshots(supernode)
+ local splitsnapshots = {}
+
+ for i=2, #snapshots do
+ local s = snapshots[i]
+ local s_prev = snapshots[i - 1]
+ local can_split = false
+
+ if supergraph:consecutiveSnapshots(s_prev, s) then
+ local v1 = supergraph:getSnapshotVertex(supernode, s_prev)
+ local v2 = supergraph:getSnapshotVertex(supernode, s)
+ local is_child1 = {}
+ local is_parent1 = {}
+ local is_neighbor1 = {}
+
+ local incoming1 = s_prev:incoming(v1)
+ local outgoing1 = s_prev:outgoing(v1)
+
+ for _,e in ipairs(incoming1) do
+ local p = supergraph:getSupervertex(e.tail)
+ if p then
+ is_parent1[p] = true
+ is_neighbor1[p] = true
+ end
+ end
+
+ for _,e in ipairs(outgoing1) do
+ local p = supergraph:getSupervertex(e.head)
+ if p then
+ is_child1[p] = true
+ is_neighbor1[p] = true
+ end
+ end
+
+ local incoming2 = s:incoming(v2)
+ local outgoing2 = s:outgoing(v2)
+
+ no_common_parent = true
+ no_common_child = true
+ no_common_neighbor = true
+ for _,e in ipairs(incoming2) do
+ local p = supergraph:getSupervertex(e.tail)
+ if p then
+ if is_neighbor1[p] then
+ no_common_neighbor = false
+ end
+ if is_parent1[p] then
+ no_common_parent = false
+ end
+ if (not no_common_neighbor) and (not no_common_parent) then
+ break
+ end
+ end
+ end
+
+ for _,e in ipairs(outgoing2) do
+ local p = supergraph:getSupervertex(e.head)
+ if p then
+ if is_neighbor1[p] then
+ no_common_neighbor = false
+ end
+ if is_child1[p] then
+ no_common_child = false
+ end
+ if (not no_common_neighbor) and (not no_common_child) then
+ break
+ end
+ end
+ end
+
+
+
+ if no_common_neighbor and split_on_no_common_neighbor then
+ can_split = true
+ --texio.write("[N@".. s.timestamp .."]")
+ end
+ if no_common_parent and split_on_no_common_parent then
+ can_split = true
+ --texio.write("[P@".. s.timestamp .."]")
+ end
+ if no_common_child and split_on_no_common_child then
+ can_split = true
+ --texio.write("[N@".. s.timestamp .."]")
+ end
+ if v2.options["split me"] then
+ can_split = true
+ end
+ else
+ can_split = true
+ --texio.write("[R@".. s.timestamp .."]")
+ end
+ if can_split or split_all then
+ table.insert(splitsnapshots, s)
+ end
+ end
+ if #splitsnapshots>0 then
+ supergraph:splitSupervertex(supernode, splitsnapshots)
+ end
+ end
+end
+
+
+
+
+-- Done
+
+return SupergraphVertexSplitOptimization
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/TimeSpec.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/TimeSpec.lua
new file mode 100644
index 0000000000..2b2168da1a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/TimeSpec.lua
@@ -0,0 +1,62 @@
+-- Copyright 2015 by Malte Skambath
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+---
+
+declare {
+ key = "snapshot",
+ type = "time",
+ initial = "0s",
+ summary = "The time of the snapshot in which a PGF node should be visible.",
+ documentation = [["
+ This option defines the time in seconds when respectively in which
+ state or snapshot of the graph the PGF represents a graph node.
+ "]],
+}
+
+---
+
+declare {
+ key = "supernode",
+ type = "string",
+ initial = "null",
+ summary = "A unique name for a node a given PGF node should be assigned to.",
+ documentation = [["
+ Because it should be possible that nodes can change their
+ appearance, they are represented by separate PGF nodes in each
+ snapshot. To identify PGF nodes of the same supernode we have to
+ specify this key.
+ "]],
+}
+
+---
+
+declare {
+ key = "fadein time",
+ type = "time",
+ initial = "0.5s",
+ summary = [["
+ The time in seconds it should take that a nodes will be fade in
+ when it disappears in the graph.
+ "]],
+}
+
+---
+
+declare {
+ key = "fadeout time",
+ type = "time",
+ initial = "0.5s",
+ summary = "",
+ documentation = "The same as |fadein time| but for disappearing nodes.",
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/doc.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/doc.lua
new file mode 100644
index 0000000000..dbd8146275
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/doc.lua
@@ -0,0 +1,120 @@
+-- Copyright 2012 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "animated tree layout"
+
+summary "This layout uses the Reingold--Tilform method for drawing trees."
+
+documentation
+[[
+A method to create layouts for evolving graphs as an SVG animation.The Reingold--Tilford method is a standard method for drawing
+trees. It is described in:
+
+The algorithm, which is based on the Reingold--Tilford algorithm and
+its implementation in |graphdrawing.trees|, is introduced in my Masthesis:
+%
+\begin{itemize}
+ \item
+ M.\ Skambath,
+ \newblock Algorithmic Drawing of Evolving Trees, Masterthesis, 2016
+\end{itemize}
+
+You can use the same known graph macros as for other graph drawing
+algorithms in Ti\emph{k}Z. In addition all keys and features that
+are available for the static tree algorithm can be used:
+%
+\begin{codeexample}[animation list={1,1.5,2,2.5,3,3.5,4}]
+ \tikz \graph[animated binary tree layout,
+ nodes={draw,circle}, auto supernode,
+ ] {
+ {[when=1] 15 -> {10 -> { ,11}, 20 }},
+ {[when=2] 15 -> {10 -> {3,11}, 20 }},
+ {[when=3] 15 -> {10 -> {3, }, 20 }},
+ {[when=4] 15 -> {10 -> {3, }, 20 -> 18 }},
+ };
+\end{codeexample}
+]]
+
+
+example
+[[
+\tikz[animated binary tree layout]
+ \graph[nodes={draw,circle}, auto supernode] {
+ {[when=1] 15 -> {10 -> { ,11}, 20 }},
+ {[when=2] 15 -> {10 -> {3,11}, 20 }},
+ {[when=3] 15 -> {10 -> {3, }, 20 }},
+ {[when=4] 15 -> {10 -> {3, }, 20 -> 18 }},
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "animated binary tree layout"
+
+summary
+[[ A layout based on the Reingold--Tilford method for drawing
+binary trees.
+]]
+
+documentation
+[[
+This key executes:
+%
+\begin{enumerate}
+ \item |animated tree layout|, thereby selecting the Reingold--Tilford method,
+ \item |minimum number of children=2|, thereby ensuring the all nodes
+ have (at least) two children or none at all, and
+\end{enumerate}
+]]
+
+
+example
+[[
+]]
+
+example
+[[
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "extended animated binary tree layout"
+
+summary
+[[ This algorithm is similar to |animated binary tree layout|, only the
+option \texttt{missing nodes get space} is executed and the
+\texttt{significant sep} is zero.
+]]
+
+example
+[[
+]]
+--------------------------------------------------------------------
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/layered.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/layered.lua
new file mode 100644
index 0000000000..15df9990f8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/layered.lua
@@ -0,0 +1,107 @@
+-- Copyright 2012 by Till Tantau
+-- Copyright 2015 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+
+
+local temporallayered = {}
+
+-- Namespace
+
+--require("pgf.gd").layered = layered
+--require("pgf.gd.experimental.evolving").layered = layered
+
+-- Import
+local lib = require "pgf.gd.lib"
+local Storage = require "pgf.gd.lib.Storage"
+local layered = require "pgf.gd.layered"
+
+--
+-- This file defines some basic functions to compute and/or set the
+-- ideal distances between nodes of any kind of layered drawing of a
+-- graph.
+
+
+
+---
+-- Position nodes in layers using baselines
+--
+-- @param layers A |Storage| object assigning layers to vertices.
+-- @param paddings A |Storage| object storing the computed distances
+-- (paddings).
+-- @param graph The graph in which the nodes reside
+-- @param snapshots The list of snapshots over which the overlaying evolving
+-- graph exists
+function temporallayered.arrange_layers_by_baselines (layers, paddings, graph, snapshots, vertex_snapshots)
+ assert(vertex_snapshots, "vertex_snapshots must not be nil")
+ --local layer_vertices = Storage.newTableStorage()
+ local snapshots_layers = Storage.newTableStorage()
+ local count_layers = 0
+ -- Decompose into layers:
+ for _,v in ipairs(graph.vertices) do
+ local layer_vertices = snapshots_layers[vertex_snapshots[v]] or {}
+ if layer_vertices[layers[v]] == nil then
+ assert( layers[v], "layer of node " .. v.name .. " has not been computed.")
+ layer_vertices[layers[v]] = {}
+ end
+ table.insert(layer_vertices[layers[v]], v)
+ count_layers = math.max(count_layers, layers[v])
+ end
+
+ if count_layers > 0 then
+
+
+ -- Now compute ideal distances and store
+ local height = 0
+
+ for _, s in ipairs(snapshots) do
+ local layer_vertices = snapshots_layers[s]
+ if #layer_vertices > 0 then -- sanity check
+ for _,v in ipairs(layer_vertices[1]) do
+ v.pos.y = 0
+ end
+ end
+ end
+
+ for i=2, count_layers do
+ local distance = 0
+ for _, s in ipairs(snapshots) do
+ local layer_vertices = snapshots_layers[s]
+ if #layer_vertices >= i then
+ distance = math.max(
+ distance,
+ layered.baseline_distance(
+ paddings,
+ s,
+ layer_vertices[i-1],
+ layer_vertices[i]))
+ end
+ end
+
+ height = height + distance
+
+ for _, s in ipairs(snapshots) do
+ local layer_vertices = snapshots_layers[s]
+ if #layer_vertices >= i then
+ for _,v in ipairs(layer_vertices[i]) do
+ v.pos.y = height
+ end
+ end
+ end
+ end
+ end
+end
+
+
+
+
+-- Done
+
+return temporallayered
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/library.lua
new file mode 100644
index 0000000000..bb50eaf2cb
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/experimental/evolving/library.lua
@@ -0,0 +1,33 @@
+-- Copyright 2016 by Malte Skambath
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+
+-- @library
+
+local evolving -- Library name
+
+-- Load dependencies:
+require "pgf.gd.trees.ChildSpec"
+require "pgf.gd.trees.ReingoldTilford1981"
+require "pgf.gd.layered"
+
+-- Load declarations from:
+require "pgf.gd.experimental.evolving.TimeSpec"
+require "pgf.gd.experimental.evolving.Supergraph"
+
+-- Load preprocessing/optimization phases from:
+require "pgf.gd.experimental.evolving.SupergraphVertexSplitOptimization"
+require "pgf.gd.experimental.evolving.GreedyTemporalCycleRemoval"
+
+-- Load postprocessing/graph animation phases from:
+require "pgf.gd.experimental.evolving.GraphAnimationCoordination"
+
+-- Load algorithms from:
+require "pgf.gd.experimental.evolving.Skambath2016"
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force.lua
new file mode 100644
index 0000000000..71efda1b35
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force.lua
@@ -0,0 +1,26 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+-- Imports
+
+require "pgf"
+require "pgf.gd"
+
+
+-- Declare namespace
+pgf.gd.force = {}
+
+
+-- Done
+
+return pgf.gd.force \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua
new file mode 100644
index 0000000000..a4e51dfeff
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua
@@ -0,0 +1,435 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+--- A class for handling "coarse" versions of a graph. Such versions contain
+-- less nodes and edges than the original graph while retaining the overall
+-- structure.
+
+local Graph = require "pgf.gd.deprecated.Graph" -- we subclass from here
+local CoarseGraph = Graph.new()
+CoarseGraph.__index = CoarseGraph
+
+
+
+-- Namespace:
+local force = require "pgf.gd.force"
+force.CoarseGraph = CoarseGraph
+
+
+-- Imports
+local Node = require "pgf.gd.deprecated.Node"
+local Edge = require "pgf.gd.deprecated.Edge"
+
+local lib = require "pgf.gd.lib"
+
+
+-- Class setup
+
+CoarseGraph.COARSEN_INDEPENDENT_EDGES = 0 -- TT: Remark: These uppercase constants are *ugly*. Why do people do this?!
+CoarseGraph.COARSEN_INDEPENDENT_NODES = 1
+CoarseGraph.COARSEN_HYBRID = 2
+
+
+
+--- Creates a new coarse graph derived from an existing graph.
+--
+-- Generates a coarse graph for the input |Graph|.
+--
+-- Coarsening describes the process of reducing the amount of nodes in a graph
+-- by merging nodes into supernodes. There are different strategies, called
+-- schemes, that can be applied, like merging nodes that belong to edges in a
+-- maximal independent edge set or by creating supernodes based on a maximal
+-- independent node set.
+--
+-- Coarsening is not performed automatically. The functions |CoarseGraph:coarsen|
+-- and |CoarseGraph:interpolate| can be used to further coarsen the graph or
+-- to restore the previous state (while interpolating the node positions from
+-- the coarser version of the graph).
+--
+-- Note, however, that the input \meta{graph} is always modified in-place, so
+-- if the original version of \meta{graph} is needed in parallel to its
+-- coarse representations, a deep copy of \meta{graph} needs to be passed over
+-- to |CoarseGraph.new|.
+--
+-- @param graph An existing graph that needs to be coarsened.
+-- @param scheme Coarsening scheme to use. Possible values are:\par
+-- |CoarseGraph.COARSEN_INDEPENDENT_EDGES|:
+-- Coarsen the input graph by computing a maximal independent edge set
+-- and collapsing edges from this set. The resulting coarse graph has
+-- at least 50% of the nodes of the input graph. This coarsening scheme
+-- gives slightly better results than
+-- |CoarseGraph.COARSEN_INDEPENDENT_NODES| because it is less aggressive.
+-- However, this comes at higher computational cost.\par
+-- |CoarseGraph.COARSEN_INDEPENDENT_NODES|:
+-- Coarsen the input graph by computing a maximal independent node set,
+-- making nodes from this set supernodes in the coarse graph, merging
+-- adjacent nodes into the supernodes and connecting the supernodes
+-- if their graph distance is no greater than three. This scheme gives
+-- slightly worse results than |CoarseGraph.COARSEN_INDEPENDENT_EDGES|
+-- but is computationally more efficient.\par
+-- |CoarseGraph.COARSEN_HYBRID|: Combines the other schemes by starting
+-- with |CoarseGraph.COARSEN_INDEPENDENT_EDGES| and switching to
+-- |CoarseGraph.COARSEN_INDEPENDENT_NODES| as soon as the first scheme
+-- does not reduce the amount of nodes by a factor of 25%.
+--
+function CoarseGraph.new(graph, scheme)
+ local coarse_graph = {
+ graph = graph,
+ level = 0,
+ scheme = scheme or CoarseGraph.COARSEN_INDEPENDENT_EDGES,
+ ratio = 0,
+ }
+ setmetatable(coarse_graph, CoarseGraph)
+ return coarse_graph
+end
+
+
+
+local function custom_merge(table1, table2, first_metatable)
+ local result = table1 and lib.copy(table1) or {}
+ local first_metatable = first_metatable == true or false
+
+ for key, value in pairs(table2) do
+ if not result[key] then
+ result[key] = value
+ end
+ end
+
+ if not first_metatable or not getmetatable(result) then
+ setmetatable(result, getmetatable(table2))
+ end
+
+ return result
+end
+
+
+local function pairs_by_sorted_keys (t, f)
+ local a = {}
+ for n in pairs(t) do a[#a + 1] = n end
+ table.sort (a, f)
+ local i = 0
+ return function ()
+ i = i + 1
+ return a[i], t[a[i]]
+ end
+end
+
+
+
+function CoarseGraph:coarsen()
+ -- update the level
+ self.level = self.level + 1
+
+ local old_graph_size = #self.graph.nodes
+
+ if self.scheme == CoarseGraph.COARSEN_INDEPENDENT_EDGES then
+ local matching, unmatched_nodes = self:findMaximalMatching()
+
+ for _,edge in ipairs(matching) do
+ -- get the two nodes of the edge that we are about to collapse
+ local u, v = edge.nodes[1], edge.nodes[2]
+
+ assert(u ~= v, 'the edge ' .. tostring(edge) .. ' is a loop. loops are not supported by this algorithm')
+
+ -- create a supernode
+ local supernode = Node.new{
+ name = '(' .. u.name .. ':' .. v.name .. ')',
+ weight = u.weight + v.weight,
+ subnodes = { u, v },
+ subnode_edge = edge,
+ level = self.level,
+ }
+
+ -- add the supernode to the graph
+ self.graph:addNode(supernode)
+
+ -- collect all neighbors of the nodes to merge, create a node -> edge mapping
+ local u_neighbours = lib.map(u.edges, function(edge) return edge, edge:getNeighbour(u) end)
+ local v_neighbours = lib.map(v.edges, function(edge) return edge, edge:getNeighbour(v) end)
+
+ -- remove the two nodes themselves from the neighbor lists
+ u_neighbours = lib.map(u_neighbours, function (edge,node) if node ~= v then return edge,node end end)
+ v_neighbours = lib.map(v_neighbours, function (edge,node) if node ~= u then return edge,node end end)
+
+ -- compute a list of neighbors u and v have in common
+ local common_neighbours = lib.map(u_neighbours,
+ function (edge,node)
+ if v_neighbours[node] ~= nil then return edge,node end
+ end)
+
+ -- create a node -> edges mapping for common neighbors
+ common_neighbours = lib.map(common_neighbours, function (edge, node)
+ return { edge, v_neighbours[node] }, node
+ end)
+
+ -- drop common edges from the neighbor mappings
+ u_neighbours = lib.map(u_neighbours, function (val,node) if not common_neighbours[node] then return val,node end end)
+ v_neighbours = lib.map(v_neighbours, function (val,node) if not common_neighbours[node] then return val,node end end)
+
+ -- merge neighbor lists
+ local disjoint_neighbours = custom_merge(u_neighbours, v_neighbours)
+
+ -- create edges between the supernode and the neighbors of the merged nodes
+ for neighbour, edge in pairs_by_sorted_keys(disjoint_neighbours, function (n,m) return n.index < m.index end) do
+
+ -- create a superedge to replace the existing one
+ local superedge = Edge.new{
+ direction = edge.direction,
+ weight = edge.weight,
+ subedges = { edge },
+ level = self.level,
+ }
+
+ -- add the supernode and the neighbor to the edge
+ if u_neighbours[neighbour] then
+ superedge:addNode(neighbour)
+ superedge:addNode(supernode)
+
+ else
+ superedge:addNode(supernode)
+ superedge:addNode(neighbour)
+
+ end
+
+ -- replace the old edge
+ self.graph:addEdge(superedge)
+ self.graph:deleteEdge(edge)
+ end
+
+ -- do the same for all neighbors that the merged nodes have
+ -- in common, except that the weights of the new edges are the
+ -- sums of the of the weights of the edges to the common neighbors
+ for neighbour, edges in pairs_by_sorted_keys(common_neighbours, function (n,m) return n.index < m.index end) do
+ local weights = 0
+ for _,e in ipairs(edges) do
+ weights = weights + edge.weight
+ end
+
+ local superedge = Edge.new{
+ direction = Edge.UNDIRECTED,
+ weight = weights,
+ subedges = edges,
+ level = self.level,
+ }
+
+ -- add the supernode and the neighbor to the edge
+ superedge:addNode(supernode)
+ superedge:addNode(neighbour)
+
+ -- replace the old edges
+ self.graph:addEdge(superedge)
+ for _,edge in ipairs(edges) do
+ self.graph:deleteEdge(edge)
+ end
+ end
+
+ -- delete the nodes u and v which were replaced by the supernode
+ assert(#u.edges == 1, 'node ' .. u.name .. ' is part of a multiedge') -- if this fails, then there is a multiedge involving u
+ assert(#v.edges == 1, 'node ' .. v.name .. ' is part of a multiedge') -- same here
+ self.graph:deleteNode(u)
+ self.graph:deleteNode(v)
+ end
+ else
+ assert(false, 'schemes other than CoarseGraph.COARSEN_INDEPENDENT_EDGES are not implemented yet')
+ end
+
+ -- calculate the number of nodes ratio compared to the previous graph
+ self.ratio = #self.graph.nodes / old_graph_size
+end
+
+
+
+function CoarseGraph:revertSuperedge(superedge)
+ -- TODO we can probably skip adding edges that have one or more
+ -- subedges with the same level. But that needs more testing.
+
+ -- TODO we might have to pass the corresponding supernode to
+ -- this method so that we can move subnodes to the same
+ -- position, right? Interpolating seems to work fine without
+ -- though...
+
+ if #superedge.subedges == 1 then
+ local subedge = superedge.subedges[1]
+
+ if not self.graph:findNode(subedge.nodes[1].name) then
+ self.graph:addNode(subedge.nodes[1])
+ end
+
+ if not self.graph:findNode(subedge.nodes[2].name) then
+ self.graph:addNode(subedge.nodes[2])
+ end
+
+ if not self.graph:findEdge(subedge) then
+ subedge.nodes[1]:addEdge(subedge)
+ subedge.nodes[2]:addEdge(subedge)
+ self.graph:addEdge(subedge)
+ end
+
+ if subedge.level and subedge.level >= self.level then
+ self:revertSuperedge(subedge)
+ end
+ else
+ for _,subedge in ipairs(superedge.subedges) do
+ if not self.graph:findNode(subedge.nodes[1].name) then
+ self.graph:addNode(subedge.nodes[1])
+ end
+
+ if not self.graph:findNode(subedge.nodes[2].name) then
+ self.graph:addNode(subedge.nodes[2])
+ end
+
+ if not self.graph:findEdge(subedge) then
+ subedge.nodes[1]:addEdge(subedge)
+ subedge.nodes[2]:addEdge(subedge)
+ self.graph:addEdge(subedge)
+ end
+
+ if subedge.level and subedge.level >= self.level then
+ self:revertSuperedge(subedge)
+ end
+ end
+ end
+end
+
+
+
+function CoarseGraph:interpolate()
+ -- FIXME TODO Jannis: This does not work now that we allow multi-edges
+ -- and loops! Reverting generates the same edges multiple times which leads
+ -- to distorted drawings compared to the awesome results we had before!
+
+ local nodes = lib.copy(self.graph.nodes)
+
+ for _,supernode in ipairs(nodes) do
+ assert(not supernode.level or supernode.level <= self.level)
+
+ if supernode.level and supernode.level == self.level then
+ -- move the subnode to the position of the supernode and add it to the graph
+ supernode.subnodes[1].pos.x = supernode.pos.x
+ supernode.subnodes[1].pos.y = supernode.pos.y
+
+ if not self.graph:findNode(supernode.subnodes[1].name) then
+ self.graph:addNode(supernode.subnodes[1])
+ end
+
+ -- move the subnode to the position of the supernode and add it to the graph
+ supernode.subnodes[2].pos.x = supernode.pos.x
+ supernode.subnodes[2].pos.y = supernode.pos.y
+
+ if not self.graph:findNode(supernode.subnodes[2].name) then
+ self.graph:addNode(supernode.subnodes[2])
+ end
+
+ if not self.graph:findEdge(supernode.subnode_edge) then
+ supernode.subnodes[1]:addEdge(supernode.subnode_edge)
+ supernode.subnodes[2]:addEdge(supernode.subnode_edge)
+ self.graph:addEdge(supernode.subnode_edge)
+ end
+
+ local superedges = lib.copy(supernode.edges)
+
+ for _,superedge in ipairs(superedges) do
+ self:revertSuperedge(superedge)
+ end
+
+ self.graph:deleteNode(supernode)
+ end
+ end
+
+ -- Make sure that the nodes and edges are in the correct order:
+ table.sort (self.graph.nodes, function (a, b) return a.index < b.index end)
+ table.sort (self.graph.edges, function (a, b) return a.index < b.index end)
+ for _, n in pairs(self.graph.nodes) do
+ table.sort (n.edges, function (a, b) return a.index < b.index end)
+ end
+
+ -- update the level
+ self.level = self.level - 1
+end
+
+
+
+function CoarseGraph:getSize()
+ return #self.graph.nodes
+end
+
+
+
+function CoarseGraph:getRatio()
+ return self.ratio
+end
+
+
+
+function CoarseGraph:getLevel()
+ return self.level
+end
+
+
+
+function CoarseGraph:getGraph()
+ return self.graph
+end
+
+
+
+function CoarseGraph:findMaximalMatching()
+ local matching = {}
+ local matched_nodes = {}
+ local unmatched_nodes = {}
+
+ -- iterate over nodes in random order
+ for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do
+ local node = self.graph.nodes[j]
+ -- ignore nodes that have already been matched
+ if not matched_nodes[node] then
+ -- mark the node as matched
+ matched_nodes[node] = true
+
+ -- filter out edges adjacent to neighbors already matched
+ local edges = lib.imap(node.edges,
+ function (edge)
+ if not matched_nodes[edge:getNeighbour(node)] then return edge end
+ end)
+
+ -- FIXME TODO We use a light-vertex matching here. This is
+ -- different from the algorithm proposed by Hu which collapses
+ -- edges based on a heavy-edge matching...
+ if #edges > 0 then
+ -- sort edges by the weights of the node's neighbors
+ table.sort(edges, function (a, b)
+ return a:getNeighbour(node).weight < b:getNeighbour(node).weight
+ end)
+
+ -- match the node against the neighbor with minimum weight
+ matched_nodes[edges[1]:getNeighbour(node)] = true
+ table.insert(matching, edges[1])
+ end
+ end
+ end
+
+ -- generate a list of nodes that were not matched at all
+ for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do
+ local node = self.graph.nodes[j]
+ if not matched_nodes[node] then
+ table.insert(unmatched_nodes, node)
+ end
+ end
+
+ return matching, unmatched_nodes
+end
+
+
+-- done
+
+return CoarseGraph
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua
new file mode 100644
index 0000000000..d69d5fc6c9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua
@@ -0,0 +1,148 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+---
+-- @section subsubsection {Coarsening}
+--
+-- @end
+
+
+---
+
+declare {
+ key = "coarsen",
+ type = "boolean",
+ initial = "true",
+
+ summary = [["
+ Defines whether or not a multilevel approach is used that
+ iteratively coarsens the input graph into graphs $G_1,\dots,G_l$
+ with a smaller and smaller number of nodes. The coarsening stops as
+ soon as a minimum number of nodes is reached, as set via the
+ |minimum coarsening size| option, or if, in the last iteration, the
+ number of nodes was not reduced by at least the ratio specified via
+ |downsize ratio|.
+ "]],
+ documentation = [["
+ A random initial layout is computed for the coarsest graph $G_l$ first.
+ Afterwards, it is laid out by computing the attractive and repulsive
+ forces between its nodes.
+
+ In the subsequent steps, the previous coarse graph $G_{l-1}$ is
+ restored and its node positions are interpolated from the nodes
+ in~$G_l$. The graph $G_{l-1}$ is again laid out by computing the forces
+ between its nodes. These steps are repeated with $G_{l-2},\dots,G_1$ until
+ the original input graph $G_0$ has been restored, interpolated
+ and laid out.
+
+ The idea behind this approach is that, by arranging recursively
+ formed supernodes first and then interpolating and arranging their
+ subnodes step by step, the algorithm is less likely to settle in a
+ local energy minimum (of which there can be many, particularly for
+ large graphs). The quality of the drawings with coarsening enabled is
+ expected to be higher than graphics where this feature is not applied.
+
+ The following example demonstrates how coarsening can improve the
+ quality of graph drawings generated with Walshaw's algorihtm
+ |spring electrical layout'|.
+ "]],
+ examples = [["
+ \tikz \graph [spring electrical layout', coarsen=false, vertical=3 to 4]
+ {
+ { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 }
+ };
+
+ \tikz \graph [spring electrical layout', coarsen, vertical=3 to 4]
+ {
+ { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 }
+ };
+ "]]
+}
+
+---
+
+declare {
+ key = "minimum coarsening size",
+ type = "number",
+ initial = 2,
+
+ summary = [["
+ Defines the minimum number of nodes down to which the graph is
+ coarsened iteratively. The first graph that has a smaller or equal
+ number of nodes becomes the coarsest graph $G_l$, where $l$ is the
+ number of coarsening steps. The algorithm proceeds with the steps
+ described in the documentation of the |coarsen| option.
+ "]],
+ documentation = [["
+ In the following example the same graph is coarsened down to two
+ and four nodes, respectively. The layout of the original graph is
+ interpolated from the random initial layout and is not improved
+ further because the forces are not computed (0 iterations). Thus,
+ in the two graphs, the nodes are placed at exactly two and four
+ coordinates in the final drawing.
+ "]],
+ examples = [["
+ \tikz \graph [spring layout, iterations=0,
+ minimum coarsening size=2]
+ { subgraph C_n [n=8] };
+
+ \tikz \graph [spring layout, iterations=0,
+ minimum coarsening size=4]
+ { subgraph C_n [n=8] };
+ "]]
+}
+
+---
+
+declare {
+ key = "downsize ratio",
+ type = "number",
+ initial = "0.25",
+
+ summary = [["
+ Minimum ratio between 0 and 1 by which the number of nodes between
+ two coarse graphs $G_i$ and $G_{i+1}$ need to be reduced in order for
+ the coarsening to stop and for the algorithm to use $G_{i+1}$ as the
+ coarsest graph $G_l$. Aside from the input graph, the optimal value
+ of |downsize ratio| mostly depends on the coarsening scheme being
+ used. Possible schemes are |collapse independent edges| and
+ |connect independent nodes|.
+ "]],
+ documentation = [["
+ Increasing this option possibly reduces the number of coarse
+ graphs computed during the coarsening phase as coarsening will stop as
+ soon as a coarse graph does not reduce the number of nodes
+ substantially. This may speed up the algorithm but if the size of the
+ coarsest graph $G_l$ is much larger than |minimum coarsening size|, the
+ multilevel approach may not produce drawings as good as with a lower
+ |downsize ratio|.
+ "]],
+ examples = [["
+ % 1. ratio too high, coarsening stops early, benefits are lost
+ \tikz \graph [spring electrical layout',
+ downsize ratio=1.0,
+ node distance=7mm, vertical=3 to 4]
+ { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } };
+
+ % 2. ratio set to default, coarsening benefits are visible
+ \tikz \graph [spring electrical layout',
+ downsize ratio=0.2,
+ node distance=7mm, vertical=3 to 4]
+ { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } };
+ "]]
+}
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlDeclare.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlDeclare.lua
new file mode 100644
index 0000000000..af209d2c78
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlDeclare.lua
@@ -0,0 +1,41 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Controlling and Configuring Force-Based Algorithms}
+--
+-- All force-based algorithms are based on
+-- a general pattern which we detail in the following. Numerous options
+-- can be used to influence the behavior of this general pattern; more
+-- specific options that apply only to individual algorithms are
+-- explained along with these algorithms.
+--
+-- The vertices are initially laid out in a random configuration.
+-- Then the configuration is annealed to find a configuration of
+-- minimal energy. To avoid getting stuck in a local minimum or at a
+-- saddle point, random forces are added. All of this makes the final
+-- layout extremely susceptible to changes in the random numbers. To
+-- achieve a certain stability of the results, you should fix the
+-- random seed. However, in the recent past Lua has switched its
+-- random number generator, which means that you won't get the same
+-- sequence of random numbers as in a previous version, even for
+-- identical seed. If you rely on the long-term stability of vertex
+-- placement, you should consider using a different layout. With the
+-- spring layout you have to assume that the layout will be random.
+--
+-- @end
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlElectric.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlElectric.lua
new file mode 100644
index 0000000000..c9f129c28d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlElectric.lua
@@ -0,0 +1,105 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+---
+-- @section subsubsection {Forces and Their Effects: Electrical
+-- Repulsion}
+--
+-- @end
+
+
+---
+
+declare {
+ key = "electric charge",
+ type = "number",
+ initial = 1,
+
+ summary = [["
+ Defines the electric charge of the node. The stronger the
+ |electric charge| of a node the stronger the repulsion between the
+ node and others in the graph. A negative |electric charge| means that
+ other nodes are further attracted to the node rather than repulsed,
+ although in theory this effect strongly depends on how the
+ |spring electrical layout| algorithm works.
+ Two typical effects of increasing the |electric charge| are distortion
+ of symmetries and an upscaling of the drawings.
+ "]],
+ examples = {
+ {
+ options = [["preamble={\usetikzlibrary{graphs,graphdrawing} \usegdlibrary{force}}"]],
+ code = [["
+ \tikz \graph [spring electrical layout, horizontal=0 to 1]
+ { 0 [electric charge=1] -- subgraph C_n [n=10] };
+ "]]
+ },{
+ code = [["
+ \tikz \graph [spring electrical layout, horizontal=0 to 1]
+ { 0 [electric charge=5] -- subgraph C_n [n=10] };
+ "]]
+ },{
+ code = [["
+ \tikz \graph [spring electrical layout, horizontal=0 to 1]
+ { [clique] 1 [electric charge=5], 2, 3, 4 };
+ "]]
+ }
+ }
+}
+
+
+---
+
+declare {
+ key = "electric force order",
+ type = "number",
+ initial = "1",
+
+ summary = [["
+ Sometimes, when drawing symmetric and mesh-like graphs, the
+ peripheral distortion caused by long-range electric forces may be
+ undesired. Some electric force models allow to reduce long-range
+ forces and distortion effects by increasing
+ the order (exponent) of electric forces. Values between 0 and 1
+ increase long-range electric forces and the scaling of the
+ generated layouts. Value greater than 1 decrease long-range
+ electric forces and results in shrinking drawings.
+ "]]
+ }
+
+
+---
+
+declare {
+ key = "approximate remote forces",
+ type = "boolean",
+
+ summary = [["
+ Force based algorithms often need to compute a force for each pair
+ of vertices, which, for larger numbers of vertices, can lead to a
+ significant time overhead. This problem can be addressed by
+ approximating these forces: For a vertex far removed from a cluster
+ of vertices, instead of computing the force contribution of each
+ vertex of the cluster individually, we form a sort of
+ ``supervertex'' at the ``gravitational center'' of the cluster and
+ then compute only the force between this supervertex and the single
+ vertex.
+
+ \emph{Remark:} Currently, the implementation seems to be broken, at
+ least the results are somewhat strange when this key is used.
+ "]]
+ }
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlIteration.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlIteration.lua
new file mode 100644
index 0000000000..b8d96630cd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlIteration.lua
@@ -0,0 +1,136 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+
+---
+-- @section subsubsection {The Iterative Process and Cooling}
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "iterations",
+ type = "number",
+ initial = "500",
+
+ summary = [["
+ Limits the number of iterations of algorithms for force-based
+ layouts to \meta{number}.
+ "]],
+ documentation = [["
+ Depending on the characteristics of the input graph and the parameters
+ chosen for the algorithm, minimizing the system energy may require
+ many iterations.
+
+ In these situations it may come in handy to limit the number of
+ iterations. This feature can also be useful to draw the same graph
+ after different iterations and thereby demonstrate how the spring or
+ spring-electrical algorithm improves the drawing step by step.
+
+ The examples shows two drawings generated using two
+ different |iteration| limits.
+ "]],
+ examples = {[["
+ \tikz \graph [spring layout, iterations=10] { subgraph K_n [n=4] };
+ "]],[["
+ \tikz \graph [spring layout, iterations=500] { subgraph K_n [n=4] };
+ "]],[["
+ \tikz \graph [spring electrical layout, iterations=10]
+ { subgraph K_n [n=4] };
+ "]],[["
+ \tikz \graph [spring electrical layout, iterations=500]
+ { subgraph K_n [n=4] };
+ "]]
+ }
+}
+
+---
+
+declare {
+ key = "initial step length",
+ type = "length",
+ initial = "0",
+
+ summary = [["
+ This parameter specifies the amount by which nodes will be
+ displaced in each iteration, initially. If set to |0| (which is the
+ default), an appropriate value is computed automatically.
+ "]]
+ }
+
+---
+
+declare {
+ key = "cooling factor",
+ type = "number",
+ initial = "0.95",
+
+ summary = [["
+ This parameter helps in controlling how layouts evolve over
+ time. It is used to gradually reduce the step size
+ between one iteration to the next.
+ "]],
+ documentation = [["
+ A small positive cooling factor
+ $\ge 0$ means that the movement of nodes is quickly or abruptly
+ reduced, while a large cooling factor $\le 1$ allows for a smoother
+ step by step layout refinement at the cost of more iterations. The
+ following example demonstrates how a smaller cooling factor may
+ result in a less balanced drawing. By default, Hu2006 spring,
+ Hu2006 spring electrical, and Walshaw2000 spring electrical use a
+ cooling factor of |0.95|.
+ "]],
+ examples = {[["
+ \tikz \graph [spring layout, cooling factor=0.1]
+ { a -> b -> c -> a };
+ "]],[["
+ \tikz \graph [spring layout, cooling factor=0.5]
+ { a -> b -> c -> a };
+ "]]
+ }
+}
+
+---
+
+declare {
+ key = "convergence tolerance",
+ type = "number",
+ initial = "0.01",
+
+ summary = [["
+ All spring and spring-electrical algorithms implemented in the
+ thesis terminate as soon as the maximum movement of any node drops
+ below $k \cdot \meta{tolerance}$. This tolerance factor can be changed
+ with the convergence tolerance option:
+ "]],
+ examples = {[["
+ \tikz \graph [spring layout, convergence tolerance=0.001]
+ { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } };
+ "]],[["
+ \tikz \graph [spring layout, convergence tolerance=1.0]
+ { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } };
+ "]]
+ }
+}
+
+
+
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlSprings.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlSprings.lua
new file mode 100644
index 0000000000..9b0c1071e3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlSprings.lua
@@ -0,0 +1,59 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsubsection {Forces and Their Effects: Springs}
+--
+-- The most important parameter of springs is their ``natural
+-- length'', which can be configured using the general-purpose
+-- |node distance| parameter. It is the ``equilibrium length'' of a
+-- spring between two nodes in the graph. When an edge has this
+-- length, no forces will ``push'' or ``pull'' along the edge.
+--
+-- The following examples shows how a simple graph can be scaled by
+-- changing the |node distance|:
+-- %
+-- \begin{codeexample}[preamble={\usetikzlibrary{graphs.standard,graphdrawing}
+-- \usegdlibrary{force}}]
+-- \tikz \graph [spring layout, node distance=7mm] { subgraph C_n[n=3] };
+-- \tikz \graph [spring layout] { subgraph C_n[n=3] };
+-- \tikz \graph [spring layout, node distance=15mm]{ subgraph C_n[n=3] };
+-- \end{codeexample}
+-- %
+-- \begin{codeexample}[preamble={\usetikzlibrary{graphs.standard,graphdrawing}
+-- \usegdlibrary{force}}]
+-- \tikz \graph [spring electrical layout, node distance=0.7cm] { subgraph C_n[n=3] };
+-- \tikz \graph [spring electrical layout] { subgraph C_n[n=3] };
+-- \tikz \graph [spring electrical layout, node distance=1.5cm] { subgraph C_n[n=3] };
+-- \end{codeexample}
+--
+-- @end
+
+
+---
+
+declare {
+ key = "spring constant",
+ type = "number",
+ initial = "0.01",
+
+ summary = [["
+ The ``spring constant'' is a factor from Hooke's law describing the
+ ``stiffness'' of a spring. This factor is used inside spring-based
+ algorithms to determine how strongly edges ``pull'' and ``push'' at
+ the nodes they connect.
+ "]]
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlStart.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlStart.lua
new file mode 100644
index 0000000000..85a64b0a5a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/ControlStart.lua
@@ -0,0 +1,41 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsubsection {Start Configuration}
+--
+-- Currently, the start configuration for force-based algorithms is a
+-- random distribution of the vertices. You can influence it by
+-- changing the |random seed|:
+-- %
+-- \begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+-- \usegdlibrary{force}}]
+-- \tikz \graph [random seed=10, spring layout] {
+-- a -- {b, c, d} -- e -- f -- {g,h} -- {a,b,e};
+-- };
+-- \end{codeexample}
+-- %
+-- \begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+-- \usegdlibrary{force}}]
+-- \tikz \graph [random seed=11, spring layout] {
+-- a -- {b, c, d} -- e -- f -- {g,h} -- {a,b,e};
+-- };
+-- \end{codeexample}
+--
+-- Other methods, like a planar preembedding, are not implemented
+-- currently.
+--
+-- @end
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/QuadTree.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/QuadTree.lua
new file mode 100644
index 0000000000..3e1620dc21
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/QuadTree.lua
@@ -0,0 +1,280 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+--- An implementation of a quad trees.
+--
+-- The class QuadTree provides methods form handling quadtrees.
+--
+
+local QuadTree = {
+ -- Subclasses
+ Particle = {},
+ Cell = {}
+}
+QuadTree.__index = QuadTree
+
+-- Namespace:
+require("pgf.gd.force").QuadTree = QuadTree
+
+-- Imports:
+local Vector = require "pgf.gd.deprecated.Vector"
+local lib = require "pgf.gd.lib"
+
+
+--- Creates a new quad tree.
+--
+-- @return A newly-allocated quad tree.
+--
+function QuadTree.new(x, y, width, height, max_particles)
+ local tree = {
+ root_cell = QuadTree.Cell.new(x, y, width, height, max_particles)
+ }
+ setmetatable(tree, QuadTree)
+ return tree
+end
+
+
+
+--- Inserts a particle
+--
+-- @param param A particle of type QuadTree.Particle
+--
+function QuadTree:insert(particle)
+ self.root_cell:insert(particle)
+end
+
+
+
+--- Computes the interactions of a particle with other cells
+--
+-- @param particle A particle
+-- @param test_func A test function, which on input of a cubical cell and a particle should
+-- decide whether the cubical cell should be inserted into the result
+-- @param cells An optional array of cells, to which the found cells will be added
+--
+-- @return The cells array or a new array, if it was empty.
+--
+function QuadTree:findInteractionCells(particle, test_func, cells)
+ local test_func = test_func or function (cell, particle) return true end
+ cells = cells or {}
+
+ self.root_cell:findInteractionCells(particle, test_func, cells)
+
+ return cells
+end
+
+
+
+
+--- Particle subclass
+QuadTree.Particle.__index = QuadTree.Particle
+
+
+
+--- Creates a new particle.
+--
+-- @return A newly-allocated particle.
+--
+function QuadTree.Particle.new(pos, mass)
+ local particle = {
+ pos = pos:copy(),
+ mass = mass or 1,
+ subparticles = {},
+ }
+ setmetatable(particle, QuadTree.Particle)
+ return particle
+end
+
+
+
+--- A cell of a quadtree
+--
+-- TT: Why is it called "cubical", by the way?!
+
+QuadTree.Cell.__index = QuadTree.Cell
+
+
+
+--- Creates a new cubicle cell.
+--
+-- @return a newly-allocated cubicle cell.
+--
+function QuadTree.Cell.new(x, y, width, height, max_particles)
+ local cell = {
+ x = x,
+ y = y,
+ width = width,
+ height = height,
+ max_particles = max_particles or 1,
+ subcells = {},
+ particles = {},
+ center_of_mass = nil,
+ mass = 0,
+ }
+ setmetatable(cell, QuadTree.Cell)
+ return cell
+end
+
+
+
+function QuadTree.Cell:containsParticle(particle)
+ return particle.pos.x >= self.x and particle.pos.x <= self.x + self.width
+ and particle.pos.y >= self.y and particle.pos.y <= self.y + self.height
+end
+
+
+
+function QuadTree.Cell:findSubcell(particle)
+ return lib.find(self.subcells, function (cell)
+ return cell:containsParticle(particle)
+ end)
+end
+
+
+
+function QuadTree.Cell:createSubcells()
+ assert(type(self.subcells) == 'table' and #self.subcells == 0)
+ assert(type(self.particles) == 'table' and #self.particles <= self.max_particles)
+
+ if #self.subcells == 0 then
+ for _,x in ipairs({self.x, self.x + self.width/2}) do
+ for _,y in ipairs({self.y, self.y + self.height/2}) do
+ local cell = QuadTree.Cell.new(x, y, self.width/2, self.height/2, self.max_particles)
+ table.insert(self.subcells, cell)
+ end
+ end
+ end
+end
+
+
+
+function QuadTree.Cell:insert(particle)
+ -- check if we have a particle with the exact same position already
+ local existing = lib.find(self.particles, function (other)
+ return other.pos:equals(particle.pos)
+ end)
+
+ if existing then
+ -- we already have a particle at the same position; splitting the cell
+ -- up makes no sense; instead we add the new particle as a
+ -- subparticle of the existing one
+ table.insert(existing.subparticles, particle)
+ else
+ if #self.subcells == 0 and #self.particles < self.max_particles then
+ table.insert(self.particles, particle)
+ else
+ if #self.subcells == 0 then
+ self:createSubcells()
+ end
+
+ -- move particles to the new subcells
+ for _,existing in ipairs(self.particles) do
+ local cell = self:findSubcell(existing)
+ assert(cell, 'failed to find a cell for particle ' .. tostring(existing.pos))
+ cell:insert(existing)
+ end
+
+ self.particles = {}
+
+ local cell = self:findSubcell(particle)
+ assert(cell)
+ cell:insert(particle)
+ end
+ end
+
+ self:updateMass()
+ self:updateCenterOfMass()
+
+ assert(self.mass)
+ assert(self.center_of_mass)
+end
+
+
+
+function QuadTree.Cell:updateMass()
+ -- reset mass to zero
+ self.mass = 0
+
+ if #self.subcells == 0 then
+ -- the mass is the number of particles of the cell
+ for _,particle in ipairs(self.particles) do
+ self.mass = self.mass + particle.mass
+ for _,subparticle in ipairs(particle.subparticles) do
+ self.mass = self.mass + subparticle.mass
+ end
+ end
+ else
+ -- the mass is the sum of the masses of the subcells
+ for _,subcell in ipairs(self.subcells) do
+ self.mass = self.mass + subcell.mass
+ end
+ end
+end
+
+
+
+function QuadTree.Cell:updateCenterOfMass()
+ -- reset center of mass, assuming the cell is empty
+ self.center_of_mass = nil
+
+ if #self.subcells == 0 then
+ -- the center of mass is the average position of the particles
+ -- weighted by their masses
+ self.center_of_mass = Vector.new (2)
+ for _,p in ipairs(self.particles) do
+ for _,sp in ipairs(p.subparticles) do
+ self.center_of_mass = self.center_of_mass:plus(sp.pos:timesScalar(sp.mass))
+ end
+ self.center_of_mass = self.center_of_mass:plus(p.pos:timesScalar(p.mass))
+ end
+ self.center_of_mass = self.center_of_mass:dividedByScalar(self.mass)
+ else
+ -- the center of mass is the average of the weighted centers of mass
+ -- of the subcells
+ self.center_of_mass = Vector.new(2)
+ for _,sc in ipairs(self.subcells) do
+ if sc.center_of_mass then
+ self.center_of_mass = self.center_of_mass:plus(sc.center_of_mass:timesScalar(sc.mass))
+ else
+ assert(sc.mass == 0)
+ end
+ end
+ self.center_of_mass = self.center_of_mass:dividedByScalar(self.mass)
+ end
+end
+
+
+
+function QuadTree.Cell:findInteractionCells(particle, test_func, cells)
+ if #self.subcells == 0 or test_func(self, particle) then
+ table.insert(cells, self)
+ else
+ for _,subcell in ipairs(self.subcells) do
+ subcell:findInteractionCells(particle, test_func, cells)
+ end
+ end
+end
+
+
+function QuadTree.Cell:__tostring()
+ return '((' .. self.x .. ', ' .. self.y .. ') '
+ .. 'to (' .. self.x + self.width .. ', ' .. self.y + self.height .. '))'
+ .. (self.particle and ' => ' .. self.particle.name or '')
+ .. (self.center_of_mass and ' mass ' .. self.mass .. ' at ' .. tostring(self.center_of_mass) or '')
+end
+
+
+
+-- done
+
+return QuadTree
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua
new file mode 100644
index 0000000000..a7230eb1f6
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua
@@ -0,0 +1,633 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local SpringElectricalHu2006 = {}
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+
+---
+
+declare {
+ key = "spring electrical Hu 2006 layout",
+ algorithm = SpringElectricalHu2006,
+
+ preconditions = {
+ connected = true,
+ loop_free = true,
+ simple = true,
+ },
+
+ old_graph_model = true,
+
+ summary = [["
+ Implementation of a spring electrical graph drawing algorithm based on
+ a paper by Hu.
+ "]],
+ documentation = [["
+ \begin{itemize}
+ \item
+ Y. Hu.
+ \newblock Efficient, high-quality force-directed graph drawing.
+ \newblock \emph{The Mathematica Journal}, 2006.
+ \end{itemize}
+
+ There are some modifications compared to the original algorithm,
+ see the Diploma thesis of Pohlmann for details.
+ "]]
+}
+
+-- Imports
+
+local PathLengths = require "pgf.gd.lib.PathLengths"
+local Vector = require "pgf.gd.deprecated.Vector"
+
+local QuadTree = require "pgf.gd.force.QuadTree"
+local CoarseGraph = require "pgf.gd.force.CoarseGraph"
+
+local lib = require "pgf.gd.lib"
+
+
+function SpringElectricalHu2006:run()
+
+ -- Setup properties
+ local options = self.digraph.options
+
+ self.iterations = options['iterations']
+ self.cooling_factor = options['cooling factor']
+ self.initial_step_length = options['initial step length']
+ self.convergence_tolerance = options['convergence tolerance']
+
+ self.natural_spring_length = options['node distance']
+ self.spring_constant = options['spring constant']
+
+ self.approximate_repulsive_forces = options['approximate remote forces']
+ self.repulsive_force_order = options['electric force order']
+
+ self.coarsen = options['coarsen']
+ self.downsize_ratio = options['downsize ratio']
+ self.minimum_graph_size = options['minimum coarsening size']
+
+ -- Adjust types
+ self.downsize_ratio = math.max(0, math.min(1, self.downsize_ratio))
+ self.graph_size = #self.graph.nodes
+ self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1))
+
+ -- validate input parameters
+ assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0')
+ assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1')
+ assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0')
+ assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0')
+ assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0')
+ assert(self.spring_constant >= 0, 'the spring constant (value: ' .. self.spring_constant .. ') needs to be greater or equal to 0')
+ assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1')
+ assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2')
+
+ -- initialize node weights
+ for _,node in ipairs(self.graph.nodes) do
+ if node:getOption('electric charge') ~= nil then
+ node.weight = node:getOption('electric charge')
+ else
+ node.weight = 1
+ end
+ end
+
+ -- initialize edge weights
+ for _,edge in ipairs(self.graph.edges) do
+ edge.weight = 1
+ end
+
+ -- initialize the coarse graph data structure. note that the algorithm
+ -- is the same regardless whether coarsening is used, except that the
+ -- number of coarsening steps without coarsening is 0
+ local coarse_graph = CoarseGraph.new(self.graph)
+
+ -- check if the multilevel approach should be used
+ if self.coarsen then
+ -- coarsen the graph repeatedly until only minimum_graph_size nodes
+ -- are left or until the size of the coarse graph was not reduced by
+ -- at least the downsize ratio configured by the user
+ while coarse_graph:getSize() > self.minimum_graph_size
+ and coarse_graph:getRatio() <= (1 - self.downsize_ratio)
+ do
+ coarse_graph:coarsen()
+ end
+ end
+
+ if self.coarsen then
+ -- use the natural spring length as the initial natural spring length
+ local spring_length = self.natural_spring_length
+
+ -- compute a random initial layout for the coarsest graph
+ self:computeInitialLayout(coarse_graph.graph, spring_length)
+
+ -- set the spring length to the average edge length of the initial layout
+ spring_length = 0
+ for _,edge in ipairs(coarse_graph.graph.edges) do
+ spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm()
+ end
+ spring_length = spring_length / #coarse_graph.graph.edges
+
+ -- additionally improve the layout with the force-based algorithm
+ -- if there are more than two nodes in the coarsest graph
+ if coarse_graph:getSize() > 2 then
+ self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.adaptive_step_update)
+ end
+
+ -- undo coarsening step by step, applying the force-based sub-algorithm
+ -- to every intermediate coarse graph as well as the original graph
+ while coarse_graph:getLevel() > 0 do
+
+ -- compute the diameter of the parent coarse graph
+ local parent_diameter = PathLengths.pseudoDiameter(coarse_graph.graph)
+
+ -- interpolate the previous coarse graph from its parent
+ coarse_graph:interpolate()
+
+ -- compute the diameter of the current coarse graph
+ local current_diameter = PathLengths.pseudoDiameter(coarse_graph.graph)
+
+ -- scale node positions by the quotient of the pseudo diameters
+ for _,node in ipairs(coarse_graph.graph) do
+ node.pos:update(function (n, value)
+ return value * (current_diameter / parent_diameter)
+ end)
+ end
+
+ -- compute forces in the graph
+ self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.conservative_step_update)
+ end
+ else
+ -- compute a random initial layout for the coarsest graph
+ self:computeInitialLayout(coarse_graph.graph, self.natural_spring_length)
+
+ -- set the spring length to the average edge length of the initial layout
+ spring_length = 0
+ for _,edge in ipairs(coarse_graph.graph.edges) do
+ spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm()
+ end
+ spring_length = spring_length / #coarse_graph.graph.edges
+
+ -- improve the layout with the force-based algorithm
+ self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.adaptive_step_update)
+ end
+end
+
+
+
+function SpringElectricalHu2006:computeInitialLayout(graph, spring_length)
+ -- TODO how can supernodes and fixed nodes go hand in hand?
+ -- maybe fix the supernode if at least one of its subnodes is
+ -- fixated?
+
+ -- fixate all nodes that have a 'desired at' option. this will set the
+ -- node.fixed member to true and also set node.pos.x and node.pos.y
+ self:fixateNodes(graph)
+
+ if #graph.nodes == 2 then
+ if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then
+ local fixed_index = graph.nodes[2].fixed and 2 or 1
+ local loose_index = graph.nodes[2].fixed and 1 or 2
+
+ if not graph.nodes[1].fixed and not graph.nodes[2].fixed then
+ -- both nodes can be moved, so we assume node 1 is fixed at (0,0)
+ graph.nodes[1].pos.x = 0
+ graph.nodes[1].pos.y = 0
+ end
+
+ -- position the loose node relative to the fixed node, with
+ -- the displacement (random direction) matching the spring length
+ local direction = Vector.new{x = lib.random(1, spring_length), y = lib.random(1, spring_length)}
+ local distance = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2
+ local displacement = direction:normalized():timesScalar(distance)
+
+ graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement)
+ else
+ -- both nodes are fixed, initial layout may be far from optimal
+ end
+ else
+
+ -- use a random positioning technique
+ local function positioning_func(n)
+ local radius = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2
+ return lib.random(-radius, radius)
+ end
+
+ -- compute initial layout based on the random positioning technique
+ for _,node in ipairs(graph.nodes) do
+ if not node.fixed then
+ node.pos.x = positioning_func(1)
+ node.pos.y = positioning_func(2)
+ end
+ end
+ end
+end
+
+
+
+function SpringElectricalHu2006:computeForceLayout(graph, spring_length, step_update_func)
+ -- global (=repulsive) force function
+ function accurate_repulsive_force(distance, weight)
+ -- note: the weight is taken into the equation here. unlike in the original
+ -- algorithm different electric charges are allowed for each node in this
+ -- implementation
+ return - weight * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order)
+ end
+
+ -- global (=repulsive, approximated) force function
+ function approximated_repulsive_force(distance, mass)
+ return - mass * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order)
+ end
+
+ -- local (spring) force function
+ function attractive_force(distance)
+ return (distance * distance) / spring_length
+ end
+
+ -- define the Barnes-Hut opening criterion
+ function barnes_hut_criterion(cell, particle)
+ local distance = particle.pos:minus(cell.center_of_mass):norm()
+ return cell.width / distance <= 1.2
+ end
+
+ -- fixate all nodes that have a 'desired at' option. this will set the
+ -- node.fixed member to true and also set node.pos.x and node.pos.y
+ self:fixateNodes(graph)
+
+ -- adjust the initial step length automatically if desired by the user
+ local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length
+
+ -- convergence criteria etc.
+ local converged = false
+ local energy = math.huge
+ local iteration = 0
+ local progress = 0
+
+ while not converged and iteration < self.iterations do
+ -- remember old node positions
+ local old_positions = lib.map(graph.nodes, function (node)
+ return node.pos:copy(), node
+ end)
+
+ -- remember the old system energy and reset it for the current iteration
+ local old_energy = energy
+ energy = 0
+
+ -- build the quadtree for approximating repulsive forces, if desired
+ local quadtree = nil
+ if self.approximate_repulsive_forces then
+ quadtree = self:buildQuadtree(graph)
+ end
+
+ for _,v in ipairs(graph.nodes) do
+ if not v.fixed then
+ -- vector for the displacement of v
+ local d = Vector.new(2)
+
+ -- compute repulsive forces
+ if self.approximate_repulsive_forces then
+ -- determine the cells that have a repulsive influence on v
+ local cells = quadtree:findInteractionCells(v, barnes_hut_criterion)
+
+ -- compute the repulsive force between these cells and v
+ for _,cell in ipairs(cells) do
+ -- check if the cell is a leaf
+ if #cell.subcells == 0 then
+ -- compute the forces between the node and all particles in the cell
+ for _,particle in ipairs(cell.particles) do
+ local real_particles = lib.copy(particle.subparticles)
+ table.insert(real_particles, particle)
+
+ for _,real_particle in ipairs(real_particles) do
+ local delta = real_particle.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the node and the cell's
+ -- center of mass are located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = approximated_repulsive_force(delta:norm(), real_particle.mass)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ else
+ -- compute the distance between the node and the cell's center of mass
+ local delta = cell.center_of_mass:minus(v.pos)
+
+ -- enforce a small virtual distance if the node and the cell's
+ -- center of mass are located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = approximated_repulsive_force(delta:norm(), cell.mass)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ else
+ for _,u in ipairs(graph.nodes) do
+ if v ~= u then
+ -- compute the distance between u and v
+ local delta = u.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the nodes are
+ -- located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = accurate_repulsive_force(delta:norm(), u.weight)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ end
+
+ -- compute attractive forces between v and its neighbors
+ for _,edge in ipairs(v.edges) do
+ local u = edge:getNeighbour(v)
+
+ -- compute the distance between u and v
+ local delta = u.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the nodes are
+ -- located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the spring force vector between u and v
+ local attr_force = attractive_force(delta:norm())
+ local force = delta:normalized():timesScalar(attr_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+
+ -- really move the node now
+ -- TODO note how all nodes are moved by the same amount (step_length)
+ -- while Walshaw multiplies the normalized force with min(step_length,
+ -- d:norm()). could that improve this algorithm even further?
+ v.pos = v.pos:plus(d:normalized():timesScalar(step_length))
+
+ -- TODO Hu doesn't mention this but the energy of a particle is
+ -- typically considered as the product of its mass and the square of
+ -- its forces. This means we should probably take the weight of
+ -- the node v into the equation, doesn't it?
+ --
+ -- update the energy function
+ energy = energy + math.pow(d:norm(), 2)
+ -- vector for the displacement of v
+ local d = Vector.new(2)
+
+ -- compute repulsive forces
+ if self.approximate_repulsive_forces then
+ -- determine the cells that have a repulsive influence on v
+ local cells = quadtree:findInteractionCells(v, barnes_hut_criterion)
+
+ -- compute the repulsive force between these cells and v
+ for _,cell in ipairs(cells) do
+ -- check if the cell is a leaf
+ if #cell.subcells == 0 then
+ -- compute the forces between the node and all particles in the cell
+ for _,particle in ipairs(cell.particles) do
+ local real_particles = lib.copy(particle.subparticles)
+ table.insert(real_particles, particle)
+
+ for _,real_particle in ipairs(real_particles) do
+ local delta = real_particle.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the node and the cell's
+ -- center of mass are located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = approximated_repulsive_force(delta:norm(), real_particle.mass)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ else
+ -- compute the distance between the node and the cell's center of mass
+ local delta = cell.center_of_mass:minus(v.pos)
+
+ -- enforce a small virtual distance if the node and the cell's
+ -- center of mass are located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = approximated_repulsive_force(delta:norm(), cell.mass)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ else
+ for _,u in ipairs(graph.nodes) do
+ if v ~= u then
+ -- compute the distance between u and v
+ local delta = u.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the nodes are
+ -- located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = accurate_repulsive_force(delta:norm(), u.weight)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ end
+
+ -- compute attractive forces between v and its neighbours
+ for _,edge in ipairs(v.edges) do
+ local u = edge:getNeighbour(v)
+
+ -- compute the distance between u and v
+ local delta = u.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the nodes are
+ -- located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the spring force vector between u and v
+ local attr_force = attractive_force(delta:norm())
+ local force = delta:normalized():timesScalar(attr_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+
+ -- really move the node now
+ -- TODO note how all nodes are moved by the same amount (step_length)
+ -- while Walshaw multiplies the normalized force with min(step_length,
+ -- d:norm()). could that improve this algorithm even further?
+ v.pos = v.pos:plus(d:normalized():timesScalar(step_length))
+
+ -- TODO Hu doesn't mention this but the energy of a particle is
+ -- typically considered as the product of its mass and the square of
+ -- its forces. This means we should probably take the weight of
+ -- the node v into the equation, doesn't it?
+ --
+ -- update the energy function
+ energy = energy + math.pow(d:norm(), 2)
+ end
+ end
+
+ -- update the step length and progress counter
+ step_length, progress = step_update_func(step_length, self.cooling_factor, energy, old_energy, progress)
+
+ -- compute the maximum node movement in this iteration
+ local max_movement = 0
+ for _,x in ipairs(graph.nodes) do
+ local delta = x.pos:minus(old_positions[x])
+ max_movement = math.max(delta:norm(), max_movement)
+ end
+
+ -- the algorithm will converge if the maximum movement is below a
+ -- threshold depending on the spring length and the convergence
+ -- tolerance
+ if max_movement < spring_length * self.convergence_tolerance then
+ converged = true
+ end
+
+ -- increment the iteration counter
+ iteration = iteration + 1
+ end
+end
+
+
+
+-- Fixes nodes at their specified positions.
+--
+function SpringElectricalHu2006:fixateNodes(graph)
+ local number_of_fixed_nodes = 0
+
+ for _,node in ipairs(graph.nodes) do
+ -- read the 'desired at' option of the node
+ local coordinate = node:getOption('desired at')
+
+ if coordinate then
+ -- apply the coordinate
+ node.pos.x = coordinate.x
+ node.pos.y = coordinate.y
+
+ -- mark the node as fixed
+ node.fixed = true
+
+ number_of_fixed_nodes = number_of_fixed_nodes + 1
+ end
+ end
+ if number_of_fixed_nodes > 1 then
+ self.growth_direction = "fixed" -- do not grow, orientation is now fixed
+ end
+end
+
+
+
+function SpringElectricalHu2006:buildQuadtree(graph)
+ -- compute the minimum x and y coordinates of all nodes
+ local min_pos = graph.nodes[1].pos
+ for _,node in ipairs(graph.nodes) do
+ min_pos = Vector.new(2, function (n) return math.min(min_pos[n], node.pos[n]) end)
+ end
+
+ -- compute maximum x and y coordinates of all nodes
+ local max_pos = graph.nodes[1].pos
+ for _,node in ipairs(graph.nodes) do
+ max_pos = Vector.new(2, function (n) return math.max(max_pos[n], node.pos[n]) end)
+ end
+
+ -- make sure the maximum position is at least a tiny bit
+ -- larger than the minimum position
+ if min_pos:equals(max_pos) then
+ max_pos = max_pos:plus(Vector.new(2, function (n)
+ return 0.1 + lib.random() * 0.1
+ end))
+ end
+
+ -- make sure to make the quadtree area slightly larger than required
+ -- in theory; for some reason Lua will otherwise think that nodes with
+ -- min/max x/y coordinates are outside the box... weird? yes.
+ min_pos = min_pos:minus({1,1})
+ max_pos = max_pos:plus({1,1})
+
+ -- create the quadtree
+ quadtree = QuadTree.new(min_pos.x, min_pos.y,
+ max_pos.x - min_pos.x,
+ max_pos.y - min_pos.y)
+
+ -- insert nodes into the quadtree
+ for _,node in ipairs(graph.nodes) do
+ local particle = QuadTree.Particle.new(node.pos, node.weight)
+ particle.node = node
+ quadtree:insert(particle)
+ end
+
+ return quadtree
+end
+
+
+
+function SpringElectricalHu2006.conservative_step_update(step, cooling_factor)
+ return cooling_factor * step, nil
+end
+
+
+
+function SpringElectricalHu2006.adaptive_step_update(step, cooling_factor, energy, old_energy, progress)
+ if energy < old_energy then
+ progress = progress + 1
+ if progress >= 5 then
+ progress = 0
+ step = step / cooling_factor
+ end
+ else
+ progress = 0
+ step = cooling_factor * step
+ end
+ return step, progress
+end
+
+
+-- done
+
+return SpringElectricalHu2006
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua
new file mode 100644
index 0000000000..6ab74fc367
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua
@@ -0,0 +1,54 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Spring Electrical Layouts}
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "spring electrical layout",
+ use = {
+ { key = "spring electrical Hu 2006 layout" },
+ { key = "spring constant", value = "0.2" }
+ },
+
+ summary = [["
+ This key selects Hu's 2006 spring electrical layout with
+ appropriate settings for some parameters.
+ "]]
+}
+
+
+---
+
+declare {
+ key = "spring electrical layout'",
+ use = {
+ { key = "spring electrical Walshaw 2000 layout" },
+ { key = "spring constant", value = "0.01" },
+ { key = "convergence tolerance", value = "0.001" },
+ },
+
+ summary = [["
+ This key selects Walshaw's 2000 spring electrical layout with
+ appropriate settings for some parameters.
+ "]]
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua
new file mode 100644
index 0000000000..5f7978da4e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua
@@ -0,0 +1,520 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+local SpringElectricalWalshaw2000 = {}
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+
+---
+
+declare {
+ key = "spring electrical Walshaw 2000 layout",
+ algorithm = SpringElectricalWalshaw2000,
+
+ preconditions = {
+ connected = true,
+ loop_free = true,
+ simple = true,
+ },
+
+ old_graph_model = true,
+
+ summary = [["
+ Implementation of a spring electrical graph drawing algorithm based on
+ a paper by Walshaw.
+ "]],
+ documentation = [["
+ \begin{itemize}
+ \item
+ C. Walshaw.
+ \newblock A multilevel algorithm for force-directed graph drawing.
+ \newblock In J. Marks, editor, \emph{Graph Drawing}, Lecture Notes in
+ Computer Science, 1984:31--55, 2001.
+ \end{itemize}
+
+ The following modifications compared to the original algorithm were applied:
+ %
+ \begin{itemize}
+ \item An iteration limit was added.
+ \item The natural spring length for all coarse graphs is computed based
+ on the formula presented by Walshaw, so that the natural spring
+ length of the original graph (coarse graph 0) is the same as
+ the value requested by the user.
+ \item Users can define custom node and edge weights.
+ \item Coarsening stops when $|V(G_i+1)|/|V(G_i)| < p$ where $p = 0.75$.
+ \item Coarsening stops when the maximal matching is empty.
+ \item The runtime of the algorithm is improved by use of a quadtree
+ data structure like Hu does in his algorithm.
+ \item A limiting the number of levels of the quadtree is not implemented.
+ \end{itemize}
+ "]]
+}
+
+-- TODO Implement the following keys (or whatever seems appropriate
+-- and doable for this algorithm):
+-- - /tikz/desired at
+-- - /tikz/influence cutoff distance
+-- - /tikz/spring stiffness (could this be the equivalent to the electric
+-- charge of nodes?
+-- - /tikz/natural spring dimension per edge
+--
+-- TODO Implement the following features:
+-- - clustering of nodes using color classes
+-- - different cluster layouts (vertical line, horizontal line,
+-- normal cluster, internally fixed subgraph)
+
+
+
+local Vector = require "pgf.gd.deprecated.Vector"
+
+local QuadTree = require "pgf.gd.force.QuadTree"
+local CoarseGraph = require "pgf.gd.force.CoarseGraph"
+
+
+local lib = require "pgf.gd.lib"
+
+
+function SpringElectricalWalshaw2000:run()
+
+ -- Setup parameters
+ local options = self.digraph.options
+
+ self.iterations = options['iterations']
+ self.cooling_factor = options['cooling factor']
+ self.initial_step_length = options['initial step length']
+ self.convergence_tolerance = options['convergence tolerance']
+
+ self.natural_spring_length = options['node distance']
+ self.spring_constant = options['spring constant']
+
+ self.approximate_repulsive_forces = options['approximate remote forces']
+ self.repulsive_force_order = options['electric force order']
+
+ self.coarsen = options['coarsen']
+ self.downsize_ratio = options['downsize ratio']
+ self.minimum_graph_size = options['minimum coarsening size']
+
+ -- Adjust types
+ self.downsize_ratio = math.max(0, math.min(1, self.downsize_ratio))
+ self.graph_size = #self.graph.nodes
+ self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1))
+
+ -- validate input parameters
+ assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0')
+ assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1')
+ assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0')
+ assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0')
+ assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0')
+ assert(self.spring_constant >= 0, 'the spring constant (value: ' .. self.spring_constant .. ') needs to be greater or equal to 0')
+ assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1')
+ assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2')
+
+ -- initialize node weights
+ for _,node in ipairs(self.graph.nodes) do
+ if node:getOption('electric charge') ~= nil then
+ node.weight = node:getOption('electric charge')
+ else
+ node.weight = 1
+ end
+
+ -- a node is charged if its weight derives from the default setting
+ -- of 1 (where it has no influence on the forces)
+ node.charged = node.weight ~= 1
+ end
+
+ -- initialize edge weights
+ for _,edge in ipairs(self.graph.edges) do
+ edge.weight = 1
+ end
+
+
+ -- initialize the coarse graph data structure. note that the algorithm
+ -- is the same regardless whether coarsening is used, except that the
+ -- number of coarsening steps without coarsening is 0
+ local coarse_graph = CoarseGraph.new(self.graph)
+
+ -- check if the multilevel approach should be used
+ if self.coarsen then
+ -- coarsen the graph repeatedly until only minimum_graph_size nodes
+ -- are left or until the size of the coarse graph was not reduced by
+ -- at least the downsize ratio configured by the user
+ while coarse_graph:getSize() > self.minimum_graph_size
+ and coarse_graph:getRatio() < (1 - self.downsize_ratio)
+ do
+ coarse_graph:coarsen()
+ end
+ end
+
+ -- compute the natural spring length for the coarsest graph in a way
+ -- that will result in the desired natural spring length in the
+ -- original graph
+ local spring_length = self.natural_spring_length / math.pow(math.sqrt(4/7), coarse_graph:getLevel())
+
+ if self.coarsen then
+ -- generate a random initial layout for the coarsest graph
+ self:computeInitialLayout(coarse_graph.graph, spring_length)
+
+ -- undo coarsening step by step, applying the force-based sub-algorithm
+ -- to every intermediate coarse graph as well as the original graph
+ while coarse_graph:getLevel() > 0 do
+ -- interpolate the previous coarse graph
+ coarse_graph:interpolate()
+
+ -- update the natural spring length so that, for the original graph,
+ -- it equals the natural spring dimension configured by the user
+ spring_length = spring_length * math.sqrt(4/7)
+
+ -- apply the force-based algorithm to improve the layout
+ self:computeForceLayout(coarse_graph.graph, spring_length)
+ end
+ else
+ -- generate a random initial layout for the coarsest graph
+ self:computeInitialLayout(coarse_graph.graph, spring_length)
+
+ -- apply the force-based algorithm to improve the layout
+ self:computeForceLayout(coarse_graph.graph, spring_length)
+ end
+end
+
+
+
+function SpringElectricalWalshaw2000:computeInitialLayout(graph, spring_length)
+ -- TODO how can supernodes and fixed nodes go hand in hand?
+ -- maybe fix the supernode if at least one of its subnodes is
+ -- fixated?
+
+ -- fixate all nodes that have a 'desired at' option. this will set the
+ -- node.fixed member to true and also set node.pos.x and node.pos.y
+ self:fixateNodes(graph)
+
+ if #graph.nodes == 2 then
+ if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then
+ local fixed_index = graph.nodes[2].fixed and 2 or 1
+ local loose_index = graph.nodes[2].fixed and 1 or 2
+
+ if not graph.nodes[1].fixed and not graph.nodes[2].fixed then
+ -- both nodes can be moved, so we assume node 1 is fixed at (0,0)
+ graph.nodes[1].pos.x = 0
+ graph.nodes[1].pos.y = 0
+ end
+
+ -- position the loose node relative to the fixed node, with
+ -- the displacement (random direction) matching the spring length
+ local direction = Vector.new{x = lib.random(1, 2), y = lib.random(1, 2)}
+ local distance = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2
+ local displacement = direction:normalized():timesScalar(distance)
+
+ graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement)
+ else
+ -- both nodes are fixed, initial layout may be far from optimal
+ end
+ else
+ -- function to filter out fixed nodes
+ local function nodeNotFixed(node) return not node.fixed end
+
+ -- use the random positioning technique
+ local function positioning_func(n)
+ local radius = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2
+ return lib.random(-radius, radius)
+ end
+
+ -- compute initial layout based on the random positioning technique
+ for _,node in ipairs(graph.nodes) do
+ if not node.fixed then
+ node.pos.x = positioning_func(1)
+ node.pos.y = positioning_func(2)
+ end
+ end
+ end
+end
+
+
+
+function SpringElectricalWalshaw2000:computeForceLayout(graph, spring_length)
+ -- global (=repulsive) force function
+ local function accurate_repulsive_force(distance, weight)
+ return - self.spring_constant * weight * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order)
+ end
+
+ -- global (=repulsive, approximated) force function
+ local function approximated_repulsive_force(distance, mass)
+ return - mass * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order)
+ end
+
+ -- local (spring) force function
+ local function attractive_force(distance, d, weight, charged, repulsive_force)
+ -- for charged nodes, never subtract the repulsive force; we want ALL other
+ -- nodes to be attracted more / repulsed less (not just non-adjacent ones),
+ -- depending on the charge of course
+ if charged then
+ return (distance - spring_length) / d - accurate_repulsive_force(distance, weight)
+ else
+ return (distance - spring_length) / d - (repulsive_force or 0)
+ end
+ end
+
+ -- define the Barnes-Hut opening criterion
+ function barnes_hut_criterion(cell, particle)
+ local distance = particle.pos:minus(cell.center_of_mass):norm()
+ return cell.width / distance <= 1.2
+ end
+
+ -- fixate all nodes that have a 'desired at' option. this will set the
+ -- node.fixed member to true and also set node.pos.x and node.pos.y
+ self:fixateNodes(graph)
+
+ -- adjust the initial step length automatically if desired by the user
+ local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length
+
+ -- convergence criteria
+ local converged = false
+ local i = 0
+
+ while not converged and i < self.iterations do
+
+ -- assume that we are converging
+ converged = true
+ i = i + 1
+
+ -- build the quadtree for approximating repulsive forces, if desired
+ local quadtree = nil
+ if self.approximate_repulsive_forces then
+ quadtree = self:buildQuadtree(graph)
+ end
+
+ local function nodeNotFixed(node) return not node.fixed end
+
+ -- iterate over all nodes
+ for _,v in ipairs(graph.nodes) do
+ if not v.fixed then
+ -- vector for the displacement of v
+ local d = Vector.new(2)
+
+ -- repulsive force induced by other nodes
+ local repulsive_forces = {}
+
+ -- compute repulsive forces
+ if self.approximate_repulsive_forces then
+ -- determine the cells that have an repulsive influence on v
+ local cells = quadtree:findInteractionCells(v, barnes_hut_criterion)
+
+ -- compute the repulsive force between these cells and v
+ for _,cell in ipairs(cells) do
+ -- check if the cell is a leaf
+ if #cell.subcells == 0 then
+ -- compute the forces between the node and all particles in the cell
+ for _,particle in ipairs(cell.particles) do
+ -- build a table that contains the particle plus all its subparticles
+ -- (particles at the same position)
+ local real_particles = lib.copy(particle.subparticles)
+ table.insert(real_particles, particle)
+
+ for _,real_particle in ipairs(real_particles) do
+ local delta = real_particle.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the node and the cell's
+ -- center of mass are located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = approximated_repulsive_force(delta:norm(), real_particle.mass)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- remember the repulsive force for the particle so that we can
+ -- subtract it later when computing the attractive forces with
+ -- adjacent nodes
+ repulsive_forces[real_particle.node] = repulsive_force
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ else
+ -- compute the distance between the node and the cell's center of mass
+ local delta = cell.center_of_mass:minus(v.pos)
+
+ -- enforce a small virtual distance if the node and the cell's
+ -- center of mass are located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = approximated_repulsive_force(delta:norm(), cell.mass)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- TODO for each neighbor of v, check if it is in this cell.
+ -- if this is the case, compute the quadtree force for the mass
+ -- 'node.weight / cell.mass' and remember this as the repulsive
+ -- force of the neighbor; (it is not necessarily at
+ -- the center of mass of the cell, so the result is only an
+ -- approximation of the real repulsive force generated by the
+ -- neighbor)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ else
+ for _,u in ipairs(graph.nodes) do
+ if u.name ~= v.name then
+ -- compute the distance between u and v
+ local delta = u.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the nodes are
+ -- located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the repulsive force vector
+ local repulsive_force = accurate_repulsive_force(delta:norm(), u.weight)
+ local force = delta:normalized():timesScalar(repulsive_force)
+
+ -- remember the repulsive force so we can later subtract them
+ -- when computing the attractive forces
+ repulsive_forces[u] = repulsive_force
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+ end
+
+ -- compute attractive forces between v and its neighbors
+ for _,edge in ipairs(v.edges) do
+ local u = edge:getNeighbour(v)
+
+ -- compute the distance between u and v
+ local delta = u.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the nodes are
+ -- located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ -- compute the spring force between them
+ local attr_force = attractive_force(delta:norm(), #v.edges, u.weight, u.charged, repulsive_forces[u])
+ local force = delta:normalized():timesScalar(attr_force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+
+ -- remember the previous position of v
+ old_position = v.pos:copy()
+
+ if d:norm() > 0 then
+ -- reposition v according to the force vector and the current temperature
+ v.pos = v.pos:plus(d:normalized():timesScalar(math.min(step_length, d:norm())))
+ end
+
+ -- we need to improve the system energy as long as any of
+ -- the node movements is large enough to assume we're far
+ -- away from the minimum system energy
+ if v.pos:minus(old_position):norm() > spring_length * self.convergence_tolerance then
+ converged = false
+ end
+ end
+ end
+
+ -- update the step length using the conservative cooling scheme
+ step_length = self.cooling_factor * step_length
+ end
+end
+
+
+
+-- Fixes nodes at their specified positions.
+--
+function SpringElectricalWalshaw2000:fixateNodes(graph)
+ local number_of_fixed_nodes = 0
+
+ for _,node in ipairs(graph.nodes) do
+ -- read the 'desired at' option of the node
+ local coordinate = node:getOption('desired at')
+
+ if coordinate then
+ -- parse the coordinate
+ node.pos.x = coordinate.x
+ node.pos.y = coordinate.y
+
+ -- mark the node as fixed
+ node.fixed = true
+
+ number_of_fixed_nodes = number_of_fixed_nodes + 1
+ end
+ end
+ if number_of_fixed_nodes > 1 then
+ self.growth_direction = "fixed" -- do not grow, orientation is now fixed
+ end
+end
+
+
+
+function SpringElectricalWalshaw2000:buildQuadtree(graph)
+ -- compute the minimum x and y coordinates of all nodes
+ local min_pos = graph.nodes[1].pos
+ for _,node in ipairs(graph.nodes) do
+ min_pos = Vector.new(2, function (n) return math.min(min_pos[n], node.pos[n]) end)
+ end
+
+ -- compute maximum x and y coordinates of all nodes
+ local max_pos = graph.nodes[1].pos
+ for _,node in ipairs(graph.nodes) do
+ max_pos = Vector.new(2, function (n) return math.max(max_pos[n], node.pos[n]) end)
+ end
+
+ -- make sure the maximum position is at least a tiny bit
+ -- larger than the minimum position
+ if min_pos:equals(max_pos) then
+ max_pos = max_pos:plus(Vector.new(2, function (n)
+ return 0.1 + lib.random() * 0.1
+ end))
+ end
+
+ -- make sure to make the quadtree area slightly larger than required
+ -- in theory; for some reason Lua will otherwise think that nodes with
+ -- min/max x/y coordinates are outside the box... weird? yes.
+ min_pos = min_pos:minusScalar(1)
+ max_pos = max_pos:plusScalar(1)
+
+ -- create the quadtree
+ quadtree = QuadTree.new(min_pos.x, min_pos.y,
+ max_pos.x - min_pos.x,
+ max_pos.y - min_pos.y)
+
+ -- insert nodes into the quadtree
+ for _,node in ipairs(graph.nodes) do
+ local particle = QuadTree.Particle.new(node.pos, node.weight)
+ particle.node = node
+ quadtree:insert(particle)
+ end
+
+ return quadtree
+end
+
+
+
+-- done
+
+return SpringElectricalWalshaw2000
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua
new file mode 100644
index 0000000000..86b65abc83
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua
@@ -0,0 +1,386 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+local SpringHu2006 = {}
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+
+---
+
+declare {
+ key = "spring Hu 2006 layout",
+ algorithm = SpringHu2006,
+
+ preconditions = {
+ connected = true,
+ loop_free = true,
+ simple = true,
+ },
+
+ old_graph_model = true,
+
+ summary = [["
+ Implementation of a spring graph drawing algorithm based on
+ a paper by Hu.
+ "]],
+ documentation = [["
+ \begin{itemize}
+ \item
+ Y. Hu.
+ \newblock Efficient, high-quality force-directed graph drawing.
+ \newblock \emph{The Mathematica Journal}, 2006.
+ \end{itemize}
+
+ There are some modifications compared to the original algorithm,
+ see the Diploma thesis of Pohlmann for details.
+ "]]
+}
+
+
+-- Imports
+
+local PathLengths = require "pgf.gd.lib.PathLengths"
+local Vector = require "pgf.gd.deprecated.Vector"
+
+local CoarseGraph = require "pgf.gd.force.CoarseGraph"
+
+local lib = require("pgf.gd.lib")
+
+
+
+
+function SpringHu2006:run()
+
+ -- Setup some parameters
+ local options = self.digraph.options
+
+ self.iterations = options['iterations']
+ self.cooling_factor = options['cooling factor']
+ self.initial_step_length = options['initial step length']
+ self.convergence_tolerance = options['convergence tolerance']
+
+ self.natural_spring_length = options['node distance']
+
+ self.coarsen = options['coarsen']
+ self.downsize_ratio = options['downsize ratio']
+ self.minimum_graph_size = options['minimum coarsening size']
+
+
+ -- Setup
+
+ self.downsize_ratio = math.max(0, math.min(1, tonumber(self.downsize_ratio)))
+
+ self.graph_size = #self.graph.nodes
+ self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1))
+
+ -- validate input parameters
+ assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0')
+ assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1')
+ assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0')
+ assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0')
+ assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0')
+ assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1')
+ assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2')
+
+ -- initialize node weights
+ for _,node in ipairs(self.graph.nodes) do
+ node.weight = 1
+ end
+
+ -- initialize edge weights
+ for _,edge in ipairs(self.graph.edges) do
+ edge.weight = 1
+ end
+
+
+ -- initialize the coarse graph data structure. note that the algorithm
+ -- is the same regardless whether coarsening is used, except that the
+ -- number of coarsening steps without coarsening is 0
+ local coarse_graph = CoarseGraph.new(self.graph)
+
+ -- check if the multilevel approach should be used
+ if self.coarsen then
+ -- coarsen the graph repeatedly until only minimum_graph_size nodes
+ -- are left or until the size of the coarse graph was not reduced by
+ -- at least the downsize ratio configured by the user
+ while coarse_graph:getSize() > self.minimum_graph_size
+ and coarse_graph:getRatio() <= (1 - self.downsize_ratio)
+ do
+ coarse_graph:coarsen()
+ end
+ end
+
+ if self.coarsen then
+ -- use the natural spring length as the initial natural spring length
+ local spring_length = self.natural_spring_length
+
+ -- compute a random initial layout for the coarsest graph
+ self:computeInitialLayout(coarse_graph.graph, spring_length)
+
+ -- set the spring length to the average edge length of the initial layout
+ spring_length = 0
+ for _,edge in ipairs(coarse_graph.graph.edges) do
+ spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm()
+ end
+ spring_length = spring_length / #coarse_graph.graph.edges
+
+ -- additionally improve the layout with the force-based algorithm
+ -- if there are more than two nodes in the coarsest graph
+ if coarse_graph:getSize() > 2 then
+ self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.adaptive_step_update)
+ end
+
+ -- undo coarsening step by step, applying the force-based sub-algorithm
+ -- to every intermediate coarse graph as well as the original graph
+ while coarse_graph:getLevel() > 0 do
+ -- compute the diameter of the parent coarse graph
+ local parent_diameter = PathLengths.pseudoDiameter(coarse_graph.graph)
+
+ -- interpolate the previous coarse graph from its parent
+ coarse_graph:interpolate()
+
+ -- compute the diameter of the current coarse graph
+ local current_diameter = PathLengths.pseudoDiameter(coarse_graph.graph)
+
+ -- scale node positions by the quotient of the pseudo diameters
+ for _,node in ipairs(coarse_graph.graph) do
+ node.pos:update(function (n, value)
+ return value * (current_diameter / parent_diameter)
+ end)
+ end
+
+ -- compute forces in the graph
+ self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.conservative_step_update)
+ end
+ else
+ -- compute a random initial layout for the coarsest graph
+ self:computeInitialLayout(coarse_graph.graph, self.natural_spring_length)
+
+ -- set the spring length to the average edge length of the initial layout
+ spring_length = 0
+ for _,edge in ipairs(coarse_graph.graph.edges) do
+ spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm()
+ end
+ spring_length = spring_length / #coarse_graph.graph.edges
+
+ -- improve the layout with the force-based algorithm
+ self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.adaptive_step_update)
+ end
+
+ local avg_spring_length = 0
+ for _,edge in ipairs(self.graph.edges) do
+ avg_spring_length = avg_spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm()
+ end
+ avg_spring_length = avg_spring_length / #self.graph.edges
+end
+
+
+
+function SpringHu2006:computeInitialLayout(graph, spring_length)
+ -- TODO how can supernodes and fixed nodes go hand in hand?
+ -- maybe fix the supernode if at least one of its subnodes is
+ -- fixated?
+
+ -- fixate all nodes that have a 'desired at' option. this will set the
+ -- node.fixed member to true and also set node.pos.x and node.pos.y
+ self:fixateNodes(graph)
+
+ if #graph.nodes == 2 then
+ if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then
+ local fixed_index = graph.nodes[2].fixed and 2 or 1
+ local loose_index = graph.nodes[2].fixed and 1 or 2
+
+ if not graph.nodes[1].fixed and not graph.nodes[2].fixed then
+ -- both nodes can be moved, so we assume node 1 is fixed at (0,0)
+ graph.nodes[1].pos.x = 0
+ graph.nodes[1].pos.y = 0
+ end
+
+ -- position the loose node relative to the fixed node, with
+ -- the displacement (random direction) matching the spring length
+ local direction = Vector.new{x = lib.random(1, spring_length), y = lib.random(1, spring_length)}
+ local distance = 1.8 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2
+ local displacement = direction:normalized():timesScalar(distance)
+
+ graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement)
+ else
+ -- both nodes are fixed, initial layout may be far from optimal
+ end
+ else
+ -- use a random positioning technique
+ local function positioning_func(n)
+ local radius = 2 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2
+ return lib.random(-radius, radius)
+ end
+
+ -- compute initial layout based on the random positioning technique
+ for _,node in ipairs(graph.nodes) do
+ if not node.fixed then
+ node.pos.x = positioning_func(1)
+ node.pos.y = positioning_func(2)
+ end
+ end
+ end
+end
+
+
+
+function SpringHu2006:computeForceLayout(graph, spring_length, step_update_func)
+ -- global (=repulsive) force function
+ function repulsive_force(distance, graph_distance, weight)
+ --return (1/4) * (1/math.pow(graph_distance, 2)) * (distance - (spring_length * graph_distance))
+ return (distance - (spring_length * graph_distance))
+ end
+
+ -- fixate all nodes that have a 'desired at' option. this will set the
+ -- node.fixed member to true and also set node.pos.x and node.pos.y
+ self:fixateNodes(graph)
+
+ -- adjust the initial step length automatically if desired by the user
+ local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length
+
+ -- convergence criteria etc.
+ local converged = false
+ local energy = math.huge
+ local iteration = 0
+ local progress = 0
+
+ -- compute graph distance between all pairs of nodes
+ local distances = PathLengths.floydWarshall(graph)
+
+ while not converged and iteration < self.iterations do
+ -- remember old node positions
+ local old_positions = lib.map(graph.nodes, function (node) return node.pos:copy(), node end)
+
+ -- remember the old system energy and reset it for the current iteration
+ local old_energy = energy
+ energy = 0
+
+ for _,v in ipairs(graph.nodes) do
+ if not v.fixed then
+ -- vector for the displacement of v
+ local d = Vector.new(2)
+
+ for _,u in ipairs(graph.nodes) do
+ if v ~= u then
+ -- compute the distance between u and v
+ local delta = u.pos:minus(v.pos)
+
+ -- enforce a small virtual distance if the nodes are
+ -- located at (almost) the same position
+ if delta:norm() < 0.1 then
+ delta:update(function (n, value) return 0.1 + lib.random() * 0.1 end)
+ end
+
+ local graph_distance = (distances[u] and distances[u][v]) and distances[u][v] or #graph.nodes + 1
+
+ -- compute the repulsive force vector
+ local force = repulsive_force(delta:norm(), graph_distance, v.weight)
+ local force = delta:normalized():timesScalar(force)
+
+ -- move the node v accordingly
+ d = d:plus(force)
+ end
+ end
+
+ -- really move the node now
+ -- TODO note how all nodes are moved by the same amount (step_length)
+ -- while Walshaw multiplies the normalized force with min(step_length,
+ -- d:norm()). could that improve this algorithm even further?
+ v.pos = v.pos:plus(d:normalized():timesScalar(step_length))
+
+ -- update the energy function
+ energy = energy + math.pow(d:norm(), 2)
+ end
+ end
+
+ -- update the step length and progress counter
+ step_length, progress = step_update_func(step_length, self.cooling_factor, energy, old_energy, progress)
+
+ -- compute the maximum node movement in this iteration
+ local max_movement = 0
+ for _,x in ipairs(graph.nodes) do
+ local delta = x.pos:minus(old_positions[x])
+ max_movement = math.max(delta:norm(), max_movement)
+ end
+
+ -- the algorithm will converge if the maximum movement is below a
+ -- threshold depending on the spring length and the convergence
+ -- tolerance
+ if max_movement < spring_length * self.convergence_tolerance then
+ converged = true
+ end
+
+ -- increment the iteration counter
+ iteration = iteration + 1
+ end
+end
+
+
+
+-- Fixes nodes at their specified positions.
+--
+function SpringHu2006:fixateNodes(graph)
+ local number_of_fixed_nodes = 0
+
+ for _,node in ipairs(graph.nodes) do
+ -- read the 'desired at' option of the node
+ local coordinate = node:getOption('desired at')
+
+ if coordinate then
+ -- apply the coordinate
+ node.pos.x = coordinate.x
+ node.pos.y = coordinate.y
+
+ -- mark the node as fixed
+ node.fixed = true
+
+ number_of_fixed_nodes = number_of_fixed_nodes + 1
+ end
+ end
+ if number_of_fixed_nodes > 1 then
+ self.growth_direction = "fixed" -- do not grow, orientation is now fixed
+ end
+end
+
+
+
+function SpringHu2006.conservative_step_update(step, cooling_factor)
+ return cooling_factor * step, nil
+end
+
+
+
+function SpringHu2006.adaptive_step_update(step, cooling_factor, energy, old_energy, progress)
+ if energy < old_energy then
+ progress = progress + 1
+ if progress >= 5 then
+ progress = 0
+ step = step / cooling_factor
+ end
+ else
+ progress = 0
+ step = cooling_factor * step
+ end
+ return step, progress
+end
+
+
+-- done
+
+return SpringHu2006
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua
new file mode 100644
index 0000000000..e3ac58d571
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua
@@ -0,0 +1,36 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Spring Layouts}
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "spring layout",
+ use = {
+ { key = "spring Hu 2006 layout" },
+ },
+
+ summary = [["
+ This key selects Hu's 2006 spring layout with appropriate settings
+ for some parameters.
+ "]]
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/FruchtermanReingold.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/FruchtermanReingold.lua
new file mode 100644
index 0000000000..2450bba2a2
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/FruchtermanReingold.lua
@@ -0,0 +1,124 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+local SpringElectricNoCoarsenClass = {}
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local ForceController = require "pgf.gd.force.jedi.base.ForceController"
+local ForceCanvasDistance = require "pgf.gd.force.jedi.forcetypes.ForceCanvasDistance"
+local ForceGraphDistance = require "pgf.gd.force.jedi.forcetypes.ForceGraphDistance"
+local Storage = require "pgf.gd.lib.Storage"
+
+---
+declare {
+ key = "spring electric no coarsen layout",
+ algorithm = SpringElectricNoCoarsenClass,
+ preconditions = { connected = true },
+ postconditions = {fixed = true},
+
+ summary = [[
+ This layout uses the algorithm proposed by Fruchterman and Reingold to draw graphs."
+ ]],
+
+ documentation = [[
+ The Fruchterman-Reingold algorithm is one if the oldest methods
+ for force-based graph drawing. It is described in:
+ %
+ \begin{itemize}
+ \item
+ Thomas M.~J.~ Fruchterman and Edward M.~ Reingold,
+ \newblock Graph Drawing by Force-directed Placement,
+ \newblock \emph{Software -- practice and experience,}
+ 21(1 1), 1129-1164, 1991.
+ \end{itemize}
+ %
+ Fruchterman and Reingold had to principles in graph drawing:
+ %
+ \begin{enumerate}
+ \item Vertices connected by an edge should be drawn close to another and
+ \item in general, vertices should not be drawn too close to each other.
+ \end{itemize}
+ %
+ The spring electric no coarsen layout uses spring forces as attractive
+ forces influencing vertex pairs connected by an edge and electric forces
+ as repulsive forces between all vertex pairs. The original algorithm
+ also contained a frame that stopped the vertices from drifting too far
+ apart, but this concept was not implemented. This algorithm will not be
+ affected by coarsening. This layout was implemented by using the Jedi
+ framework.
+ ]],
+
+ example =
+ [[
+ \tikz
+ \graph[spring electric no coarsen layout, speed = 0.35, node distance = 2.5cm, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, coarsen = true, maximum step = 1]{
+ a -- {b, c, d, e, f, g, h, i, j},
+ b -- {c, d, e, f, g, h, i, j},
+ c -- {d, e, f, g, h, i, j},
+ d -- {e, f, g, h, i, j},
+ e -- {f, g, h, i, j},
+ f -- {g, h, i, j},
+ g -- {h, i, j},
+ h -- {i, j},
+ i -- j
+ };
+ ]],
+
+ example =
+ [[
+ \graph[spring electric no coarsen layout, speed = 0.25, node distance = 0.25cm, horizontal = c to l, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, coarsen = false, maximum step = 1]{
+ a -> b -> c -> {d1 -> e -> f -> g -> h -> i -> {j1 -> e, j2 -> l}, d2 -> l -> m}, m -> a
+ };
+ ]]
+}
+
+
+
+
+-- Implementation starts here
+
+--define a local time function
+local time_fun_1
+function time_fun_1 (t_total, t_now)
+ if t_now/t_total <= 0.5 then
+ return 0.5
+ else
+ return 2
+ end
+end
+
+-- define storage table to add attributes if wanted
+local fw_attributes = Storage.newTableStorage()
+
+function SpringElectricNoCoarsenClass:run()
+ -- add options to storage table
+ fw_attributes.options = self.ugraph.options
+
+ --Generate new force class
+ local spring_electric_no_coarsen = ForceController.new(self.ugraph)
+
+ spring_electric_no_coarsen:addForce{
+ force_type = ForceCanvasDistance,
+ fun_u = function (data) return data.k*data.k/(data.d) end,
+ time_fun = time_fun_1,
+ epoch = {"after expand"}
+ }
+ spring_electric_no_coarsen:addForce{
+ force_type = ForceGraphDistance,
+ fun_u = function (data) return -data.d*data.d/(data.k) end,
+ n = 1,
+ epoch = {"after expand"}
+ }
+
+ -- run algorithm
+ spring_electric_no_coarsen:run()
+end
+
+return SpringElectricNoCoarsenClass \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/HuSpringElectricalFW.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/HuSpringElectricalFW.lua
new file mode 100644
index 0000000000..57cd1547b6
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/HuSpringElectricalFW.lua
@@ -0,0 +1,95 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+local HuClass = {}
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local ForceController = require "pgf.gd.force.jedi.base.ForceController"
+local ForceCanvasDistance = require "pgf.gd.force.jedi.forcetypes.ForceCanvasDistance"
+local ForceGraphDistance = require "pgf.gd.force.jedi.forcetypes.ForceGraphDistance"
+
+---
+declare {
+ key = "jedi spring electric layout",
+ algorithm = HuClass,
+ documentation_in = "documentation_hu_layout",
+ preconditions = { connected = true },
+ postconditions = {fixed = true},
+
+ summary = "This layout uses the spring electric algorithm proposed by Hu to draw graphs.",
+
+ documentation = [[
+ The spring electric algorithm by Hu uses two kinds of forces and coarsening.
+ It is described in:
+ %
+ \begin{itemize}
+ \item
+ Yifan Hu,
+ \newblock Efficient, high quality force-directed graph drawing,
+ \newblock \emph{The Mathematica Journal,}
+ 10(1), 37--71, 2006.
+ \end{itemize}
+ %
+ This algorithm uses spring forces as attractive forces between vertices
+ connected by an edge and electric forces as repulsive forces between
+ all vertex pairs. Hu introduces coarsening, a procedure which repeatedly
+ merges vertices in order to obtain a smaller version of the graph, to
+ overcome local minima. He also uses the Barnes-Hut algorithm to enhance
+ the runtime of his algorithms. This algorithm is not used in this
+ implementation. This layout was implemented by using the Jedi framework.
+ ]],
+
+ example =
+ [[
+ \tikz
+ \graph[spring electric fw layout, speed = 0.35, node distance = 5cm, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, maximum displacement per step = 10]{
+ a -- {b, c, d, e},
+ b -- {c, d, e},
+ c -- {d, e},
+ d --e
+ };
+ ]],
+
+ example =
+ [[
+ \tikz
+ \graph[spring electric fw layout, speed = 0.35, node distance = 1cm, horizontal = c to l, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, maximum displacement per step = 10]{
+ a -> b -> c -> {d1 -> e -> f -> g -> h -> i -> {j1 -> e, j2 -> l}, d2 -> l -> m}, m -> a
+ };
+ ]]
+}
+
+
+
+
+-- Implementation starts here:
+
+function HuClass:run()
+ -- Generate new force class
+ local hu = ForceController.new(self.ugraph)
+
+ -- add all required forces
+ hu:addForce{
+ force_type = ForceCanvasDistance,
+ fun_u = function (data) return (data.k*data.k)/data.d end,
+ epoch = {"during expand", "after expand"}
+ }
+ hu:addForce{
+ force_type = ForceGraphDistance,
+ fun_u = function (data) return -(data.d*data.d)/data.k end,
+ n = 1,
+ epoch = {"during expand", "after expand"}
+ }
+
+ -- run algorithm
+ hu:run()
+end
+
+return HuClass \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SimpleSpring.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SimpleSpring.lua
new file mode 100644
index 0000000000..4dbae2b1f4
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SimpleSpring.lua
@@ -0,0 +1,74 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+local SimpleSpringClass = {}
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local ForceController = require 'pgf.gd.force.jedi.base.ForceController'
+local ForceGraphDistance = require "pgf.gd.force.jedi.forcetypes.ForceGraphDistance"
+
+---
+declare {
+ key = "trivial spring layout",
+ algorithm = SimpleSpringClass,
+ documentation_in = "pgf.gd.doc.jedi.algorithms.SimpleSpringLayout",
+ preconditions = { connected = true },
+ postconditions = {fixed = true},
+
+ summary = "This layout uses only spring forces to draw graphs.",
+
+ documentation = [[
+ The simple spring algorithm only uses one force kind: A spring force
+ that serves as both attractive and repulsive force. The edges are modeled as
+ springs and act according to Hoke's law: They have an ideal length and will
+ expand if they are contracted below this length, pushing the adjacent
+ vertices away from each other, and contract if it is stretched, pulling the
+ adjacent vertices towards each other. This ideal length is given by the
+ parameter |node distance|. There is no force repelling vertices that are not
+ connected to each other, which can lead to vertices being placed at the same
+ point. It is not a very powerful layout and will probably fail with large
+ graphs, especially if they have few edges. It can however be used to
+ demonstrate the effect of spring forces. This layout was implemented by using
+ the Jedi framework.
+ ]],
+
+ example = [[
+ \tikz
+ \graph[simple spring layout, node distance = 3cm, speed = 2, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, coarsen = true, maximum step = 1]{
+ a -- {b, c, d, e},
+ b -- {c, d, e},
+ c -- {d, e},
+ d --e
+ };
+ ]]
+}
+
+
+
+
+-- Implementation starts here:
+
+function SimpleSpringClass:run()
+ --Generate new force class
+ simple_spring = ForceController.new(self.ugraph)
+
+ --add all required forces
+ simple_spring:addForce{
+ force_type = ForceGraphDistance,
+ fun_u = function (data) return data.k*(data.k-data.d) end,
+ n = 1,
+ epoch = {"after expand", "during expand"}
+ }
+
+ -- run algorithm
+ simple_spring:run()
+end
+
+return SimpleSpringClass \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityCloseness.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityCloseness.lua
new file mode 100644
index 0000000000..1c8a1bb8d9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityCloseness.lua
@@ -0,0 +1,129 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+local SocialClass = {}
+
+--Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local ForceController = require 'pgf.gd.force.jedi.base.ForceController'
+local ForceCanvasDistance = require "pgf.gd.force.jedi.forcetypes.ForceCanvasDistance"
+local ForceCanvasPosition = require "pgf.gd.force.jedi.forcetypes.ForceCanvasPosition"
+local ForceGraphDistance = require "pgf.gd.force.jedi.forcetypes.ForceGraphDistance"
+local PathLengthsFW = require "pgf.gd.force.jedi.base.PathLengthsFW"
+local Storage = require "pgf.gd.lib.Storage"
+
+---
+declare {
+ key = "social closeness layout",
+ algorithm = SocialClass,
+ postconditions = {fixed = true},
+
+ summary = [[
+ This layout uses the social gravity algorithm proposed by Bannister
+ with closeness mass to draw graphs.
+ ]],
+
+ documentation = [[
+ Bannister et all described a social gravity algorithm that can be
+ implemented with different kinds of gravity.
+ It is described in:
+ %
+ \begin{itemize}
+ \item Michael J.~ Bannister and David Eppstein and Michael T~. Goodrich
+ and Lowell Trott,
+ \newblock Force-Directed Graph Drawing Using Social Gravity and Scaling,
+ \newblock \emph{CoRR,}
+ abs/1209.0748, 2012.
+ \end{itemize}
+ %
+ This implementation uses the closeness mass to determine the gravity of each
+ vertex. There are three forces in this algorithm: A spring force as
+ attractive force between vertices connected by an edge, an electric force as
+ repulsive force between all vertex pairs, and a gravitational force pulling
+ all vertices closer to their midpoint. The gravitational force depends on
+ the social mass of a vertex, which can be determined in different ways. This
+ algorithm uses the closeness mass. The closeness of a vertex $u$ is the
+ reciprocal of the sum of the shortest path from $u$ to every other vertex
+ $v$. The gravitational force leads to more "important" vertices ending up
+ closer to the middle of the drawing, since the social mass of a vertex is
+ proportional to its importance. The social layouts work especially well on
+ unconnected graphs like forests. This layout was implemented by using the
+ Jedi framework.
+ ]],
+
+ example = [[
+ \tikz
+ \graph[social closeness layout, speed = 0.9, gravity = 0.2, node distance = 0.65cm, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, find equilibrium = true, maximum step = 5]{
+ a -- a1 -- a2 -- a,
+ b -- b1 -- b2 -- b,
+ c -- c1 -- c2 -- c,
+ d -- d1 -- d2 -- d,
+ e -- e1 -- e2 -- e,
+ f -- f1 -- f2 -- f,
+ g -- g1 -- g2 -- g,
+ h -- h1 -- h2 -- h,
+ i -- i1 -- i2 -- i,
+ j -- j1 -- j2 -- j,
+ a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- a
+ };
+ ]],
+
+ example = [[
+ \tikz
+ \graph[social closeness layout, speed = 0.35, node distance = 0.7cm, maximum step = 5, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, radius = 1cm, gravity = 2]{
+ a -- {a1 -- a2, a3},
+ b -- {b1, b2 -- b3 -- b4 --{b5, b6}},
+ c -- {c1--c2},
+ d -- {d1, d2, d3 -- {d4, d5}, d6 --{d7, d8}}
+ };
+ ]]
+}
+
+local fw_attributes = Storage.newTableStorage()
+
+function SocialClass:run()
+ local dist = PathLengthsFW:breadthFirstSearch(self.ugraph)
+ local tmp
+ for vertex, n in pairs(dist) do
+ tmp = fw_attributes[vertex]
+ local sum = 0
+ for i, w in pairs(n) do
+ sum = sum + w
+ end
+ sum = sum / # self.ugraph.vertices
+ tmp.mass = 1/sum
+ end
+
+ fw_attributes.options = self.ugraph.options
+
+ --Generate new force class
+ social_gravity = ForceController.new(self.ugraph, fw_attributes)
+
+ --add all required forces
+ social_gravity:addForce{
+ force_type = ForceCanvasDistance,
+ fun_u = function (data) return data.k/(data.d*data.d) end,
+ epoch = {"after expand", "during expand"}
+ }
+ social_gravity:addForce{
+ force_type = ForceCanvasPosition,
+ fun_u = function (data) return data.attributes[data.u].mass*data.attributes.options.gravity end,
+ epoch = {"after expand", "during expand"}
+ }
+ social_gravity:addForce{
+ force_type = ForceGraphDistance,
+ fun_u = function (data) return -data.d/(data.k*data.k) end,
+ n = 1,
+ epoch = {"after expand", "during expand"}
+ }
+
+ social_gravity:run()
+end
+
+return SocialClass
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityDegree.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityDegree.lua
new file mode 100644
index 0000000000..6408349107
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/algorithms/SocialGravityDegree.lua
@@ -0,0 +1,183 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local ForceController = require 'pgf.gd.force.jedi.base.ForceController'
+local ForceCanvasDistance = require "pgf.gd.force.jedi.forcetypes.ForceCanvasDistance"
+local ForceCanvasPosition = require "pgf.gd.force.jedi.forcetypes.ForceCanvasPosition"
+local ForceGraphDistance = require "pgf.gd.force.jedi.forcetypes.ForceGraphDistance"
+local Storage = require "pgf.gd.lib.Storage"
+
+local SocialClass = {}
+
+---
+declare {
+ key = "social degree layout",
+ algorithm = SocialClass,
+ postconditions = {fixed = true},
+
+ summary = [[
+ This layout uses the social gravity algorithm proposed by Bannister
+ with closeness mass to draw graphs.]],
+
+ documentation = [[
+ Bannister et all described a social gravity algorithm that can be
+ implemented with different kinds of gravity.
+ It is described in:
+ %
+ \begin{itemize}
+ \item
+ Michael J.~ Bannister and David Eppstein and Michael T~. Goodrich and
+ Lowell Trott,
+ \newblock Force-Directed Graph Drawing Using Social Gravity and Scaling,
+ \newblock \emph{CoRR,} abs/1209.0748, 2012.
+ \end{itemize}
+ %
+ This implementation uses the degree mass to determine the gravity of each
+ vertex. There are three forces in this algorithm: A spring force as
+ attractive force between vertices connected by an edge, an electric force as
+ repulsive force between all vertex pairs, and a gravitational force pulling
+ all vertices closer to their midpoint. The gravitational force depends on
+ the social mass of a vertex, which can be determined in different ways. This
+ algorithm uses the degree of each vertex as its mass. The gravitational
+ force leads to more "important" vertices ending up closer to the middle of
+ the drawing, since the social mass of a vertex is proportional to its
+ importance. The social layouts work especially well on unconnected graphs
+ like forests. This layout was implemented by using the Jedi framework.
+ ]],
+
+ example =
+ [[
+ \tikz
+ \graph[social degree layout, speed = 0.9, gravity = 0.2, node distance = 0.65cm, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, find equilibrium = true, maximum step = 5]{
+ a -- a1 -- a2 -- a,
+ b -- b1 -- b2 -- b,
+ c -- c1 -- c2 -- c,
+ d -- d1 -- d2 -- d,
+ e -- e1 -- e2 -- e,
+ f -- f1 -- f2 -- f,
+ g -- g1 -- g2 -- g,
+ h -- h1 -- h2 -- h,
+ i -- i1 -- i2 -- i,
+ j -- j1 -- j2 -- j,
+ a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- a
+ };
+ ]],
+
+ example =
+ [[
+ \tikz
+ \graph[social degree layout, speed = 0.35, node distance = 0.7cm, maximum step = 15, nodes={as=,circle, draw, inner sep=3pt,outer sep=0pt}, radius = 1cm, gravity = 0.2]{
+ a -- {a1 -- a2, a3},
+ b -- {b1, b2 -- b3 -- b4 --{b5, b6}},
+ c -- {c1--c2},
+ d -- {d1, d2, d3 -- {d4, d5}, d6 --{d7, d8}}
+ };
+ ]]
+}
+
+---
+declare {
+ key = "gravity",
+ type = "number",
+ initial = 0.2,
+
+ summary = "The gravity key describes the magnitude of the gravitational force.",
+
+ documentation = [[
+ This parameter currently only affects the \lstinline{social degree layout}
+ and the \lstinline{social closeness layout}. The gravity key determines the
+ strength used to pull the vertices to the center of the canvas.
+ ]],
+
+ example =
+ [[
+ \tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, maximum step = 10]{
+ a1[weight = 2] -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+ ]],
+
+ example = [[
+ \tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, gravity = 0.5, maximum step = 10]{
+ a1 -- {a2 [mass = 2], a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+ ]]
+}
+
+
+
+
+-- Implementation starts here:
+
+-- define time functions
+local time_fun_1, time_fun_2, time_fun_3
+
+function time_fun_1 (t_total, t_now)
+ if t_now > 3*t_total/4 then
+ return t_now/t_total
+ end
+ return 0
+end
+
+function time_fun_3 (t_total, t_now)
+ if t_now >= t_total/2 then
+ return 2
+ else
+ return 1
+ end
+end
+
+-- define table to store variables if needed
+local fw_attributes = Storage.newTableStorage()
+
+function SocialClass:run()
+ --initialize masses
+ local tmp
+ for _, vertex in ipairs(self.ugraph.vertices) do
+ tmp = fw_attributes[vertex]
+ tmp.social_mass = #self.ugraph:incoming(vertex)
+ end
+
+ -- add options to storage table
+ fw_attributes.options = self.ugraph.options
+
+ -- generate new force class
+ local social_gravity = ForceController.new(self.ugraph, fw_attributes)
+
+ -- add all required forces
+ social_gravity:addForce{
+ force_type = ForceCanvasDistance,
+ fun_u = function (data) return 4*data.k/(data.d*data.d) end,
+ time_fun = time_fun_2,
+ epoch = {"after expand", "during expand"}
+ }
+ social_gravity:addForce{
+ force_type = ForceCanvasPosition,
+ fun_u = function (data) return data.attributes[data.u].social_mass*data.attributes.options.gravity end,
+ time_fun = time_fun_1,
+ epoch = {"after expand", "during expand"}
+ }
+ social_gravity:addForce{
+ force_type = ForceGraphDistance,
+ fun_u = function (data) return -data.d/(data.k*data.k) end,
+ n = 1,
+ time_fun = time_fun_3,
+ epoch = {"after expand", "during expand"}
+ }
+
+ -- run algorithm
+ social_gravity:run()
+end
+
+return SocialClass \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/CoarseGraphFW.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/CoarseGraphFW.lua
new file mode 100644
index 0000000000..0487214654
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/CoarseGraphFW.lua
@@ -0,0 +1,264 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- A class for creating and handling "coarse" versions of a graph. Such versions contain
+-- less nodes and edges than the original graph while retaining the overall
+-- structure. This class offers functions to create coarse graphs and to expand them
+-- to regain their original size.
+
+-- Imports
+local Digraph = require "pgf.gd.model.Digraph"
+local Vertex = require "pgf.gd.model.Vertex"
+local Arc = require "pgf.gd.model.Arc"
+
+local lib = require "pgf.gd.lib"
+
+local CoarseGraph = Digraph.new()
+CoarseGraph.__index = CoarseGraph
+
+--- Creates a new coarse graph derived from an existing graph.
+--
+-- Generates a coarse graph for the input |Digraph|.
+--
+-- Coarsening describes the process of reducing the amount of vertices in a graph
+-- by merging vertices into pseudo-vertices. There are different strategies,
+-- to decide which vertices should be merged, like merging vertices that belong to edges in a
+-- maximal independent edge set or by creating pseudo-vertices based on a maximal
+-- independent node set. Those strategies are called
+-- schemes.
+--
+-- Coarsening is not performed automatically. The function |CoarseGraph:coarsen|
+-- can be used to further coarsen the graph, or the function |CoarseGraph:uncoarsen|
+-- can be used to restore the previous state.
+--
+-- Note, however, that the input \meta{graph} is always modified in-place, so
+-- if the original version of \meta{graph} is needed in parallel to its
+-- coarse representations, a deep copy of \meta{graph} needs to be passed over
+-- to |CoarseGraph.new|.
+--
+-- @param graph An existing graph that needs to be coarsened.
+-- @param fw_attributes The user defined attributes, possibly attached to vertices.
+
+function CoarseGraph.new(ugraph, fw_attributes)
+ local coarse_graph = {
+ ugraph = ugraph,
+ level = 0,
+ scheme = CoarseGraph.coarsen_independent_edges,
+ ratio = 0,
+ fw_attributes = fw_attributes,
+ collapsed_vertices = {}
+ }
+ setmetatable(coarse_graph, CoarseGraph)
+ return coarse_graph
+end
+
+-- locals for performance
+local find_maximal_matching, arc_function
+
+-- This function performs one coarsening step: It finds all independent vertex
+-- set according to |scheme|, coarsens them and adds the newly created
+-- vertices to the collapsed_vertices table, associating them with the current
+-- level.
+function CoarseGraph:coarsen()
+ -- update the level
+ self.level = self.level + 1
+
+ local vertices = self.ugraph.vertices
+ local old_graph_size = #vertices
+ local c = {}
+ local fw_attributes = self.fw_attributes
+ local ugraph = self.ugraph
+
+ if self.scheme == CoarseGraph.coarsen_independent_edges then
+ local matching = find_matching(ugraph)
+ local collapse_vertex
+
+ for _,arc in ipairs(matching) do
+ -- get the two nodes of the edge that we are about to collapse
+ local a_h = arc.head
+ local a_t = arc.tail
+ local collapse_vertices = {a_h, a_t}
+ collapse_vertex = Vertex.new {weight = 0, mass = 0}
+
+ ugraph:collapse(collapse_vertices,
+ collapse_vertex,
+ function (a,b)
+ a.weight = a.weight + b.weight
+ a.mass = a.mass + b.mass
+ if fw_attributes then
+ for key,value in pairs(fw_attributes[b]) do
+ if fw_attributes.functions[key] then
+ fw_attributes.functions[key](a,b)
+ elseif type(value) == "number" then
+ local tmp = fw_attributes[a]
+ if not tmp[key] then
+ tmp[key] = 0
+ end
+ tmp[key] = tmp[key] + value
+ end
+ end
+ end
+ end,
+ function (a,b)
+ if a.weight == nil then
+ a.weight = b.weight
+ else
+ a.weight = a.weight + b.weight
+ end
+ end)
+
+ local c_v_p = collapse_vertex.pos
+ local a_h_p = a_h.pos
+ local a_t_p = a_t.pos
+ c_v_p.x = (a_h_p.x + a_t_p.x)/2
+ c_v_p.y = (a_h_p.y + a_t_p.y)/2
+
+ c[#c+1] = collapse_vertex
+ ugraph:remove{a_h, a_t}
+ end
+
+ -- Enter all collapsed vertices into a table to uncoarsen one level at a time
+ self.collapsed_vertices[self.level] = c
+ else
+ assert(false, 'schemes other than CoarseGraph.coarsen_independent_edges are not implemented yet')
+ end
+ -- calculate the number of nodes ratio compared to the previous graph
+ self.ratio = #vertices / old_graph_size
+end
+
+-- This function expands all vertices associated with the current level, then
+-- updates the level.
+function CoarseGraph:uncoarsen()
+ local a = self.collapsed_vertices[self.level]
+ local ugraph = self.ugraph
+ local random = lib.random
+ local randomseed = lib.randomseed
+
+ for j=#a,1,-1 do
+ randomseed(42)
+ local to_expand = a[j]
+
+ ugraph:expand(to_expand, function(a,b)
+ b.pos.x = a.pos.x + random()*10
+ b.pos.y = a.pos.y + random()*10
+ end)
+ ugraph:remove{to_expand}
+ ugraph:sync()
+ end
+
+ self.level = self.level - 1
+end
+
+-- Getters
+function CoarseGraph:getSize()
+ return #self.ugraph.vertices
+end
+
+
+function CoarseGraph:getRatio()
+ return self.ratio
+end
+
+
+function CoarseGraph:getLevel()
+ return self.level
+end
+
+
+function CoarseGraph:getGraph()
+ return self.ugraph
+end
+
+-- Private helper function to determine whether the second vertex in the
+-- current arc has been matched already
+--
+-- @param arc The arc in question
+-- @param vertex One of the arc's endpoints, either head or tail
+-- @param matched_vertices The table holding all matched vertices
+--
+-- @return The arc if the other endpoint has not been matched yet
+function arc_function (arc, vertex, matched_vertices)
+ local x
+ if arc.head ~= vertex then
+ x = arc.head
+ else
+ x = arc.tail
+ end
+ if not matched_vertices[x] then
+ return arc
+ end
+end
+
+-- The function finding a maximum matching of independent arcs.
+--
+-- @param ugraph The current graph
+--
+-- @return A table of arcs which are in the matching
+function find_matching(ugraph)
+ local matching = {}
+ local matched_vertices = {}
+ local unmatched_vertices = {}
+ local vertices = ugraph.vertices
+
+ -- iterate over nodes in random order
+ for _,j in ipairs(lib.random_permutation(#vertices)) do
+ local vertex = vertices[j]
+ -- ignore nodes that have already been matched
+ if not matched_vertices[vertex] then
+ local arcs = {}
+ local all_arcs = {}
+ for _,v in pairs(ugraph:incoming(vertex)) do all_arcs[#all_arcs+1] = v end
+ for _,v in pairs(ugraph:outgoing(vertex)) do all_arcs[#all_arcs+1] = v end
+ -- mark the node as matched
+ matched_vertices[vertex] = true
+
+ for _, a in ipairs(all_arcs) do
+ arcs[#arcs +1] = arc_function(a, vertex, matched_vertices)
+ end
+
+ if #arcs > 0 then
+ -- sort edges by the weights of the adjacent vertices
+ table.sort(arcs, function (a, b)
+ local x, y
+ if a.head == vertex then
+ x = a.tail
+ else
+ x = a.head
+ end
+ if b.head == vertex then
+ y = b.tail
+ else
+ y = b.head
+ end
+ return x.weight < y.weight
+ end)
+
+ -- match the node against the neighbor with minimum weight
+ matched_vertices[arcs[1].head] = true
+ matched_vertices[arcs[1].tail] = true
+ table.insert(matching, arcs[1])
+ end
+ end
+ end
+
+ -- generate a list of nodes that were not matched at all
+ for _,j in ipairs(lib.random_permutation(#vertices)) do
+ local vertex = vertices[j]
+ if not matched_vertices[vertex] then
+ table.insert(unmatched_vertices, vertex)
+ end
+ end
+ return matching
+end
+
+
+-- done
+
+return CoarseGraph
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceController.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceController.lua
new file mode 100644
index 0000000000..ab30ada5b3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceController.lua
@@ -0,0 +1,489 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This class is the most basic class for the Jedi framework. It manages the
+-- forces, epochs, options and streamlines the graph drawing process.
+-- In detail, the force template will do the following:
+-- %
+-- \begin{itemize}
+-- \item Hold the table with all epochs currently defined, and provide
+-- a function to add new ones
+-- \item Hold the table associating forces with the epochs, and provide a
+-- function to add new ones
+-- \item Define all the non-algorithm-specific options provided by Jedi
+-- \item Assert user options to catch exceptions
+-- \item Save user options and library functions to local variables to enhance
+-- runtime.
+-- \item Add any forces that are indicated by set options
+-- \item Find and call the initial positioning algorithm requested
+-- \item Determine if coarsening is enabled, and manage coarsening process if so
+-- \item Call the preprocessing function of each force to obtain a vertex list the
+-- force will be applied to
+-- \item Calculate the forces affecting each vertex.
+-- \item Move the vertices, check for equilibria/used up iterations, update
+-- virtual time
+-- \end{itemize}
+
+local ForceController = {}
+ForceController.__index = ForceController
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local Coordinate = require "pgf.gd.model.Coordinate"
+local CoarseGraph = require 'pgf.gd.force.jedi.base.CoarseGraphFW'
+local PriorityQueue = require "pgf.gd.lib.PriorityQueue"
+local ForcePullToPoint = require "pgf.gd.force.jedi.forcetypes.ForcePullToPoint"
+local ForcePullToGrid = require "pgf.gd.force.jedi.forcetypes.ForcePullToGrid"
+
+local epochs = {
+ [1] = "preprocessing",
+ [2] = "initial layout",
+ [3] = "start coarsening process",
+ [4] = "before coarsen",
+ [5] = "start coarsen",
+ [6] = "during coarsen",
+ [7] = "end coarsen",
+ [8] = "before expand",
+ [9] = "start expand",
+ [10] = "during expand",
+ [11] = "end expand",
+ [12] = "end coarsening process",
+ [13] = "after expand",
+ [14] = "postprocessing"
+}
+
+-- Automatic parameter generation for epoch-variables
+for _,e in ipairs(epochs) do
+ ---
+ declare {
+ key = "iterations " .. e,
+ type = "number"
+ }
+
+ ---
+ declare {
+ key = "maximum displacement per step " .. e,
+ type = "number"
+ }
+
+ ---
+ declare {
+ key = "global speed factor " .. e,
+ type = "length"
+ }
+
+ ---
+ declare {
+ key = "maximum time " .. e,
+ type = "number"
+ }
+
+ ---
+ declare {
+ key = "find equilibrium ".. e,
+ type = "boolean"
+ }
+
+ ---
+ declare {
+ key = "equilibrium threshold ".. e,
+ type = "number"
+ }
+end
+
+-- Implementation starts here
+
+--- Function allowing user to add an at the specified position
+--
+-- @params epoch A string that names the epoch
+-- @params position The position in the epoch array at which the epoch should be inserted
+
+function ForceController:addEpoch(epoch, position)
+ table.insert(epochs, position, epoch)
+end
+
+--- Function allowing the user to find an epoch's position in the epoch table
+--
+-- @params epoch The epoch who's position we are trying to find
+--
+-- @return An integer value matching the epch's index, or $-1$ if epoch was not found
+
+function ForceController:findEpoch(epoch)
+ for j, e in ipairs(epochs) do
+ if e == epoch then
+ return j
+ end
+ end
+ return -1
+end
+
+
+-- locals for performance
+local net_forces = {}
+local sqrt = math.sqrt
+local abs = math.abs
+local sum_up, options, move_vertices, get_net_force, preprocessing, epoch_forces
+
+--- Creating a new force algorithm
+-- @params ugraph The ugraph object the graph drawing algorithm will run on
+-- @params fw_attributes The storage object holding the additional attributes defined by
+-- the engineer
+--
+-- @returns A new instance of force template
+function ForceController.new(ugraph, fw_attributes)
+ return setmetatable(
+ {epoch_forces = {},
+ ugraph = ugraph,
+ fw_attributes = fw_attributes,
+ pull_to_point = false,
+ }, ForceController)
+end
+
+--- Running the force algorithm
+
+function ForceController:run()
+ -- locals for performance
+ local ugraph = self.ugraph
+ local coarse_graph = CoarseGraph.new(ugraph, self.fw_attributes)
+ local vertices_initalized = false
+ options = ugraph.options
+ epoch_forces = self.epoch_forces
+ local minimum_graph_size = options["minimum coarsening size"]
+ local vertices = ugraph.vertices
+ local arcs = ugraph.arcs
+ local downsize_ratio = options["downsize ratio"]
+ local natural_spring_length = options["node distance"]
+ local snap_to_grid = options["snap to grid"]
+ local coarsen = options["coarsen"]
+
+ -- Assert user input
+ assert(minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. minimum_graph_size .. ') needs to be greater than or equal to 2')
+ assert(downsize_ratio >= 0 and downsize_ratio <=1, 'the downsize ratio of the coarse graphs (value: ' .. downsize_ratio .. ') needs to be greater than or equal to 0 and smaller than or equal to 1')
+ assert(natural_spring_length >= 0, 'the node distance (value: ' .. natural_spring_length .. ') needs to be greater than or equal to 0')
+
+ -- initialize vertex and arc weights
+ for _,vertex in ipairs(vertices) do
+ vertex.weight = vertex.options["coarsening weight"]
+ vertex.mass = vertex.options.mass
+ end
+
+ for _,arc in ipairs(arcs) do
+ arc.weight = 1
+ end
+
+ -- Initialize epoch_forces table entries as empty tables
+ for _, e in ipairs(epochs) do
+ if not self.epoch_forces[e] then
+ self.epoch_forces[e] = {}
+ end
+ end
+
+ -- Find initial positioning algorithm
+ local initial_positioning_class = options.algorithm_phases['initial positioning force framework'] -- initial_types[self.initial_layout]
+
+ -- If snap to grid option is set and no force was added yet, add an extra
+ -- force to post-processing
+ if snap_to_grid then
+ self:addForce{
+ force_type = ForcePullToGrid,
+ cap = 1,
+ time_fun = function() return 40 end,
+ epoch = {"postprocessing"}
+ }
+ options["iterations postprocessing"] = options["iterations postprocessing"] or 200
+ options["maximum time postprocessing"] = options["maximum time postprocessing"] or 200
+ options["find equilibrium postprocessing"] = options["find equilibrium postprocessing"] or true
+ options["equilibrium threshold postprocessing"] = options["equilibrium threshold postprocessing"] or 1
+ options["maximum displacement per step postprocessing"] = options["maximum displacement per step postprocessing"] or 1
+ options["global speed factor postprocessing"] = options["global speed factor postprocessing"] or 1
+ end
+
+ -- Find marker epochs
+ local start_coarsening = self:findEpoch("start coarsening process")
+ local end_coarsening = self:findEpoch("end coarsening process")
+ local start_coarsen = self:findEpoch("start coarsen")
+ local end_coarsen = self:findEpoch("end coarsen")
+ local start_expand = self:findEpoch("start expand")
+ local end_expand = self:findEpoch("end expand")
+
+
+ -- iterate over epoch table
+ local i = 1
+ while i <= #epochs do
+ local e = epochs[i]
+
+ local iterations = options["iterations "..e] or options["iterations"]
+ -- assert input
+ assert(iterations >= 0, 'iterations (value: ' .. iterations .. ') needs to be greater than 0')
+
+ -- Check for desired vertices and collect them in a table if any are found
+ local desired = false
+ local desired_vertices = {}
+ -- initialize node weights
+ for _,vertex in ipairs(vertices) do
+ if vertex.options then
+ if vertex.options["desired at"] then
+ desired = true
+ desired_vertices[vertex] = vertex.options["desired at"]
+ end
+ end
+ end
+
+ -- Add pull to point force if desired vertices were found and engineer did not add
+ -- this force
+ if desired and not self.pull_to_point then
+ self:addForce{
+ force_type = ForcePullToPoint,
+ time_fun = function(t_now, t_max) return 5 end
+ }
+ end
+
+ -- initialize the coarse graph data structure.
+ if coarsen then
+ -- vertices = coarse_graph.ugraph.vertices
+ -- arcs = coarse_graph.ugraph.arcs
+ if i >= start_coarsening and i < end_coarsening then
+ -- coarsen the graph repeatedly until only minimum_graph_size nodes
+ -- are left or until the size of the coarse graph was not reduced by
+ -- at least the downsize ratio configured by the user
+ if i >= start_coarsen and i < start_expand then
+ if coarse_graph:getSize() > minimum_graph_size and coarse_graph:getRatio() <= (1 - downsize_ratio) then
+ if i == start_coarsen then
+ coarse_graph:coarsen()
+ elseif i < end_coarsen then
+ preprocessing(coarse_graph.ugraph.vertices, coarse_graph.ugraph.arcs, e, coarse_graph.ugraph)
+ move_vertices(coarse_graph.ugraph.vertices, e)
+ else
+ i = start_coarsen - 1
+ end
+ end
+ end
+
+ -- between coarsening and expanding
+ if (i > end_coarsen) and (i < start_expand) then
+ -- use the natural spring length as the initial natural spring length
+ local spring_length = natural_spring_length
+
+ if not vertices_initalized then
+ initial_positioning_class.new { vertices = coarse_graph.ugraph.vertices,
+ options = options,
+ desired_vertices = desired_vertices
+ }:run()
+ vertices_initalized = true
+ end
+
+ preprocessing(coarse_graph.ugraph.vertices, coarse_graph.ugraph.arcs, e, coarse_graph.ugraph)
+
+ -- set the spring length to the average arc length of the initial layout
+ local spring_length = 0
+ for _,arc in ipairs(arcs) do
+ local x = abs(arc.head.pos.x - arc.tail.pos.x)
+ local y = abs(arc.head.pos.y - arc.tail.pos.y)
+ spring_length = spring_length + sqrt(x * x + y * y)
+ end
+ spring_length = spring_length / #arcs
+
+ -- additionally improve the layout with the force-based algorithm
+ -- if there are more than two nodes in the coarsest graph
+ if coarse_graph:getSize() > 2 and end_coarsen and not start_expand then
+ move_vertices(coarse_graph.ugraph.vertices, e)
+ end
+ end
+
+ -- undo coarsening step by step, applying the force-based sub-algorithm
+ -- to every intermediate coarse graph as well as the original graph
+ if i >= start_expand then
+ if coarse_graph:getLevel() > 0 then
+ if i == start_expand then
+ coarse_graph:uncoarsen()
+ elseif i < end_expand then
+ preprocessing(coarse_graph.ugraph.vertices, coarse_graph.ugraph.arcs, e, coarse_graph.ugraph)
+ move_vertices(coarse_graph.ugraph.vertices, e)
+ else
+ i = start_expand - 1
+ end
+ else
+ preprocessing(coarse_graph.ugraph.vertices, coarse_graph.ugraph.arcs, e, coarse_graph.ugraph)
+ move_vertices(coarse_graph.ugraph.vertices, e)
+ end
+ end
+ -- Before and after the coarsening process
+ elseif i < start_coarsening or i > end_coarsening then
+ if not vertices_initalized then
+ initial_positioning_class.new {
+ vertices = coarse_graph.ugraph.vertices,
+ options = options,
+ desired_vertices = desired_vertices }:run()
+ vertices_initalized = true
+ end
+ preprocessing(coarse_graph.ugraph.vertices, coarse_graph.ugraph.arcs, e, coarse_graph.ugraph)
+ move_vertices(coarse_graph.ugraph.vertices, e)
+ end
+ else
+ -- Same without coarsen
+ if i < start_coarsening or i > end_coarsening then
+ if not vertices_initalized then
+ initial_positioning_class.new {
+ vertices = vertices,
+ options = options,
+ desired_vertices = desired_vertices }:run()
+ vertices_initalized = true
+ end
+ preprocessing(vertices, arcs, e, ugraph)
+ move_vertices(vertices, e, self.ugraph)
+ end
+ end
+ i = i + 1
+ end
+end
+
+
+--- Preprocessing for all force types in force configuration
+--
+-- @params v The vertices of the current graph
+-- @params a The arcs of the current graph
+-- @params epoch The preprocessing algorithm will only be applied to the forces
+-- associated with this epoch.
+-- @params ugraph The current graph object
+
+function preprocessing(v, a, epoch, ugraph)
+ for _, fc in ipairs(epoch_forces[epoch]) do
+ fc:preprocess(v, a, ugraph)
+ end
+end
+
+
+--- Adding forces to the algorithm.
+--
+-- @params force_data A table containing force type, time function, force function,
+-- capping thresholds and the epochs in which this force will be active
+
+function ForceController:addForce(force_data)
+ local t = force_data.force_type
+ if t == ForcePullToPoint then
+ self.pull_to_point = true
+ end
+
+ local f = t.new {force = force_data, options = self.ugraph.options, fw_attributes = self.fw_attributes or {}}
+ if force_data.epoch == nil then
+ force_data.epoch = {}
+ end
+ for _,e in ipairs(force_data.epoch) do
+ local tab = self.epoch_forces[e]
+ if not tab then
+ tab = {}
+ end
+ tab[#tab +1] = f
+ self.epoch_forces[e] = tab
+ end
+end
+
+
+--- Moving vertices according to force functions until the maximum number of
+-- iterations is reached
+--
+-- @params vertices The vertices in the current graph
+-- @params epoch The current epoch, to find the forces that are active
+
+function move_vertices(vertices, epoch, g)
+ if #epoch_forces[epoch] == 0 then
+ return
+ end
+ local iterations = options["iterations ".. epoch] or options["iterations"]
+ local find_equilibrium = options["find equilibrium ".. epoch] or options["find equilibrium"]
+ local epsilon = options["equilibrium threshold ".. epoch] or options["equilibrium threshold"]
+ local speed = options["global speed factor ".. epoch] or options["global speed factor"]
+ local max_step = options["maximum displacement per step ".. epoch] or options["maximum displacement per step"]
+
+ assert(epsilon >= 0, 'the threshold for finding an equilibirum (equilibrium threshold) (value: ' .. epsilon .. ') needs to be greater than or equal to 0')
+ assert(speed > 0, 'the speed at which the vertices move (value: ' .. speed .. ') needs to be greater than 0')
+ assert(max_step > 0, 'the maximum displacement per step each vertex can move per iteration (value: ' .. max_step .. ') needs to be greater than 0')
+
+ local max_time = options["maximum time ".. epoch] or options["maximum time"]
+ local d_t = max_time/iterations
+ local t_now = 0
+ local random = lib.random
+ local randomseed = lib.randomseed
+
+ for j = 1 , iterations do
+ t_now = t_now + d_t
+ net_forces = get_net_force(vertices, j, t_now, epoch)
+
+ -- normalize the force vector if necessary
+ for v, c in pairs(net_forces) do
+ local n = sqrt(c.x*c.x+c.y*c.y)
+ if n > max_step then
+ local factor = max_step/n
+ c.x = c.x*factor
+ c.y = c.y*factor
+ end
+ end
+
+ -- if not in equilibrium yet, apply forces
+ if not find_equilibrium or sum_up(net_forces)*d_t > epsilon then
+ local cool_down_dt = d_t
+ if cool_down_dt > 1 then
+ cool_down_dt = 1 + 1/d_t
+ end
+ for _, v in ipairs(vertices) do
+ local factor = 1/(v.mass or 1)
+ local c1 = net_forces[v]
+ local x = speed * cool_down_dt * c1.x * factor
+ local y = speed * cool_down_dt * c1.y * factor
+ local p = v.pos
+ p.x = p.x + x
+ p.y = p.y + y
+ end
+ else
+ break
+ end
+ end
+end
+
+
+-- calculate the net force for each vertex in one iteration
+--
+-- @params vertices the vertices of the current graph
+-- @params j The current iteration
+-- @params t_now The current virtual time
+-- @params epoch The current epoch
+--
+-- @return A table of coordinate-objects associated with vertices. The
+-- coordinate object hold the calculated net displacement for
+-- the $x$ and $y$ coordinate.
+function get_net_force(vertices, j, t_now, epoch)
+ local net_forces = {}
+ local natural_spring_length = options["node distance"]
+
+ for _,v in ipairs(vertices) do
+ net_forces[v] = Coordinate.new(0,0)
+ end
+
+ for _,force_class in ipairs(epoch_forces[epoch]) do
+ force_class:applyTo{net_forces = net_forces, options = options, j = j, t_now = t_now, k = natural_spring_length}
+ end
+
+ return net_forces
+end
+
+-- Helper function to sum up all calculated forces
+--
+-- @params tab A table holding coordinate objects as values
+--
+-- @returns The sum of the absolute $x$ and $y$ values in this table
+function sum_up(tab)
+ local sum = 0
+ for v, c in pairs(tab) do
+ sum = sum + abs(c.x) + abs(c.y)
+ end
+ return sum
+end
+
+return ForceController
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceTemplate.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceTemplate.lua
new file mode 100644
index 0000000000..29370fc029
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/ForceTemplate.lua
@@ -0,0 +1,44 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This is the parent class for forces. It provides a constructor and methods
+-- stubs to be overwritten in the subclasses.
+
+-- Imports
+local lib = require "pgf.gd.lib"
+
+local ForceTemplate = lib.class {}
+
+-- constructor
+function ForceTemplate:constructor()
+ self.force = self.force
+ self.fw_attributes = self.fw_attributes
+ if not self.force.time_fun then
+ self.force.time_fun = function() return 1 end
+ end
+end
+
+-- Method stub for preprocessing
+--
+-- @param v The vertices the list will be build on
+
+function ForceTemplate:preprocess(v)
+end
+
+-- Method stub for applying the forces
+--
+-- @param data A table holding data like the table the forces are collected
+-- in, the current iteration, the current time stamp, some options
+-- or the natural spring length
+
+function ForceTemplate:applyTo(data)
+end
+
+return ForceTemplate \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/InitialTemplate.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/InitialTemplate.lua
new file mode 100644
index 0000000000..762717f64a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/InitialTemplate.lua
@@ -0,0 +1,64 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This is the parent class for initial layout algorithms. It provides a
+-- constructor and methods stubs to be overwritten in the subclasses as well
+-- as placing vertices which are |desired at| a certain point.
+
+-- Imports
+local lib = require "pgf.gd.lib"
+
+local InitialTemplate = lib.class {}
+
+-- constructor
+function InitialTemplate:constructor()
+ self.vertices = self.vertices
+ self.options = self.options
+ self.desired_vertices = self.desired_vertices
+end
+
+-- Method placing |desired at| vertices at the point they are desired
+--
+-- @params desired_vertices A table containing all the vertices where the
+-- |desired at| option is set.
+--
+-- @return |placed| A boolean array stating if vertices have been placed yet
+-- @return |centroid_x| The x-coordinate of the midpoint of all placed vertices
+-- @return |centroid_y| The y-coordinate of the midpoint of all placed vertices
+
+function InitialTemplate:desired(desired_vertices)
+ local placed = {}
+
+ local centroid_x, centroid_y = 0, 0
+
+ local size = 0
+ for v, da in pairs(desired_vertices) do
+ local p = v.pos
+ local x, y = da.x, da.y
+ p.x = x or 0
+ p.y = y or 0
+ centroid_x = centroid_x + x
+ centroid_y = centroid_y + y
+ placed[v] = true
+ size = size +1
+ end
+ if size>0 then
+ centroid_x = centroid_x / size
+ centroid_y = centroid_y / size
+ end
+
+ return placed, centroid_x, centroid_y
+end
+
+-- Method stub for running the layout algorithm
+function InitialTemplate:run()
+end
+
+return InitialTemplate \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/PathLengthsFW.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/PathLengthsFW.lua
new file mode 100644
index 0000000000..2d50677fa5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/PathLengthsFW.lua
@@ -0,0 +1,174 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- This is a helper class providing different functions that deal with graph
+-- distances. This class can be used by engineers and implementers if they
+-- need to calculate anything regarding graph distances.
+
+local PathLengths = {}
+
+-- Imports
+local PriorityQueue = require "pgf.gd.lib.PriorityQueue"
+local Preprocessing = require "pgf.gd.force.jedi.base.Preprocessing"
+
+-- This algorithm conducts a breadth first search on the graph it is given.
+--
+-- @param ugraph The graph on which the search should be conducted
+--
+-- @return A table holding every vertex $v$ as key and a table as value. The
+-- value table holds all other vertices $u$ as keys and their shortest
+-- distance to $v$ as value
+
+function PathLengths:breadthFirstSearch(ugraph)
+ local distances = {}
+ local vertices = ugraph.vertices
+ local arcs = ugraph.arcs
+
+ for _,v in ipairs(vertices) do
+ distances[v] = {}
+ local dist = distances[v]
+ for _,w in ipairs(vertices) do
+ dist[w] = #vertices +1
+ end
+ dist[v] = 0
+ end
+ local n = 1
+ local p = Preprocessing.overExactlyNPairs(vertices, arcs, n)
+ while (#p > 0) do
+ for _, v in ipairs(p) do
+ local tab = distances[v.tail]
+ tab[v.head] = n
+ end
+ n = n + 1
+ p = Preprocessing.overExactlyNPairs(vertices, arcs, n)
+ end
+ return(distances)
+end
+
+
+-- This function performs Dijkstra's algorithm on the graph.
+--
+-- @param ugraph The graph where the paths should be found
+-- @param source The source vertex
+--
+-- @return |distance| A table holding every vertex $v$ as key and a table as
+-- value. The value table holds all other vertices $u$ as
+-- keys and their shortest distance to $v$ as value
+-- @return |levels| A table holding the levels of the graph as keys and a
+-- table holding the vertices found on that level as values
+-- @return |parent| A table holding each vertex as key and it's parent vertex
+-- as value
+
+function PathLengths:dijkstra(ugraph, source)
+ local distance = {}
+ local levels = {}
+ local parent = {}
+
+ local queue = PriorityQueue.new()
+
+ -- reset the distance of all nodes and insert them into the priority queue
+ for _,v in ipairs(ugraph.vertices) do
+ if v == source then
+ distance[v] = 0
+ parent[v] = nil
+ queue:enqueue(v, distance[v])
+ else
+ distance[v] = #ugraph.vertices + 1 -- this is about infinity ;)
+ queue:enqueue(v, distance[v])
+ end
+ end
+
+ while not queue:isEmpty() do
+ local u = queue:dequeue()
+
+ assert(distance[u] < #ugraph.vertices + 1, 'the graph is not connected, Dijkstra will not work')
+
+ if distance[u] > 0 then
+ levels[distance[u]] = levels[distance[u]] or {}
+ table.insert(levels[distance[u]], u)
+ end
+
+
+
+ for _,edge in ipairs(ugraph:outgoing(u)) do
+ local v = edge.head
+ local alternative = distance[u] + 1
+ if alternative < distance[v] then
+ distance[v] = alternative
+
+ parent[v] = u
+
+ -- update the priority of v
+ queue:updatePriority(v, distance[v])
+ end
+ end
+ end
+
+ return distance, levels, parent
+end
+
+-- This function finds the pseudo diameter of the graph, which is the longest
+-- shortest path in the graph
+--
+-- @param ugraph The graph who's pseudo diameter is wanted
+--
+-- @ return |diameter| The pseudo diameter of the graph
+-- @ return |start_node| The start node of the longest shortest path in the
+-- graph
+-- @ return |end_node| The end node of the longest shortest path in the graph
+
+function PathLengths:pseudoDiameter(ugraph)
+
+ -- find a node with minimum degree
+ local start_node = ugraph.vertices[1]
+ for _,v in ipairs(ugraph.vertices) do
+ if #ugraph:incoming(v) + #ugraph:outgoing(v) < #ugraph:incoming(start_node) + #ugraph:outgoing(start_node) then
+ start_node = v
+ end
+ end
+
+ assert(start_node)
+
+ local old_diameter = 0
+ local diameter = 0
+ local end_node = nil
+
+ while true do
+ local distance, levels = self:dijkstra(ugraph, start_node)
+
+ -- the number of levels is the same as the distance of the nodes
+ -- in the last level to the start node
+ old_diameter = diameter
+ diameter = #levels
+
+ -- abort if the diameter could not be improved
+ if diameter == old_diameter then
+ end_node = levels[#levels][1]
+ break
+ end
+
+ -- select the node with the smallest degree from the last level as
+ -- the start node for the next iteration
+ start_node = levels[#levels][1]
+ for _,node in ipairs(levels[#levels]) do
+ if #ugraph:incoming(node)+#ugraph:outgoing(node) < #ugraph:incoming(start_node) + #ugraph:outgoing(start_node) then
+ start_node = node
+ end
+ end
+
+ assert(start_node)
+ end
+
+ assert(start_node)
+ assert(end_node)
+
+ return diameter, start_node, end_node
+end
+
+return PathLengths \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/Preprocessing.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/Preprocessing.lua
new file mode 100644
index 0000000000..de59e0cb5c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/base/Preprocessing.lua
@@ -0,0 +1,122 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This file holds functions to create lists of vertex pairs. All
+-- functions return a Graph object containing the vertices of the
+-- original graph and an edge between the vertices forming a pair
+-- under the specified conditions. The lists can be precomputed to
+-- enhance performance.
+
+local PreprocessClass = {}
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local Digraph = require "pgf.gd.model.Digraph"
+
+
+-- Creates a graph object with an arc between all pairwise disjoint vertex
+-- pairs and returns the arc table
+--
+-- @param vertices The vertices of the original graph
+--
+-- @return An arc table
+
+function PreprocessClass.allPairs(vertices)
+ local aP = Digraph.new{}
+ for _, vertex in ipairs(vertices) do
+ for _, vertex2 in ipairs(vertices) do
+ if vertex ~= vertex2 then
+ if not aP:contains(vertex) then
+ aP:add {vertex}
+ end
+ if not aP:contains(vertex2) then
+ aP:add {vertex2}
+ end
+ if not aP:arc(vertex, vertex2) and not aP:arc(vertex2, vertex) then
+ aP:connect(vertex, vertex2)
+ end
+ end
+ end
+ end
+ return aP.arcs
+end
+
+
+-- Creates a graph object with an arc between all pairwise disjoint vertex
+-- pairs that are connected by a shortest path of length n in the original
+-- graph and returns the arc table
+--
+-- @param vertices The vertices of the original graph
+-- @param arcs The arcs of the original graph
+-- @param n The length of the shortest path we are looking for
+--
+-- @return An arc table
+
+function PreprocessClass.overExactlyNPairs(vertices, arcs, n)
+ local waste, p_full = PreprocessClass.overMaxNPairs(vertices, arcs, n)
+ local waste, p_small = PreprocessClass.overMaxNPairs(vertices, arcs, n-1)
+ for _, paar in ipairs(p_full.arcs) do
+ if p_small:arc(paar.head, paar.tail) ~= nil or p_small:arc(paar.tail, paar.head) ~= nil then
+ p_full:disconnect(paar.head, paar.tail)
+ p_full:disconnect(paar.tail, paar.head)
+ end
+ end
+ return p_full.arcs
+end
+
+
+-- Creates a graph object with an arc between all pairwise disjoint vertex
+-- pairs that are connected by a shortest path of length n or shorter in the
+-- original graph and returns the arc table
+--
+-- @param vertices The vertices of the original graph
+-- @param arcs The arcs of the original graph
+-- @param n The length of the shortest path we are looking for
+--
+-- @return An arc table
+
+function PreprocessClass.overMaxNPairs(vertices, arcs, n)
+ assert(n >= 0, 'n (value: ' .. n.. ') needs to be greater or equal 0')
+ local p = Digraph.new{}
+ local oneHop = Digraph.new{}
+ if n> 0 then
+ for _, arc in ipairs(arcs) do
+ local vertex = arc.head
+ local vertex2 = arc.tail
+ if not p:contains(vertex) then
+ p:add {vertex}
+ oneHop:add {vertex}
+ end
+ if not p:contains(vertex2) then
+ p:add {vertex2}
+ oneHop:add {vertex2}
+ end
+ if p:arc(vertex, vertex2) == nil and p:arc(vertex2, vertex) == nil then
+ p:connect(vertex, vertex2)
+ oneHop:connect(vertex, vertex2)
+ end
+ end
+ end
+
+ n = n-1
+ while n > 0 do
+ for _, paar in ipairs(p.arcs) do
+ for _, vertex in ipairs(vertices) do
+ if paar.head ~= vertex and p:arc(paar.head, vertex) == nil and p:arc(vertex, paar.head) == nil and (oneHop:arc(paar.tail, vertex) ~= nil or oneHop:arc(vertex, paar.tail) ~= nil) then
+ p:connect(paar.head, vertex)
+ end
+ end
+ end
+ n = n-1
+ end
+ return p.arcs, p
+end
+
+return PreprocessClass
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/doc.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/doc.lua
new file mode 100644
index 0000000000..19baca7333
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/doc.lua
@@ -0,0 +1,377 @@
+-- Copyright 2014 by Ida Bruhns and Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- Imports
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "maximum step"
+
+summary
+[[
+This option determines the maximum distance every vertex is allowed to travel
+in one iteration.
+]]
+
+documentation
+[[
+No matter how large the forces influencing a vertex, the effect
+on the drawing should be limited to avoid vertices "jumping" from one side of
+the canvas to each other due to a strong force pulling them further than their
+ideal destination. The amount of space a vertex is allowed to travel in one
+iteration is limited by the \lstinline{maximum step} parameter. It is $5000$
+by default. That means by default, this parameter should not get in your way.
+]]
+
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 2, maximum time = 2, maximum step = 6pt, coarsen = false]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 2, maximum time = 2, maximum step = 12pt, coarsen = false]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+
+
+--------------------------------------------------------------------
+key "speed"
+
+summary
+[[
+This is a factor every calculated step is multiplied by.
+]]
+
+documentation
+[[
+The speed is the distance a vertex travels if it is influenced by a force of
+$1$N$\cdot\gamma$. The speed is only a factor that will influence the total
+amount every vertex can move: Half the speed makes half the movement, twice
+the speed doubles the distance traveled.
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 1, maximum time = 1, maximum step = 100, speed = 0.2, coarsen = false]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 1, maximum time= 1, maximum step = 100, speed = 0.4, coarsen = false]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "maximum time"
+
+summary
+[[
+The highest amount of virtual time the algorithm is allowed to take.
+]]
+
+documentation
+[[
+This option is part of the virtual time construct of Jedi. The virtual time
+concept allows graph drawing algorithm engineers to switch forces on and of
+after a relative or absolute amount of time has elapsed. If the iterations
+stay the same, doubling the maximum time has the same effect as doubling the
+speed: Vertices move faster, but it is possible they miss their intended
+destination. Also increasing the iterations changes the "resolution" of the
+graph drawing algorithm: More steps are simulated in the same time.
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 20, maximum time = 100, coarsen = false, maximum step = 0.5, gravity = 2]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 20, maximum time = 200, coarsen = false, maximum step = 0.5, gravity = 2]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "find equilibrium"
+
+summary
+[[
+If this option is |true|, the framework checks the vertex movement to detect
+low movement near the equilibrium and stop the algorithm.
+]]
+
+documentation
+[[
+Since we often do not know how many iterations are enough, the framework will
+detect when the vertices (almost) stop moving and stop the algorithm. After
+each iteration, the framework adds up the net force influencing all the
+vertices. If it falls below the threshold |epsilon|, the algorithm
+will ignore the left over iterations and terminate. You can disable this
+behavior by setting this parameter to |false|. Allowing the framework to find
+the equilibrium usually saves you time, while allowing more iterations (or a
+lower threshold) generates higher quality drawings.
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 300, maximum time = 300, coarsen = false, maximum step = 10, epsilon = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 300, maximum time = 300, maximum step = 10, find equilibrium = false]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "epsilon"
+
+summary
+[[
+The threshold for the |find equilibrium| option.
+]]
+
+documentation
+[[
+This key specifies the threshold for the |find equilibrium| option. The lower
+epsilon, the longer the graph drawing algorithm will take, but the closer the
+resulting drawing will be to the true energy minimum.
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 200, maximum time = 200, maximum step = 10, coarsen = false, epsilon = 2]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 200, maximum time = 200, maximum step = 10, epsilon = 12, coarsen = false]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "snap to grid"
+
+summary
+[[
+This option enables the post-processing step |snap to grid|.
+]]
+
+documentation
+[[
+This key is the on/off-switch for the grid forces. The |snap to grid| option
+triggers a form of post-processing were all vertices are pulled to the closest
+point on a virtual grid. Please note that there is no repulsive force between
+the vertices, so it is possible that two vertices are pulled to the same grid
+point. The grid size is determined by the parameters |grid x length| and
+|grid y length|.
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, maximum step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz{
+ \graph[social degree layout, iterations = 100, maximum time = 100, snap to grid =true, grid x length = 5mm, grid y length = 5mm, maximum step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "grid x length"
+
+summary
+[[
+This option determines the cell size in $x$ direction for the |snap to grid|
+option.
+]]
+
+documentation
+[[
+The size of the cells of the virtual grid can be configured by the user. This
+key allows a configuration of the horizontal cell width.
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, snap to grid =true, grid x length = 5mm, grid y length = 5mm, maximum step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, snap to grid =true, grid x length = 9mm, grid y length = 5mm, maximum step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "grid y length"
+
+summary
+[[
+This option determines the cell size in $x$ direction for the |snap to grid|
+option.
+]]
+
+documentation
+[[
+Same as |grid x length|, but in vertical direction (height of the cells).
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, snap to grid =true, grid x length = 5mm, grid y length = 5mm, maximum step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+\tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, snap to grid =true, grid x length = 5mm, grid y length = 9mm, maximum step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+--------------------------------------------------------------------
+key "mass"
+
+summary
+[[
+ The mass of a vertex determines how fast it can move. Vertices
+ with higher mass move slower.
+]]
+
+documentation
+[[
+ The mass of a vertex determines how fast this vertex
+ moves. Mass is directly inverse proportional to the distance the vertex
+ moves. In contrast to the global speed factor, mass usually only affects a
+ single vertex. A vertex with a higher mass will move slower if affected by
+ the same mass than a vertex with a lower mass. By default, each vertex has a
+ mass of $1$.
+]]
+
+example
+[[
+ \tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, maximum displacement per step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1 -- {b2 -- {b3, b4}, b5}
+ };
+]]
+
+example
+[[
+ \tikz
+ \graph[social degree layout, iterations = 100, maximum time = 100, maximum displacement per step = 10]{
+ a1 -- {a2, a3, a4, a5},
+ b1[mass = 4] -- {b2 -- {b3, b4}, b5}
+ };
+]]
+--------------------------------------------------------------------
+
+
+--------------------------------------------------------------------
+key "coarsening weight"
+
+summary
+[[
+ The coarsening weight of a vertex determines when it will be
+ coarsened.
+]]
+
+documentation
+[[
+ Vertices with higher coarsening weight are considered more important and
+ will be coarsened later, or not at all.
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceAbsoluteValue.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceAbsoluteValue.lua
new file mode 100644
index 0000000000..4634b70123
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceAbsoluteValue.lua
@@ -0,0 +1,94 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- This is a subclass of ForceTemplate, which is used to implement forces
+-- that work on individual vertices. Forces of this kind simply add an
+-- absolute value set in the force data to each vertex' $x$ and $y$ coordinate
+
+-- Imports
+local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate"
+local lib = require "pgf.gd.lib"
+local Preprocessing = require "pgf.gd.force.jedi.base.Preprocessing"
+
+-- Localize math functions
+local max = math.max
+local sqrt = math.sqrt
+local min = math.min
+
+-- Implementation starts here:
+
+local ForceAbsoluteValue = lib.class { base_class = ForceTemplate }
+
+function ForceAbsoluteValue:constructor ()
+ ForceTemplate.constructor(self)
+ self.p = {}
+end
+
+
+-- This force class works on a vertex array that is part of the force data
+-- defined when adding the force. This array is copied into p. All vertices of
+-- the graph are saved in the local variable |ver|.
+--
+-- @param v The vertices of the graph we are trying to find a layout for.
+
+function ForceAbsoluteValue:preprocess(v)
+ self.ver = v
+ self.p = self.force.vertices
+end
+
+
+-- Applying the force to the vertices and adding the effect to the passed net
+-- force array
+--
+-- @param data The parameters needed to apply the force: The options table,
+-- the current time stamp, an array containing the summed up net
+-- forces
+
+function ForceAbsoluteValue:applyTo(data)
+ -- locals for speed
+ local cap = self.force.cap
+ local value = self.force.value
+ local net_forces = data.net_forces
+ local t_max = self.options["maximum time"]
+ local t_now = data.t_now
+ local p = self.p
+ local time_fun = self.force.time_fun
+
+ -- Evaluate time function
+ local time_factor = time_fun(t_max, t_now)
+ if time_factor == 0 then
+ return
+ end
+
+ for _,v in ipairs(self.ver) do
+ for _, i in ipairs (self.p) do
+ -- Is the vertex in the list?
+ if v.name == i then
+
+ local f = value * time_factor
+
+ -- cap effect if necessary
+ if cap then
+ if f <= 0 then
+ x = max(-cap, f)
+ else
+ x = min(cap, f)
+ end
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[v]
+ c1.x = c1.x + f
+ c1.y = c1.y + f
+ end
+ end
+ end
+end
+
+return ForceAbsoluteValue \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua
new file mode 100644
index 0000000000..8cea1aec6a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua
@@ -0,0 +1,201 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This is a subclass of ForceTemplate, which is used to implement forces between
+-- vertex pairs. The forces depend on the canvas distance of the vertices in
+-- the pair. This class is e.~g.~ used for electric forces.
+
+-- Imports
+local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate"
+local lib = require "pgf.gd.lib"
+local Preprocessing = require "pgf.gd.force.jedi.base.Preprocessing"
+
+-- Localize math functions
+local max = math.max
+local sqrt = math.sqrt
+local min = math.min
+
+-- Implementation starts here:
+local ForceCanvasDistance = lib.class { base_class = ForceTemplate }
+
+function ForceCanvasDistance:constructor ()
+ ForceTemplate.constructor(self)
+ self.p = {}
+end
+
+
+-- This force class works on all pairwise disjoint vertex pairs. This
+-- function generates a new graph object containing all vertices from the
+-- original graph and arcs between all pairwise disjoint vertex pairs. The
+-- arcs-table of this new object will be saved in the variable |p|.
+--
+-- @param v The vertices of the graph we are trying to find a layout for.
+
+function ForceCanvasDistance:preprocess(v)
+ self.p = Preprocessing.allPairs(v)
+end
+
+
+-- Applying the force to the vertices and adding the effect to the passed net
+-- force array
+--
+-- @param data The parameters needed to apply the force: The options table,
+-- the current time stamp, an array containing the summed up net
+-- forces
+
+function ForceCanvasDistance:applyTo(data)
+ -- locals for speed
+ local cap = self.force.cap
+ local fun_u = self.force.fun_u
+ local fun_v = self.force.fun_v
+ local net_forces = data.net_forces
+ local t_max = self.options["maximum time"]
+ local t_now = data.t_now
+ local k = data.k
+ local p = self.p
+ local time_fun = self.force.time_fun
+ local fw_attributes = self.fw_attributes
+
+ -- Evaluate time function
+ local time_factor = time_fun(t_max, t_now)
+ if time_factor == 0 then
+ return
+ end
+
+ if not fun_v then
+ local data = { k = k, attributes = fw_attributes }
+ for _, i in ipairs(p) do
+ -- dereference
+ local p2 = i.head
+ local p1 = i.tail
+ local p2_pos = p2.pos
+ local p1_pos = p1.pos
+
+ -- calculate distance between two points
+ local x = p2_pos.x - p1_pos.x
+ local y = p2_pos.y - p1_pos.y
+ local d = max(sqrt(x*x+y*y),0.1)
+
+ -- apply force function
+ data.u = p2
+ data.v = p1
+ data.d = d
+ local e = fun_u(data)
+
+ -- Include time function
+ local f = e * time_factor / d
+
+ -- calculate effect on x/y
+ local g = x * f
+ local h = y * f
+
+ -- cap effect if necessary
+ if cap then
+ if g <= 0 then
+ x = max(-cap, g)
+ else
+ x = min(cap, g)
+ end
+
+ if h <= 0 then
+ y = max(-cap, h)
+ else
+ y = min(cap, h)
+ end
+ else
+ x = g
+ y = h
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[p1]
+ c1.x = c1.x - x
+ c1.y = c1.y - y
+ local c2 = net_forces[p2]
+ c2.x = c2.x + x
+ c2.y = c2.y + y
+ end
+ else
+ -- There are different functions for head and tail vertex
+ local data = { k = k, attributes = fw_attributes }
+ for _, i in ipairs(p) do
+ -- dereference
+ local p2 = i.head
+ local p1 = i.tail
+ local p2_pos = p2.pos
+ local p1_pos = p1.pos
+
+ -- calculate distance between two points
+ local x = p2_pos.x - p1_pos.x
+ local y = p2_pos.y - p1_pos.y
+ local d = max(sqrt(x*x+y*y),0.1)
+
+ -- apply force function to distance and k (natural spring length
+ data.u = p2
+ data.v = p1
+ data.d = d
+ local e_head = fun_u(data)
+ local e_tail = fun_v(data)
+
+ -- Include time function
+ local f_head = time_factor * e_head / d
+ local f_tail = time_factor * e_tail / d
+
+ -- calculate effect on x/y
+ local g_head = x * f_head
+ local g_tail = x * f_tail
+ local h_head = y * f_head
+ local h_tail = y * f_tail
+
+ -- cap effect if necessary
+ local x_head, x_tail, y_head, y_tail
+ if cap then
+ if g_head <= 0 then
+ x_head = max(-cap, g_head)
+ else
+ x_head = min(cap, g_head)
+ end
+
+ if g_tail <= 0 then
+ x_tail = max(-cap, g_tail)
+ else
+ x_tail = min(cap, g_tail)
+ end
+
+ if h_head <= 0 then
+ y_head = max(-cap, h_head)
+ else
+ y_head = min(cap, h_head)
+ end
+
+ if h_tail <= 0 then
+ y_tail = max(-cap, h_tail)
+ else
+ y_tail = min(cap, h_tail)
+ end
+ else
+ x_head = g_head
+ x_tail = g_tail
+ y_head = h_head
+ y_tail = h_tail
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[p1]
+ c1.x = c1.x - x_tail
+ c1.y = c1.y - y_tail
+ local c2 = net_forces[p2]
+ c2.x = c2.x + x_head
+ c2.y = c2.y + y_head
+ end
+ end
+end
+
+return ForceCanvasDistance \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua
new file mode 100644
index 0000000000..41edaba358
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua
@@ -0,0 +1,117 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This is a subclass of ForceTemplate, which is used to implement forces
+-- that work on individual vertices. The forces depend on the canvas position
+-- of the vertices. This class is e.~g.~ used for gravitational forces.
+
+local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate"
+local lib = require "pgf.gd.lib"
+
+local ForceCanvasPosition = lib.class { base_class = ForceTemplate }
+
+-- Localize math functions
+local max = math.max
+local sqrt = math.sqrt
+local min = math.min
+
+-- Implementation starts here:
+
+function ForceCanvasPosition:constructor ()
+ ForceTemplate.constructor(self)
+ self.p = {}
+end
+
+
+-- This force class works on individual vertices and only depends on their
+-- current position. Thus the vertex table of the current graph is simply
+-- copied to the variable |p|.
+--
+-- @param v The vertices of the graph we are trying to find a layout for.
+
+function ForceCanvasPosition:preprocess(v)
+ self.p = v
+end
+
+
+-- Applying the force to the vertices and adding the effect to the passed net
+-- force array
+--
+-- @param data The parameters needed to apply the force: The options table,
+-- the current time stamp, an array containing the summed up net
+-- forces
+
+function ForceCanvasPosition:applyTo(data)
+ --localize
+ local cap = self.force.cap
+ local fun_u = self.force.fun_u
+ local net_forces = data.net_forces
+ local t_max = self.options["maximum time"]
+ local t_now = data.t_now
+ local p = self.p
+ local time_fun = self.force.time_fun
+ local initial_gravity = self.options["gravity"]
+ local fw_attributes = self.fw_attributes
+
+ -- evaluate time function
+ local time_factor = time_fun(t_max, t_now)
+ if time_factor == 0 then
+ return
+ end
+
+ -- Find midpoint of all vertices since they will be attracted to this point
+ local centroid_x, centroid_y = 0,0
+ for _, v in ipairs(p) do
+ local pos = v.pos
+ centroid_x = centroid_x + pos.x
+ centroid_y = centroid_y + pos.y
+ end
+ centroid_x = centroid_x/#p
+ centroid_y = centroid_y/#p
+
+ -- Iterate over the precomputed vertex list
+ for _, v in ipairs(p) do
+ -- localize
+ local p1 = v.pos
+
+ -- apply force function
+ local factor = fun_u{attributes = fw_attributes, u = v}
+
+ -- calculate distance between vertex and centroid
+ local x = centroid_x - p1.x
+ local y = centroid_y - p1.y
+
+ -- calculate effect on x/y
+ local h = factor * time_factor
+ x = x * h
+ y = y * h
+
+ -- cap effect if necessary
+ if cap then
+ if x <= 0 then
+ x = max(-cap, x)
+ else
+ x = min(cap, x)
+ end
+ if y <= 0 then
+ y = max(-cap, y)
+ else
+ y = min(cap, y)
+ end
+ end
+
+ -- add calculated effect to net forces
+ local c = net_forces[v]
+ c.x = c.x + x
+ c.y = c.y + y
+ end
+end
+
+return ForceCanvasPosition \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceGraphDistance.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceGraphDistance.lua
new file mode 100644
index 0000000000..86d67f2678
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceGraphDistance.lua
@@ -0,0 +1,205 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This is a subclass of ForceTemplate, which is used to implement forces between
+-- vertex pairs. The forces depend on the graph distance of the vertices in
+-- the pair. This class is e.\,g.\ used for spring forces.
+
+
+local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate"
+local lib = require "pgf.gd.lib"
+local Preprocessing = require "pgf.gd.force.jedi.base.Preprocessing"
+
+-- Localize math functions
+local max = math.max
+local sqrt = math.sqrt
+local min = math.min
+
+-- Implementation starts here:
+
+local ForceGraphDistance = lib.class { base_class = ForceTemplate }
+
+function ForceGraphDistance:constructor ()
+ ForceTemplate.constructor(self)
+ self.p = {}
+end
+
+
+-- This force class works on all pairwise disjoint vertex pairs connected by
+-- a path of length maximum $n$. The parameter $n$ is given by the engineer in
+-- the force declaration. This function generates a new graph object
+-- containing all vertices from the original graph and arcs between all
+-- pairwise disjoint vertex pairs. The arcs-table of this new object will be
+-- saved in the variable |p|.
+--
+-- @param v The vertices of the graph we are trying to find a layout for.
+
+function ForceGraphDistance:preprocess(v, a)
+ self.p = Preprocessing.overExactlyNPairs(v, a, self.force.n)
+end
+
+
+-- Applying the force to the vertices and adding the effect to the passed net
+-- force array
+--
+-- @param data The parameters needed to apply the force: The options table,
+-- the current time stamp, an array containing the summed up net
+-- forces
+
+function ForceGraphDistance:applyTo(data)
+ -- locals for speed
+ local cap = self.force.cap
+ local fun_u = self.force.fun_u
+ local fun_v = self.force.fun_v
+ local net_forces = data.net_forces
+ local t_max = self.options["maximum time"]
+ local t_now = data.t_now
+ local k = data.k
+ local p = self.p
+ local time_fun = self.force.time_fun
+ local fw_attributes = self.fw_attributes
+
+ -- Evaluate time function
+ local time_factor = time_fun(t_max, t_now)
+ if time_factor == 0 then
+ return
+ end
+
+ if not fun_v then
+ local data = { k = k, attributes = fw_attributes }
+ for _, i in ipairs(p) do
+ -- dereference
+ local p2 = i.head
+ local p1 = i.tail
+ local p2_pos = p2.pos
+ local p1_pos = p1.pos
+
+ -- calculate distance between two points
+ local x = p2_pos.x - p1_pos.x
+ local y = p2_pos.y - p1_pos.y
+ local d = max(sqrt(x*x+y*y),0.1)
+
+ -- apply force function to distance and k (natural spring length)
+ data.u = p2
+ data.v = p1
+ data.d = d
+ local e = fun_u(data)
+
+ -- Include time function
+ local f = e * time_factor / d
+
+ -- calculate effect on x/y
+ local g = x * f
+ local h = y * f
+
+ -- cap effect if necessary
+ if cap then
+ if g <= 0 then
+ x = max(-cap, g)
+ else
+ x = min(cap, g)
+ end
+
+ if g <= 0 then
+ y = max(-cap, h)
+ else
+ y = min(cap, h)
+ end
+ else
+ x = g
+ y = h
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[p1]
+ c1.x = c1.x - x
+ c1.y = c1.y - y
+ local c2 = net_forces[p2]
+ c2.x = c2.x + x
+ c2.y = c2.y + y
+ end
+ else
+ -- There are different functions for head and tail vertex
+ local data = { k = k, attributes = fw_attributes }
+ for _, i in ipairs(p) do
+ -- dereference
+ local p2 = i.head
+ local p1 = i.tail
+ local p2_pos = p2.pos
+ local p1_pos = p1.pos
+
+ -- calculate distance between two points
+ local x = p2_pos.x - p1_pos.x
+ local y = p2_pos.y - p1_pos.y
+
+ local d = max(sqrt(x*x+y*y),0.1)
+
+ -- apply force function to distance and k (natural spring length
+ data.u = p2
+ data.v = p1
+ data.d = d
+ local e_head = fun_u(data)
+ local e_tail = fun_v(data)
+
+ -- Include time function
+ local f_head = time_factor * e_head / d
+ local f_tail = time_factor * e_tail / d
+
+ -- calculate effect on x/y
+ local g_head = x * f_head
+ local g_tail = x * f_tail
+ local h_head = y * f_head
+ local h_tail = y * f_tail
+
+ -- cap effect if necessary
+ local x_head, x_tail, y_head, y_tail
+ if cap then
+ if g_head <= 0 then
+ x_head = max(-cap, g_head)
+ else
+ x_head = min(cap, g_head)
+ end
+
+ if g_tail <= 0 then
+ x_tail = max(-cap, g_tail)
+ else
+ x_tail = min(cap, g_tail)
+ end
+
+ if h_head <= 0 then
+ y_head = max(-cap, h_head)
+ else
+ y_head = min(cap, h_head)
+ end
+
+ if h_tail <= 0 then
+ y_tail = max(-cap, h_tail)
+ else
+ y_tail = min(cap, h_tail)
+ end
+ else
+ x_head = g_head
+ x_tail = g_tail
+ y_head = h_head
+ y_tail = h_tail
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[p1]
+ c1.x = c1.x - x_tail
+ c1.y = c1.y - y_tail
+ local c2 = net_forces[p2]
+ c2.x = c2.x + x_head
+ c2.y = c2.y + y_head
+ end
+ end
+end
+
+return ForceGraphDistance \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToGrid.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToGrid.lua
new file mode 100644
index 0000000000..5f53f5da78
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToGrid.lua
@@ -0,0 +1,123 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- This is a subclass of ForceTemplate, which is used to implement forces
+-- that work on individual vertices and pulls them to a virtual grid with
+-- cells of the size determined by the user options |grid x length| and
+-- |grid y length|. The forces depend on the canvas position
+-- of the vertices relative to th next grid point. This class is e.\,g.\ used
+-- for the post-processing technique |snap to grid|.
+
+
+-- Imports
+local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate"
+local lib = require "pgf.gd.lib"
+local Preprocessing = require "pgf.gd.force.jedi.base.Preprocessing"
+
+-- Localize math functions
+local max = math.max
+local sqrt = math.sqrt
+local min = math.min
+local floor = math.floor
+local round
+function round(number)
+ return floor((number * 10 + 0.5) / 10)
+end
+
+-- Implementation starts here:
+
+local ForcePullToGrid = lib.class { base_class = ForceTemplate }
+
+function ForcePullToGrid:constructor ()
+ ForceTemplate.constructor(self)
+ self.p = {}
+end
+
+-- This force class works on individual vertices and only depends on their
+-- current position. Thus the vertex table of the current graph is simply
+-- copied to the variable |p|.
+--
+-- @param v The vertices of the graph we are trying to find a layout for.
+
+function ForcePullToGrid:preprocess(v)
+ self.p = v
+end
+
+
+-- Applying the force to the vertices and adding the effect to the passed net
+-- force array
+--
+-- @param data The parameters needed to apply the force: The options table,
+-- the current time stamp, an array containing the summed up net
+-- forces
+
+function ForcePullToGrid:applyTo(data)
+ -- locals for speed
+ local cap = self.force.cap
+ local net_forces = data.net_forces
+ local t_max = self.options["maximum time"]
+ local grid_x_distance = self.options["grid x length"]
+ local grid_y_distance = self.options["grid y length"]
+ local t_now = data.t_now
+ local p = self.p
+ local time_fun = self.force.time_fun
+ local length = 5--self.options["node distance"]
+
+ -- Evaluate time function
+ local time_factor = time_fun(t_max, t_now)
+ if time_factor == 0 then
+ return
+ end
+
+ for _, v in ipairs(p) do
+ -- dereference
+ local p1 = v.pos
+ local p2_x = round(p1.x/grid_x_distance)*grid_x_distance
+ local p2_y = round(p1.y/grid_y_distance)*grid_y_distance
+
+ -- calculate distance between vertex and grid point
+ local x = p1.x - p2_x
+ local y = p1.y - p2_y
+ local d = max(sqrt(x*x+y*y),0.1)
+ local l = -d/(length*length)
+
+ -- Include time function
+ local h = l * time_factor
+
+ -- scale effect according to direction
+ local f = x * h
+ local g = y * h
+
+ -- cap effect if necessary
+ if cap then
+ if f <= 0 then
+ x = max(-cap, f)
+ else
+ x = min(cap, f)
+ end
+
+ if g <= 0 then
+ y = max(-cap, g)
+ else
+ y = min(cap, g)
+ end
+ else
+ x = f
+ y = g
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[v]
+ c1.x = c1.x - x
+ c1.y = c1.y - y
+ end
+end
+
+return ForcePullToGrid \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToPoint.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToPoint.lua
new file mode 100644
index 0000000000..985b8eec2e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForcePullToPoint.lua
@@ -0,0 +1,119 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- This is a subclass of ForceTemplate, which is used to implement forces
+-- that work on individual vertices and pulls them to a specific point on the
+-- canvas. This point is given by the |desired at| option. The forces depend
+-- on the canvas position of the vertices relative to the canvas point it is
+-- pulled to.
+
+
+-- Imports
+local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate"
+local lib = require "pgf.gd.lib"
+local Preprocessing = require "pgf.gd.force.jedi.base.Preprocessing"
+
+-- Localize math functions
+local max = math.max
+local sqrt = math.sqrt
+local min = math.min
+
+-- Implementation starts here:
+
+local ForcePullToPoint = lib.class { base_class = ForceTemplate }
+
+function ForcePullToPoint:constructor ()
+ ForceTemplate.constructor(self)
+ self.p = {}
+end
+
+-- This force class works on individual vertices and depends on their
+-- current position as well as the point it is desired at. Thus all vertices
+-- where the |desired at| option is set are added to the table |p| together
+-- with the point where they are wanted.
+--
+-- @param v The vertices of the graph we are trying to find a layout for.
+
+function ForcePullToPoint:preprocess(v)
+ for _,vertex in ipairs(v) do
+ if vertex.options then
+ local da = vertex.options["desired at"]
+ if da then
+ self.p[vertex]= {da}
+ end
+ end
+ end
+end
+
+
+-- Applying the force to the vertices and adding the effect to the passed net
+-- force array
+--
+-- @param data The parameters needed to apply the force: The options table,
+-- the current time stamp, an array containing the summed up net
+-- forces
+
+function ForcePullToPoint:applyTo(data)
+ -- locals for speed
+ local cap = self.force.cap
+ local net_forces = data.net_forces
+ local t_max = self.options["maximum time"]
+ local t_now = data.t_now
+ local p = self.p
+ local time_fun = self.force.time_fun
+
+ -- Evaluate time function
+ local time_factor = time_fun(t_max, t_now)
+ if time_factor == 0 then
+ return
+ end
+
+ for v, point in pairs(p) do
+ -- dereference
+ local p1 = v.pos
+ local p2 = point[1]
+
+ -- calculate distance between vertex and centroid
+ local x = p1.x - p2.x
+ local y = p1.y - p2.y
+ local d = max(sqrt(x*x+y*y),0.1)
+
+ -- Include time function
+ local h = d * time_factor
+
+ -- scale effect according to direction
+ local f = x * h
+ local g = y * h
+
+ -- cap effect if necessary
+ if cap then
+ if f <= 0 then
+ x = max(-cap, f)
+ else
+ x = min(cap, f)
+ end
+
+ if g <= 0 then
+ y = max(-cap, g)
+ else
+ y = min(cap, g)
+ end
+ else
+ x = f
+ y = g
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[v]
+ c1.x = c1.x - x
+ c1.y = c1.y - y
+ end
+end
+
+return ForcePullToPoint \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/CircularInitialPositioning.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/CircularInitialPositioning.lua
new file mode 100644
index 0000000000..ab8f1fad9a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/CircularInitialPositioning.lua
@@ -0,0 +1,60 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- This class implements an initial position algorithm for graph drawing, placing the vertices on
+-- a circle with th radius given by the |radius| key
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local InitialTemplate = require "pgf.gd.force.jedi.base.InitialTemplate"
+local lib = require "pgf.gd.lib"
+
+local CircularInitialPositioning = lib.class { base_class = InitialTemplate }
+
+
+---
+declare {
+ key = "circular initial position",
+ algorithm = CircularInitialPositioning,
+ phase = "initial positioning force framework",
+ phase_default = true
+}
+
+-- Implementation starts here:
+
+function CircularInitialPositioning:constructor ()
+ InitialTemplate.constructor(self)
+end
+
+function CircularInitialPositioning:run()
+ -- locals for speed
+ local vertices = self.vertices
+ local tmp = (self.options["node pre sep"] + self.options["node post sep"]) +
+ (self.options["sibling pre sep"] + self.options["sibling post sep"])
+ local min_radius = tmp * #self.vertices/2/math.pi
+ local radius = math.max(self.options.radius, min_radius)
+ local desired_vertices = self.desired_vertices
+ -- place vertices where the |desired at | option has been set first
+ local placed, centroid_x, centroid_y = InitialTemplate:desired(desired_vertices)
+ local angle = 2*math.pi / #vertices
+ local a = angle
+ local sin = math.sin
+ local cos = math.cos
+
+ for _, vertex in ipairs(vertices) do
+ -- place all other vertices with respect to the one already placed
+ if placed[vertex] == nil then
+ local p = vertex.pos
+ p.x = sin(a) * radius + centroid_x
+ p.y = cos(a) * radius + centroid_y
+ a = a + angle
+ end
+ end
+end
+
+
+return CircularInitialPositioning \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/GridInitialPositioning.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/GridInitialPositioning.lua
new file mode 100644
index 0000000000..2b131e8ad9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/GridInitialPositioning.lua
@@ -0,0 +1,60 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- This class implements an initial position algorithm for graph drawing,
+-- placing the vertices on a grid with square cells with width |node distance|
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local InitialTemplate = require "pgf.gd.force.jedi.base.InitialTemplate"
+local lib = require "pgf.gd.lib"
+
+local GridInitialPositioning = lib.class { base_class = InitialTemplate }
+
+
+---
+declare {
+ key = "grid initial position",
+ algorithm = GridInitialPositioning,
+ phase = "initial positioning force framework",
+}
+
+-- Implementation starts here:
+
+function GridInitialPositioning:constructor ()
+ InitialTemplate.constructor(self)
+end
+
+function GridInitialPositioning:run()
+ -- locals for speed
+ local vertices = self.vertices
+ local dist = self.options["node distance"]
+ local desired_vertices = self.desired_vertices
+ -- place vertices where the |desired at | option has been set first
+ local placed, centroid_x, centroid_y = InitialTemplate:desired(desired_vertices)
+ local n = math.ceil(math.sqrt(#vertices))
+ local x = -dist
+ local y = 0
+
+ for i, vertex in ipairs(vertices) do
+ -- place all other vertices with respect to the one already placed
+ if placed[vertex] == nil then
+ if i <= (y/dist+1)*n then
+ x = x + dist
+ else
+ x = 0
+ y = y + dist
+ end
+ local p = vertex.pos
+ p.x = x + centroid_x
+ p.y = y + centroid_y
+ end
+ end
+end
+
+
+return GridInitialPositioning \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/RandomInitialPositioning.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/RandomInitialPositioning.lua
new file mode 100644
index 0000000000..ce3a40582c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/initialpositioning/RandomInitialPositioning.lua
@@ -0,0 +1,49 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- This class implements an initial position algorithm for graph drawing,
+-- placing the vertices at random positions.
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+local InitialTemplate = require "pgf.gd.force.jedi.base.InitialTemplate"
+local lib = require "pgf.gd.lib"
+
+local RandomInitialPositioning = lib.class { base_class = InitialTemplate }
+
+---
+declare {
+ key = "random initial position",
+ algorithm = RandomInitialPositioning,
+ phase = "initial positioning force framework"
+}
+
+-- Implementation starts here:
+
+function RandomInitialPositioning:constructor ()
+ InitialTemplate.constructor(self)
+end
+
+function RandomInitialPositioning:run()
+ -- locals for speed
+ local random = lib.random
+ local vertices = self.vertices
+ local desired_vertices = self.desired_vertices
+ -- place vertices where the |desired at | option has been set first
+ local placed, centroid_x, centroid_y = InitialTemplate:desired(desired_vertices)
+
+ for _, vertex in ipairs(vertices) do
+ -- place all other vertices with respect to the one already placed
+ if placed[vertex] == nil then
+ p = vertex.pos
+ p.x = 100 * random() + centroid_x
+ p.y = 100 * random() + centroid_y
+ end
+ end
+end
+
+return RandomInitialPositioning
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/library.lua
new file mode 100644
index 0000000000..5d5554ce35
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/library.lua
@@ -0,0 +1,115 @@
+-- Copyright 2014 by Ida Bruhns
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+
+--- The library providing the graph drawing framework Jedi
+-- This library requires all graph drawing algorithms and initial
+-- positioning algorithms provided with the first release of Jedi.
+-- It also defines the mass key attached to all vertices.
+
+-- Library name
+local jedi
+
+-- require initial positioning algorithms
+require "pgf.gd.force.jedi.initialpositioning.CircularInitialPositioning"
+require "pgf.gd.force.jedi.initialpositioning.RandomInitialPositioning"
+require "pgf.gd.force.jedi.initialpositioning.GridInitialPositioning"
+
+-- require graph drawing algorithms
+require "pgf.gd.force.jedi.algorithms.FruchtermanReingold"
+require "pgf.gd.force.jedi.algorithms.HuSpringElectricalFW"
+require "pgf.gd.force.jedi.algorithms.SimpleSpring"
+require "pgf.gd.force.jedi.algorithms.SocialGravityCloseness"
+require "pgf.gd.force.jedi.algorithms.SocialGravityDegree"
+
+
+-- define parameter
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+---
+declare {
+ key = "maximum displacement per step",
+ type = "length",
+ initial = "100",
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "global speed factor",
+ type = "length",
+ initial = "1",
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "maximum time",
+ type = "number",
+ initial = "50",
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "find equilibrium",
+ type = "boolean",
+ initial = true,
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "equilibrium threshold",
+ type = "number",
+ initial = "3",
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "grid x length",
+ type = "length",
+ initial = "10pt",
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "grid y length",
+ type = "length",
+ initial = "10pt",
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "snap to grid",
+ type = "boolean",
+ initial = false,
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "mass",
+ type = "number",
+ initial = "1",
+
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
+
+---
+declare {
+ key = "coarsening weight",
+ type = "number",
+ initial = "1",
+
+ documentation_in = "pgf.gd.force.jedi.doc"
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/library.lua
new file mode 100644
index 0000000000..acfda34ffc
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/library.lua
@@ -0,0 +1,126 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- Nature creates beautiful graph layouts all the time. Consider a
+-- spider's web: Nodes are connected by edges in a visually most pleasing
+-- manner (if you ignore the spider in the middle). The layout of a
+-- spider's web is created just by the physical forces exerted by the
+-- threads. The idea behind force-based graph drawing algorithms is to
+-- mimic nature: We treat edges as threads that exert forces and simulate
+-- into which configuration the whole graph is ``pulled'' by these
+-- forces.
+--
+-- When you start thinking about for a moment, it turns out that there
+-- are endless variations of the force model. All of these models have
+-- the following in common, however:
+-- %
+-- \begin{itemize}
+-- \item ``Forces'' pull and push at the nodes in different directions.
+-- \item The effect of these forces is simulated by iteratively moving
+-- all the nodes simultaneously a little in the direction of the forces
+-- and by then recalculating the forces.
+-- \item The iteration is stopped either after a certain number of
+-- iterations or when a \emph{global energy minimum} is reached (a very
+-- scientific way of saying that nothing happens anymore).
+-- \end{itemize}
+--
+-- The main difference between the different force-based approaches is
+-- how the forces are determined. Here are some ideas what could cause a
+-- force to be exerted between two nodes (and there are more):
+-- %
+-- \begin{itemize}
+-- \item If the nodes are connected by an edge, one can treat the edge as
+-- a ``spring'' that has a ``natural spring dimension''. If the nodes
+-- are nearer than the spring dimension, they are push apart; if they
+-- are farther aways than the spring dimension, they are pulled together.
+-- \item If two nodes are connected by a path of a certain length, the
+-- nodes may ``wish to be at a distance proportional to the path
+-- length''. If they are nearer, they are pushed apart; if they are
+-- farther, they are pulled together. (This is obviously a
+-- generalization of the previous idea.)
+-- \item There may be a general force field that pushes nodes apart (an
+-- electrical field), so that nodes do not tend to ``cluster''.
+-- \item There may be a general force field that pulls nodes together (a
+-- gravitational field), so that nodes are not too loosely scattered.
+-- \item There may be highly nonlinear forces depending on the distance of
+-- nodes, so that nodes very near to each get pushed apart strongly,
+-- but the effect wears of rapidly at a distance. (Such forces are
+-- known as strong nuclear forces.)
+-- \item There rotational forces caused by the angles between the edges
+-- leaving a node. Such forces try to create a \emph{perfect angular
+-- resolution} (a very scientific way of saying that all angles
+-- at a node are equal).
+-- \end{itemize}
+--
+-- Force-based algorithms combine one or more of the above ideas into a
+-- single algorithm that uses ``good'' formulas for computing the
+-- forces.
+--
+-- Currently, three algorithms are implemented in this library, two of
+-- which are from the first of the following paper, while the third is
+-- from the third paper:
+-- %
+-- \begin{itemize}
+-- \item
+-- Y. Hu.
+-- \newblock Efficient, high-quality force-directed graph drawing.
+-- \newblock \emph{The Mathematica Journal}, 2006.
+-- \item
+-- C. Walshaw.
+-- \newblock A multilevel algorithm for force-directed graph
+-- drawing.
+-- \newblock In J. Marks, editor, \emph{Graph Drawing}, Lecture Notes in
+-- Computer Science, 1984:31--55, 2001.
+-- \end{itemize}
+--
+-- Our implementation is described in detail in the following
+-- diploma thesis:
+-- %
+-- \begin{itemize}
+-- \item
+-- Jannis Pohlmann,
+-- \newblock \emph{Configurable Graph Drawing Algorithms
+-- for the \tikzname\ Graphics Description Language,}
+-- \newblock Diploma Thesis,
+-- \newblock Institute of Theoretical Computer Science, Universit\"at
+-- zu L\"ubeck, 2011.\\[.5em]
+-- \newblock Online at
+-- \url{http://www.tcs.uni-luebeck.de/downloads/papers/2011/}\\ \url{2011-configurable-graph-drawing-algorithms-jannis-pohlmann.pdf}
+-- \end{itemize}
+--
+-- In the future, I hope that most, if not all, of the force-based
+-- algorithms become ``just configuration options'' of a general
+-- force-based algorithm similar to the way the modular Sugiyama method
+-- is implemented in the |layered| graph drawing library.
+--
+-- @library
+
+local force -- Library name
+
+-- Load declarations from:
+require "pgf.gd.force.ControlDeclare"
+require "pgf.gd.force.ControlStart"
+require "pgf.gd.force.ControlIteration"
+require "pgf.gd.force.ControlSprings"
+require "pgf.gd.force.ControlElectric"
+require "pgf.gd.force.ControlCoarsening"
+
+require "pgf.gd.force.SpringLayouts"
+require "pgf.gd.force.SpringElectricalLayouts"
+
+-- Load algorithms from:
+require "pgf.gd.force.SpringHu2006"
+require "pgf.gd.force.SpringElectricalHu2006"
+require "pgf.gd.force.SpringElectricalWalshaw2000"
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface.lua
new file mode 100644
index 0000000000..df2649521b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface.lua
@@ -0,0 +1,26 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+-- Imports
+
+require "pgf"
+require "pgf.gd"
+
+
+-- Declare namespace
+pgf.gd.interface = {}
+
+
+-- Done
+
+return pgf.gd.interface \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua
new file mode 100644
index 0000000000..8473eb3f10
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua
@@ -0,0 +1,191 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This class provides the core functionality of the interface between
+-- all the different layers (display layer, binding layer, and
+-- algorithm layer). The two classes |InterfaceToAlgorithms| and
+-- |InterfaceToDisplay| use, in particular, the data structures
+-- provided by this class.
+--
+-- @field binding This field stores the ``binding''. The graph drawing
+-- system is ``bound'' to the display layer through such a binding (a
+-- subclass of |Binding|). Such a binding can be thought of as a
+-- ``driver'' in operating systems terminology: It is a small set of
+-- functions needed to adapt the functionality to one specific display
+-- system. Note that the whole graph drawing scope is bound to exactly
+-- one display layer; to use several bindings you need to setup a
+-- completely new Lua instance.
+--
+-- @field scopes This is a stack of graph drawing scopes. All
+-- interface methods refer to the top of this stack.
+--
+-- @field collection_kinds This table stores which collection kinds
+-- have been defined together with their properties.
+--
+-- @field algorithm_classes A table that maps algorithm keys (like
+-- |tree layout| to class objects).
+--
+-- @field keys A lookup table of all declared keys. Each entry of this
+-- table consists of the original entry passed to the |declare|
+-- method. Each of these tables is both index at a number (so you can
+-- iterate over it using |ipairs|) and also via the key's name.
+
+local InterfaceCore = {
+ -- The main binding. Set by |InterfaceToDisplay.bind| method.
+ binding = nil,
+
+ -- The stack of Scope objects.
+ scopes = {},
+
+ -- The collection kinds.
+ collection_kinds = {},
+
+ -- The algorithm classes
+ algorithm_classes = {},
+
+ -- The declared keys
+ keys = {},
+
+ -- The phase kinds
+ phase_kinds = {},
+
+ -- Internals for handling the options stack
+ option_stack = {},
+ option_cache_height = nil,
+ option_initial = {
+ algorithm_phases = {
+ ["preprocessing stack"] = {},
+ ["edge routing stack"] = {},
+ ["postprocessing stack"] = {},
+ }
+ },
+ option_aliases = {
+ [{}] = true -- Remove, once Lua Link Bug is fixed
+ },
+
+ -- Constant strings for special collection kinds.
+ sublayout_kind = "INTERNAL_sublayout_kind",
+ subgraph_node_kind = "INTERNAL_subgraph_node_kind",
+}
+
+-- Namespace
+require("pgf.gd.interface").InterfaceCore = InterfaceCore
+
+
+InterfaceCore.option_initial.__index = InterfaceCore.option_initial
+InterfaceCore.option_initial.algorithm_phases.__index = InterfaceCore.option_initial.algorithm_phases
+
+
+-- Imports
+local Coordinate = require "pgf.gd.model.Coordinate"
+
+
+--- Returns the top scope
+--
+-- @return The current top scope, which is the scope in which
+-- everything should happen right now.
+
+function InterfaceCore.topScope()
+ return assert(InterfaceCore.scopes[#InterfaceCore.scopes], "no graph drawing scope open")
+end
+
+
+
+local factors = {
+ cm=28.45274,
+ mm=2.84526,
+ pt=1.0,
+ bp=1.00374,
+ sp=0.00002,
+ pc=12.0,
+ em=10,
+ ex=4.30554,
+ ["in"]=72.27,
+ dd=1.07,
+ cc=12.8401,
+ [""]=1,
+}
+
+local time_factors = {
+ s=1,
+ ms=0.001,
+ min=60,
+ h=3600
+}
+
+local directions = {
+ down = -90,
+ up = 90,
+ left = 180,
+ right = 0,
+ south = -90,
+ north = 90,
+ west = 180,
+ east = 0,
+ ["north east"] = 45,
+ ["north west"] = 135,
+ ["south east"] = -45,
+ ["south west"] = -135,
+ ["-"] = 0,
+ ["|"] = -90,
+}
+
+---
+-- Converts parameters types. This method is used by both the
+-- algorithm layer as well as the display layer to convert strings
+-- into the different types of parameters. When a parameter
+-- is pushed onto the option stack, you can either provide a value of
+-- the parameter's type; but you can also provide a string. This
+-- string can then be converted by this function to a value of the
+-- correct type.
+--
+-- @param s A parameter value or a string.
+-- @param t The type of the parameter
+--
+-- @return If |s| is not a string, it is just returned. If it is a
+-- string, it is converted to the type |t|.
+
+function InterfaceCore.convert(s,t)
+ if type(s) ~= "string" then
+ return s
+ elseif t == "number" then
+ return tonumber(s)
+ elseif t == "length" then
+ local num, dim = string.match(s, "([%d.]+)(.*)")
+ return tonumber(num) * assert(factors[dim], "unknown unit")
+ elseif t == "time" then
+ local num, dim = string.match(s, "([%d.]+)(.*)")
+ return tonumber(num) * assert(time_factors[dim], "unknown time unit")
+ elseif t == "string" then
+ return s
+ elseif t == "canvas coordinate" or t == "coordinate" then
+ local x, y = string.match(s,"%(([%d.]+)pt,([%d.]+)pt%)")
+ return Coordinate.new(tonumber(x),tonumber(y))
+ elseif t == "boolean" then
+ return s == "true"
+ elseif t == "raw" then
+ return loadstring(s)()
+ elseif t == "direction" then
+ return directions[s] or tonumber(s)
+ elseif t == "nil" or t == nil then
+ return nil
+ else
+ error ("unknown parameter type")
+ end
+end
+
+
+-- Done
+
+return InterfaceCore
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua
new file mode 100644
index 0000000000..1187fbc313
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua
@@ -0,0 +1,968 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This class provides the interface between the graph drawing system
+-- and algorithms. Another class, |InterfaceToDisplay|, binds the
+-- display layers (like \tikzname\ or a graph drawing editor) to the
+-- graph drawing system ``from the other side''.
+--
+-- The functions declared here can be used by algorithms to
+-- communicate with the graph drawing system, which will usually
+-- forward the ``requests'' of the algorithms to the display layers in
+-- some way. For instance, when you declare a new parameter, this
+-- parameter will become available on the display layer.
+
+local InterfaceToAlgorithms = {}
+
+-- Namespace
+require("pgf.gd.interface").InterfaceToAlgorithms = InterfaceToAlgorithms
+
+
+-- Imports
+local InterfaceCore = require "pgf.gd.interface.InterfaceCore"
+local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay"
+local InterfaceToC = require "pgf.gd.interface.InterfaceToC"
+
+local LookupTable = require "pgf.gd.lib.LookupTable"
+local LayoutPipeline = require "pgf.gd.control.LayoutPipeline"
+
+local Edge = require "pgf.gd.model.Edge"
+
+local lib = require "pgf.gd.lib"
+
+local doc = require "pgf.gd.doc"
+
+-- Forwards
+
+local declare_handlers
+
+
+
+
+---
+-- Adds a handler for the |declare| function. The |declare|
+-- command is just a ``dispatcher'' to one of many possible
+-- declaration functions. Which function is used, depends on which
+-- fields are present in the table passed to |declare|. For each
+-- registered handler, we call the |test| function. If it returns
+-- neither |nil| nor |false|, the |handler| field of this handler is
+-- called. If it returns |true|, the handler immediately
+-- finishes. Otherwise, the next handler is tried.
+
+function InterfaceToAlgorithms.addHandler(test, handler)
+ table.insert(declare_handlers, 1, { test = test, handler = handler })
+end
+
+
+
+-- Local stuff
+
+local key_metatable = {}
+
+---
+-- This function is the ``work-horse'' for declaring things. It allows
+-- you to specify on the algorithmic layer that a key ``is available''
+-- for use on the display layer. There is just one function for
+-- handling all declarations in order to make the declarations
+-- easy-to-use since you just need to import a single function:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+--\end{codeexample}
+--
+-- You can now use |declare| it as follows: You pass it a table
+-- containing information about the to-be-declared key. The table
+-- \emph{must} have a field |key| whose value is unique and must be a
+-- string. If the value of |key| is, say, |"foo"|, the
+-- parameter can be set on the display layer such as, say, the
+-- \tikzname\ layer, using |/graph drawing/foo|. Here is a typical
+-- example of how a declaration is done:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- ---
+-- declare {
+-- key = "electrical charge",
+-- type = "number",
+-- initial = "1.0",
+--
+-- summary = "The ``electrical charge'' is a property...",
+-- documentation = [[...]],
+-- examples = [[...]]
+-- }
+--\end{codeexample}
+--
+-- \medskip\noindent\textbf{Inlining Documentation.}
+-- The three keys |summary|, |documentation| and |examples| are
+-- intended for the display layer to give the users information about
+-- what the key does. The |summary| should be a string that succinctly
+-- describes the option. This text will typically be displayed for
+-- instance as a ``tool tip'' or in an option overview. The
+-- |documentation| optionally provides more information and should be
+-- typeset using \TeX. The |examples| can either be a single string or
+-- an array of strings. Each should be a \tikzname\ example
+-- demonstrating how the key is used.
+--
+-- Note that you can take advantage of the Lua syntax of enclosing
+-- very long multi-line strings in |[[| and |]]|. As a bonus, if the
+-- summary, documentation, or an example starts and ends with a quote,
+-- these two quotes will be stripped. This allows you to enclose the
+-- whole multi-line string (additionally) in quotes, leading to better
+-- syntax highlighting in editors.
+--
+-- \medskip\noindent\textbf{External Documentation.}
+-- It is sometimes more desirable to put the documentation of a key
+-- into an external file. First, this makes the code leaner and, thus,
+-- faster to read (both for humans and for computers). Second, for C
+-- code, it is quite inconvenient to have long strings inside a C
+-- file. In such cases, you can use the |documentation_in| field:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- ---
+-- declare {
+-- key = "electrical charge",
+-- type = "number",
+-- initial = "1.0",
+-- documentation_in = "some_filename"
+-- }
+--\end{codeexample}
+--
+-- The |some_filename| must be the name of a Lua file that will be
+-- read ``on demand'', that is, whenever someone tries to access the
+-- documentation, summary, or examples field of the key, this file
+-- will be loaded using |require|. The file should then use
+-- |pgf.gd.doc| to install the missing information in the keys.
+--
+-- \medskip\noindent\textbf{The Use Field.}
+-- When you declare a key, you can provide a |use| field. If present,
+-- you must set it to an array of small tables which have two fields:
+-- %
+-- \begin{itemize}
+-- \item |key| This is the name of another key or a function.
+-- \item |value| This is either a value (like a string or a number) or
+-- a function or |nil|.
+-- \end{itemize}
+--
+-- Here is an example:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- ---
+-- declare {
+-- key = "binary tree layout",
+-- use = {
+-- { key = "minimum number of children", value = 2 },
+-- { key = "significant sep", value = 12 },
+-- { key = "tree layout" }
+-- },
+-- summary = "The |binary tree layout| places node...",
+-- documentation = ...,
+-- examples = ...,
+-- }
+--\end{codeexample}
+--
+-- The effect of a |use| field is the following: Whenever the key is
+-- encountered on the option stack, the key is first handled
+-- normally. Then, we iterate over all elements of the |use|
+-- array. For each element, we perform the action as if the |key| of
+-- the array had been set explicitly to the value given by the |value|
+-- field. If the |value| is a function, we pass a different value to
+-- the key, namely the result of applying the function to the value
+-- originally passed to the original key. Here is a typical example:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- ---
+-- declare {
+-- key = "level sep",
+-- type = "length",
+-- use = {
+-- { key = "level pre sep", value = function (v) return v/2 end },
+-- { key = "level post sep", value = function (v) return v/2 end }
+-- },
+-- summary = "..."
+-- }
+--\end{codeexample}
+--
+-- Just like the value, the key itself can also be a function. In this
+-- case, the to-be-used key is also computed by applying the function
+-- to the value passed to the original key.
+--
+-- As mentioned at the beginning, |declare| is a work-horse that will call
+-- different internal functions depending on whether you declare a
+-- parameter key or a new algorithm or a collection kind. Which kind
+-- of declaration is being done is detected by the presence of certain
+-- fields in the table passed to |t|. The different kind of
+-- possible declarations are documented in the |declare_...|
+-- functions. Note that these functions are internal and cannot be
+-- called from outside; you must use the |declare| function.
+--
+-- @param t A table contain the field |key| and other fields as
+-- described.
+
+function InterfaceToAlgorithms.declare (t)
+ local keys = InterfaceCore.keys
+
+ -- Sanity check:
+ assert (type(t.key) == "string" and t.key ~= "", "parameter key may not be the empty string")
+ if keys[t.key] or t.keys == "algorithm_phases" then
+ error("parameter '" .. t.key .. "' already declared")
+ end
+
+ for _,h in ipairs (declare_handlers) do
+ if h.test(t) then
+ if h.handler(t) then
+ break
+ end
+ end
+ end
+
+ -- Attach metatable:
+ setmetatable (t, key_metatable)
+
+ -- Set!
+ keys[t.key] = t
+ keys[#keys + 1] = t
+end
+
+
+function key_metatable.__index (key_table, what)
+ if what == "documentation" or what == "summary" or what == "examples" then
+ local doc = rawget(key_table,"documentation_in")
+ if doc then
+ require (doc)
+ return rawget(key_table, what)
+ end
+ end
+end
+
+
+
+---
+-- This function is called by |declare| for ``normal parameter keys'',
+-- which are all keys for which no special field like |algorithm| or
+-- |layer| is declared. You write
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- ---
+-- declare {
+-- key = "electrical charge",
+-- type = "number",
+-- initial = "1.0",
+--
+-- summary = "The ``electrical charge'' is a property...",
+-- documentation = [[...]],
+-- examples = [[...]]
+-- }
+--\end{codeexample}
+--
+-- When an author writes |my node[electrical charge=5-3]| in the
+-- description of her graph, the object |vertex| corresponding to the
+-- node |my node| will have a field |options| attached to it with
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--vertex.options["electrical charge"] == 2
+--\end{codeexample}
+--
+-- The |type| field does not refer to Lua types. Rather, these types are
+-- sensible types for graph drawing and they are mapped by the higher
+-- layers to Lua types. In detail, the following types are available:
+-- %
+-- \begin{itemize}
+-- \item |number| A dimensionless number. Will be mapped to a normal
+-- Lua |number|. So, when the author writes |foo=5*2|, the |foo| key
+-- of the |options| field of the corresponding object will be set to
+-- |10.0|.
+-- \item |length| A ``dimension'' in the sense of \TeX\ (a number with
+-- a dimension like |cm| attached to it). It is the job of the display
+-- layer to map this to a number in ``\TeX\ points'', that is, to a
+-- multiple of $1/72.27$th of an inch.
+-- \item |time| A ``time'' in the sense of |\pgfparsetime|. Examples
+-- are |6s| or |0.1min| or |6000ms|, all of which will map to |6|.
+-- \item |string| Some text. Will be mapped to a Lua |string|.
+-- \item |canvas coordinate| A position on the canvas. Will be mapped
+-- to a |model.Coordinate|.
+-- \item |boolean| A Boolean value.
+-- \item |raw| Some to-be-executed Lua text.
+-- \item |direction| Normally, an angle; however,
+-- the special values of |down|, |up|, |left|, |right| as well as the
+-- directions |north|, |north west|, and so on are also legal on the
+-- display layer. All of them will be mapped to a number. Furthermore,
+-- a vertical bar (\verb!|!) will be mapped to |-90| and a minus sign
+-- (|-|) will be mapped to |0|.
+-- \item |hidden| A key of this type ``cannot be set'', that is,
+-- users cannot set this key at all. However algorithms can still read
+-- this key and, through the use of |alias|, can use the key as a
+-- handle to another key.
+-- \item |user value| The key stores a Lua user value (userdata). Such
+-- keys can only be set from C since user values cannot be created in
+-- Lua (let alone in \tikzname).
+-- \end{itemize}
+--
+-- If the |type| field is missing, it is automatically set to
+-- |"string"|.
+--
+-- A parameter can have an |initial| value. This value will be used
+-- whenever the parameter has not been set explicitly for an object.
+--
+-- A parameter can have a |default| value. This value will be used as
+-- the parameter value whenever the parameter is explicitly set, but
+-- no value is provided. For a key of type |"boolean"|, if no
+-- |default| is provided, |"true"| will be used automatically.
+--
+-- A parameter can have an |alias| field. This field must be set to
+-- the name of another key or to a function. Whenever you access the
+-- current key and this key is not set, the |alias| key is tried
+-- instead. If it is set, its value will be returned (if the |alias|
+-- key has itself an alias set, this is tried recursively). If the
+-- alias is not set either and neither does it have an initial value,
+-- the |initial| value is used. Note that in case the alias has its
+-- |initial| field set, the |initial| value of the current key will
+-- never be used.
+--
+-- The main purpose of the current key is to allow algorithms to
+-- introduce their own terminology for keys while still having access
+-- to the standard keys. For instance, the |OptimalHierarchyLayout|
+-- class uses the name |layerDistance| for what would be called
+-- |level distance| in the rest of the graph drawing system. In this
+-- case, we can declare the |layerDistance| key as follows:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- declare {
+-- key = "layerDistance",
+-- type = "length",
+-- alias = "level distance"
+-- }
+--\end{codeexample}
+--
+-- Inside the algorithm, we can write |...options.layerDistance| and
+-- will get the current value of the |level distance| unless the
+-- |layerDistance| has been set explicitly. Indeed, we might set the
+-- |type| to |hidden| to ensure that \emph{only} the |level distance|
+-- can and must set to set the layerDistance.
+--
+-- Note that there is a difference between |alias| and the |use|
+-- field: Suppose we write
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- declare {
+-- key = "layerDistance",
+-- type = "length",
+-- use = {
+-- { key = "level distance", value = lib.id }
+-- }
+-- }
+--\end{codeexample}
+--
+-- Here, when you say |layerDistance=1cm|, the |level distance| itself
+-- will be modified. When the |level distance| is set, however, the
+-- |layerDistance| will not be modified.
+--
+-- If the alias is a function, it will be called with the option table
+-- as its parameter. You can thus say things like
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- declare {
+-- key = "layerDistance",
+-- type = "length",
+-- alias = function (option)
+-- return option["layer pre dist"] + option["layer post dist"]
+-- end
+-- }
+--\end{codeexample}
+--
+-- As a special courtesy to C code, you can also set the key
+-- |alias_function_string|, which allows you to put the function into
+-- a string that is read using |loadstring|.
+--
+-- (You cannot call this function directly, it is included for
+-- documentation purposes only.)
+--
+-- @param t The table originally passed to |declare|.
+
+local function declare_parameter (t)
+
+ t.type = t.type or "string"
+
+ if t.type == "boolean" and t.default == nil then
+ t.default = true
+ end
+
+ -- Normal key
+ assert (type(t.type) == "string", "key type must be a string")
+
+ -- Declare via the hub:
+ if t.type ~= "hidden" then
+ InterfaceCore.binding:declareCallback(t)
+
+ -- Handle initials:
+ if t.initial then
+ InterfaceCore.option_initial[t.key] = InterfaceCore.convert(t.initial, t.type)
+ end
+ end
+
+ if t.alias_function_string and not t.alias then
+ local count = 0
+ t.alias = load (
+ function ()
+ count = count + 1
+ if count == 1 then
+ return "return "
+ elseif count == 2 then
+ return t.alias_function_string
+ else
+ return nil
+ end
+ end)()
+ end
+
+ if t.alias then
+ assert (type(t.alias) == "string" or type(t.alias == "function"), "alias must be a string or a function")
+ InterfaceCore.option_aliases[t.key] = t.alias
+ end
+
+ return true
+end
+
+
+
+
+---
+-- This function is called by |declare| for ``algorithm
+-- keys''. These keys are normally used without a value as in just
+-- |\graph[tree layout]|, but you can optionally pass a value to
+-- them. In this case, this value must be the name of a \emph{phase}
+-- and the algorithm of this phase will be set (and not the
+-- default phase of the key), see the description of phases below for
+-- details.
+--
+-- Algorithm keys are detected by the presence of the field |algorithm|
+-- in the table |t| passed to |declare|. Here is an example of how it
+-- is used:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- local ReingoldTilford1981 = {}
+--
+-- ---
+-- declare {
+-- key = "tree layout",
+-- algorithm = ReingoldTilford1981,
+--
+-- preconditions = {
+-- connected = true,
+-- tree = true
+-- },
+--
+-- postconditions = {
+-- upward_oriented = true
+-- },
+--
+-- summary = "The Reingold--Tilford method is...",
+-- documentation = ...,
+-- examples = ...,
+-- }
+--
+-- function ReingoldTilford1981:run()
+-- ...
+-- end
+--\end{codeexample}
+--
+-- The |algorithm| field expects either a table or a string as
+-- value. If you provide a string, then |require| will be applied to
+-- this string to obtain the table; however, this will happen only
+-- when the key is actually used for the first time. This means that
+-- you can declare (numerous) algorithms in a library without these
+-- algorithms actually being loaded until they are needed.
+--
+-- Independently of how the table is obtained, it will be ``upgraded''
+-- to a class by setting its |__index| field and installing a static
+-- |new| function (which takes a table of initial values as
+-- argument). Both these settings will only be done if they have not
+-- yet been performed.
+--
+-- Next, you can specify the fields |preconditions| and
+-- |postconditions|. The preconditions are a table that tell the graph
+-- drawing engine what kind of graphs your algorithm expects. If the
+-- input graph is not of this kind, it will be automatically
+-- transformed to meet this condition. Similarly, the postconditions
+-- tell the engine about properties of your graph after the algorithm
+-- has run. Again, additional transformations may be performed.
+--
+-- You can also specify the field |phase|. This tells the graph
+-- drawing engine which ``phase'' of the graph drawing process your
+-- option applies to. Each time you select an algorithm later on
+-- through use of the algorithm's key, the algorithm for this phase
+-- will be set; algorithms of other phases will not be changed.
+-- For instance, when an algorithm is part of the spanning tree
+-- computation, its phase will be |"spanning tree computation"| and
+-- using its key does not change the main algorithm, but only the
+-- algorithm used during the computation of a spanning tree for the
+-- current graph (in case this is needed by the main algorithm). In
+-- case the |phase| field is missing, the phase |main| is used. Thus,
+-- when no phase field is given, the key will change the main
+-- algorithm used to draw the graph.
+--
+-- Later on, the algorithm set for the current phase can be accessed
+-- through the special |algorithm_phases| field of |options|
+-- tables. The |algorithm_phases| table will contain two fields for each
+-- phase for which some algorithm has been set: One field is the name
+-- of the phase and its value will be the most recently set algorithm
+-- (class) set for this phase. The other field is the name of the
+-- phase followed by |" stack"|. It will contain an array of all
+-- algorithm classes that have been set for this key with the most
+-- recently at the end.
+--
+-- The following example shows the declaration of an algorithm that is
+-- the default for the phase |"spanning tree computation"|:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- ---
+-- declare {
+-- key = "breadth first spanning tree",
+-- algorithm = {
+-- run =
+-- function (self)
+-- return SpanningTreeComputation.computeSpanningTree(self.ugraph, false, self.events)
+-- end
+-- },
+-- phase = "spanning tree computation",
+-- phase_default = true,
+-- summary = ...
+-- }
+--\end{codeexample}
+--
+-- The algorithm is called as follows during a run of the main
+-- algorithms:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- local graph = ... -- the graph object
+-- local spanning_algorithm_class = graph.options.algorithm_phases["spanning tree computation"]
+-- local spanning_algorithm =
+-- spanning_algorithm_class.new{
+-- ugraph = ugraph,
+-- events = scope.events
+-- }
+-- local spanning_tree = spanning_algorithm:run()
+--\end{codeexample}
+--
+-- If you set the |phase_default| field of |t| to |true|, the algorithm will
+-- be installed as the default algorithm for the phase. This can be
+-- done only once per phase. Furthermore, for such a default algorithm
+-- the |algorithm| key must be table, it may not be a string (in other
+-- words, all default algorithms are loaded immediately). Accessing
+-- the |algorithm_phases| table for a phase for which no algorithm has
+-- been set will result in the default algorithm and the phase stack
+-- will also contain this algorithm; otherwise the phase stack will be empty.
+--
+-- (You cannot call this function directly, it is included for
+-- documentation purposes only.)
+--
+-- @param t The table originally passed to |declare|.
+
+local function declare_algorithm (t)
+ -- Algorithm declaration!
+ assert(type(t.algorithm) == "table" or type(t.algorithm) == "string")
+
+ t.phase = t.phase or "main"
+
+ local function make_class ()
+ local class
+
+ if type(t.algorithm) == "table" then
+ class = lib.class(t.algorithm)
+ else
+ class = lib.class(require(t.algorithm))
+ end
+
+ -- Now, save pre- and postconditions
+ class.preconditions = t.preconditions or {}
+ class.postconditions = t.postconditions or {}
+
+ -- Save phase
+ class.phase = t.phase
+
+ -- Compatibility
+ class.old_graph_model = t.old_graph_model
+
+ return class
+ end
+
+ -- Store this:
+ local store_me
+ if type(t.algorithm) == "table" then
+ store_me = make_class()
+ else
+ store_me = make_class
+ end
+
+ -- Save in the algorithm_classes table:
+ InterfaceCore.algorithm_classes[t.key] = store_me
+
+ assert(t.type == nil, "type may not be set for an algorithm key")
+ t.type = "string"
+
+ -- Install!
+ InterfaceCore.binding:declareCallback(t)
+
+ if t.phase_default then
+ assert (not InterfaceCore.option_initial.algorithm_phases[t.phase],
+ "default algorithm for phase already set")
+ assert (type(store_me) == "table",
+ "default algorithms must be loaded immediately")
+ InterfaceCore.option_initial.algorithm_phases[t.phase] = store_me
+ InterfaceCore.option_initial.algorithm_phases[t.phase .. " stack"] = { store_me }
+ else
+ InterfaceCore.option_initial.algorithm_phases[t.phase .. " stack"] = {
+ dummy = true -- Remove once Lua Link Bug is fixed
+ }
+ end
+
+ return true
+end
+
+
+
+
+---
+-- This function is called by |declare| for ``collection kinds''. They
+-- are detected by the presence of the field |layer|
+-- in the table |t| passed to |declare|. See the class |Collection|
+-- for details on what a collection and a collection kind is.
+--
+-- The |key| field of the table |t| passed to this function is both
+-- the name of the to-be-declared collection kind as well as the key
+-- that is used on the display layer to indicate that a node or edge
+-- belongs to a collection.
+--
+-- \medskip
+-- \noindent\textbf{The Display Layer.}
+-- Let us first have a look at what happens on the display layer:
+-- A key |t.key| is setup on the display layer that, when used inside
+-- a graph drawing scope, starts a new collection of the specified
+-- kind. ``Starts'' means that all nodes and edges mentioned in the
+-- rest of the current option scope will belong to a new collection
+-- of kind |t.key|.
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--declare { key = "hyper", layer = 1 }
+--\end{codeexample}
+-- %
+-- you can say on the \tikzname\ layer
+-- %
+--\begin{codeexample}[code only]
+-- \graph {
+-- a, b, c, d;
+-- { [hyper] a, b, c }
+-- { [hyper] b, c, d }
+-- };
+--\end{codeexample}
+--
+-- In this case, the nodes |a|, |b|, |c| will belong to a collection of
+-- kind |hyper|. The nodes |b|, |c|, and |d| will (also) belong to
+-- another collection of the same kind |hyper|. You can nest
+-- collections; in this case, nodes will belong to several
+-- collections.
+--
+-- The effect of declaring a collection kind on the algorithm layer
+-- it, first of all, that |scope.collections| will have a field named
+-- by the collection kind. This field will store an array that
+-- contains all collections that were declared as part of the
+-- graph. For instance, |collections.hyper| will contain all
+-- hyperedges, each of which is a table with the following fields: The
+-- |vertices| and |edges| fields each contain arrays of all objects
+-- being part of the collection. The |sub| field is an array of
+-- ``subcollections'', that is, all collections that were started
+-- inside another collection. (For the collection kinds |hyper| and
+-- |same layer| this makes no sense, but subgraphs could, for instance,
+-- be nested.)
+--
+-- \medskip
+-- \noindent\textbf{Rendering of Collections.}
+-- For some kinds of collections, it makes sense to \emph{render} them,
+-- but only after the graph drawing algorithm has run. For this
+-- purpose, the binding layer will use a callback for each collection
+-- kind and each collection, see the |Binding| class for details.
+-- Suppose, for instance, you would
+-- like hyperedges to be rendered. In this case, a graph drawing
+-- algorithm should iterate over all collections of type |hyper| and
+-- compute some hints on how to render the hyperedge and store this
+-- information in the |generated_options| table of the hyperedge. Then,
+-- the binding layer will ask the display layer to run some some code
+-- that is able to read key--value pairs passed to
+-- it (which are the key--value pairs of the |generated_options| table)
+-- and use this information to nicely draw the hyperedge.
+--
+-- The number |t.layer| determines in which order the different
+-- collection kinds are rendered.
+--
+-- The last parameter, the layer number, is used to specify the order
+-- in which the different collection kinds are rendered. The higher the
+-- number, the later the collection will be rendered. Thus, if there is
+-- a collection kind with layer number 10 and another with layer number
+-- 20, all collections of the first kind will be rendered first,
+-- followed by all collections of the second kind.
+--
+-- Collections whose layer kinds are non-negative get rendered
+-- \emph{after} the nodes and edges have already been rendered. In
+-- contrast, collections with a negative layer number get shown
+-- ``below'' the nodes and edges.
+--
+-- (You cannot call this function directly, it is included for
+-- documentation purposes only.)
+--
+-- @param t The table originally passed to |declare|.
+
+local function declare_collection_kind (t)
+ assert (type(t.layer) == "number", "layer must be a number")
+
+ local layer = t.layer
+ local kind = t.key
+ local kinds = InterfaceCore.collection_kinds
+ local new_entry = { kind = kind, layer = layer }
+
+ -- Insert into table part:
+ kinds[kind] = new_entry
+
+ -- Insert into array part:
+ local found
+ for i=1,#kinds do
+ if kinds[i].layer > layer or (kinds[i].layer == layer and kinds[i].kind > kind) then
+ table.insert(kinds, i, new_entry)
+ return
+ end
+ end
+
+ kinds[#kinds+1] = new_entry
+
+ -- Bind
+ InterfaceCore.binding:declareCallback(t)
+
+ return true
+end
+
+
+
+-- Build in handlers:
+
+declare_handlers = {
+ { test = function (t) return t.algorithm_written_in_c end, handler = InterfaceToC.declare_algorithm_written_in_c },
+ { test = function (t) return t.algorithm end, handler = declare_algorithm },
+ { test = function (t) return t.layer end, handler = declare_collection_kind },
+ { test = function (t) return true end, handler = declare_parameter }
+}
+
+
+
+
+
+
+
+
+---
+-- Finds a node by its name. This method should be used by algorithms
+-- for which a node name is specified in some option and, thus, needs
+-- to be converted to a vertex object during a run of the algorithm.
+--
+-- @param name A node name
+--
+-- @return The vertex of the given name in the syntactic digraph or
+-- |nil|.
+
+function InterfaceToAlgorithms.findVertexByName(name)
+ return InterfaceCore.topScope().node_names[name]
+end
+
+
+
+
+
+-- Helper function
+local function add_to_collections(collection,where,what)
+ if collection then
+ LookupTable.addOne(collection[where],what)
+ add_to_collections(collection.parent,where,what)
+ end
+end
+
+local unique_count = 1
+
+---
+-- Generate a new vertex in the syntactic digraph. Calling this method
+-- allows algorithms to create vertices that are not present in the
+-- original input graph. Using the graph drawing coroutine, this
+-- function will pass back control to the display layer in order to
+-- render the vertex and, thereby, create precise size information
+-- about it.
+--
+-- Note that creating new vertices in the syntactic digraph while the
+-- algorithm is already running is a bit at odds with the notion of
+-- treating graph drawing as a series of graph transformations: For
+-- instance, when a new vertex is created, the graph will (at least
+-- temporarily) no longer be connected; even though an algorithm may
+-- have requested that it should only be fed connected
+-- graphs. Likewise, more complicated requirements like insisting on
+-- the graph being a tree also cannot be met.
+--
+-- For these reasons, the following happens, when a new vertex is
+-- created using the function:
+-- %
+-- \begin{enumerate}
+-- \item The vertex is added to the syntactic digraph.
+-- \item It is added to all layouts on the current layout stack. When
+-- a graph drawing algorithm is run, it is not necessarily run on the
+-- original syntactic digraph. Rather, a sequence / stack of nested
+-- layouts may currently
+-- be processed and the vertex is added to all of them.
+-- \item The vertex is added to both the |digraph| and the |ugraph| of
+-- the current algorithm.
+-- \end{enumerate}
+--
+-- @param algorithm An algorithm for whose syntactic digraph the node
+-- should be added
+-- @param init A table of initial values for the node that is passed
+-- to |Binding:createVertex|, see that function for details.
+--
+-- @return The newly created node
+--
+function InterfaceToAlgorithms.createVertex(algorithm, init)
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+ local binding = InterfaceCore.binding
+
+ -- Setup node
+ if not init.name then
+ init.name = "internal@gd@node@" .. unique_count
+ unique_count = unique_count + 1
+ end
+
+ -- Does vertex already exist?
+ assert (not scope.node_names[name], "node already created")
+
+ if not init.shape or init.shape == "none" then
+ init.shape = "rectangle"
+ end
+
+ -- Call binding
+ binding:createVertex(init)
+
+ local v = assert(scope.node_names[init.name], "internal node creation failed")
+
+ -- Add vertex to the algorithm's digraph and ugraph
+ algorithm.syntactic_component:add {v}
+ algorithm.digraph:add {v}
+ algorithm.ugraph:add {v}
+
+ -- Compute bounding boxes:
+ LayoutPipeline.prepareBoundingBoxes(algorithm.rotation_info, algorithm.adjusted_bb, algorithm.digraph, {v})
+
+ -- Add the node to the layout stack:
+ add_to_collections(algorithm.layout, "vertices", v)
+
+ algorithm.layout_graph:add { v }
+
+ return v
+end
+
+
+
+---
+-- Generate a new edge in the syntactic digraph. This method is quite
+-- similar to |createVertex| and has the same effects with respect to
+-- the edge: The edge is added to the syntactic digraph and also to
+-- all layouts on the layout stack. Furthermore, appropriate edges are
+-- added to the |digraph| and the |ugraph| of the algorithm currently
+-- running.
+--
+-- @param algorithm An algorithm for whose syntactic digraph the node should be added
+-- @param tail A syntactic tail vertex
+-- @param head A syntactic head vertex
+-- @param init A table of initial values for the edge.
+--
+-- The following fields are useful for |init|:
+-- %
+-- \begin{itemize}
+-- \item |init.direction| If present, a direction for the edge. Defaults to "--".
+-- \item |init.options| If present, some options for the edge.
+-- \item |init.generated_options| A table that is passed back to the
+-- display layer as a list of key-value pairs in the syntax of
+-- |declare_parameter|.
+-- \end{itemize}
+
+function InterfaceToAlgorithms.createEdge(algorithm, tail, head, init)
+
+ init = init or {}
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+ local binding = InterfaceCore.binding
+ local syntactic_digraph = algorithm.layout_graph
+ local syntactic_component = algorithm.syntactic_component
+
+ assert (syntactic_digraph:contains(tail) and
+ syntactic_digraph:contains(head),
+ "attempting to create edge between nodes that are not in the syntactic digraph")
+
+ local arc = syntactic_digraph:connect(tail, head)
+
+ local edge = Edge.new {
+ head = head,
+ tail = tail,
+ direction = init.direction or "--",
+ options = init.options or algorithm.layout.options,
+ path = init.path,
+ generated_options = init.generated_options
+ }
+
+ -- Add to arc
+ arc.syntactic_edges[#arc.syntactic_edges+1] = edge
+
+ local s_arc = syntactic_component:connect(tail, head)
+ s_arc.syntactic_edges = arc.syntactic_edges
+
+ -- Create Event
+ local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges })
+ edge.event = e
+
+ -- Make part of collections
+ for _,c in ipairs(edge.options.collections) do
+ LookupTable.addOne(c.edges, edge)
+ end
+
+ -- Call binding
+ binding.storage[edge] = {}
+ binding:everyEdgeCreation(edge)
+
+ -- Add edge to digraph and ugraph
+ local direction = edge.direction
+ if direction == "->" then
+ algorithm.digraph:connect(tail, head)
+ elseif direction == "<-" then
+ algorithm.digraph:connect(head, tail)
+ elseif direction == "--" or direction == "<->" then
+ algorithm.digraph:connect(tail, head)
+ algorithm.digraph:connect(head, tail)
+ end
+ algorithm.ugraph:connect(tail, head)
+ algorithm.ugraph:connect(head, tail)
+
+ -- Add edge to layouts
+ add_to_collections(algorithm.layout, "edges", edge)
+
+end
+
+
+
+
+
+-- Done
+
+return InterfaceToAlgorithms
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua
new file mode 100644
index 0000000000..282727b66a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua
@@ -0,0 +1,78 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- This table contains functions that are used (on the Lua side) to
+-- prepare a graph for use in C and, vice versa, to translate back the
+-- results of C to Lua.
+
+local InterfaceToC = {}
+
+-- Imports
+
+local lib = require "pgf.gd.lib"
+
+
+---
+-- This function is called by |declare| for ``algorithm
+-- keys'' where the algorithm is not written in Lua, but rather in the
+-- programming language C. You do not call this function yourself;
+-- |InterfaceFromC.h| will do it for you. Nevertheless, if you
+-- provide a table to |declare| with the field
+-- |algorithm_written_in_c| set, the following happens: The table's
+-- |algorithm| field is set to an algorithm class object whose |run|
+-- method calls the function passed via the
+-- |algorithm_written_in_c| field. It will be called with the
+-- following parameters (in that order):
+-- %
+-- \begin{enumerate}
+-- \item The to-be-laid out digraph. This will not be the whole layout
+-- graph (syntactic digraph) if preprocessing like decomposition into
+-- connected components is used.
+-- \item An array of the digraph's vertices, but with the table part
+-- hashing vertex objects to their indices in the array part.
+-- \item An array of the syntactic edges of the digraph. Like the
+-- array, the table part will hash back the indices of the edge objects.
+-- \item The algorithm object.
+-- \end{enumerate}
+--
+-- @param t The table originally passed to |declare|.
+
+function InterfaceToC.declare_algorithm_written_in_c (t)
+ t.algorithm = {
+ run = function (self)
+ local back_table = lib.icopy(self.ugraph.vertices)
+ for i,v in ipairs(self.ugraph.vertices) do
+ back_table[v] = i
+ end
+ local edges = {}
+ for _,a in ipairs(self.ugraph.arcs) do
+ local b = self.layout_graph:arc(a.tail,a.head)
+ if b then
+ lib.icopy(b.syntactic_edges, edges)
+ end
+ end
+ for i=1,#edges do
+ edges[edges[i]] = i
+ end
+ collectgarbage("stop") -- Remove once Lua Link Bug is fixed
+ t.algorithm_written_in_c (self.digraph, back_table, edges, self)
+ collectgarbage("restart") -- Remove once Lua Link Bug is fixed
+ end
+ }
+end
+
+
+
+-- Done
+
+return InterfaceToC
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua
new file mode 100644
index 0000000000..23018efcaa
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua
@@ -0,0 +1,1002 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This class provides the interface between a display
+-- layer (like \tikzname\ or a graph editor) and graph drawing
+-- system. Another class, |InterfaceToAlgorithms|, binds the algorithm
+-- layer (which are written in Lua) to the graph drawing system.
+--
+-- The functions declared here are independent of the actual display
+-- layer. Rather, the differences between the layers are encapsulated
+-- by subclasses of the |Binding| class, see that class for
+-- details. Thus, when a new display layer is written, the present
+-- class is \emph{used}, but not \emph{modified}. Instead, only a new
+-- binding is created and all display layer specific interaction is
+-- put there.
+--
+-- The job of this class is to provide convenient methods that can be
+-- called by the display layer. For instance, it provides methods for
+-- starting a graph drawing scope, managing the stack of such scope,
+-- adding a node to a graph and so on.
+
+local InterfaceToDisplay = {}
+
+-- Namespace
+require("pgf.gd.interface").InterfaceToDisplay = InterfaceToDisplay
+
+
+-- Imports
+local InterfaceCore = require "pgf.gd.interface.InterfaceCore"
+local Scope = require "pgf.gd.interface.Scope"
+
+local Binding = require "pgf.gd.bindings.Binding"
+
+local Sublayouts = require "pgf.gd.control.Sublayouts"
+local LayoutPipeline = require "pgf.gd.control.LayoutPipeline"
+
+local Digraph = require "pgf.gd.model.Digraph"
+local Vertex = require "pgf.gd.model.Vertex"
+local Edge = require "pgf.gd.model.Edge"
+local Collection = require "pgf.gd.model.Collection"
+
+local Storage = require "pgf.gd.lib.Storage"
+local LookupTable = require "pgf.gd.lib.LookupTable"
+local Event = require "pgf.gd.lib.Event"
+
+local lib = require "pgf.gd.lib"
+
+
+-- Forward declarations
+local get_current_options_table
+local render_collections
+local push_on_option_stack
+local vertex_created
+
+-- Local objects
+
+local phase_unique = {} -- a unique handle
+local collections_unique = {} -- a unique handle
+local option_cache = nil -- The option cache
+
+
+
+
+---
+-- Initialize the binding. This function is called once by the display
+-- layer at the very beginning. For instance, \tikzname\ does the
+-- following call:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--InterfaceToDisplay.bind(require "pgf.gd.bindings.BindingToPGF")
+--\end{codeexample}
+--
+-- Inside this call, many standard declarations will be executed, that
+-- is, the declared binding will be used immediately.
+--
+-- Subsequently, the |binding| field of the |InterfaceCore| can be used.
+--
+-- @param class A subclass of |Binding|.
+
+function InterfaceToDisplay.bind(class)
+ assert (not InterfaceCore.binding, "binding already initialized")
+
+ -- Create a new object
+ InterfaceCore.binding = setmetatable({}, class)
+
+ -- Load these libraries, which contain many standard declarations:
+ require "pgf.gd.model.library"
+ require "pgf.gd.control.library"
+end
+
+
+
+
+---
+-- Start a graph drawing scope. Note that this is not the same as
+-- starting a subgraph / sublayout, which are local to a graph drawing
+-- scope: When a new graph drawing scope is started, it is pushed on
+-- top of a stack of graph drawing scopes and all other ``open''
+-- scopes are no longer directly accessible. All method calls to an
+-- |Interface...| object will refer to this newly created scope until
+-- either a new scope is opened or until the current scope is closed
+-- once more.
+--
+-- Each graph drawing scope comes with a syntactic digraph that is
+-- build using methods like |addVertex| or |addEdge|.
+--
+-- @param height The to-be-used height of the options stack. All
+-- options above this height will be popped prior to attacking the
+-- options to the syntactic digraph.
+
+function InterfaceToDisplay.beginGraphDrawingScope(height)
+
+ -- Create a new scope table
+ local scope = Scope.new {}
+
+ -- Setup syntactic digraph:
+ local g = scope.syntactic_digraph
+
+ g.options = get_current_options_table(height)
+ g.syntactic_digraph = g
+ g.scope = scope
+
+ -- Push scope:
+ InterfaceCore.scopes[#InterfaceCore.scopes + 1] = scope
+end
+
+
+
+---
+-- Arranges the current graph using the specified algorithm and options.
+--
+-- This function should be called after the graph drawing scope has
+-- been opened and the syntactic digraph has been completely
+-- specified. It will now start running the algorithm specified
+-- through the |algorithm_phase| options.
+--
+-- Internally, this function creates a coroutine that will run the current graph
+-- drawing algorithm. Coroutines are needed since a graph drawing
+-- algorithm may choose to create a new node. In this case, the
+-- algorithm needs to be suspended and control must be returned back
+-- to the display layer, so that the node can be typeset in order to
+-- determine the precise size information. Once this is done, control
+-- must be passed back to the exact point inside the algorithm where
+-- the node was created. Clearly, all of these actions are exactly
+-- what coroutines are for.
+--
+-- @return Time it took to run the algorithm
+
+function InterfaceToDisplay.runGraphDrawingAlgorithm()
+
+ -- Time things
+ local start = os.clock()
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+ assert(not scope.coroutine, "coroutine already created for current gd scope")
+
+ -- The actual drawing function
+ local function run ()
+ if #scope.syntactic_digraph.vertices == 0 then
+ -- Nothing needs to be done
+ return
+ end
+
+ LayoutPipeline.run(scope)
+ end
+
+ scope.coroutine = coroutine.create(run)
+
+ -- Run it:
+ InterfaceToDisplay.resumeGraphDrawingCoroutine()
+
+ -- End timing:
+ local stop = os.clock()
+
+ return stop - start
+end
+
+
+---
+-- Resume the graph drawing coroutine.
+--
+-- This function is the work horse of the coroutine management. It
+-- gets called whenever control passes back from the display layer to
+-- the algorithm level. We resume the graph drawing coroutine so that the
+-- algorithm can start/proceed. The tricky part is when the algorithm
+-- yields, but is not done. In this case, the code needed for creating
+-- a new node is passed back to the display layer through the binding,
+-- which must then execute the code and then resuming the coroutine.
+--
+function InterfaceToDisplay.resumeGraphDrawingCoroutine()
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+ local binding = InterfaceCore.binding
+
+ -- Asserts
+ assert(scope.coroutine, "coroutine not created for current gd scope")
+
+ -- Run
+ local ok, text = coroutine.resume(scope.coroutine)
+ assert(ok, text)
+ if coroutine.status(scope.coroutine) ~= "dead" then
+ -- Ok, ask binding to continue
+ binding:resumeGraphDrawingCoroutine(text)
+ end
+end
+
+
+
+--- Ends the current graph drawing scope.
+--
+function InterfaceToDisplay.endGraphDrawingScope()
+ assert(#InterfaceCore.scopes > 0, "no gd scope open")
+ InterfaceCore.scopes[#InterfaceCore.scopes] = nil -- pop
+end
+
+
+
+
+---
+-- Creates a new vertex in the syntactic graph of the current graph
+-- drawing scope. The display layer should call this function for each
+-- node of the graph. The |name| must be a unique string identifying
+-- the node. The newly created vertex will be added to the syntactic
+-- digraph. The binding function |everyVertexCreation| will then be
+-- called, allowing the binding to store information regarding the newly
+-- created vertex.
+--
+-- For each vertex an event will be created in the event
+-- sequence. This event will have the kind |"node"| and its
+-- |parameter| will be the vertex.
+--
+-- @param name Name of the vertex.
+--
+-- @param shape The shape of the vertex such as |"circle"| or
+-- |"rectangle"|. This shape may help a graph drawing algorithm
+-- figuring out how the node should be placed.
+--
+-- @param path A |Path| object representing the vertex's path.
+--
+-- @param height The to-be-used height of the options stack. All
+-- options above this height will be popped prior to attacking the
+-- options to the syntactic digraph.
+--
+-- @param binding_infos These options are passed to and are specific
+-- to the current |Binding|.
+--
+-- @param anchors A table of anchors (mapping anchor positions to
+-- |Coordinates|).
+
+
+function InterfaceToDisplay.createVertex(name, shape, path, height, binding_infos, anchors)
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+ local binding = InterfaceCore.binding
+
+ -- Does vertex already exist?
+ local v = scope.node_names[name]
+ assert (not v or not v.created_on_display_layer, "node already created")
+
+ -- Create vertex
+ if not v then
+ v = Vertex.new {
+ name = name,
+ shape = shape,
+ kind = "node",
+ path = path,
+ options = get_current_options_table(height),
+ anchors = anchors,
+ }
+
+ vertex_created(v,scope)
+ else
+ assert(v.kind == "subgraph node", "subgraph node expected")
+ v.shape = shape
+ v.path = path
+ v.anchors = anchors
+ end
+
+ v.created_on_display_layer = true
+
+ -- Call binding
+ binding.storage[v] = binding_infos
+ binding:everyVertexCreation(v)
+end
+
+
+-- This is a helper function
+function vertex_created(v,scope)
+
+ -- Create Event
+ local e = InterfaceToDisplay.createEvent ("node", v)
+ v.event = e
+
+ -- Create name lookup
+ scope.node_names[v.name] = v
+
+ -- Add vertex to graph
+ scope.syntactic_digraph:add {v}
+
+ -- Add to collections
+ for _,c in ipairs(v.options.collections) do
+ LookupTable.addOne(c.vertices, v)
+ end
+
+end
+
+
+
+---
+-- Creates a new vertex in the syntactic graph of the current graph
+-- drawing scope that is a subgraph vertex. Such a vertex
+-- ``surrounds'' the vertices of a subgraph. The special property of a
+-- subgraph node opposed to a normal node is that it is created only
+-- after the subgraph has been laid out. However, the difference to a
+-- collection like |hyper| is that the node is available immediately as
+-- a normal node in the sense that you can connect edges to it.
+--
+-- What happens internally is that subgraph nodes get ``registered''
+-- immediately both on the display level and on the algorithm level,
+-- but the actual node is only created inside the layout pipeline
+-- using a callback of the binding. The present function is used to
+-- perform this registering. The node creation happens when the
+-- innermost layout in which the subgraph node is declared has
+-- finished. For each subgraph node, a collection is created that
+-- contains all vertices (and edges) being part of the subgraph. For
+-- this reason, this method is a |push...| method, since it pushes
+-- something on the options stack.
+--
+-- The |init| parameter will be used during the creation of the node,
+-- see |Binding:createVertex| for details on the fields. Note that
+-- |init.text| is often not displayed for such ``vast'' nodes as those
+-- created for whole subgraphs, but a shape may use it nevertheless
+-- (for instance, one might display this text at the top of the node
+-- or, in case of a \textsc{uml} package, in a special box above the
+-- actual node).
+--
+-- The |init.generated_options| will be augmented by additional
+-- key--value pairs when the vertex is created:
+-- %
+-- \begin{itemize}
+-- \item The key |subgraph point cloud| will have as its value a
+-- string that is be a list of points (without separating commas)
+-- like |"(10pt,20pt)(0pt,0pt)(30pt,40pt)"|, always in
+-- this syntax. The list will contain all points inside the
+-- subgraph. In particular, a bounding box around these points will
+-- encompass all nodes and bend points of the subgraph.
+-- The bounding box of this point cloud is guaranteed to be centered on
+-- the origin.
+-- \item The key |subgraph bounding box width| will have as its value
+-- the width of a bounding box (in \TeX\ points, as a string with the
+-- suffix |"pt"|).
+-- \item The key |subgraph bounding box height| stores the height of a
+-- bounding box.
+-- \end{itemize}
+--
+-- @param name The name of the node.
+-- @param height Height of the options stack. Note that this method
+-- pushes something (namely a collection) on the options stack.
+-- @param info A table passed to |Binding:createVertex|, see that function.
+--
+function InterfaceToDisplay.pushSubgraphVertex(name, height, info)
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+ local binding = InterfaceCore.binding
+
+ -- Does vertex already exist?
+ assert (not scope.node_names[name], "node already created")
+
+ -- Create vertex
+ local v = Vertex.new {
+ name = name,
+ kind = "subgraph node",
+ options = get_current_options_table(height-1)
+ }
+
+ vertex_created(v,scope)
+
+ -- Store info
+ info.generated_options = info.generated_options or {}
+ info.name = name
+ v.subgraph_info = info
+
+ -- Create collection and link it to v
+ local _, _, entry = InterfaceToDisplay.pushOption(InterfaceCore.subgraph_node_kind, nil, height)
+ v.subgraph_collection = entry.value
+ v.subgraph_collection.subgraph_node = v
+
+ -- Find parent collection in options stack:
+ local collections = v.options.collections
+ for i=#collections,1,-1 do
+ if collections[i].kind == InterfaceCore.sublayout_kind then
+ v.subgraph_collection.parent_layout = collections[i]
+ break
+ end
+ end
+end
+
+
+
+---
+-- Add options for an already existing vertex.
+--
+-- This function allows you to add options to an already existing
+-- vertex. The options that will be added are all options on the
+-- current options stack; they will overwrite existing options of the
+-- same name. For collections, the vertex stays in all collections it
+-- used to, it is only added to all collections that are currently on
+-- the options stack.
+--
+-- @param name Name of the vertex.
+-- @param height The option stack height.
+
+function InterfaceToDisplay.addToVertexOptions(name, height)
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+
+ -- Does vertex already exist?
+ local v = assert (scope.node_names[name], "node is missing, cannot add options")
+
+ v.options = get_current_options_table(height, v.options)
+
+ -- Add to collections
+ for _,c in ipairs(v.options.collections) do
+ LookupTable.addOne(c.vertices, v)
+ end
+
+end
+
+
+
+
+
+---
+-- Creates a new edge in the syntactic graph of the current graph
+-- drawing scope. The display layer should call this function for each
+-- edge that is created. Both the |from| vertex and the |to| vertex
+-- must exist (have been created through |createVertex|) prior to your
+-- being able to call this function.
+--
+-- After the edge has been created, the binding layer's function
+-- |everyEdgeCreation| will be called, allowing the binding layer to
+-- store information about the edge.
+--
+-- For each edge an event is created, whose kind is |"edge"| and whose
+-- |parameter| is a two-element array whose first entry is the edge's
+-- arc in the syntactic digraph and whose second entry is the position
+-- of the edge in the arc's array of syntactic edges.
+--
+-- @param tail Name of the node the edge begins at.
+-- @param head Name of the node the edge ends at.
+-- @param direction Direction of the edge (e.g. |--| for an undirected edge
+-- or |->| for a directed edge from the first to the second
+-- node).
+-- @param height The option stack height, see for instance |createVertex|.
+--
+-- @param binding_infos These options will be stored in the |storage|
+-- of the vertex at the field index by the binding.
+
+function InterfaceToDisplay.createEdge(tail, head, direction, height, binding_infos)
+
+ -- Setup
+ local scope = InterfaceCore.topScope()
+ local binding = InterfaceCore.binding
+
+ -- Does vertex already exist?
+ local h = scope.node_names[head]
+ local t = scope.node_names[tail]
+ assert (h and t, "attempting to create edge between nodes that are not in the graph")
+
+ -- Create Arc object
+ local arc = scope.syntactic_digraph:connect(t, h)
+
+ -- Create Edge object
+ local edge = Edge.new {
+ head = h,
+ tail = t,
+ direction = direction,
+ options = get_current_options_table(height)
+ }
+
+ -- Add to arc
+ arc.syntactic_edges[#arc.syntactic_edges+1] = edge
+
+ -- Create Event
+ local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges })
+ edge.event = e
+
+ -- Make part of collections
+ for _,c in ipairs(edge.options.collections) do
+ LookupTable.addOne(c.edges, edge)
+ end
+
+ -- Call binding
+ binding.storage[edge] = binding_infos
+ binding:everyEdgeCreation(edge)
+
+end
+
+
+
+
+
+---
+-- Push an option to the stack of options.
+--
+-- As a graph is parsed, a stack of ``current options''
+-- is created. To add something to this table, the display layers may
+-- call the method |pushOption|. To pop something from this stack,
+-- just set the |height| value during the next push to the position to
+-- which you actually wish to push something; everything above and
+-- including this position will be popped from the stack.
+--
+-- When an option is pushed, several additional options may also be
+-- pushed, namely whenever the option has a |use| field set. These
+-- additional options may, in turn, also push new options. Because of
+-- this, this function returns a new stack height, representing the
+-- resulting stack height.
+--
+-- In addition to this stack height, this function returns a Boolean
+-- value indicating whether a ``main algorithm phase was set''. This
+-- happens whenever a key is executed (directly or indirectly through
+-- the |use| field) that selects an algorithm for the ``main''
+-- algorithm phase. This information may help the caller to setup the
+-- graph drawing scopes correctly.
+--
+-- @param key A parameter (must be a string).
+-- @param value A value (can be anything). If it is a string, it will
+-- be converted to whatever the key expects.
+-- @param height A stack height at which to insert the key. Everything
+-- above this height will be removed.
+--
+-- @return A new stack height
+-- @return A Boolean that is |true| if the main algorithm phase was
+-- set by the option or one option |use|d by it.
+-- @return The newly created entry on the stack. If more entries are
+-- created through the use of the |use| field, the original entry is
+-- returned nevertheless.
+
+
+function InterfaceToDisplay.pushOption(key, value, height)
+ assert(type(key) == "string", "illegal key")
+
+ local key_record = assert(InterfaceCore.keys[key], "unknown key")
+ local main_phase_set = false
+
+ if value == nil and key_record.default then
+ value = key_record.default
+ end
+
+ -- Find out what kind of key we are pushing:
+
+ if key_record.algorithm then
+ -- Push a phase
+ if type(InterfaceCore.algorithm_classes[key]) == "function" then
+ -- Call the constructor function
+ InterfaceCore.algorithm_classes[key] = InterfaceCore.algorithm_classes[key]()
+ end
+
+ local algorithm = InterfaceCore.algorithm_classes[key]
+
+ assert (algorithm, "algorithm class not found")
+
+ push_on_option_stack(phase_unique,
+ { phase = value or key_record.phase, algorithm = algorithm },
+ height)
+
+ if key_record.phase == "main" then
+ main_phase_set = true
+ end
+
+ elseif key_record.layer then
+ -- Push a collection
+ local stack = InterfaceCore.option_stack
+ local scope = InterfaceCore.topScope()
+
+ -- Get the stack above "height":
+ local options = get_current_options_table(height-1)
+
+ -- Create the collection event
+ local event = InterfaceToDisplay.createEvent ("collection", key)
+
+ -- Create collection object:
+ local collection = Collection.new { kind = key, options = options, event = event }
+
+ -- Store in collections table of current scope:
+ local collections = scope.collections[key] or {}
+ collections[#collections + 1] = collection
+ scope.collections[key] = collections
+
+ -- Build collection tree
+ collection:registerAsChildOf(options.collections[#options.collections])
+
+ -- Push on stack
+ push_on_option_stack(collections_unique, collection, height)
+
+ else
+
+ -- A normal key
+ push_on_option_stack(key, InterfaceCore.convert(value, InterfaceCore.keys[key].type), height)
+
+ end
+
+ local newly_created = InterfaceCore.option_stack[#InterfaceCore.option_stack]
+
+ -- Now, push use keys:
+ local use = key_record.use
+ if key_record.use then
+ local flag
+ for _,u in ipairs(InterfaceCore.keys[key].use) do
+ local use_k = u.key
+ local use_v = u.value
+ if type(use_k) == "function" then
+ use_k = use_k(value)
+ end
+ if type(use_v) == "function" then
+ use_v = use_v(value)
+ end
+ height, flag = InterfaceToDisplay.pushOption(use_k, use_v, height+1)
+ main_phase_set = main_phase_set or flag
+ end
+ end
+
+ return height, main_phase_set, newly_created
+end
+
+
+---
+-- Push a layout on the stack of options. As long as this layout is on
+-- the stack, all vertices and edges will be part of this layout. For
+-- details on layouts, please see |Sublayouts|.
+--
+-- @param height A stack height at which to insert the key. Everything
+-- above this height will be removed.
+
+function InterfaceToDisplay.pushLayout(height)
+ InterfaceToDisplay.pushOption(InterfaceCore.sublayout_kind, nil, height)
+end
+
+
+
+---
+-- Creates an event and adds it to the event string of the current scope.
+--
+-- @param kind Name/kind of the event.
+-- @param parameters Parameters of the event.
+--
+-- @return The newly pushed event
+--
+function InterfaceToDisplay.createEvent(kind, param)
+ local scope = InterfaceCore.topScope()
+ local n = #scope.events + 1
+ local e = Event.new { kind = kind, parameters = param, index = n }
+ scope.events[n] = e
+
+ return e
+end
+
+
+
+---
+-- This method allows you to query the table of all declared keys. It
+-- contains them both as an array and also as a table index by the
+-- keys's names. In particular, you can then iterate over it using
+-- |ipairs| and you can check whether a key is defined by accessing
+-- the table at the key's name. Each entry of the table is the
+-- original table passed to |InterfaceToAlgorithms.declare|.
+--
+-- @return A lookup table of all declared keys.
+
+function InterfaceToDisplay.getDeclaredKeys()
+ return InterfaceCore.keys
+end
+
+
+
+
+---
+-- Renders the graph.
+--
+-- This function is called after the graph has been laid out by the
+-- graph drawing algorithms. It will trigger a sequence of calls to
+-- the binding layer that will, via callbacks, start rendering the
+-- whole graph.
+--
+-- In detail, this function calls:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local binding = InterfaceCore.binding
+--
+--binding:renderStart()
+--render_vertices()
+--render_edges()
+--render_collections()
+--binding:renderStop()
+--\end{codeexample}
+--
+-- Here, the |render_...| functions are local, internal functions that are,
+-- nevertheless, documented here.
+--
+-- @param name Returns the algorithm class that has been declared using
+-- |declare| under the given name.
+
+function InterfaceToDisplay.renderGraph()
+ local scope = InterfaceCore.topScope()
+ local syntactic_digraph = scope.syntactic_digraph
+
+ local binding = InterfaceCore.binding
+
+ binding:renderStart()
+ render_vertices(syntactic_digraph.vertices)
+ render_edges(syntactic_digraph.arcs)
+ render_collections(scope.collections)
+ binding:renderStop()
+end
+
+
+
+
+
+---
+-- Render the vertices after the graph drawing algorithm has
+-- finished. This function is local and internal and included only for
+-- documenting the call graph.
+--
+-- When the graph drawing algorithm is done, the interface will start
+-- rendering the vertices by calling appropriate callbacks of the
+-- binding layer.
+--
+-- Consider the following code:
+-- %
+--\begin{codeexample}[code only]
+--\graph [... layout] {
+-- a -- b -- c -- d;
+--};
+--\end{codeexample}
+--
+-- In this case, after the graph drawing algorithm has run, the
+-- present function will call:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local binding = InterfaceCore.binding
+--
+--binding:renderVerticesStart()
+--binding:renderVertex(vertex_a)
+--binding:renderVertex(vertex_b)
+--binding:renderVertex(vertex_c)
+--binding:renderVertex(vertex_d)
+--binding:renderVerticesStop()
+--\end{codeexample}
+--
+-- @param vertices An array of all vertices in the syntactic digraph.
+
+function render_vertices(vertices)
+ InterfaceCore.binding:renderVerticesStart()
+ for _,vertex in ipairs(vertices) do
+ InterfaceCore.binding:renderVertex(vertex)
+ end
+ InterfaceCore.binding:renderVerticesStop()
+end
+
+
+---
+-- Render the collections whose layer is not |0|. This local, internal
+-- function is called to render the different collection kinds.
+--
+-- Collection kinds rendered in the order provided by the |layer|
+-- field passed to |declare| during the declaration of the collection
+-- kind, see also |declare_collection|. If several collection kinds
+-- have the same layer, they are rendered in lexicographical ordering
+-- (to ensure that they are always rendered in the same order).
+--
+-- Consider the following code:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--declare { key = "hyper", layer = 1 }
+--\end{codeexample}
+-- you can say on the \tikzname\ layer
+--\begin{codeexample}[code only]
+--\graph {
+-- a, b, c, d;
+-- { [hyper] a, b, c }
+-- { [hyper] b, c, d }
+--};
+--\end{codeexample}
+--
+-- In this case, after the graph drawing algorithm has run, the
+-- present function will call:
+--
+--\begin{codeexample}[code only, tikz syntax=false]
+--local binding = InterfaceCore.binding
+--
+--binding:renderCollectionStartKind("hyper", 1)
+--binding:renderCollection(collection_containing_abc)
+--binding:renderCollection(collection_containing_bcd)
+--binding:renderCollectionStopKind("hyper", 1)
+--\end{codeexample}
+--
+-- @param collections The |collections| table of the current scope.
+
+function render_collections(collections)
+ local kinds = InterfaceCore.collection_kinds
+ local binding = InterfaceCore.binding
+
+ for i=1,#kinds do
+ local kind = kinds[i].kind
+ local layer = kinds[i].layer
+
+ if layer ~= 0 then
+ binding:renderCollectionStartKind(kind, layer)
+ for _,c in ipairs(collections[kind] or {}) do
+ binding:renderCollection(c)
+ end
+ binding:renderCollectionStopKind(kind, layer)
+ end
+ end
+end
+
+
+---
+-- Render the syntactic edges of a graph after the graph drawing
+-- algorithm has finished. This function is local and internal and included only
+-- for documenting the call graph.
+--
+-- When the graph drawing algorithm is done, the interface will first
+-- rendering the vertices using |render_vertices|, followed by calling
+-- this function, which in turn calls appropriate callbacks to the
+-- binding layer.
+--
+-- Consider the following code:
+-- %
+--\begin{codeexample}[code only]
+-- \graph [... layout] {
+-- a -- b -- c -- d;
+-- };
+--\end{codeexample}
+--
+-- In this case, after the graph drawing algorithm has run, the
+-- present function will call:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+-- local binding = InterfaceCore.binding
+--
+-- binding:renderEdgesStart()
+-- binding:renderEdge(edge_from_a_to_b)
+-- binding:renderEdge(edge_from_b_to_c)
+-- binding:renderEdge(edge_from_c_to_d)
+-- binding:renderEdgesStop()
+--\end{codeexample}
+--
+-- @param arcs The array of arcs of the syntactic digraph.
+
+function render_edges(arcs)
+ InterfaceCore.binding:renderEdgesStart()
+ for _,a in ipairs(arcs) do
+ for _,e in ipairs (a.syntactic_edges) do
+ InterfaceCore.binding:renderEdge(e)
+ end
+ end
+ InterfaceCore.binding:renderEdgesStop()
+end
+
+
+local aliases = InterfaceCore.option_aliases
+local option_initial = InterfaceCore.option_initial
+
+local option_metatable = {
+ __index =
+ function (t, key)
+ local k = aliases[key]
+ if k then
+ local v = (type(k) == "string" and t[k]) or (type(k) == "function" and k(t)) or nil
+ if v ~= nil then
+ return v
+ end
+ end
+ return option_initial[key]
+ end
+}
+
+
+---
+-- Get the current options table.
+--
+-- An option table can be accessed like a normal table; however, there
+-- is a global fallback for this table. If an index is not defined,
+-- the value of this index in the global fallback table is used. (This
+-- reduces the overall amount of option keys that need to be stored
+-- with object.)
+--
+-- (This function is local and internal and included only for documentation
+-- purposes.)
+--
+-- @param height The stack height for which the option table is
+-- required.
+-- @param table If non |nil|, the options will be added to this
+-- table.
+--
+-- @return The option table as described above.
+
+function get_current_options_table (height, table)
+ local stack = InterfaceCore.option_stack
+ assert (height >= 0 and height <= #stack, "height value out of bounds")
+
+ if height == InterfaceCore.option_cache_height and not table then
+ return option_cache
+ else
+ -- Clear superfluous part of stack
+ for i=#stack,height+1,-1 do
+ stack[i] = nil
+ end
+
+ -- Build options table
+ local cache
+ if not table then
+ cache = setmetatable(
+ {
+ algorithm_phases = setmetatable({}, InterfaceCore.option_initial.algorithm_phases),
+ collections = {}
+ }, option_metatable)
+ else
+ cache = lib.copy(table)
+ cache.algorithm_phases = lib.copy(cache.algorithm_phases)
+ cache.collections = lib.copy(cache.collections)
+ end
+
+ local algorithm_phases = cache.algorithm_phases
+ local collections = cache.collections
+ local keys = InterfaceCore.keys
+
+ local function handle (k, v)
+ if k == phase_unique then
+ algorithm_phases[v.phase] = v.algorithm
+ local phase_stack = v.phase .. " stack"
+ local t = rawget(algorithm_phases, phase_stack)
+ if not t then
+ t = algorithm_phases[phase_stack]
+ assert(type(t) == "table", "unknown phase")
+ t = lib.copy(t)
+ algorithm_phases[phase_stack] = t
+ end
+ t[#t + 1] = v.algorithm
+ elseif k == collections_unique then
+ LookupTable.addOne(collections, v)
+ else
+ cache[k] = v
+ end
+ end
+
+ for _,s in ipairs(stack) do
+ handle (s.key, s.value)
+ end
+
+ -- Cache it, if this was not added:
+ if not table then
+ InterfaceCore.option_cache_height = height
+ option_cache = cache
+ end
+
+ return cache
+ end
+end
+
+
+
+-- A helper function
+
+function push_on_option_stack(key, value, height)
+ local stack = InterfaceCore.option_stack
+
+ assert (type(height) == "number" and height > 0 and height <= #stack + 1,
+ "height value out of bounds")
+
+ -- Clear superfluous part of stack
+ for i=#stack,height+1,-1 do
+ stack[i] = nil
+ end
+
+ stack[height] = { key = key, value = value }
+ InterfaceCore.option_cache_height = nil -- invalidate cache
+end
+
+
+
+-- Done
+
+return InterfaceToDisplay
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/Scope.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/Scope.lua
new file mode 100644
index 0000000000..a750308e69
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/interface/Scope.lua
@@ -0,0 +1,92 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- In theory, graph drawing algorithms take graphs as input and
+-- output graphs embedded into the plane as output. In practice, however,
+-- the input to a graph drawing algorithm is not ``just'' the
+-- graph. Rather, additional information about the graph, in particular
+-- about the way the user specified the graph, is also important to many
+-- graph drawing algorithms.
+--
+-- The graph drawing system gathers both the original input graph as well
+-- as all additional information that is provided in the graph drawing
+-- scope inside a scope table. The object has a number of fields that
+-- inform an algorithm about the input.
+--
+-- For each graph drawing scope, a new |Scope| object is
+-- created. Graph drawing scopes are kept track of using a stack, but
+-- only the top of this stack is available to the interface classes.
+--
+-- @field syntactic_digraph The syntactic digraph is a digraph that
+-- faithfully encodes the way the input graph is represented
+-- syntactically. However, this does not mean that the syntactic
+-- digraph contains the actual textual representation of the input
+-- graph. Rather, when an edge is specified as, say, |a <- b|, the
+-- syntactic digraph will contains an arc from |a| to |b| with an edge
+-- object attached to it that is labeled as a ``backward''
+-- edge. Similarly, an edge |a -- b| is also stored as a directed arc
+-- from |a| to |b| with the label |--| attached to it. Algorithms will
+-- often be more interested graphs derived from the syntactic digraph
+-- such as its underlying undirected graph. These derived graphs are
+-- made accessible by the graph drawing engine during the preprocessing.
+--
+-- @field events An array of |Event| objects. These objects, see the
+-- |Event| class for details, are created during the parsing of the
+-- input graph.
+--
+-- @field node_names A table that maps the names of nodes to node
+-- objects. Every node must have a unique name.
+--
+-- @field coroutine A Lua coroutine that is used internally to allow
+-- callbacks to the display layer to be issued deep down during a run
+-- of an algorithm.
+--
+-- @field collections The collections specified inside the scope, see
+-- the |Collection| class.
+
+local Scope = {}
+Scope.__index = Scope
+
+-- Namespace
+require("pgf.gd.interface").Scope = Scope
+
+-- Imports
+local lib = require "pgf.gd.lib"
+local Storage = require "pgf.gd.lib.Storage"
+
+local Digraph = require "pgf.gd.model.Digraph"
+
+---
+-- Create a new |Scope| object.
+--
+-- @param initial A table of initial values for the newly created
+-- |Scope| object.
+--
+-- @return The new scope object.
+
+function Scope.new(initial)
+ return setmetatable(lib.copy(initial,
+ {
+ syntactic_digraph = Digraph.new{},
+ events = {},
+ node_names = {},
+ coroutine = nil,
+ collections = {},
+ }), Scope)
+end
+
+
+-- Done
+
+return Scope
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered.lua
new file mode 100644
index 0000000000..6988e7a3d9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered.lua
@@ -0,0 +1,159 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+local layered = {}
+
+-- Namespace
+
+require("pgf.gd").layered = layered
+
+
+local lib = require "pgf.gd.lib"
+local Storage = require "pgf.gd.lib.Storage"
+
+--
+-- This file defines some basic functions to compute and/or set the
+-- ideal distances between nodes of any kind of layered drawing of a
+-- graph.
+
+
+---
+-- Compute the ideal distance between two siblings
+--
+-- @param paddings A |Storage| object in which the computed distances
+-- (paddings) are stored.
+-- @param graph The graph object
+-- @param n1 The first node
+-- @param n2 The second node
+
+function layered.ideal_sibling_distance (paddings, graph, n1, n2)
+ local ideal_distance
+ local sep
+
+ local n1_is_node = n1.kind == "node"
+ local n2_is_node = n2.kind == "node"
+
+ if not n1_is_node and not n2_is_node then
+ ideal_distance = graph.options['sibling distance']
+ sep = graph.options['sibling post sep']
+ + graph.options['sibling pre sep']
+ else
+ if n1_is_node then
+ ideal_distance = lib.lookup_option('sibling distance', n1, graph)
+ else
+ ideal_distance = lib.lookup_option('sibling distance', n2, graph)
+ end
+ sep = (n1_is_node and lib.lookup_option('sibling post sep', n1, graph) or 0)
+ + (n2_is_node and lib.lookup_option('sibling pre sep', n2, graph) or 0)
+ end
+
+ return math.max(ideal_distance, sep +
+ ((n1_is_node and paddings[n1].sibling_post) or 0) -
+ ((n2_is_node and paddings[n2].sibling_pre) or 0))
+end
+
+
+
+---
+-- Compute the baseline distance between two layers
+--
+-- The "baseline" distance is the distance between two layers that
+-- corresponds to the distance of the two layers if the nodes where
+-- "words" on two adjacent lines. In this case, the distance is
+-- normally the layer_distance, but will be increased such that if we
+-- draw a horizontal line below the deepest character on the first
+-- line and a horizontal line above the highest character on the
+-- second line, the lines will have a minimum distance of layer sep.
+--
+-- Since each node on the lines might have a different layer sep and
+-- layer distance specified, the maximum over all the values is taken.
+--
+-- @param paddings A |Storage| object in which the distances
+-- (paddings) are stored.
+-- @param graph The graph in which the nodes reside
+-- @param l1 An array of the nodes of the first layer
+-- @param l2 An array of the nodes of the second layer
+
+function layered.baseline_distance (paddings, graph, l1, l2)
+
+ if #l1 == 0 or #l2 == 0 then
+ return 0
+ end
+
+ local layer_distance = -math.huge
+ local layer_pre_sep = -math.huge
+ local layer_post_sep = -math.huge
+
+ local max_post = -math.huge
+ local min_pre = math.huge
+
+ for _,n in ipairs(l1) do
+ layer_distance = math.max(layer_distance, lib.lookup_option('level distance', n, graph))
+ layer_post_sep = math.max(layer_post_sep, lib.lookup_option('level post sep', n, graph))
+ if n.kind == "node" then
+ max_post = math.max(max_post, paddings[n].layer_post)
+ end
+ end
+
+ for _,n in ipairs(l2) do
+ layer_pre_sep = math.max(layer_pre_sep, lib.lookup_option('level pre sep', n, graph))
+ if n.kind == "node" then
+ min_pre = math.min(min_pre, paddings[n].layer_pre)
+ end
+ end
+
+ return math.max(layer_distance, layer_post_sep + layer_pre_sep + max_post - min_pre)
+end
+
+
+
+---
+-- Position nodes in layers using baselines
+--
+-- @param layers A |Storage| object assigning layers to vertices.
+-- @param paddings A |Storage| object storing the computed distances
+-- (paddings).
+-- @param graph The graph in which the nodes reside
+
+function layered.arrange_layers_by_baselines (layers, paddings, graph)
+
+ local layer_vertices = Storage.newTableStorage()
+
+ -- Decompose into layers:
+ for _,v in ipairs(graph.vertices) do
+ table.insert(layer_vertices[layers[v]], v)
+ end
+
+ if #layer_vertices > 0 then -- sanity check
+ -- Now compute ideal distances and store
+ local height = 0
+
+ for _,v in ipairs(layer_vertices[1]) do
+ v.pos.y = 0
+ end
+
+ for i=2,#layer_vertices do
+ height = height + layered.baseline_distance(paddings, graph, layer_vertices[i-1], layer_vertices[i])
+
+ for _,v in ipairs(layer_vertices[i]) do
+ v.pos.y = height
+ end
+ end
+ end
+end
+
+
+
+
+-- Done
+
+return layered
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua
new file mode 100644
index 0000000000..da9ff9698c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua
@@ -0,0 +1,342 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+local CrossingMinimizationGansnerKNV1993 = {}
+
+
+-- Imports
+
+local lib = require "pgf.gd.lib"
+local DepthFirstSearch = require "pgf.gd.lib.DepthFirstSearch"
+
+
+
+function CrossingMinimizationGansnerKNV1993:run()
+
+ self:computeInitialRankOrdering()
+
+ local best_ranking = self.ranking:copy()
+ local best_crossings = self:countRankCrossings(best_ranking)
+
+ for iteration=1,24 do
+ local direction = (iteration % 2 == 0) and 'down' or 'up'
+
+ self:orderByWeightedMedian(direction)
+ self:transpose(direction)
+
+ local current_crossings = self:countRankCrossings(self.ranking)
+
+ if current_crossings < best_crossings then
+ best_ranking = self.ranking:copy()
+ best_crossings = current_crossings
+ end
+ end
+
+ self.ranking = best_ranking:copy()
+
+ return self.ranking
+end
+
+
+
+function CrossingMinimizationGansnerKNV1993:computeInitialRankOrdering()
+
+ local best_ranking = self.ranking:copy()
+ local best_crossings = self:countRankCrossings(best_ranking)
+
+ for _,direction in ipairs({'down', 'up'}) do
+
+ local function init(search)
+ for i=#self.graph.nodes,1,-1 do
+ local node = self.graph.nodes[i]
+ if direction == 'down' then
+ if node:getInDegree() == 0 then
+ search:push(node)
+ search:setDiscovered(node)
+ end
+ else
+ if node:getOutDegree() == 0 then
+ search:push(node)
+ search:setDiscovered(node)
+ end
+ end
+ end
+ end
+
+ local function visit(search, node)
+ search:setVisited(node, true)
+
+ local rank = self.ranking:getRank(node)
+ local pos = self.ranking:getRankSize(rank)
+ self.ranking:setRankPosition(node, pos)
+
+ if direction == 'down' then
+ local out = node:getOutgoingEdges()
+ for i=#out,1,-1 do
+ local neighbour = out[i]:getNeighbour(node)
+ if not search:getDiscovered(neighbour) then
+ search:push(neighbour)
+ search:setDiscovered(neighbour)
+ end
+ end
+ else
+ local into = node:getIncomingEdges()
+ for i=#into,1,-1 do
+ local neighbour = into[i]:getNeighbour(node)
+ if not search:getDiscovered(neighbour) then
+ search:push(neighbour)
+ search:setDiscovered(neighbour)
+ end
+ end
+ end
+ end
+
+ DepthFirstSearch.new(init, visit):run()
+
+ local crossings = self:countRankCrossings(self.ranking)
+
+ if crossings < best_crossings then
+ best_ranking = self.ranking:copy()
+ best_crossings = crossings
+ end
+ end
+
+ self.ranking = best_ranking:copy()
+
+end
+
+
+
+function CrossingMinimizationGansnerKNV1993:countRankCrossings(ranking)
+
+ local crossings = 0
+
+ local ranks = ranking:getRanks()
+
+ for rank_index = 2, #ranks do
+ local nodes = ranking:getNodes(ranks[rank_index])
+ for i = 1, #nodes-1 do
+ for j = i+1, #nodes do
+ local v = nodes[i]
+ local w = nodes[j]
+
+ -- TODO Jannis: We are REQUIRED to only check edges that lead to nodes
+ -- on the next or previous rank, depending on the sweep direction!!!!
+ local cn_vw = self:countNodeCrossings(ranking, v, w, 'down')
+
+ crossings = crossings + cn_vw
+ end
+ end
+ end
+
+ return crossings
+end
+
+
+
+function CrossingMinimizationGansnerKNV1993:countNodeCrossings(ranking, left_node, right_node, sweep_direction)
+
+ local ranks = ranking:getRanks()
+ local _, rank_index = lib.find(ranks, function (rank)
+ return rank == ranking:getRank(left_node)
+ end)
+ local other_rank_index = (sweep_direction == 'down') and rank_index-1 or rank_index+1
+
+ assert(ranking:getRank(left_node) == ranking:getRank(right_node))
+ assert(rank_index >= 1 and rank_index <= #ranks)
+
+ -- 0 crossings if we're at the top or bottom and are sweeping down or up
+ if other_rank_index < 1 or other_rank_index > #ranks then
+ return 0
+ end
+
+ local left_edges = {}
+ local right_edges = {}
+
+ if sweep_direction == 'down' then
+ left_edges = left_node:getIncomingEdges()
+ right_edges = right_node:getIncomingEdges()
+ else
+ left_edges = left_node:getOutgoingEdges()
+ right_edges = right_node:getOutgoingEdges()
+ end
+
+ local crossings = 0
+
+ local function left_neighbour_on_other_rank(edge)
+ local neighbour = edge:getNeighbour(left_node)
+ return ranking:getRank(neighbour) == ranking:getRanks()[other_rank_index]
+ end
+
+ local function right_neighbour_on_other_rank(edge)
+ local neighbour = edge:getNeighbour(right_node)
+ return ranking:getRank(neighbour) == ranking:getRanks()[other_rank_index]
+ end
+
+ for _,left_edge in ipairs(left_edges) do
+ if left_neighbour_on_other_rank(left_edge) then
+ local left_neighbour = left_edge:getNeighbour(left_node)
+
+ for _,right_edge in ipairs(right_edges) do
+ if right_neighbour_on_other_rank(right_edge) then
+ local right_neighbour = right_edge:getNeighbour(right_node)
+
+ local left_position = ranking:getRankPosition(left_neighbour)
+ local right_position = ranking:getRankPosition(right_neighbour)
+
+ local neighbour_diff = right_position - left_position
+
+ if neighbour_diff < 0 then
+ crossings = crossings + 1
+ end
+ end
+ end
+ end
+ end
+
+ return crossings
+end
+
+
+
+function CrossingMinimizationGansnerKNV1993:orderByWeightedMedian(direction)
+
+ local median = {}
+
+ local function get_index(n, node) return median[node] end
+ local function is_fixed(n, node) return median[node] < 0 end
+
+ if direction == 'down' then
+ local ranks = self.ranking:getRanks()
+
+ for rank_index = 2, #ranks do
+ median = {}
+ local nodes = self.ranking:getNodes(ranks[rank_index])
+ for _,node in ipairs(nodes) do
+ median[node] = self:computeMedianPosition(node, ranks[rank_index-1])
+ end
+
+ self.ranking:reorderRank(ranks[rank_index], get_index, is_fixed)
+ end
+ else
+ local ranks = self.ranking:getRanks()
+
+ for rank_index = 1, #ranks-1 do
+ median = {}
+ local nodes = self.ranking:getNodes(ranks[rank_index])
+ for _,node in ipairs(nodes) do
+ median[node] = self:computeMedianPosition(node, ranks[rank_index+1])
+ end
+
+ self.ranking:reorderRank(ranks[rank_index], get_index, is_fixed)
+ end
+ end
+end
+
+
+
+function CrossingMinimizationGansnerKNV1993:computeMedianPosition(node, prev_rank)
+
+ local positions = lib.imap(
+ node.edges,
+ function (edge)
+ local n = edge:getNeighbour(node)
+ if self.ranking:getRank(n) == prev_rank then
+ return self.ranking:getRankPosition(n)
+ end
+ end)
+
+ table.sort(positions)
+
+ local median = math.ceil(#positions / 2)
+ local position = -1
+
+ if #positions > 0 then
+ if #positions % 2 == 1 then
+ position = positions[median]
+ elseif #positions == 2 then
+ return (positions[1] + positions[2]) / 2
+ else
+ local left = positions[median-1] - positions[1]
+ local right = positions[#positions] - positions[median]
+ position = (positions[median-1] * right + positions[median] * left) / (left + right)
+ end
+ end
+
+ return position
+end
+
+
+
+function CrossingMinimizationGansnerKNV1993:transpose(sweep_direction)
+
+ local function transpose_rank(rank)
+
+ local improved = false
+
+ local nodes = self.ranking:getNodes(rank)
+
+ for i = 1, #nodes-1 do
+ local v = nodes[i]
+ local w = nodes[i+1]
+
+ local cn_vw = self:countNodeCrossings(self.ranking, v, w, sweep_direction)
+ local cn_wv = self:countNodeCrossings(self.ranking, w, v, sweep_direction)
+
+ if cn_vw > cn_wv then
+ improved = true
+
+ self:switchNodePositions(v, w)
+ end
+ end
+
+ return improved
+ end
+
+ local ranks = self.ranking:getRanks()
+
+ local improved = false
+ repeat
+ local improved = false
+
+ if sweep_direction == 'down' then
+ for rank_index = 1, #ranks-1 do
+ improved = transpose_rank(ranks[rank_index]) or improved
+ end
+ else
+ for rank_index = #ranks-1, 1, -1 do
+ improved = transpose_rank(ranks[rank_index]) or improved
+ end
+ end
+ until not improved
+end
+
+
+
+function CrossingMinimizationGansnerKNV1993:switchNodePositions(left_node, right_node)
+ assert(self.ranking:getRank(left_node) == self.ranking:getRank(right_node))
+ assert(self.ranking:getRankPosition(left_node) < self.ranking:getRankPosition(right_node))
+
+ local left_position = self.ranking:getRankPosition(left_node)
+ local right_position = self.ranking:getRankPosition(right_node)
+
+ self.ranking:switchPositions(left_node, right_node)
+
+ local nodes = self.ranking:getNodes(self.ranking:getRank(left_node))
+end
+
+
+
+-- done
+
+return CrossingMinimizationGansnerKNV1993
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua
new file mode 100644
index 0000000000..76deb8adaf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua
@@ -0,0 +1,74 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local CycleRemovalBergerS1990a = {}
+
+local lib = require("pgf.gd.lib")
+
+
+function CycleRemovalBergerS1990a:run()
+ -- remember edges that were removed
+ local removed = {}
+
+ -- remember edges that need to be reversed
+ local reverse = {}
+
+ -- iterate over all nodes of the graph
+ for _,node in ipairs(self.graph.nodes) do
+ -- get all outgoing edges that have not been removed yet
+ local out_edges = lib.imap(node:getOutgoingEdges(),
+ function (edge)
+ if not removed[edge] then return edge end
+ end)
+
+ -- get all incoming edges that have not been removed yet
+ local in_edges = lib.imap(node:getIncomingEdges(),
+ function (edge)
+ if not removed[edge] then return edge end
+ end)
+
+ if #out_edges >= #in_edges then
+ -- we have more outgoing than incoming edges, reverse all incoming
+ -- edges and mark all incident edges as removed
+
+ for _,edge in ipairs(out_edges) do
+ removed[edge] = true
+ end
+ for _,edge in ipairs(in_edges) do
+ reverse[edge] = true
+ removed[edge] = true
+ end
+ else
+ -- we have more incoming than outgoing edges, reverse all outgoing
+ -- edges and mark all incident edges as removed
+
+ for _,edge in ipairs(out_edges) do
+ reverse[edge] = true
+ removed[edge] = true
+ end
+ for _,edge in ipairs(in_edges) do
+ removed[edge] = true
+ end
+ end
+ end
+
+ -- mark edges as reversed
+ for edge in pairs(reverse) do
+ edge.reversed = true
+ end
+end
+
+
+
+-- done
+
+return CycleRemovalBergerS1990a
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua
new file mode 100644
index 0000000000..d8f28980c8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua
@@ -0,0 +1,76 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local CycleRemovalBergerS1990b = {}
+
+local lib = require("pgf.gd.lib")
+
+
+function CycleRemovalBergerS1990b:run()
+ -- remember edges that were removed
+ local removed = {}
+
+ -- remember edges that need to be reversed
+ local reverse = {}
+
+ -- iterate over all nodes of the graph
+ for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do
+ local node = self.graph.nodes[j]
+ -- get all outgoing edges that have not been removed yet
+ -- get all outgoing edges that have not been removed yet
+ local out_edges = lib.imap(node:getOutgoingEdges(),
+ function (edge)
+ if not removed[edge] then return edge end
+ end)
+
+ -- get all incoming edges that have not been removed yet
+ local in_edges = lib.imap(node:getIncomingEdges(),
+ function (edge)
+ if not removed[edge] then return edge end
+ end)
+
+ if #out_edges >= #in_edges then
+ -- we have more outgoing than incoming edges, reverse all incoming
+ -- edges and mark all incident edges as removed
+
+ for _,edge in ipairs(out_edges) do
+ removed[edge] = true
+ end
+ for _,edge in ipairs(in_edges) do
+ reverse[edge] = true
+ removed[edge] = true
+ end
+ else
+ -- we have more incoming than outgoing edges, reverse all outgoing
+ -- edges and mark all incident edges as removed
+
+ for _,edge in ipairs(out_edges) do
+ reverse[edge] = true
+ removed[edge] = true
+ end
+ for _,edge in ipairs(in_edges) do
+ removed[edge] = true
+ end
+ end
+ end
+
+ -- mark edges as reversed
+ for edge in pairs(reverse) do
+ edge.reversed = true
+ end
+end
+
+
+
+-- done
+
+return CycleRemovalBergerS1990b
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua
new file mode 100644
index 0000000000..ffb919b209
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua
@@ -0,0 +1,124 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+-- Declare
+local CycleRemovalEadesLS1993 = {}
+
+-- Import
+local lib = require "pgf.gd.lib"
+
+
+function CycleRemovalEadesLS1993:run()
+ local copied_graph = self.graph:copy()
+
+ local copied_node = {}
+ local origin_node = {}
+ local copied_edge = {}
+ local origin_edge = {}
+
+ local preserve = {}
+
+ for _,edge in ipairs(self.graph.edges) do
+ copied_edge[edge] = edge:copy()
+ origin_edge[copied_edge[edge]] = edge
+
+ for _,node in ipairs(edge.nodes) do
+ if copied_node[node] then
+ copied_edge[edge]:addNode(copied_node[node])
+ else
+ copied_node[node] = node:copy()
+ origin_node[copied_node[node]] = node
+
+ copied_graph:addNode(copied_node[node])
+ copied_edge[edge]:addNode(copied_node[node])
+ end
+ end
+ end
+
+ local function node_is_sink(node)
+ return node:getOutDegree() == 0
+ end
+
+ local function node_is_source(node)
+ return node:getInDegree() == 0
+ end
+
+ local function node_is_isolated(node)
+ return node:getDegree() == 0
+ end
+
+ while #copied_graph.nodes > 0 do
+ local sink = lib.find(copied_graph.nodes, node_is_sink)
+ while sink do
+ for _,edge in ipairs(sink:getIncomingEdges()) do
+ preserve[edge] = true
+ end
+ copied_graph:deleteNode(sink)
+ sink = lib.find(copied_graph.nodes, node_is_sink)
+ end
+
+ local isolated_node = lib.find(copied_graph.nodes, node_is_isolated)
+ while isolated_node do
+ copied_graph:deleteNode(isolated_node)
+ isolated_node = lib.find(copied_graph.nodes, node_is_isolated)
+ end
+
+ local source = lib.find(copied_graph.nodes, node_is_source)
+ while source do
+ for _,edge in ipairs(source:getOutgoingEdges()) do
+ preserve[edge] = true
+ end
+ copied_graph:deleteNode(source)
+ source = lib.find(copied_graph.nodes, node_is_source)
+ end
+
+ if #copied_graph.nodes > 0 then
+ local max_node = nil
+ local max_out_edges = nil
+ local max_in_edges = nil
+
+ for _,node in ipairs(copied_graph.nodes) do
+ local out_edges = node:getOutgoingEdges()
+ local in_edges = node:getIncomingEdges()
+
+ if max_node == nil or (#out_edges - #in_edges > #max_out_edges - #max_in_edges) then
+ max_node = node
+ max_out_edges = out_edges
+ max_in_edges = in_edges
+ end
+ end
+
+ assert(max_node and max_out_edges and max_in_edges)
+
+ for _,edge in ipairs(max_out_edges) do
+ preserve[edge] = true
+ copied_graph:deleteEdge(edge)
+ end
+ for _,edge in ipairs(max_in_edges) do
+ copied_graph:deleteEdge(edge)
+ end
+
+ copied_graph:deleteNode(max_node)
+ end
+ end
+
+ for _,edge in ipairs(self.graph.edges) do
+ if not preserve[copied_edge[edge]] then
+ edge.reversed = true
+ end
+ end
+end
+
+-- done
+
+return CycleRemovalEadesLS1993 \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua
new file mode 100644
index 0000000000..e52b0d38d1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua
@@ -0,0 +1,52 @@
+-- Copyright 2011 by Jannis Pohlmann and 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local CycleRemovalGansnerKNV1993 = {}
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+local Simplifiers = require "pgf.gd.lib.Simplifiers"
+
+
+function CycleRemovalGansnerKNV1993:run ()
+ -- merge nonempty sets into supernodes
+ --
+ -- ignore self-loops
+ --
+ -- merge multiple edges into one edge each, whose weight is the sum of the
+ -- individual edge weights
+ --
+ -- ignore leaf nodes that are not part of the user-defined sets (their ranks
+ -- are trivially determined)
+ --
+ -- ensure that supernodes S_min and S_max are assigned first and last ranks
+ -- reverse in-edges of S_min
+ -- reverse out-edges of S_max
+ --
+ -- ensure the supernodes S_min and S_max are are the only nodes in these ranks
+ -- for all nodes with indegree of 0, insert temporary edge (S_min, v) with delta=0
+ -- for all nodes with outdegree of 0, insert temporary edge (v, S_max) with delta=0
+
+ -- classify edges as tree/forward, cross and back edges using a DFS traversal
+ local tree_or_forward_edges, cross_edges, back_edges = Simplifiers:classifyEdges(self.graph)
+
+ -- reverse the back edges in order to make the graph acyclic
+ for _,edge in ipairs(back_edges) do
+ edge.reversed = true
+ end
+end
+
+
+-- done
+
+return CycleRemovalGansnerKNV1993 \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua
new file mode 100644
index 0000000000..c451f74116
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua
@@ -0,0 +1,22 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+local EdgeRoutingGansnerKNV1993 = {}
+
+
+function EdgeRoutingGansnerKNV1993:run()
+end
+
+
+-- done
+return EdgeRoutingGansnerKNV1993 \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua
new file mode 100644
index 0000000000..0ccf7694ca
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua
@@ -0,0 +1,898 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+--- This file contains an implementation of the network simplex method
+--- for node ranking and x coordinate optimization in layered drawing
+--- algorithms, as proposed in
+---
+--- "A Technique for Drawing Directed Graphs"
+-- by Gansner, Koutsofios, North, Vo, 1993.
+
+
+local NetworkSimplex = {}
+NetworkSimplex.__index = NetworkSimplex
+
+-- Namespace
+local layered = require "pgf.gd.layered"
+layered.NetworkSimplex = NetworkSimplex
+
+
+-- Imports
+local DepthFirstSearch = require "pgf.gd.lib.DepthFirstSearch"
+local Ranking = require "pgf.gd.layered.Ranking"
+local Graph = require "pgf.gd.deprecated.Graph"
+local lib = require "pgf.gd.lib"
+
+
+
+-- Definitions
+
+NetworkSimplex.BALANCE_TOP_BOTTOM = 1
+NetworkSimplex.BALANCE_LEFT_RIGHT = 2
+
+
+function NetworkSimplex.new(graph, balancing)
+ local simplex = {
+ graph = graph,
+ balancing = balancing,
+ }
+ setmetatable(simplex, NetworkSimplex)
+ return simplex
+end
+
+
+
+function NetworkSimplex:run()
+
+ assert (#self.graph.nodes > 0, "graph must contain at least one node")
+
+ -- initialize the tree edge search index
+ self.search_index = 1
+
+ -- initialize internal edge parameters
+ self.cut_value = {}
+ for _,edge in ipairs(self.graph.edges) do
+ self.cut_value[edge] = 0
+ end
+
+ -- reset graph information needed for ranking
+ self.lim = {}
+ self.low = {}
+ self.parent_edge = {}
+ self.ranking = Ranking.new()
+
+ if #self.graph.nodes == 1 then
+ self.ranking:setRank(self.graph.nodes[1], 1)
+ else
+ self:rankNodes()
+ end
+end
+
+
+
+function NetworkSimplex:rankNodes()
+ -- construct feasible tree of tight edges
+ self:constructFeasibleTree()
+
+ -- iteratively replace edges with negative cut values
+ -- with non-tree edges (chosen by minimum slack)
+ local leave_edge = self:findNegativeCutEdge()
+ while leave_edge do
+ local enter_edge = self:findReplacementEdge(leave_edge)
+
+ assert(enter_edge, 'no non-tree edge to replace ' .. tostring(leave_edge) .. ' could be found')
+
+ -- exchange leave_edge and enter_edge in the tree, updating
+ -- the ranks and cut values of all nodes
+ self:exchangeTreeEdges(leave_edge, enter_edge)
+
+ -- find the next tree edge with a negative cut value, if
+ -- there are any left
+ leave_edge = self:findNegativeCutEdge()
+ end
+
+ if self.balancing == NetworkSimplex.BALANCE_TOP_BOTTOM then
+ -- normalize by setting the least rank to zero
+ self.ranking:normalizeRanks()
+
+ -- move nodes to feasible ranks with the least number of nodes
+ -- in order to avoid crowding and to improve the overall aspect
+ -- ratio of the drawing
+ self:balanceRanksTopBottom()
+ elseif self.balancing == NetworkSimplex.BALANCE_LEFT_RIGHT then
+ self:balanceRanksLeftRight()
+ end
+end
+
+
+
+function NetworkSimplex:constructFeasibleTree()
+
+ self:computeInitialRanking()
+
+ -- find a maximal tree of tight edges in the graph
+ while self:findTightTree() < #self.graph.nodes do
+
+ local min_slack_edge = nil
+
+ for _,node in ipairs(self.graph.nodes) do
+ local out_edges = node:getOutgoingEdges()
+ for _,edge in ipairs(out_edges) do
+ if not self.tree_edge[edge] and self:isIncidentToTree(edge) then
+ if not min_slack_edge or self:edgeSlack(edge) < self:edgeSlack(min_slack_edge) then
+ min_slack_edge = edge
+ end
+ end
+ end
+ end
+
+ if min_slack_edge then
+ local delta = self:edgeSlack(min_slack_edge)
+
+ if delta > 0 then
+ local head = min_slack_edge:getHead()
+ local tail = min_slack_edge:getTail()
+
+ if self.tree_node[head] then
+ delta = -delta
+ end
+
+
+ for _,node in ipairs(self.tree.nodes) do
+ local rank = self.ranking:getRank(self.orig_node[node])
+ self.ranking:setRank(self.orig_node[node], rank + delta)
+ end
+ end
+ end
+ end
+
+ self:initializeCutValues()
+end
+
+
+
+function NetworkSimplex:findNegativeCutEdge()
+ local minimum_edge = nil
+
+ for n=1,#self.tree.edges do
+ local index = self:nextSearchIndex()
+
+ local edge = self.tree.edges[index]
+
+ if self.cut_value[edge] < 0 then
+ if minimum_edge then
+ if self.cut_value[minimum_edge] > self.cut_value[edge] then
+ minimum_edge = edge
+ end
+ else
+ minimum_edge = edge
+ end
+ end
+ end
+
+ return minimum_edge
+end
+
+
+
+function NetworkSimplex:findReplacementEdge(leave_edge)
+ local tail = leave_edge:getTail()
+ local head = leave_edge:getHead()
+
+ local v = nil
+ local direction = nil
+
+ if self.lim[tail] < self.lim[head] then
+ v = tail
+ direction = 'in'
+ else
+ v = head
+ direction = 'out'
+ end
+
+ local search_root = v
+ local enter_edge = nil
+ local slack = math.huge
+
+ -- TODO Jannis: Get rid of this recursion:
+
+ local function find_edge(v, direction)
+
+ if direction == 'out' then
+ local out_edges = self.orig_node[v]:getOutgoingEdges()
+ for _,edge in ipairs(out_edges) do
+ local head = edge:getHead()
+ local tree_head = self.tree_node[head]
+
+ assert(head and tree_head)
+
+ if not self.tree_edge[edge] then
+ if not self:inTailComponentOf(tree_head, search_root) then
+ if self:edgeSlack(edge) < slack or not enter_edge then
+ enter_edge = edge
+ slack = self:edgeSlack(edge)
+ end
+ end
+ else
+ if self.lim[tree_head] < self.lim[v] then
+ find_edge(tree_head, 'out')
+ end
+ end
+ end
+
+ for _,edge in ipairs(v:getIncomingEdges()) do
+ if slack <= 0 then
+ break
+ end
+
+ local tail = edge:getTail()
+
+ if self.lim[tail] < self.lim[v] then
+ find_edge(tail, 'out')
+ end
+ end
+ else
+ local in_edges = self.orig_node[v]:getIncomingEdges()
+ for _,edge in ipairs(in_edges) do
+ local tail = edge:getTail()
+ local tree_tail = self.tree_node[tail]
+
+ assert(tail and tree_tail)
+
+ if not self.tree_edge[edge] then
+ if not self:inTailComponentOf(tree_tail, search_root) then
+ if self:edgeSlack(edge) < slack or not enter_edge then
+ enter_edge = edge
+ slack = self:edgeSlack(edge)
+ end
+ end
+ else
+ if self.lim[tree_tail] < self.lim[v] then
+ find_edge(tree_tail, 'in')
+ end
+ end
+ end
+
+ for _,edge in ipairs(v:getOutgoingEdges()) do
+ if slack <= 0 then
+ break
+ end
+
+ local head = edge:getHead()
+
+ if self.lim[head] < self.lim[v] then
+ find_edge(head, 'in')
+ end
+ end
+ end
+ end
+
+ find_edge(v, direction)
+
+ return enter_edge
+end
+
+
+
+function NetworkSimplex:exchangeTreeEdges(leave_edge, enter_edge)
+
+ self:rerankBeforeReplacingEdge(leave_edge, enter_edge)
+
+ local cutval = self.cut_value[leave_edge]
+ local head = self.tree_node[enter_edge:getHead()]
+ local tail = self.tree_node[enter_edge:getTail()]
+
+ local ancestor = self:updateCutValuesUpToCommonAncestor(tail, head, cutval, true)
+ local other_ancestor = self:updateCutValuesUpToCommonAncestor(head, tail, cutval, false)
+
+ assert(ancestor == other_ancestor)
+
+ -- remove the old edge from the tree
+ self:removeEdgeFromTree(leave_edge)
+
+ -- add the new edge to the tree
+ local tree_edge = self:addEdgeToTree(enter_edge)
+
+ -- set its cut value
+ self.cut_value[tree_edge] = -cutval
+
+ -- update DFS search tree traversal information
+ self:calculateDFSRange(ancestor, self.parent_edge[ancestor], self.low[ancestor])
+end
+
+
+
+function NetworkSimplex:balanceRanksTopBottom()
+
+ -- available ranks
+ local ranks = self.ranking:getRanks()
+
+ -- node to in/out weight mappings
+ local in_weight = {}
+ local out_weight = {}
+
+ -- node to lowest/highest possible rank mapping
+ local min_rank = {}
+ local max_rank = {}
+
+ -- compute the in and out weights of each node
+ for _,node in ipairs(self.graph.nodes) do
+ -- assume there are no restrictions on how to rank the node
+ min_rank[node], max_rank[node] = ranks[1], ranks[#ranks]
+
+ for _,edge in ipairs(node:getIncomingEdges()) do
+ -- accumulate the weights of all incoming edges
+ in_weight[node] = (in_weight[node] or 0) + edge.weight
+
+ -- update the minimum allowed rank (which is the maximum of
+ -- the ranks of all parent neighbors plus the minimum level
+ -- separation caused by the connecting edges)
+ local neighbour = edge:getNeighbour(node)
+ local neighbour_rank = self.ranking:getRank(neighbour)
+ min_rank[node] = math.max(min_rank[node], neighbour_rank + edge.minimum_levels)
+ end
+
+ for _,edge in ipairs(node:getOutgoingEdges()) do
+ -- accumulate the weights of all outgoing edges
+ out_weight[node] = (out_weight[node] or 0) + edge.weight
+
+ -- update the maximum allowed rank (which is the minimum of
+ -- the ranks of all child neighbors minus the minimum level
+ -- separation caused by the connecting edges)
+ local neighbour = edge:getNeighbour(node)
+ local neighbour_rank = self.ranking:getRank(neighbour)
+ max_rank[node] = math.min(max_rank[node], neighbour_rank - edge.minimum_levels)
+ end
+
+ -- check whether the in- and outweight is the same
+ if in_weight[node] == out_weight[node] then
+
+ -- check which of the allowed ranks has the least number of nodes
+ local min_nodes_rank = min_rank[node]
+ for n = min_rank[node] + 1, max_rank[node] do
+ if #self.ranking:getNodes(n) < #self.ranking:getNodes(min_nodes_rank) then
+ min_nodes_rank = n
+ end
+ end
+
+ -- only move the node to the rank with the least number of nodes
+ -- if it differs from the current rank of the node
+ if min_nodes_rank ~= self.ranking:getRank(node) then
+ self.ranking:setRank(node, min_nodes_rank)
+ end
+
+ end
+ end
+end
+
+
+
+function NetworkSimplex:balanceRanksLeftRight()
+ for _,edge in ipairs(self.tree.edges) do
+ if self.cut_value[edge] == 0 then
+ local other_edge = self:findReplacementEdge(edge)
+ if other_edge then
+ local delta = self:edgeSlack(other_edge)
+ if delta > 1 then
+ if self.lim[edge:getTail()] < self.lim[edge:getHead()] then
+ self:rerank(edge:getTail(), delta / 2)
+ else
+ self:rerank(edge:getHead(), -delta / 2)
+ end
+ end
+ end
+ end
+ end
+end
+
+
+
+function NetworkSimplex:computeInitialRanking()
+
+ -- queue for nodes to rank next
+ local queue = {}
+
+ -- convenience functions for managing the queue
+ local function enqueue(node) table.insert(queue, node) end
+ local function dequeue() return table.remove(queue, 1) end
+
+ -- reset the two-dimensional mapping from ranks to lists
+ -- of corresponding nodes
+ self.ranking:reset()
+
+ -- mapping of nodes to the number of unscanned incoming edges
+ local remaining_edges = {}
+
+ -- add all sinks to the queue
+ for _,node in ipairs(self.graph.nodes) do
+ local edges = node:getIncomingEdges()
+
+ remaining_edges[node] = #edges
+
+ if #edges == 0 then
+ enqueue(node)
+ end
+ end
+
+ -- run long as there are nodes to be ranked
+ while #queue > 0 do
+
+ -- fetch the next unranked node from the queue
+ local node = dequeue()
+
+ -- get a list of its incoming edges
+ local in_edges = node:getIncomingEdges()
+
+ -- determine the minimum possible rank for the node
+ local rank = 1
+ for _,edge in ipairs(in_edges) do
+ local neighbour = edge:getNeighbour(node)
+ if self.ranking:getRank(neighbour) then
+ -- the minimum possible rank is the maximum of all neighbor ranks plus
+ -- the corresponding edge lengths
+ rank = math.max(rank, self.ranking:getRank(neighbour) + edge.minimum_levels)
+ end
+ end
+
+ -- rank the node
+ self.ranking:setRank(node, rank)
+
+ -- get a list of the node's outgoing edges
+ local out_edges = node:getOutgoingEdges()
+
+ -- queue neighbors of nodes for which all incoming edges have been scanned
+ for _,edge in ipairs(out_edges) do
+ local head = edge:getHead()
+ remaining_edges[head] = remaining_edges[head] - 1
+ if remaining_edges[head] <= 0 then
+ enqueue(head)
+ end
+ end
+ end
+end
+
+
+
+function NetworkSimplex:findTightTree()
+
+ -- TODO: Jannis: Remove the recursion below:
+
+ local marked = {}
+
+ local function build_tight_tree(node)
+
+ local out_edges = node:getOutgoingEdges()
+ local in_edges = node:getIncomingEdges()
+
+ local edges = lib.copy(out_edges)
+ for _,v in ipairs(in_edges) do
+ edges[#edges + 1] = v
+ end
+
+ for _,edge in ipairs(edges) do
+ local neighbour = edge:getNeighbour(node)
+ if (not marked[neighbour]) and math.abs(self:edgeSlack(edge)) < 0.00001 then
+ self:addEdgeToTree(edge)
+
+ for _,node in ipairs(edge.nodes) do
+ marked[node] = true
+ end
+
+ if #self.tree.edges == #self.graph.nodes-1 then
+ return true
+ end
+
+ if build_tight_tree(neighbour) then
+ return true
+ end
+ end
+ end
+
+ return false
+ end
+
+ for _,node in ipairs(self.graph.nodes) do
+ self.tree = Graph.new()
+ self.tree_node = {}
+ self.orig_node = {}
+ self.tree_edge = {}
+ self.orig_edge = {}
+
+ build_tight_tree(node)
+
+ if #self.tree.edges > 0 then
+ break
+ end
+ end
+
+ return #self.tree.nodes
+end
+
+
+
+function NetworkSimplex:edgeSlack(edge)
+ -- make sure this is never called with a tree edge
+ assert(not self.orig_edge[edge])
+
+ local head_rank = self.ranking:getRank(edge:getHead())
+ local tail_rank = self.ranking:getRank(edge:getTail())
+ local length = head_rank - tail_rank
+ return length - edge.minimum_levels
+end
+
+
+
+function NetworkSimplex:isIncidentToTree(edge)
+ -- make sure this is never called with a tree edge
+ assert(not self.orig_edge[edge])
+
+ local head = edge:getHead()
+ local tail = edge:getTail()
+
+ if self.tree_node[head] and not self.tree_node[tail] then
+ return true
+ elseif self.tree_node[tail] and not self.tree_node[head] then
+ return true
+ else
+ return false
+ end
+end
+
+
+
+function NetworkSimplex:initializeCutValues()
+ self:calculateDFSRange(self.tree.nodes[1], nil, 1)
+
+ local function init(search)
+ search:push({ node = self.tree.nodes[1], parent_edge = nil })
+ end
+
+ local function visit(search, data)
+ search:setVisited(data, true)
+
+ local into = data.node:getIncomingEdges()
+ local out = data.node:getOutgoingEdges()
+
+ for i=#into,1,-1 do
+ local edge = into[i]
+ if edge ~= data.parent_edge then
+ search:push({ node = edge:getTail(), parent_edge = edge })
+ end
+ end
+
+ for i=#out,1,-1 do
+ local edge = out[i]
+ if edge ~= data.parent_edge then
+ search:push({ node = edge:getHead(), parent_edge = edge })
+ end
+ end
+ end
+
+ local function complete(search, data)
+ if data.parent_edge then
+ self:updateCutValue(data.parent_edge)
+ end
+ end
+
+ DepthFirstSearch.new(init, visit, complete):run()
+end
+
+
+
+--- DFS algorithm that calculates post-order traversal indices and parent edges.
+--
+-- This algorithm performs a depth-first search in a directed or undirected
+-- graph. For each node it calculates the node's post-order traversal index, the
+-- minimum post-order traversal index of its descendants as well as the edge by
+-- which the node was reached in the depth-first traversal.
+--
+function NetworkSimplex:calculateDFSRange(root, edge_from_parent, lowest)
+
+ -- global traversal index counter
+ local lim = lowest
+
+ -- start the traversal at the root node
+ local function init(search)
+ search:push({ node = root, parent_edge = edge_from_parent, low = lowest })
+ end
+
+ -- visit nodes in depth-first order
+ local function visit(search, data)
+ -- mark node as visited so we only visit it once
+ search:setVisited(data, true)
+
+ -- remember the parent edge
+ self.parent_edge[data.node] = data.parent_edge
+
+ -- remember the minimum traversal index for this branch of the search tree
+ self.low[data.node] = lim
+
+ -- next we push all outgoing and incoming edges in reverse order
+ -- to simulate recursive calls
+
+ local into = data.node:getIncomingEdges()
+ local out = data.node:getOutgoingEdges()
+
+ for i=#into,1,-1 do
+ local edge = into[i]
+ if edge ~= data.parent_edge then
+ search:push({ node = edge:getTail(), parent_edge = edge })
+ end
+ end
+
+ for i=#out,1,-1 do
+ local edge = out[i]
+ if edge ~= data.parent_edge then
+ search:push({ node = edge:getHead(), parent_edge = edge })
+ end
+ end
+ end
+
+ -- when completing a node, store its own traversal index
+ local function complete(search, data)
+ self.lim[data.node] = lim
+ lim = lim + 1
+ end
+
+ -- kick off the depth-first search
+ DepthFirstSearch.new(init, visit, complete):run()
+
+ local lim_lookup = {}
+ local min_lim = math.huge
+ local max_lim = -math.huge
+ for _,node in ipairs(self.tree.nodes) do
+ assert(self.lim[node])
+ assert(self.low[node])
+ assert(not lim_lookup[self.lim[node]])
+ lim_lookup[self.lim[node]] = true
+ min_lim = math.min(min_lim, self.lim[node])
+ max_lim = math.max(max_lim, self.lim[node])
+ end
+ for n = min_lim, max_lim do
+ assert(lim_lookup[n] == true)
+ end
+end
+
+
+
+function NetworkSimplex:updateCutValue(tree_edge)
+
+ local v = nil
+ if self.parent_edge[tree_edge:getTail()] == tree_edge then
+ v = tree_edge:getTail()
+ dir = 1
+ else
+ v = tree_edge:getHead()
+ dir = -1
+ end
+
+ local sum = 0
+
+ local out_edges = self.orig_node[v]:getOutgoingEdges()
+ local in_edges = self.orig_node[v]:getIncomingEdges()
+ local edges = lib.copy(out_edges)
+ for _,v in ipairs(in_edges) do
+ edges[#edges + 1] = v
+ end
+
+ for _,edge in ipairs(edges) do
+ local other = edge:getNeighbour(self.orig_node[v])
+
+ local f = 0
+ local rv = 0
+
+ if not self:inTailComponentOf(self.tree_node[other], v) then
+ f = 1
+ rv = edge.weight
+ else
+ f = 0
+
+ if self.tree_edge[edge] then
+ rv = self.cut_value[self.tree_edge[edge]]
+ else
+ rv = 0
+ end
+
+ rv = rv - edge.weight
+ end
+
+ local d = 0
+
+ if dir > 0 then
+ if edge:isHead(self.orig_node[v]) then
+ d = 1
+ else
+ d = -1
+ end
+ else
+ if edge:isTail(self.orig_node[v]) then
+ d = 1
+ else
+ d = -1
+ end
+ end
+
+ if f > 0 then
+ d = -d
+ end
+
+ if d < 0 then
+ rv = -rv
+ end
+
+ sum = sum + rv
+ end
+
+ self.cut_value[tree_edge] = sum
+end
+
+
+
+function NetworkSimplex:inTailComponentOf(node, v)
+ return (self.low[v] <= self.lim[node]) and (self.lim[node] <= self.lim[v])
+end
+
+
+
+function NetworkSimplex:nextSearchIndex()
+ local index = 1
+
+ -- avoid tree edge index out of bounds by resetting the search index
+ -- as soon as it leaves the range of edge indices in the tree
+ if self.search_index > #self.tree.edges then
+ self.search_index = 1
+ index = 1
+ else
+ index = self.search_index
+ self.search_index = self.search_index + 1
+ end
+
+ return index
+end
+
+
+
+function NetworkSimplex:rerank(node, delta)
+ local function init(search)
+ search:push({ node = node, delta = delta })
+ end
+
+ local function visit(search, data)
+ search:setVisited(data, true)
+
+ local orig_node = self.orig_node[data.node]
+ self.ranking:setRank(orig_node, self.ranking:getRank(orig_node) - data.delta)
+
+ local into = data.node:getIncomingEdges()
+ local out = data.node:getOutgoingEdges()
+
+ for i=#into,1,-1 do
+ local edge = into[i]
+ if edge ~= self.parent_edge[data.node] then
+ search:push({ node = edge:getTail(), delta = data.delta })
+ end
+ end
+
+ for i=#out,1,-1 do
+ local edge = out[i]
+ if edge ~= self.parent_edge[data.node] then
+ search:push({ node = edge:getHead(), delta = data.delta })
+ end
+ end
+ end
+
+ DepthFirstSearch.new(init, visit):run()
+end
+
+
+
+function NetworkSimplex:rerankBeforeReplacingEdge(leave_edge, enter_edge)
+ local delta = self:edgeSlack(enter_edge)
+
+ if delta > 0 then
+ local tail = leave_edge:getTail()
+
+ if #tail.edges == 1 then
+ self:rerank(tail, delta)
+ else
+ local head = leave_edge:getHead()
+
+ if #head.edges == 1 then
+ self:rerank(head, -delta)
+ else
+ if self.lim[tail] < self.lim[head] then
+ self:rerank(tail, delta)
+ else
+ self:rerank(head, -delta)
+ end
+ end
+ end
+ end
+end
+
+
+
+function NetworkSimplex:updateCutValuesUpToCommonAncestor(v, w, cutval, dir)
+
+ while not self:inTailComponentOf(w, v) do
+ local edge = self.parent_edge[v]
+
+ if edge:isTail(v) then
+ d = dir
+ else
+ d = not dir
+ end
+
+ if d then
+ self.cut_value[edge] = self.cut_value[edge] + cutval
+ else
+ self.cut_value[edge] = self.cut_value[edge] - cutval
+ end
+
+ if self.lim[edge:getTail()] > self.lim[edge:getHead()] then
+ v = edge:getTail()
+ else
+ v = edge:getHead()
+ end
+ end
+
+ return v
+end
+
+
+
+function NetworkSimplex:addEdgeToTree(edge)
+ assert(not self.tree_edge[edge])
+
+ -- create the new tree edge
+ local tree_edge = edge:copy()
+ self.orig_edge[tree_edge] = edge
+ self.tree_edge[edge] = tree_edge
+
+ -- create tree nodes if necessary
+ for _,node in ipairs(edge.nodes) do
+ local tree_node
+
+ if self.tree_node[node] then
+ tree_node = self.tree_node[node]
+ else
+ tree_node = node:copy()
+ self.orig_node[tree_node] = node
+ self.tree_node[node] = tree_node
+ end
+
+ self.tree:addNode(tree_node)
+ tree_edge:addNode(tree_node)
+ end
+
+ self.tree:addEdge(tree_edge)
+
+ return tree_edge
+end
+
+
+
+function NetworkSimplex:removeEdgeFromTree(edge)
+ self.tree:deleteEdge(edge)
+ self.tree_edge[self.orig_edge[edge]] = nil
+ self.orig_edge[edge] = nil
+end
+
+
+
+
+-- Done
+
+return NetworkSimplex \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua
new file mode 100644
index 0000000000..3e5a0f8f87
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua
@@ -0,0 +1,154 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+local NodePositioningGansnerKNV1993 = {}
+
+
+-- Imports
+
+local layered = require "pgf.gd.layered"
+
+local Graph = require "pgf.gd.deprecated.Graph"
+local Edge = require "pgf.gd.deprecated.Edge"
+local Node = require "pgf.gd.deprecated.Node"
+
+local NetworkSimplex = require "pgf.gd.layered.NetworkSimplex"
+local Storage = require "pgf.gd.lib.Storage"
+
+
+function NodePositioningGansnerKNV1993:run()
+ local auxiliary_graph = self:constructAuxiliaryGraph()
+
+ local simplex = NetworkSimplex.new(auxiliary_graph, NetworkSimplex.BALANCE_LEFT_RIGHT)
+ simplex:run()
+ local x_ranking = simplex.ranking
+
+ local layers = Storage.new()
+
+ local ranks = self.ranking:getRanks()
+ for _,rank in ipairs(ranks) do
+ local nodes = self.ranking:getNodes(rank)
+ for _,node in ipairs(nodes) do
+ node.pos.x = x_ranking:getRank(node.aux_node)
+ layers[node.orig_vertex] = rank
+ end
+ end
+
+ layered.arrange_layers_by_baselines(layers, self.main_algorithm.adjusted_bb, self.main_algorithm.ugraph)
+
+ -- Copy back
+ for _,rank in ipairs(ranks) do
+ local nodes = self.ranking:getNodes(rank)
+ for _,node in ipairs(nodes) do
+ node.pos.y = node.orig_vertex.pos.y
+ end
+ end
+end
+
+
+
+
+function NodePositioningGansnerKNV1993:constructAuxiliaryGraph()
+
+ local aux_graph = Graph.new()
+
+ local edge_node = {}
+
+ for _,node in ipairs(self.graph.nodes) do
+ local copy = Node.new{
+ name = node.name,
+ orig_node = node,
+ }
+ node.aux_node = copy
+ aux_graph:addNode(copy)
+ end
+
+ for i=#self.graph.edges,1,-1 do
+ local edge = self.graph.edges[i]
+ local node = Node.new{
+ name = '{' .. tostring(edge) .. '}',
+ }
+
+ aux_graph:addNode(node)
+
+ node.orig_edge = edge
+ edge_node[edge] = node
+
+ local head = edge:getHead()
+ local tail = edge:getTail()
+
+ local tail_edge = Edge.new{
+ direction = Edge.RIGHT,
+ minimum_levels = 0,
+ weight = edge.weight * self:getOmega(edge),
+ }
+ tail_edge:addNode(node)
+ tail_edge:addNode(tail.aux_node)
+ aux_graph:addEdge(tail_edge)
+
+ local head_edge = Edge.new{
+ direction = Edge.RIGHT,
+ minimum_levels = 0,
+ weight = edge.weight * self:getOmega(edge),
+ }
+ head_edge:addNode(node)
+ head_edge:addNode(head.aux_node)
+ aux_graph:addEdge(head_edge)
+ end
+
+ local ranks = self.ranking:getRanks()
+ for _,rank in ipairs(ranks) do
+ local nodes = self.ranking:getNodes(rank)
+ for n = 1, #nodes-1 do
+ local v = nodes[n]
+ local w = nodes[n+1]
+
+ local separator_edge = Edge.new{
+ direction = Edge.RIGHT,
+ minimum_levels = self:getDesiredHorizontalDistance(v, w),
+ weight = 0,
+ }
+ separator_edge:addNode(v.aux_node)
+ separator_edge:addNode(w.aux_node)
+ aux_graph:addEdge(separator_edge)
+ end
+ end
+
+ return aux_graph
+end
+
+
+
+function NodePositioningGansnerKNV1993:getOmega(edge)
+ local node1 = edge.nodes[1]
+ local node2 = edge.nodes[2]
+
+ if (node1.kind == "dummy") and (node2.kind == "dummy") then
+ return 8
+ elseif (node1.kind == "dummy") or (node2.kind == "dummy") then
+ return 2
+ else
+ return 1
+ end
+end
+
+
+
+function NodePositioningGansnerKNV1993:getDesiredHorizontalDistance(v, w)
+ return layered.ideal_sibling_distance(self.main_algorithm.adjusted_bb, self.graph.orig_digraph, v.orig_vertex, w.orig_vertex)
+end
+
+
+-- done
+
+return NodePositioningGansnerKNV1993 \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua
new file mode 100644
index 0000000000..d6765ae2f0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua
@@ -0,0 +1,159 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local NodeRankingGansnerKNV1993 = {}
+
+
+-- Imports
+
+local Edge = require "pgf.gd.deprecated.Edge"
+local Node = require "pgf.gd.deprecated.Node"
+
+local NetworkSimplex = require "pgf.gd.layered.NetworkSimplex"
+
+
+
+function NodeRankingGansnerKNV1993:run()
+
+ local simplex = NetworkSimplex.new(self.graph, NetworkSimplex.BALANCE_TOP_BOTTOM)
+ simplex:run()
+ self.ranking = simplex.ranking
+
+ return simplex.ranking
+end
+
+
+
+function NodeRankingGansnerKNV1993:mergeClusters()
+
+ self.cluster_nodes = {}
+ self.cluster_node = {}
+ self.cluster_edges = {}
+
+ self.original_nodes = {}
+ self.original_edges = {}
+
+ for _,cluster in ipairs(self.graph.clusters) do
+
+ local cluster_node = Node.new{
+ name = 'cluster@' .. cluster.name,
+ }
+ table.insert(self.cluster_nodes, cluster_node)
+
+ for _,node in ipairs(cluster.nodes) do
+ self.cluster_node[node] = cluster_node
+ table.insert(self.original_nodes, node)
+ end
+
+ self.graph:addNode(cluster_node)
+ end
+
+ for _,edge in ipairs(self.graph.edges) do
+ local tail = edge:getTail()
+ local head = edge:getHead()
+
+ if self.cluster_node[tail] or self.cluster_node[head] then
+ table.insert(self.original_edges, edge)
+
+ local cluster_edge = Edge.new{
+ direction = Edge.RIGHT,
+ weight = edge.weight,
+ minimum_levels = edge.minimum_levels,
+ }
+ table.insert(self.cluster_edges, cluster_edge)
+
+ if self.cluster_node[tail] then
+ cluster_edge:addNode(self.cluster_node[tail])
+ else
+ cluster_edge:addNode(tail)
+ end
+
+ if self.cluster_node[head] then
+ cluster_edge:addNode(self.cluster_node[head])
+ else
+ cluster_edge:addNode(head)
+ end
+
+ end
+ end
+
+ for _,edge in ipairs(self.cluster_edges) do
+ self.graph:addEdge(edge)
+ end
+
+ for _,edge in ipairs(self.original_edges) do
+ self.graph:deleteEdge(edge)
+ end
+
+ for _,node in ipairs(self.original_nodes) do
+ self.graph:deleteNode(node)
+ end
+end
+
+
+
+function NodeRankingGansnerKNV1993:createClusterEdges()
+ for n = 1, #self.cluster_nodes-1 do
+ local first_cluster = self.cluster_nodes[n]
+ local second_cluster = self.cluster_nodes[n+1]
+
+ local edge = Edge.new{
+ direction = Edge.RIGHT,
+ weight = 1,
+ minimum_levels = 1,
+ }
+
+ edge:addNode(first_cluster)
+ edge:addNode(second_cluster)
+
+ self.graph:addEdge(edge)
+
+ table.insert(self.cluster_edges, edge)
+ end
+end
+
+
+
+function NodeRankingGansnerKNV1993:removeClusterEdges()
+end
+
+
+
+function NodeRankingGansnerKNV1993:expandClusters()
+
+ for _,node in ipairs(self.original_nodes) do
+ assert(self.ranking:getRank(self.cluster_node[node]))
+ self.ranking:setRank(node, self.ranking:getRank(self.cluster_node[node]))
+ self.graph:addNode(node)
+ end
+
+ for _,edge in ipairs(self.original_edges) do
+ for _,node in ipairs(edge.nodes) do
+ node:addEdge(edge)
+ end
+ self.graph:addEdge(edge)
+ end
+
+ for _,node in ipairs(self.cluster_nodes) do
+ self.ranking:setRank(node, nil)
+ self.graph:deleteNode(node)
+ end
+
+ for _,edge in ipairs(self.cluster_edges) do
+ self.graph:deleteEdge(edge)
+ end
+end
+
+
+-- done
+
+return NodeRankingGansnerKNV1993 \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua
new file mode 100644
index 0000000000..644b99c28a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua
@@ -0,0 +1,47 @@
+-- Copyright 2011 by Jannis Pohlmann
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local NodeRankingMinimumHeight = {}
+
+-- Imports
+
+local Ranking = require "pgf.gd.layered.Ranking"
+local Iterators = require "pgf.gd.deprecated.Iterators"
+
+
+function NodeRankingMinimumHeight:run()
+ local ranking = Ranking.new()
+
+ for node in Iterators.topologicallySorted(self.graph) do
+ local edges = node:getIncomingEdges()
+
+ if #edges == 0 then
+ ranking:setRank(node, 1)
+ else
+ local max_rank = -math.huge
+ for _,edge in ipairs(edges) do
+ max_rank = math.max(max_rank, ranking:getRank(edge:getNeighbour(node)))
+ end
+
+ assert(max_rank >= 1)
+
+ ranking:setRank(node, max_rank + 1)
+ end
+ end
+
+ return ranking
+end
+
+
+-- done
+
+return NodeRankingMinimumHeight
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Ranking.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Ranking.lua
new file mode 100644
index 0000000000..6ed63b0249
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Ranking.lua
@@ -0,0 +1,291 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+--- The Ranking class is used by the Sugiyama algorithm to compute an
+-- ordering on the nodes of a layer
+
+local Ranking = {}
+Ranking.__index = Ranking
+
+-- Namespace
+local layered = require "pgf.gd.layered"
+layered.Ranking = Ranking
+
+
+local lib = require "pgf.gd.lib"
+
+
+-- TODO Jannis: document!
+
+
+function Ranking.new()
+ local ranking = {
+ rank_to_nodes = {},
+ node_to_rank = {},
+ position_in_rank = {},
+ }
+ setmetatable(ranking, Ranking)
+ return ranking
+end
+
+
+
+function Ranking:copy()
+ local copied_ranking = Ranking.new()
+
+ -- copy rank to nodes mapping
+ for rank, nodes in pairs(self.rank_to_nodes) do
+ copied_ranking.rank_to_nodes[rank] = lib.copy(self.rank_to_nodes[rank])
+ end
+
+ -- copy node to rank mapping
+ copied_ranking.node_to_rank = lib.copy(self.node_to_rank)
+
+ -- copy node to position in rank mapping
+ copied_ranking.position_in_rank = lib.copy(self.position_in_rank)
+
+ return copied_ranking
+end
+
+
+
+function Ranking:reset()
+ self.rank_to_nodes = {}
+ self.node_to_rank = {}
+ self.position_in_rank = {}
+end
+
+
+
+function Ranking:getRanks()
+ local ranks = {}
+ for rank, nodes in pairs(self.rank_to_nodes) do
+ table.insert(ranks, rank)
+ end
+ table.sort(ranks)
+ return ranks
+end
+
+
+
+function Ranking:getRankSize(rank)
+ if self.rank_to_nodes[rank] then
+ return #self.rank_to_nodes[rank]
+ else
+ return 0
+ end
+end
+
+
+
+function Ranking:getNodeInfo(node)
+ return self:getRank(node), self:getRankPosition(node)
+end
+
+
+
+function Ranking:getNodes(rank)
+ return self.rank_to_nodes[rank] or {}
+end
+
+
+
+function Ranking:getRank(node)
+ return self.node_to_rank[node]
+end
+
+
+
+function Ranking:setRank(node, new_rank)
+ local rank, pos = self:getNodeInfo(node)
+
+ if rank == new_rank then
+ return
+ end
+
+ if rank then
+ for n = pos+1, #self.rank_to_nodes[rank] do
+ local other_node = self.rank_to_nodes[rank][n]
+ self.position_in_rank[other_node] = self.position_in_rank[other_node]-1
+ end
+
+ table.remove(self.rank_to_nodes[rank], pos)
+ self.node_to_rank[node] = nil
+ self.position_in_rank[node] = nil
+
+ if #self.rank_to_nodes[rank] == 0 then
+ self.rank_to_nodes[rank] = nil
+ end
+ end
+
+ if new_rank then
+ self.rank_to_nodes[new_rank] = self.rank_to_nodes[new_rank] or {}
+ table.insert(self.rank_to_nodes[new_rank], node)
+ self.node_to_rank[node] = new_rank
+ self.position_in_rank[node] = #self.rank_to_nodes[new_rank]
+ end
+end
+
+
+
+function Ranking:getRankPosition(node)
+ return self.position_in_rank[node]
+end
+
+
+
+function Ranking:setRankPosition(node, new_pos)
+ local rank, pos = self:getNodeInfo(node)
+
+ assert((rank and pos) or ((not rank) and (not pos)))
+
+ if pos == new_pos then
+ return
+ end
+
+ if rank and pos then
+ for n = pos+1, #self.rank_to_nodes[rank] do
+ local other_node = self.rank_to_nodes[rank][n]
+ self.position_in_rank[other_node] = self.position_in_rank[other_node]-1
+ end
+
+ table.remove(self.rank_to_nodes[rank], pos)
+ self.node_to_rank[node] = nil
+ self.position_in_rank[node] = nil
+ end
+
+ if new_pos then
+ self.rank_to_nodes[rank] = self.rank_to_nodes[rank] or {}
+
+ for n = new_pos+1, #self.rank_to_nodes[rank] do
+ local other_node = self.rank_to_nodes[rank][new_pos]
+ self.position_in_rank[other_node] = self.position_in_rank[other_node]+1
+ end
+
+ table.insert(self.rank_to_nodes[rank], node)
+ self.node_to_rank[node] = rank
+ self.position_in_rank[node] = new_pos
+ end
+end
+
+
+
+function Ranking:normalizeRanks()
+
+ -- get the current ranks
+ local ranks = self:getRanks()
+
+ local min_rank = ranks[1]
+ local max_rank = ranks[#ranks]
+
+ -- clear ranks
+ self.rank_to_nodes = {}
+
+ -- iterate over all nodes and rerank them manually
+ for node in pairs(self.position_in_rank) do
+ local rank, pos = self:getNodeInfo(node)
+ local new_rank = rank - (min_rank - 1)
+
+ self.rank_to_nodes[new_rank] = self.rank_to_nodes[new_rank] or {}
+ self.rank_to_nodes[new_rank][pos] = node
+
+ self.node_to_rank[node] = new_rank
+ end
+end
+
+
+
+function Ranking:switchPositions(left_node, right_node)
+ local left_rank = self.node_to_rank[left_node]
+ local right_rank = self.node_to_rank[right_node]
+
+ assert(left_rank == right_rank, 'only positions of nodes in the same rank can be switched')
+
+ local left_pos = self.position_in_rank[left_node]
+ local right_pos = self.position_in_rank[right_node]
+
+ self.rank_to_nodes[left_rank][left_pos] = right_node
+ self.rank_to_nodes[left_rank][right_pos] = left_node
+
+ self.position_in_rank[left_node] = right_pos
+ self.position_in_rank[right_node] = left_pos
+end
+
+
+
+function Ranking:reorderRank(rank, get_index_func, is_fixed_func)
+ self:reorderTable(self.rank_to_nodes[rank], get_index_func, is_fixed_func)
+
+ for n = 1, #self.rank_to_nodes[rank] do
+ self.position_in_rank[self.rank_to_nodes[rank][n]] = n
+ end
+end
+
+
+
+function Ranking:reorderTable(input, get_index_func, is_fixed_func)
+ -- collect all allowed indices
+ local allowed_indices = {}
+ for n = 1, #input do
+ if not is_fixed_func(n, input[n]) then
+ table.insert(allowed_indices, n)
+ end
+ end
+
+ -- collect all desired indices; for each of these desired indices,
+ -- remember by which element it was requested
+ local desired_to_real_indices = {}
+ local sort_indices = {}
+ for n = 1, #input do
+ if not is_fixed_func(n, input[n]) then
+ local index = get_index_func(n, input[n])
+ if not desired_to_real_indices[index] then
+ desired_to_real_indices[index] = {}
+ table.insert(sort_indices, index)
+ end
+ table.insert(desired_to_real_indices[index], n)
+ end
+ end
+
+ -- sort the desired indices
+ table.sort(sort_indices)
+
+ -- compute the final indices by counting the final indices generated
+ -- prior to the current one and by mapping this number to the allowed
+ -- index with the same number
+ local final_indices = {}
+ local n = 1
+ for _,index in ipairs(sort_indices) do
+ local real_indices = desired_to_real_indices[index]
+ for _,real_index in ipairs(real_indices) do
+ final_indices[real_index] = allowed_indices[n]
+ n = n + 1
+ end
+ end
+
+ -- flat-copy the input table so that we can still access the elements
+ -- using their real index while overwriting the input table in-place
+ local input_copy = lib.copy(input)
+
+ -- move flexible elements to their final indices
+ for old_index, new_index in pairs(final_indices) do
+ input[new_index] = input_copy[old_index]
+ end
+end
+
+
+
+-- Done
+
+return Ranking \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua
new file mode 100644
index 0000000000..c91818dc30
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua
@@ -0,0 +1,476 @@
+-- Copyright 2011 by Jannis Pohlmann, 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {The Modular Sugiyama Method}
+--
+-- @end
+
+local Sugiyama = {}
+
+-- Namespace
+require("pgf.gd.layered").Sugiyama = Sugiyama
+
+-- Imports
+local layered = require "pgf.gd.layered"
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+local Ranking = require "pgf.gd.layered.Ranking"
+local Simplifiers = require "pgf.gd.lib.Simplifiers"
+
+-- Deprecated stuff. Need to get rid of it!
+local Edge = require "pgf.gd.deprecated.Edge"
+local Node = require "pgf.gd.deprecated.Node"
+
+local Iterators = require "pgf.gd.deprecated.Iterators"
+local Vector = require "pgf.gd.deprecated.Vector"
+
+
+
+---
+
+declare {
+ key = "layered layout",
+ algorithm = Sugiyama,
+
+ preconditions = {
+ connected = true,
+ loop_free = true,
+ },
+
+ postconditions = {
+ upward_oriented = true
+ },
+
+ old_graph_model = true,
+
+ summary = [["
+ The |layered layout| is the key used to select the modular Sugiyama
+ layout algorithm.
+ "]],
+ documentation = [["
+ This algorithm consists of five consecutive steps, each of which can be
+ configured independently of the other ones (how this is done is
+ explained later in this section). Naturally, the ``best'' heuristics
+ are selected by default, so there is typically no need to change the
+ settings, but what is the ``best'' method for one graph need not be
+ the best one for another graph.
+
+ As can be seen in the first example, the algorithm will not only
+ position the nodes of a graph, but will also perform an edge
+ routing. This will look visually quite pleasing if you add the
+ |rounded corners| option:
+ "]],
+ examples = {[["
+ \tikz \graph [layered layout, sibling distance=7mm]
+ {
+ a -> {
+ b,
+ c -> { d, e, f }
+ } ->
+ h ->
+ a
+ };
+ "]],[["
+ \tikz [rounded corners] \graph [layered layout, sibling distance=7mm]
+ {
+ a -> {
+ b,
+ c -> { d, e, f }
+ } ->
+ h ->
+ a
+ };
+ "]]
+ }
+}
+
+---
+
+declare {
+ key = "minimum layers",
+ type = "number",
+ initial = "1",
+
+ summary = [["
+ The minimum number of levels that an edge must span. It is a bit of
+ the opposite of the |weight| parameter: While a large |weight|
+ causes an edge to become shorter, a larger |minimum layers| value
+ causes an edge to be longer.
+ "]],
+ examples = [["
+ \tikz \graph [layered layout] {
+ a -- {b [> minimum layers=3], c, d} -- e -- a;
+ };
+ "]]
+}
+
+
+---
+
+declare {
+ key = "same layer",
+ layer = 0,
+
+ summary = [["
+ The |same layer| collection allows you to enforce that several nodes
+ a on the same layer of a layered layout (this option is also known
+ as |same rank|). You use it like this:
+ "]],
+ examples = {[["
+ \tikz \graph [layered layout] {
+ a -- b -- c -- d -- e;
+
+ { [same layer] a, b };
+ { [same layer] d, e };
+ };
+ "]],[["
+ \tikz [rounded corners] \graph [layered layout] {
+ 1972 -> 1976 -> 1978 -> 1980 -> 1982 -> 1984 -> 1986 -> 1988 -> 1990 -> future;
+
+ { [same layer] 1972, Thompson };
+ { [same layer] 1976, Mashey, Bourne },
+ { [same layer] 1978, Formshell, csh },
+ { [same layer] 1980, esh, vsh },
+ { [same layer] 1982, ksh, "System-V" },
+ { [same layer] 1984, v9sh, tcsh },
+ { [same layer] 1986, "ksh-i" },
+ { [same layer] 1988, KornShell ,Perl, rc },
+ { [same layer] 1990, tcl, Bash },
+ { [same layer] "future", POSIX, "ksh-POSIX" },
+
+ Thompson -> { Mashey, Bourne, csh -> tcsh},
+ Bourne -> { ksh, esh, vsh, "System-V", v9sh -> rc, Bash},
+ { "ksh-i", KornShell } -> Bash,
+ { esh, vsh, Formshell, csh } -> ksh,
+ { KornShell, "System-V" } -> POSIX,
+ ksh -> "ksh-i" -> KornShell -> "ksh-POSIX",
+ Bourne -> Formshell,
+
+ { [edge={draw=none}]
+ Bash -> tcl,
+ KornShell -> Perl
+ }
+ };
+ "]]
+ }
+}
+
+
+
+-- Implementation
+
+function Sugiyama:run()
+ if #self.graph.nodes <= 1 then
+ return
+ end
+
+ local options = self.digraph.options
+
+ local cycle_removal_algorithm_class = options.algorithm_phases['cycle removal']
+ local node_ranking_algorithm_class = options.algorithm_phases['node ranking']
+ local crossing_minimization_algorithm_class = options.algorithm_phases['crossing minimization']
+ local node_positioning_algorithm_class = options.algorithm_phases['node positioning']
+ local edge_routing_algorithm_class = options.algorithm_phases['layer edge routing']
+
+ self:preprocess()
+
+ -- Helper function for collapsing multiedges
+ local function collapse (m,e)
+ m.weight = (m.weight or 0) + e.weight
+ m.minimum_levels = math.max((m.minimum_levels or 0), e.minimum_levels)
+ end
+
+ -- Rank using cluster
+
+ -- Create a subalgorithm object. Needed so that removed loops
+ -- are not stored on top of removed loops from main call.
+ local cluster_subalgorithm = { graph = self.graph }
+ self.graph:registerAlgorithm(cluster_subalgorithm)
+
+ self:mergeClusters()
+
+ Simplifiers:removeLoopsOldModel(cluster_subalgorithm)
+ Simplifiers:collapseMultiedgesOldModel(cluster_subalgorithm, collapse)
+
+ cycle_removal_algorithm_class.new { main_algorithm = self, graph = self.graph }:run()
+ self.ranking = node_ranking_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run()
+ self:restoreCycles()
+
+ Simplifiers:expandMultiedgesOldModel(cluster_subalgorithm)
+ Simplifiers:restoreLoopsOldModel(cluster_subalgorithm)
+
+ self:expandClusters()
+
+ -- Now do actual computation
+ Simplifiers:collapseMultiedgesOldModel(cluster_subalgorithm, collapse)
+ cycle_removal_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run()
+ self:insertDummyNodes()
+
+ -- Main algorithm
+ crossing_minimization_algorithm_class.new{
+ main_algorithm = self,
+ graph = self.graph,
+ ranking = self.ranking
+ }:run()
+ node_positioning_algorithm_class.new{
+ main_algorithm = self,
+ graph = self.graph,
+ ranking = self.ranking
+ }:run()
+
+ -- Cleanup
+ self:removeDummyNodes()
+ Simplifiers:expandMultiedgesOldModel(cluster_subalgorithm)
+ edge_routing_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run()
+ self:restoreCycles()
+
+end
+
+
+
+function Sugiyama:preprocess()
+ -- initialize edge parameters
+ for _,edge in ipairs(self.graph.edges) do
+ -- read edge parameters
+ edge.weight = edge:getOption('weight')
+ edge.minimum_levels = edge:getOption('minimum layers')
+
+ -- validate edge parameters
+ assert(edge.minimum_levels >= 0, 'the edge ' .. tostring(edge) .. ' needs to have a minimum layers value greater than or equal to 0')
+ end
+end
+
+
+
+function Sugiyama:insertDummyNodes()
+ -- enumerate dummy nodes using a globally unique numeric ID
+ local dummy_id = 1
+
+ -- keep track of the original edges removed
+ self.original_edges = {}
+
+ -- keep track of dummy nodes introduced
+ self.dummy_nodes = {}
+
+ for node in Iterators.topologicallySorted(self.graph) do
+ local in_edges = node:getIncomingEdges()
+
+ for _,edge in ipairs (in_edges) do
+ local neighbour = edge:getNeighbour(node)
+ local dist = self.ranking:getRank(node) - self.ranking:getRank(neighbour)
+
+ if dist > 1 then
+ local dummies = {}
+
+ for i=1,dist-1 do
+ local rank = self.ranking:getRank(neighbour) + i
+
+ local dummy = Node.new{
+ pos = Vector.new(),
+ name = 'dummy@' .. neighbour.name .. '@to@' .. node.name .. '@at@' .. rank,
+ kind = "dummy",
+ orig_vertex = pgf.gd.model.Vertex.new{}
+ }
+
+ dummy_id = dummy_id + 1
+
+ self.graph:addNode(dummy)
+ self.ugraph:add {dummy.orig_vertex}
+
+ self.ranking:setRank(dummy, rank)
+
+ table.insert(self.dummy_nodes, dummy)
+ table.insert(edge.bend_nodes, dummy)
+
+ table.insert(dummies, dummy)
+ end
+
+ table.insert(dummies, 1, neighbour)
+ table.insert(dummies, #dummies+1, node)
+
+ for i = 2, #dummies do
+ local source = dummies[i-1]
+ local target = dummies[i]
+
+ local dummy_edge = Edge.new{
+ direction = Edge.RIGHT,
+ reversed = false,
+ weight = edge.weight, -- TODO or should we divide the weight of the original edge by the number of virtual edges?
+ }
+
+ dummy_edge:addNode(source)
+ dummy_edge:addNode(target)
+
+ self.graph:addEdge(dummy_edge)
+ end
+
+ table.insert(self.original_edges, edge)
+ end
+ end
+ end
+
+ for _,edge in ipairs(self.original_edges) do
+ self.graph:deleteEdge(edge)
+ end
+end
+
+
+
+function Sugiyama:removeDummyNodes()
+ -- delete dummy nodes
+ for _,node in ipairs(self.dummy_nodes) do
+ self.graph:deleteNode(node)
+ end
+
+ -- add original edge again
+ for _,edge in ipairs(self.original_edges) do
+ -- add edge to the graph
+ self.graph:addEdge(edge)
+
+ -- add edge to the nodes
+ for _,node in ipairs(edge.nodes) do
+ node:addEdge(edge)
+ end
+
+ -- convert bend nodes to bend points for TikZ
+ for _,bend_node in ipairs(edge.bend_nodes) do
+ local point = bend_node.pos:copy()
+ table.insert(edge.bend_points, point)
+ end
+
+ if edge.reversed then
+ local bp = edge.bend_points
+ for i=1,#bp/2 do
+ local j = #bp + 1 - i
+ bp[i], bp[j] = bp[j], bp[i]
+ end
+ end
+
+ -- clear the list of bend nodes
+ edge.bend_nodes = {}
+ end
+end
+
+
+
+function Sugiyama:mergeClusters()
+
+ self.cluster_nodes = {}
+ self.cluster_node = {}
+ self.cluster_edges = {}
+ self.cluster_original_edges = {}
+ self.original_nodes = {}
+
+ for _,cluster in ipairs(self.graph.clusters) do
+
+ local cluster_node = cluster.nodes[1]
+ table.insert(self.cluster_nodes, cluster_node)
+
+ for n = 2, #cluster.nodes do
+ local other_node = cluster.nodes[n]
+ self.cluster_node[other_node] = cluster_node
+ table.insert(self.original_nodes, other_node)
+ end
+ end
+
+ for _,edge in ipairs(self.graph.edges) do
+ local tail = edge:getTail()
+ local head = edge:getHead()
+
+ if self.cluster_node[tail] or self.cluster_node[head] then
+ local cluster_edge = Edge.new{
+ direction = Edge.RIGHT,
+ weight = edge.weight,
+ minimum_levels = edge.minimum_levels,
+ }
+
+ if self.cluster_node[tail] then
+ cluster_edge:addNode(self.cluster_node[tail])
+ else
+ cluster_edge:addNode(tail)
+ end
+
+ if self.cluster_node[head] then
+ cluster_edge:addNode(self.cluster_node[head])
+ else
+ cluster_edge:addNode(head)
+ end
+
+ table.insert(self.cluster_edges, cluster_edge)
+ table.insert(self.cluster_original_edges, edge)
+ end
+ end
+
+ for n = 1, #self.cluster_nodes-1 do
+ local first_node = self.cluster_nodes[n]
+ local second_node = self.cluster_nodes[n+1]
+
+ local edge = Edge.new{
+ direction = Edge.RIGHT,
+ weight = 1,
+ minimum_levels = 1,
+ }
+
+ edge:addNode(first_node)
+ edge:addNode(second_node)
+
+ table.insert(self.cluster_edges, edge)
+ end
+
+ for _,node in ipairs(self.original_nodes) do
+ self.graph:deleteNode(node)
+ end
+ for _,edge in ipairs(self.cluster_edges) do
+ self.graph:addEdge(edge)
+ end
+ for _,edge in ipairs(self.cluster_original_edges) do
+ self.graph:deleteEdge(edge)
+ end
+end
+
+
+
+function Sugiyama:expandClusters()
+
+ for _,node in ipairs(self.original_nodes) do
+ self.ranking:setRank(node, self.ranking:getRank(self.cluster_node[node]))
+ self.graph:addNode(node)
+ end
+
+ for _,edge in ipairs(self.cluster_original_edges) do
+ for _,node in ipairs(edge.nodes) do
+ node:addEdge(edge)
+ end
+ self.graph:addEdge(edge)
+ end
+
+ for _,edge in ipairs(self.cluster_edges) do
+ self.graph:deleteEdge(edge)
+ end
+end
+
+
+function Sugiyama:restoreCycles()
+ for _,edge in ipairs(self.graph.edges) do
+ edge.reversed = false
+ end
+end
+
+
+
+
+
+-- done
+
+return Sugiyama
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua
new file mode 100644
index 0000000000..54a1fafb23
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua
@@ -0,0 +1,81 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Crossing Minimization (Node Ordering)}
+--
+-- The number of edge crossings in a layered drawing is determined by
+-- the ordering of nodes at each of its layers. Therefore, crossing
+-- minimization is the problem of reordering the nodes at each layer
+-- so that the overall number of edge crossings is minimized. The
+-- crossing minimization step takes a proper layering where every edge
+-- connects nodes in neighbored layers, allowing algorithms to
+-- minimize crossings layer by layer rather than all at once. While
+-- this does not reduce the complexity of the problem, it does make it
+-- considerably easier to understand and implement. Techniques based
+-- on such an iterative approach are also known as layer-by-layer
+-- sweep methods. They are used in many popular heuristics due to
+-- their simplicity and the good results they produce.
+--
+-- Sweeping refers to moving up and down from one layer to the next,
+-- reducing crossings along the way. In layer-by-layer sweep methods,
+-- an initial node ordering for one of the layers is computed
+-- first. Depending on the sweep direction this can either be the
+-- first layer or the last; in rare occasions the layer in the middle
+-- is used instead. Followed by this, the actual layer-by-layer sweep
+-- is performed. Given an initial ordering for the first layer $L_1$, a
+-- downward sweep first holds the nodes in $L_1$ fixed while reordering
+-- the nodes in the second layer $L_2$ to reduce the number of
+-- crossings between $L_1$ and $L_2$. It then goes on to reorder the
+-- third layer while holding the second layer fixed. This is continued
+-- until all layers except for the first one have been
+-- examined. Upward sweeping and sweeping from the middle work
+-- analogous.
+--
+-- Obviously, the central aspect of the layer-by-layer sweep is how
+-- the nodes of a specific layer are reordered using a neighbored
+-- layer as a fixed reference. This problem is known as one-sided
+-- crossing minimization, which unfortunately is NP-hard. In the
+-- following various heuristics to solve this problem are
+-- presented.
+--
+-- For more details, please see Section 4.1.4 of Pohlmann's Diploma
+-- thesis.
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "sweep crossing minimization",
+ algorithm = require "pgf.gd.layered.CrossingMinimizationGansnerKNV1993",
+ phase = "crossing minimization",
+ phase_default = true,
+
+ summary = [["
+ Gansner et al. combine an initial ordering based on a depth-first
+ search with the median and greedy switch heuristics applied in the
+ form of an alternating layer-by-layer sweep based on a weighted
+ median.
+ "]],
+ documentation = [["
+ For more details, please see Section~4.1.4 of Pohlmann's Diploma
+ thesis.
+
+ This is the default algorithm for crossing minimization.
+ "]]
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua
new file mode 100644
index 0000000000..18670df14e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua
@@ -0,0 +1,136 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Cycle Removal}
+--
+-- The Sugiyama method works only on directed \emph{acyclic}
+-- graphs. For this reason, if the input graph is not (yet) acyclic, a
+-- number of edges need to be redirected so that acyclicity arises. In
+-- the following, the different options that allow you to fine-tune
+-- this process are documented.
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "depth first cycle removal",
+ algorithm = require "pgf.gd.layered.CycleRemovalGansnerKNV1993",
+ phase = "cycle removal",
+ phase_default = true,
+
+ summary = [["
+ Selects a cycle removal algorithm that is especially
+ appropriate for graphs specified ``by hand''.
+ "]],
+ documentation = [["
+ When graphs are created by humans manually, one can
+ make assumptions about the input graph that would otherwise not
+ be possible. For instance, it seems reasonable to assume that the
+ order in which nodes and edges are entered by the user somehow
+ reflects the natural flow the user has had in mind for the graph.
+
+ In order to preserve the natural flow of the input graph, Gansner
+ et al.\ propose to remove cycles by performing a series of
+ depth-first searches starting at individual nodes in the order they
+ appear in the graph. This algorithm implicitly constructs a spanning
+ tree of the nodes reached during the searches. It thereby partitions
+ the edges of the graph into tree edges and non-tree edges. The
+ non-tree edges are further subdivided into forward edges, cross edges,
+ and back edges. Forward edges point from a tree nodes to one of their
+ descendants. Cross edges connect unrelated branches in the search tree.
+ Back edges connect descendants to one of their ancestors. It is not
+ hard to see that reversing back edges will not only introduce no new
+ cycles but will also make any directed graph acyclic.
+ Gansner et al.\ argue that this approach is more stable than others
+ in that fewer inappropriate edges are reversed compared to other
+ methods, despite the lack of a provable upper bound for the number
+ of reversed edges.
+
+ See section~4.1.1 of Pohlmann's Diplom thesis for more details.
+
+ This is the default algorithm for cycle removals.
+ "]]
+ }
+
+---
+
+declare {
+ key = "prioritized greedy cycle removal",
+ algorithm = "pgf.gd.layered.CycleRemovalEadesLS1993",
+ phase = "cycle removal",
+
+ summary = [["
+ This algorithm implements a greedy heuristic of Eades et al.\ for
+ cycle removal that prioritizes sources and sinks.
+ "]],
+ documentation = [["
+ See section~4.1.1 of Pohlmann's Diploma theses for details.
+ "]]
+}
+
+
+---
+
+declare {
+ key = "greedy cycle removal",
+ algorithm = "pgf.gd.layered.CycleRemovalEadesLS1993",
+ phase = "cycle removal",
+
+ summary = [["
+ This algorithm implements a greedy heuristic of Eades et al.\ for
+ cycle removal that prioritizes sources and sinks.
+ "]],
+ documentation = [["
+ See section~4.1.1 of Pohlmann's Diploma theses for details.
+ "]]
+ }
+
+---
+
+declare {
+ key = "naive greedy cycle removal",
+ algorithm = "pgf.gd.layered.CycleRemovalBergerS1990a",
+ phase = "cycle removal",
+
+ summary = [["
+ This algorithm implements a greedy heuristic of Berger and Shor for
+ cycle removal. It is not really compared to the other heuristics and
+ only included for demonstration purposes.
+ "]],
+ documentation = [["
+ See section~4.1.1 of Pohlmann's Diploma theses for details.
+ "]]
+ }
+
+---
+
+declare {
+ key = "random greedy cycle removal",
+ algorithm = "pgf.gd.layered.CycleRemovalBergerS1990b",
+ phase = "cycle removal",
+
+ summary = [["
+ This algorithm implements a randomized greedy heuristic of Berger
+ and Shor for cycle removal. It, too, is not really compared to
+ the other heuristics and only included for demonstration purposes.
+ "]],
+ documentation = [["
+ See section~4.1.1 of Pohlmann's Diploma theses for details.
+ "]]
+ } \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/edge_routing.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/edge_routing.lua
new file mode 100644
index 0000000000..eb9939c74c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/edge_routing.lua
@@ -0,0 +1,49 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Edge Routing}
+--
+-- The original layered drawing method described by Eades and Sugiyama
+-- in does not include the routing or shaping of edges as a main
+-- step. This makes sense if all nodes have the same size and
+-- shape. In practical scenarios, however, this assumption often does
+-- not hold. In these cases, advanced techniques may have to be
+-- applied in order to avoid overlaps of nodes and edges.
+--
+-- For more details, please see Section~4.1.5 of Pohlmann's Diploma
+-- thesis.
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "polyline layer edge routing",
+ algorithm = require "pgf.gd.layered.EdgeRoutingGansnerKNV1993",
+ phase = "layer edge routing",
+ phase_default = true,
+
+ summary = [["
+ This edge routing algorithm uses polygonal lines to connect nodes.
+ "]],
+ documentation = [["
+ For more details, please see Section~4.1.5 of Pohlmann's Diploma thesis.
+
+ This is the default algorithm for edge routing.
+ "]]
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/library.lua
new file mode 100644
index 0000000000..950e02ffa3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/library.lua
@@ -0,0 +1,94 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- A ``layered'' layout of a graph tries to arrange the nodes in
+-- consecutive horizontal layers (naturally, by rotating the graph, this
+-- can be changed in to vertical layers) such that edges tend to be only
+-- between nodes on adjacent layers. Trees, for instance, can always be
+-- laid out in this way. This method of laying out a graph is especially
+-- useful for hierarchical graphs.
+--
+-- The method implemented in this library is often called the
+-- \emph{Sugiyama method}, which is a rather advanced method of
+-- assigning nodes to layers and positions on these layers. The same
+-- method is also used in the popular GraphViz program, indeed, the
+-- implementation in \tikzname\ is based on the same pseudo-code from the
+-- same paper as the implementation used in GraphViz and both programs
+-- will often generate the same layout (but not always, as explained
+-- below). The current implementation is due to Jannis Pohlmann, who
+-- implemented it as part of his Diploma thesis. Please consult this
+-- thesis for a detailed explanation of the Sugiyama method and its
+-- history:
+-- %
+-- \begin{itemize}
+-- \item
+-- Jannis Pohlmann,
+-- \newblock \emph{Configurable Graph Drawing Algorithms
+-- for the \tikzname\ Graphics Description Language,}
+-- \newblock Diploma Thesis,
+-- \newblock Institute of Theoretical Computer Science, Universit\"at
+-- zu L\"ubeck, 2011.\\[.5em]
+-- \newblock Available online via
+-- \url{http://www.tcs.uni-luebeck.de/downloads/papers/2011/}\\
+-- \url{2011-configurable-graph-drawing-algorithms-jannis-pohlmann.pdf}
+-- \\[.5em]
+-- (Note that since the publication of this thesis some option names
+-- have been changed. Most noticeably, the option name
+-- |layered drawing| was changed to |layered layout|, which is somewhat
+-- more consistent with other names used in the graph drawing
+-- libraries. Furthermore, the keys for choosing individual
+-- algorithms for the different algorithm phases, have all changed.)
+-- \end{itemize}
+--
+-- The Sugiyama methods lays out a graph in five steps:
+-- %
+-- \begin{enumerate}
+-- \item Cycle removal.
+-- \item Layer assignment (sometimes called node ranking).
+-- \item Crossing minimization (also referred to as node ordering).
+-- \item Node positioning (or coordinate assignment).
+-- \item Edge routing.
+-- \end{enumerate}
+-- %
+-- It turns out that behind each of these steps there lurks an
+-- NP-complete problem, which means, in practice, that each step is
+-- impossible to perform optimally for larger graphs. For this reason,
+-- heuristics and approximation algorithms are used to find a ``good''
+-- way of performing the steps.
+--
+-- A distinctive feature of Pohlmann's implementation of the Sugiyama
+-- method for \tikzname\ is that the algorithms used for each of the
+-- steps can easily be exchanged, just specify a different option. For
+-- the user, this means that by specifying a different option and thereby
+-- using a different heuristic for one of the steps, a better layout can
+-- often be found. For the researcher, this means that one can very
+-- easily test new approaches and new heuristics without having to
+-- implement all of the other steps anew.
+--
+-- @library
+
+local layered
+
+
+-- Load declarations from:
+require "pgf.gd.layered"
+
+-- Load algorithms from:
+require "pgf.gd.layered.Sugiyama"
+require "pgf.gd.layered.cycle_removal"
+require "pgf.gd.layered.node_ranking"
+require "pgf.gd.layered.crossing_minimization"
+require "pgf.gd.layered.node_positioning"
+require "pgf.gd.layered.edge_routing"
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_positioning.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_positioning.lua
new file mode 100644
index 0000000000..e51382d642
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_positioning.lua
@@ -0,0 +1,55 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Node Positioning (Coordinate Assignment)}
+--
+-- The second last step of the Sugiyama method decides about the final
+-- $x$- and $y$-coordinates of the nodes. The main objectives of this
+-- step are to position nodes so that the number of edge bends is kept
+-- small and edges are drawn as vertically as possible. Another goal
+-- is to avoid node and edge overlaps which is crucial in particular
+-- if the nodes are allowed to have non-uniform sizes. The
+-- $y$-coordinates of the nodes have no influence on the number of
+-- bends. Obviously, nodes need to be separated enough geometrically
+-- so that they do not overlap. It feels natural to aim at separating
+-- all layers in the drawing by the same amount. Large nodes, however,
+-- may force node positioning algorithms to override this uniform
+-- level distance in order to avoid overlaps.
+--
+-- For more details, please see Section~4.1.2 of Pohlmann's Diploma thesis.
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "linear optimization node positioning",
+ algorithm = require "pgf.gd.layered.NodePositioningGansnerKNV1993",
+ phase = "node positioning",
+ phase_default = true,
+
+ summary = [["
+ This node positioning method, due to Gasner et al., is based on a
+ linear optimization problem.
+ "]],
+ documentation = [["
+ For more details, please see Section~4.1.3 of Pohlmann's Diploma thesis.
+
+ This is the default algorithm for layer assignments.
+ "]]
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_ranking.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_ranking.lua
new file mode 100644
index 0000000000..c663d9ce36
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/layered/node_ranking.lua
@@ -0,0 +1,72 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+---
+-- @section subsection {Layer Assignment (Node Ranking)}
+--
+-- Algorithms for producing layered drawings place nodes on discrete
+-- layers from top to bottom. Layer assignment is the problem of
+-- finding a partition so that for all edges $e = (u,v) \in E(G)$ the
+-- equation $\mathit{layer}(u) < \mathit{layer}(v)$ holds. Such a
+-- partition is called a \emph{layering}. This definition can be extended by
+-- introducing edge weights or priorities and minimum length
+-- constraints which has practical applications and allows users to
+-- fine-tune the results.
+--
+-- For more details, please see Section~4.1.2 of Pohlmann's Diploma
+-- thesis.
+--
+-- @end
+
+
+
+---
+
+declare {
+ key = "linear optimization layer assignment",
+ algorithm = require "pgf.gd.layered.NodeRankingGansnerKNV1993",
+ phase = "node ranking",
+ phase_default = true,
+
+ summary = [["
+ This layer assignment method, due to Gasner et al., is based on a
+ linear optimization problem.
+ "]],
+ documentation = [["
+ For more details, please see Section~4.1.2 of Pohlmann's Diploma
+ thesis.
+
+ This is the default algorithm for layer assignments.
+ "]]
+}
+
+
+
+---
+
+declare {
+ key = "minimum height layer assignment",
+ algorithm = "pgf.gd.layered.NodeRankingMinimumHeight",
+ phase = "node ranking",
+
+ summary = [["
+ This layer assignment method minimizes the height of the resulting graph.
+ "]],
+ documentation = [["
+ For more details, please see Section~4.1.3 of Pohlmann's Diploma thesis.
+ "]]
+}
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib.lua
new file mode 100644
index 0000000000..cc39ddd607
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib.lua
@@ -0,0 +1,435 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- Basic library functions
+
+local lib = {}
+
+-- Declare namespace
+
+require("pgf.gd").lib = lib
+
+
+-- General lib functions:
+
+
+---
+-- Finds the first value in the |array| for which |test| is true.
+--
+-- @param array An array to search in.
+-- @param test A function that is applied to each element of the
+-- array together with the index of the element and the
+-- whole table.
+--
+-- @return The value of the first value where the test is true.
+-- @return The index of the first value where the test is true.
+-- @return The function value of the first value where the test is
+-- true (only returned if test is a function).
+--
+function lib.find(array, test)
+ for i=1,#array do
+ local t = array[i]
+ local result = test(t,i,array)
+ if result then
+ return t,i,result
+ end
+ end
+end
+
+
+---
+-- Finds the first value in the |array| for which a function
+-- returns a minimal value
+--
+-- @param array An array to search in.
+-- @param f A function that is applied to each element of the
+-- array together with the index of the element and the
+-- whole table. It should return an integer and, possibly, a value.
+--
+-- Among all elements for which a non-nil integer is returned, let |i|
+-- by the index of the element where this integer is minimal.
+--
+-- @return |array[i]|
+-- @return |i|
+-- @return The return value(s) of the function at |array[i]|.
+--
+function lib.find_min(array, f)
+ local best = math.huge
+ local best_result
+ local best_index
+ for i=1,#array do
+ local t = array[i]
+ local result, p = f(t,i,array)
+ if result and p < best then
+ best = p
+ best_result = result
+ best_index = i
+ end
+ end
+ if best_index then
+ return array[best_index],best_index,best_result,best
+ end
+end
+
+
+
+
+---
+-- Copies a table while preserving its metatable.
+--
+-- @param source The table to copy.
+-- @param target The table to which values are to be copied or |nil| if a new
+-- table is to be allocated.
+--
+-- @return The |target| table or a newly allocated table containing all
+-- keys and values of the |source| table.
+--
+function lib.copy(source, target)
+ if not target then
+ target = {}
+ end
+ for key, val in pairs(source) do
+ target[key] = val
+ end
+ return setmetatable(target, getmetatable(source))
+end
+
+
+---
+-- Copies an array while preserving its metatable.
+--
+-- @param source The array to copy.
+-- @param target The array to which values are to be copied or |nil| if a new
+-- table is to be allocated. The elements of the
+-- |source| array will be added at the end.
+--
+-- @return The |target| table or a newly allocated table containing all
+-- keys and values of the |source| table.
+--
+function lib.icopy(source, target)
+ target = target or {}
+ for _, val in ipairs(source) do
+ target[#target+1] = val
+ end
+ return setmetatable(target, getmetatable(source))
+end
+
+
+
+
+---
+-- Apply a function to all pairs of a table, resulting in a new table.
+--
+-- @param source The table.
+-- @param fun A function taking two arguments (|val| and |key|, in
+-- that order). Should return two values (a |new_val| and a
+-- |new_key|). This pair will be inserted into the new table. If,
+-- however, |new_key| is |nil|, the |new_value| will be inserted at
+-- the position |key|. This means, in particular, that if the |fun|
+-- takes only a single argument and returns only a single argument,
+-- you have a ``classical'' value mapper. Also note that if
+-- |new_value| is |nil|, the value is removed from the table.
+--
+-- @return The new table.
+--
+function lib.map(source, fun)
+ local target = {}
+ for key, val in pairs(source) do
+ local new_val, new_key = fun(val, key)
+ if new_key == nil then
+ new_key = key
+ end
+ target[new_key] = new_val
+ end
+ return target
+end
+
+
+
+---
+-- Apply a function to all elements of an array, resulting in a new
+-- array.
+--
+-- @param source The array.
+-- @param fun A function taking two arguments (|val| and |i|, the
+-- current index). This function is applied to all elements of the
+-- array. The result of this function is placed at the end of a new
+-- array, expect when the function returns |nil|, in which case the
+-- element is skipped. If this function is not provided (is |nil|),
+-- the identity function is used.
+-- @param new The target array (if |nil|, a new array is create).
+-- %
+--\begin{codeexample}[code only]
+-- local a = lib.imap(array, function(v) if some_test(v) then return v end end)
+--\end{codeexample}
+--
+-- The above code is a filter that will remove all elements from the
+-- array that do not pass |some_test|.
+-- %
+--\begin{codeexample}[code only]
+-- lib.imap(a, lib.id, b)
+--\end{codeexample}
+--
+-- The above code has the same effect as |lib.icopy(a,b)|.
+--
+-- @return The new array
+--
+function lib.imap(source, fun, new)
+ if not new then
+ new = { }
+ end
+ for i, v in ipairs(source) do
+ new[#new+1] = fun(v, i)
+ end
+ return new
+end
+
+
+---
+-- Generate a random permutation of the numbers $1$ to $n$ in time
+-- $O(n)$. Knuth's shuffle is used for this.
+--
+-- @param n The desired size of the table
+-- @return A random permutation
+
+function lib.random_permutation(n)
+ local p = {}
+ for i=1,n do
+ p[i] = i
+ end
+ for i=1,n-1 do
+ local j = lib.random(i,n)
+ p[i], p[j] = p[i], p[j]
+ end
+ return p
+end
+
+
+---
+-- The identity function, so you can write |lib.id| instead of
+-- |function (x) return x end|.
+--
+
+function lib.id(...)
+ return ...
+end
+
+
+
+---
+-- Tries to find an option in different objects that have an
+-- options field.
+--
+-- This function iterates over all objects given as parameters. In
+-- each, it tries to find out whether the options field of the object
+-- contains the option |name| and, if so,
+-- returns the value. The important point is that checking whether the
+-- option table of an object contains the name field is done using
+-- |rawget| for all but the last parameter. This means that when you
+-- write
+-- %
+--\begin{codeexample}[code only]
+--lib.lookup_option("foo", vertex, graph)
+--\end{codeexample}
+-- %
+-- and if |/graph drawing/foo| has an initial value set, if the
+-- parameter is not explicitly set in a vertex, you will get the value
+-- set for the graph or, if it is not set there either, the initial
+-- value. In contrast, if you write
+-- %
+--\begin{codeexample}[code only]
+-- vertex.options["foo"] or graph.options["foo"]
+--\end{codeexample}
+-- %
+-- what happens is that the first access to |.options| will
+-- \emph{always} return something when an initial parameter has been
+-- set for the option |foo|.
+--
+-- @param name The name of the options
+-- @param ... Any number of objects. Each must have an options
+-- field.
+--
+-- @return The found option
+
+function lib.lookup_option(name, ...)
+ local list = {...}
+ for i=1,#list-1 do
+ local o = list[i].options
+ if o then
+ local v = rawget(o, name)
+ if v then
+ return v
+ end
+ end
+ end
+ return list[#list].options[name]
+end
+
+
+
+---
+-- Turns a table |t| into a class in the sense of object oriented
+-- programming. In detail, this means that |t| is augmented by
+-- a |new| function, which takes an optional table of |initial| values
+-- and which outputs a new table whose metatable is the
+-- class. The |new| function will call the function |constructor| if
+-- it exists. Furthermore, the class object's |__index| is set to itself
+-- and its meta table is set to the |base_class| field of the
+-- table. If |t| is |nil|, a new table is created.
+--
+-- Here is a typical usage of this function:
+-- %
+--\begin{codeexample}[code only]
+--local Point = lib.class {}
+--
+--function Point:length()
+-- return math.sqrt(self.x*self.x + self.y*self.y)
+--end
+--
+--local p = Point.new { x = 5, y = 6 }
+--
+--print(p:length())
+--\end{codeexample}
+-- %
+-- We can subclass this as follows:
+-- %
+--\begin{codeexample}[code only]
+--local Point3D = lib.class { base_class = Point }
+--
+--function Point3D:length()
+-- local l = Point.length(self) -- Call base class's function
+-- return math.sqrt(l*l + self.z*self.zdy)
+--end
+--
+--local p = Point3D.new { x = 5, y = 6, z = 6 }
+--
+--print(p:length())
+--\end{codeexample}
+--
+-- @param t A table that gets augmented to a class. If |nil|, a new
+-- table is created.
+-- @return The augmented table.
+
+function lib.class(t)
+ t = t or {}
+
+ -- First, setup indexing, if necessary
+ if not t.__index then
+ t.__index = t
+ end
+
+ -- Second, setup new method, if necessary
+ t.new = t.new or
+ function (initial)
+
+ -- Create new object
+ local obj = {}
+ for k,v in pairs(initial or {}) do
+ obj[k] = v
+ end
+ setmetatable(obj, t)
+
+ if obj.constructor then
+ obj:constructor()
+ end
+
+ return obj
+ end
+
+ -- Third, setup inheritance, if necessary
+ if not getmetatable(t) then
+ setmetatable(t, t.base_class)
+ end
+
+ return t
+end
+
+
+
+---
+-- Returns a method that is loaded only on demand for a class.
+--
+-- The idea behind this function is that you may have a class (or just
+-- a table) for which some methods are needed only seldomly. In this
+-- case, you can put these methods in a separate file and then use
+-- |ondemand| to indicate that the methods are found in a
+-- another file.
+-- %
+--\begin{codeexample}[code only]
+-- -- File Foo.lua
+-- local Foo = {}
+-- function Foo.bar () ... end
+-- function Foo.bar2 () ... end
+-- Foo.bar3 = lib.ondemand("Foo_extra", Foo, "bar3")
+-- Foo.bar4 = lib.ondemand("Foo_extra", Foo, "bar4")
+--
+-- return Foo
+--
+-- -- Foo_extra.lua
+-- local Foo = require "Foo"
+-- function Foo.bar3 () ... end
+-- function Foo.bar4 () ... end
+--\end{codeexample}
+--
+-- @param filename The name of the file when extra methods are
+-- located.
+-- @param table The table for which the missing functions should be
+-- loaded when they are accessed.
+-- @param method The name of the method.
+--
+-- @return A function that, when called, loads the filename using
+-- |require| and, then, forwards the call to the method.
+
+function lib.ondemand(filename, table, name)
+ return function(...)
+ require (filename)
+ return table[name] (...)
+ end
+end
+
+
+
+---
+-- This implements the a random number generator similar to the one
+-- provided by Lua, but based on the tex.uniformdeviate primitive to
+-- avoid differences in random numbers due to platform specifics.
+--
+-- @param l Lower bound
+-- @param u Upper bound
+-- @return A random number
+function lib.random(l,u)
+ local fraction_one = 268435456
+ local r = tex.uniform_rand(fraction_one)/fraction_one
+ if l and u then
+ assert(l <= u)
+ return math.floor(r*(u-l+1)) + l
+ elseif l then
+ assert(1.0 <= l)
+ return math.floor(r*l) + 1.0
+ else
+ return r
+ end
+end
+
+---
+-- Provide the seed for the random number generator
+--
+-- @param seed random seed
+function lib.randomseed(seed)
+ tex.init_rand(seed)
+end
+
+-- Done
+
+return lib
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Bezier.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Bezier.lua
new file mode 100644
index 0000000000..e4fe21d942
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Bezier.lua
@@ -0,0 +1,160 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This library offers a number of methods for working with Bezi\'er
+-- curves.
+
+local Bezier = {}
+
+-- Namespace
+require("pgf.gd.lib").Bezier = Bezier
+
+
+-- Imports
+
+local Coordinate = require 'pgf.gd.model.Coordinate'
+
+
+---
+-- Compute a point ``along a curve at a time''. You provide the four
+-- coordinates of the curve and a time. You get a point on the curve
+-- as return value as well as the two support vector for curve
+-- before this point and two support vectors for the curve after the
+-- point.
+--
+-- For speed reasons and in order to avoid superfluous creation of
+-- lots of tables, all values are provided and returned as pairs of
+-- values rather than as |Coordinate| objects.
+--
+-- @param ax The coordinate where the curve starts.
+-- @param ay
+-- @param bx The first support point.
+-- @param by
+-- @param cx The second support point.
+-- @param cy
+-- @param dx The coordinate where the curve ends.
+-- @param dy
+-- @param t A time (a number).
+--
+-- @return The point |p| on the curve at time |t| ($x$-part).
+-- @return The point |p| on the curve at time |t| ($y$-part).
+-- @return The first support point of the curve between |a| and |p| ($x$-part).
+-- @return The first support point of the curve between |a| and |p| ($y$-part).
+-- @return The second support point of the curve between |a| and |p| ($x$-part).
+-- @return The second support point of the curve between |a| and |p| ($y$-part).
+-- @return The first support point of the curve between |p| and |d| ($x$-part).
+-- @return The first support point of the curve between |p| and |d| ($y$-part).
+-- @return The second support point of the curve between |p| and |d| ($x$-part).
+-- @return The second support point of the curve between |p| and |d| ($y$-part).
+
+function Bezier.atTime(ax,ay,bx,by,cx,cy,dx,dy,t)
+
+ local s = 1-t
+
+ local ex, ey = ax*s + bx*t, ay*s + by*t
+ local fx, fy = bx*s + cx*t, by*s + cy*t
+ local gx, gy = cx*s + dx*t, cy*s + dy*t
+
+ local hx, hy = ex*s + fx*t, ey*s + fy*t
+ local ix, iy = fx*s + gx*t, fy*s + gy*t
+
+ local jx, jy = hx*s + ix*t, hy*s + iy*t
+
+ return jx, jy, ex, ey, hx, hy, ix, iy, gx, gy
+end
+
+
+---
+-- The ``coordinate version'' of the |atTime| function, where both the
+-- parameters and the return values are coordinate objects.
+
+function Bezier.atTimeCoordinates(a,b,c,d,t)
+ local jx, jy, ex, ey, hx, hy, ix, iy, gx, gy =
+ Bezier.atTime(a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y,t)
+
+ return
+ Coordinate.new(jx, jy),
+ Coordinate.new(ex, ey),
+ Coordinate.new(hx, hy),
+ Coordinate.new(ix, iy),
+ Coordinate.new(gx, gy)
+end
+
+
+---
+-- Computes the support points of a Bezier curve based on two points
+-- on the curves at certain times.
+--
+-- @param from The start point of the curve
+-- @param p1 A first point on the curve
+-- @param t1 A time when this point should be reached
+-- @param p2 A second point of the curve
+-- @param t2 A time when this second point should be reached
+-- @param to The end of the curve
+--
+-- @return sup1 A first support point of the curve
+-- @return sup2 A second support point of the curve
+
+function Bezier.supportsForPointsAtTime(from, p1, t1, p2, t2, to)
+
+ local s1 = 1 - t1
+ local s2 = 1 - t2
+
+ local f1a = s1^3
+ local f1b = t1 * s1^2 * 3
+ local f1c = t1^2 * s1 * 3
+ local f1d = t1^3
+
+ local f2a = s2^3
+ local f2b = t2 * s2^2 * 3
+ local f2c = t2^2 * s2 * 3
+ local f2d = t2^3
+
+ -- The system:
+ -- p1.x - from.x * f1a - to.x * f1d = sup1.x * f1b + sup2.x * f1c
+ -- p2.x - from.x * f2a - to.x * f2d = sup1.x * f2b + sup2.x * f2c
+ --
+ -- p1.y - from.y * f1a - to.y * f1d = sup1.y * f1b + sup2.y * f1c
+ -- p2.y - from.y * f2a - to.y * f2d = sup1.y * f2b + sup2.y * f2c
+
+ local a = f1b
+ local b = f1c
+ local c = p1.x - from.x * f1a - to.x * f1d
+ local d = f2b
+ local e = f2c
+ local f = p2.x - from.x * f2a - to.x * f2d
+
+ local det = a*e - b*d
+ local x1 = -(b*f - e*c)/det
+ local x2 = -(c*d - a*f)/det
+
+ local c = p1.y - from.y * f1a - to.y * f1d
+ local f = p2.y - from.y * f2a - to.y * f2d
+
+ local det = a*e - b*d
+ local y1 = -(b*f - e*c)/det
+ local y2 = -(c*d - a*f)/det
+
+ return Coordinate.new(x1,y1), Coordinate.new(x2,y2)
+
+end
+
+
+
+
+
+
+-- Done
+
+return Bezier \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua
new file mode 100644
index 0000000000..564b8f6839
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua
@@ -0,0 +1,125 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+--- The DepthFirstSearch class implements a generic depth first function. It does not
+-- require that it is run on graphs, but can be used for anything where a visit function and
+-- a complete function is available.
+
+local DepthFirstSearch = {}
+DepthFirstSearch.__index = DepthFirstSearch
+
+-- Namespace
+require("pgf.gd.lib").DepthFirstSearch = DepthFirstSearch
+
+-- Imports
+local Stack = require "pgf.gd.lib.Stack"
+
+
+
+-- TT: TODO Jannis: Please document...
+
+function DepthFirstSearch.new(init_func, visit_func, complete_func)
+ local dfs = {
+ init_func = init_func,
+ visit_func = visit_func,
+ complete_func = complete_func,
+
+ stack = Stack.new(),
+ discovered = {},
+ visited = {},
+ completed = {},
+ }
+ setmetatable(dfs, DepthFirstSearch)
+ return dfs
+end
+
+
+
+function DepthFirstSearch:run()
+ self:reset()
+ self.init_func(self)
+
+ while self.stack:getSize() > 0 do
+ local data = self.stack:peek()
+
+ if not self:getVisited(data) then
+ if self.visit_func then
+ self.visit_func(self, data)
+ end
+ else
+ if self.complete_func then
+ self.complete_func(self, data)
+ end
+ self:setCompleted(data, true)
+ self.stack:pop()
+ end
+ end
+end
+
+
+
+function DepthFirstSearch:reset()
+ self.discovered = {}
+ self.visited = {}
+ self.completed = {}
+ self.stack = Stack.new()
+end
+
+
+
+function DepthFirstSearch:setDiscovered(data, discovered)
+ self.discovered[data] = discovered
+end
+
+
+
+function DepthFirstSearch:getDiscovered(data)
+ return self.discovered[data]
+end
+
+
+
+function DepthFirstSearch:setVisited(data, visited)
+ self.visited[data] = visited
+end
+
+
+
+function DepthFirstSearch:getVisited(data)
+ return self.visited[data]
+end
+
+
+
+function DepthFirstSearch:setCompleted(data, completed)
+ self.completed[data] = completed
+end
+
+
+
+function DepthFirstSearch:getCompleted(data)
+ return self.completed[data]
+end
+
+
+
+function DepthFirstSearch:push(data)
+ self.stack:push(data)
+end
+
+
+
+-- Done
+
+return DepthFirstSearch \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Direct.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Direct.lua
new file mode 100644
index 0000000000..81728a1a44
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Direct.lua
@@ -0,0 +1,95 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+--- Direct is a class that collects algorithms for computing new
+-- versions of a graph where arcs point in certain directions.
+
+local Direct = {}
+
+-- Namespace
+require("pgf.gd.lib").Direct = Direct
+
+-- Imports
+local Digraph = require "pgf.gd.model.Digraph"
+
+
+--- Compute a digraph from a syntactic digraph.
+--
+-- This function takes a syntactic digraph and compute a new digraph
+-- where all arrow point in the "semantic direction" of the syntactic
+-- arrows. For instance, while "a <- b" will cause an arc from a to be
+-- to be added to the syntactic digraph, calling this function will
+-- return a digraph in which there is an arc from b to a rather than
+-- the other way round. In detail, "a <- b" is translated as just
+-- described, "a -> b" yields an arc from a to b as expected, "a <-> b"
+-- and "a -- b" yield arcs in both directions and, finally, "a -!- b"
+-- yields no arc at all.
+--
+-- @param syntactic_digraph A syntactic digraph, usually the "input"
+-- graph as specified syntactically be the user.
+--
+-- @return A new "semantic" digraph object.
+
+function Direct.digraphFromSyntacticDigraph(syntactic_digraph)
+ local digraph = Digraph.new(syntactic_digraph) -- copy
+
+ -- Now go over all arcs of the syntactic_digraph and turn them into
+ -- arcs with the correct direction in the digraph:
+ for _,a in ipairs(syntactic_digraph.arcs) do
+ for _,m in ipairs(a.syntactic_edges) do
+ local direction = m.direction
+ if direction == "->" then
+ digraph:connect(a.tail, a.head)
+ elseif direction == "<-" then
+ digraph:connect(a.head, a.tail)
+ elseif direction == "--" or direction == "<->" then
+ digraph:connect(a.tail, a.head)
+ digraph:connect(a.head, a.tail)
+ end
+ -- Case -!-: No edges...
+ end
+ end
+
+ return digraph
+end
+
+
+--- Turn an arbitrary graph into a directed graph
+--
+-- Takes a digraph as input and returns its underlying undirected
+-- graph, coded as a digraph. This means that between any two vertices
+-- if there is an arc in one direction, there is also one in the other.
+--
+-- @param digraph A directed graph
+--
+-- @return The underlying undirected graph of digraph.
+
+function Direct.ugraphFromDigraph(digraph)
+ local ugraph = Digraph.new(digraph)
+
+ -- Now go over all arcs of the syntactic_digraph and turn them into
+ -- arcs with the correct direction in the digraph:
+ for _,a in ipairs(digraph.arcs) do
+ ugraph:connect(a.head,a.tail)
+ ugraph:connect(a.tail,a.head)
+ end
+
+ return ugraph
+end
+
+
+
+
+-- Done
+
+return Direct
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Event.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Event.lua
new file mode 100644
index 0000000000..880796ce97
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Event.lua
@@ -0,0 +1,98 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- Events are used to communicate ``interesting'' events from the
+-- parser to the graph drawing algorithms.
+--
+-- As a syntactic description of some graph is being parsed, vertices,
+-- arcs, and a digraph object representing this graph get
+-- constructed. However, even though syntactic annotations such as
+-- options for the vertices and arcs are attached to them and can be
+-- accessed through the graph objects, some syntactic information is
+-- neither represented in the digraph object nor in the vertices and
+-- the arcs. A typical example is a ``missing'' node in a tree: Since
+-- it is missing, there is neither a vertex object nor arc objects
+-- representing it. It is also not a global option of the graph.
+--
+-- For these reasons, in addition to the digraph object itself,
+-- additional information can be passed by a parser to graph drawing
+-- algorithms through the means of events. Each |Event| consists of a
+-- |kind| field, which is just some string, and a |parameters| field,
+-- which stores additional, kind-specific information. As a graph is
+-- being parsed, a string of events is accumulated and is later on
+-- available through the |events| field of the graph drawing scope.
+--
+-- The following events are created during the parsing process by the
+-- standard parsers of \tikzname:
+-- %
+-- \begin{itemize}
+-- \item[|node|] When a node of the input graph has been parsed and
+-- a |Vertex| object has been created for it, an event with kind
+-- |node| is created. The |parameter| of this event is the
+-- just-created vertex.
+--
+-- The same kind of event is used to indicate ``missing'' nodes. In
+-- this case, the |parameters| field is |nil|.
+-- \item[|edge|] When an edge of the input graph has been parsed, an
+-- event is created of kind |edge|. The |parameters| field will store
+-- an array with two entries: The first is the |Arc| object whose
+-- |syntactic_edges| field stores the |edge|. The second is the index
+-- of the edge inside the |syntactic_edges| field.
+-- \item[|begin|]
+-- Signals the beginning of a group, which will be ended with a
+-- corresponding |end| event later on. The |parameters| field will
+-- indicate the kind of group. Currently, only the string
+-- |"descendants"| is used as |parameters|, indicating the start of
+-- several nodes that are descendants of a given node. This
+-- information can be used by algorithms for reconstructing the
+-- input structure of trees.
+-- \item[|end|] Signals the end of a group begun by a |begin| event
+-- earlier on.
+-- \end{itemize}
+--
+-- @field kind A string representing the kind of the events.
+-- @field parameters Kind-specific parameters.
+-- @field index A number that stores the events logical position in
+-- the sequence of events. The number need not be an integer array
+-- index.
+--
+local Event = {}
+Event.__index = Event
+
+
+-- Namespace
+require("pgf.gd.lib").Event = Event
+
+
+
+---
+-- Create a new event object
+--
+-- @param initial Initial fields of the new event.
+--
+-- @return The new object
+
+function Event.new(values)
+ local new = {}
+ for k,v in pairs(values) do
+ new[k] = v
+ end
+ return setmetatable(new, Event)
+end
+
+
+
+-- done
+
+return Event \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/LookupTable.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/LookupTable.lua
new file mode 100644
index 0000000000..fc2043d523
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/LookupTable.lua
@@ -0,0 +1,111 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This table provides two utility functions for managing ``lookup
+-- tables''. Such a table is a mixture of an array and a hashtable:
+-- It stores (only) tables. Each table is stored once in a normal
+-- array position. Additionally, the lookup table is also indexed at
+-- the position of the table (used as a key) and this position is set
+-- to |true|. This means that you can test whether a table |t| is in the
+-- lookup table |l| simply by testing whether |l[t]| is true.
+--
+local LookupTable = {}
+
+-- Namespace
+require("pgf.gd.lib").LookupTable = LookupTable
+
+
+
+---
+-- Add all elements in the |array| to a lookup table. If an element of
+-- the array is already present in the table, it will not be added
+-- again.
+--
+-- This operation takes time $O(|\verb!array!|)$.
+--
+-- @param l Lookup table
+-- @param array An array of to-be-added tables.
+
+function LookupTable.add(l, array)
+ for i=1,#array do
+ local t = array[i]
+ if not l[t] then
+ l[t] = true
+ l[#l + 1] = t
+ end
+ end
+end
+
+
+---
+-- Add one element to a lookup table. If it is already present in the
+-- table, it will not be added again.
+--
+-- This operation takes time $O(1)$.
+--
+-- @param l Lookup table
+-- @param e The to-be-added element.
+
+function LookupTable.addOne(l, e)
+ if not l[e] then
+ l[e] = true
+ l[#l + 1] = e
+ end
+end
+
+
+---
+-- Remove tables from a lookup table.
+--
+-- Note that this operation is pretty expensive insofar as it will
+-- always cost a traversal of the whole lookup table. However, this is
+-- also the maximum cost, even when a lot of entries need to be
+-- deleted. Thus, it is much better to ``pool'' multiple remove
+-- operations in a single one.
+--
+-- This operation takes time $O(\max\{|\verb!array!|, |\verb!l!|\})$.
+--
+-- @param l Lookup table
+-- @param t An array of to-be-removed tables.
+
+function LookupTable.remove(l, array)
+ -- Step 1: Mark all to-be-deleted entries
+ for i=1,#array do
+ local t = array[i]
+ if l[t] then
+ l[t] = false
+ end
+ end
+
+ -- Step 2: Collect garbage...
+ local target = 1
+ for i=1,#l do
+ local t = l[i]
+ if l[t] == false then
+ l[t] = nil
+ else
+ l[target] = t
+ target = target + 1
+ end
+ end
+ for i=#l,target,-1 do
+ l[i] = nil
+ end
+end
+
+
+
+-- Done
+
+return LookupTable \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PathLengths.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PathLengths.lua
new file mode 100644
index 0000000000..4bfa896ef9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PathLengths.lua
@@ -0,0 +1,209 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This table provides algorithms for computing distances between
+-- nodes of a graph (in the sense of path lengths).
+
+local PathLengths = {}
+
+-- Namespace
+require("pgf.gd.lib").PathLengths = PathLengths
+
+-- Import
+local PriorityQueue = require "pgf.gd.lib.PriorityQueue"
+
+
+
+---
+-- Performs the Dijkstra algorithm to solve the single-source shortest path problem.
+--
+-- The algorithm computes the shortest paths from |source| to all nodes
+-- in the graph. It also generates a table with distance level sets, each of
+-- which contain all nodes that have the same corresponding distance to
+-- |source|. Finally, a mapping of nodes to their parents along the
+-- shortest paths is generated to allow the reconstruction of the paths
+-- that were chosen by the Dijkstra algorithm.
+--
+-- @param graph The graph to compute the shortest paths for.
+-- @param source The node to compute the distances to.
+--
+-- @return A mapping of nodes to their distance to |source|.
+-- @return An array of distance level sets. The set at index |i| contains
+-- all nodes that have a distance of |i| to |source|.
+-- @return A mapping of nodes to their parents to allow the reconstruction
+-- of the shortest paths chosen by the Dijkstra algorithm.
+--
+function PathLengths.dijkstra(graph, source)
+ local distance = {}
+ local levels = {}
+ local parent = {}
+
+ local queue = PriorityQueue.new()
+
+ -- reset the distance of all nodes and insert them into the priority queue
+ for _,node in ipairs(graph.nodes) do
+ if node == source then
+ distance[node] = 0
+ parent[node] = nil
+ queue:enqueue(node, distance[node])
+ else
+ distance[node] = #graph.nodes + 1 -- this is about infinity ;)
+ queue:enqueue(node, distance[node])
+ end
+ end
+
+ while not queue:isEmpty() do
+ local u = queue:dequeue()
+
+ assert(distance[u] < #graph.nodes + 1, 'the graph is not connected, Dijkstra will not work')
+
+ if distance[u] > 0 then
+ levels[distance[u]] = levels[distance[u]] or {}
+ table.insert(levels[distance[u]], u)
+ end
+
+ for _,edge in ipairs(u.edges) do
+ local v = edge:getNeighbour(u)
+ local alternative = distance[u] + 1
+ if alternative < distance[v] then
+ distance[v] = alternative
+
+ parent[v] = u
+
+ -- update the priority of v
+ queue:updatePriority(v, distance[v])
+ end
+ end
+ end
+
+ return distance, levels, parent
+end
+
+
+
+
+---
+-- Performs the Floyd-Warshall algorithm to solve the all-source shortest path problem.
+--
+-- @param graph The graph to compute the shortest paths for.
+--
+-- @return A distance matrix
+--
+function PathLengths.floydWarshall(graph)
+ local distance = {}
+ local infinity = math.huge
+
+ for _,i in ipairs(graph.nodes) do
+ distance[i] = {}
+ for _,j in ipairs(graph.nodes) do
+ distance[i][j] = infinity
+ end
+ end
+
+ for _,i in ipairs(graph.nodes) do
+ for _,edge in ipairs(i.edges) do
+ local j = edge:getNeighbour(i)
+ distance[i][j] = edge.weight or 1
+ end
+ end
+
+ for _,k in ipairs(graph.nodes) do
+ for _,i in ipairs(graph.nodes) do
+ for _,j in ipairs(graph.nodes) do
+ distance[i][j] = math.min(distance[i][j], distance[i][k] + distance[k][j])
+ end
+ end
+ end
+
+ return distance
+end
+
+
+
+
+---
+-- Computes the pseudo diameter of a graph.
+--
+-- The diameter of a graph is the maximum of the shortest paths between
+-- any pair of nodes in the graph. A pseudo diameter is an approximation
+-- of the diameter that is computed by picking a starting node |u| and
+-- finding a node |v| that is farthest away from |u| and has the smallest
+-- degree of all nodes that have the same distance to |u|. The algorithm
+-- continues with |v| as the new starting node and iteratively tries
+-- to find an end node that is generates a larger pseudo diameter.
+-- It terminates as soon as no such end node can be found.
+--
+-- @param graph The graph.
+--
+-- @return The pseudo diameter of the graph.
+-- @return The start node of the corresponding approximation of a maximum
+-- shortest path.
+-- @return The end node of that path.
+--
+function PathLengths.pseudoDiameter(graph)
+
+ -- find a node with minimum degree
+ local start_node = graph.nodes[1]
+ for _,node in ipairs(graph.nodes) do
+ if node:getDegree() < start_node:getDegree() then
+ start_node = node
+ end
+ end
+
+ assert(start_node)
+
+ local old_diameter = 0
+ local diameter = 0
+ local end_node = nil
+
+ while true do
+ local distance, levels = PathLengths.dijkstra(graph, start_node)
+
+ -- the number of levels is the same as the distance of the nodes
+ -- in the last level to the start node
+ old_diameter = diameter
+ diameter = #levels
+
+ -- abort if the diameter could not be improved
+ if diameter == old_diameter then
+ end_node = levels[#levels][1]
+ break
+ end
+
+ -- select the node with the smallest degree from the last level as
+ -- the start node for the next iteration
+ start_node = levels[#levels][1]
+ for _,node in ipairs(levels[#levels]) do
+ if node:getDegree() < start_node:getDegree() then
+ start_node = node
+ end
+ end
+
+ assert(start_node)
+ end
+
+ assert(start_node)
+ assert(end_node)
+
+ return diameter, start_node, end_node
+end
+
+
+
+
+
+-- Done
+
+return PathLengths \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua
new file mode 100644
index 0000000000..3fd29cdb74
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua
@@ -0,0 +1,342 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- A PriorityQueue supports operations for quickly finding the minimum from a set of elements
+--
+-- Its implementation is based on (simplified) Fibonacci heaps.
+local PriorityQueue = {}
+PriorityQueue.__index = PriorityQueue
+
+
+-- Namespace
+local lib = require "pgf.gd.lib"
+lib.PriorityQueue = PriorityQueue
+
+
+
+-- Local declarations
+local FibonacciHeap = {}
+local FibonacciHeapNode = {}
+
+
+
+
+--- Creates a new priority queue
+--
+-- @return The newly created queue
+
+function PriorityQueue.new()
+ local queue = {
+ heap = FibonacciHeap.new(),
+ nodes = {},
+ values = {},
+ }
+ setmetatable(queue, PriorityQueue)
+ return queue
+end
+
+
+
+--- Add an element with a certain priority to the queue
+--
+-- @param value An object
+-- @param priority Its priority
+
+function PriorityQueue:enqueue(value, priority)
+ local node = self.heap:insert(priority)
+ self.nodes[value] = node
+ self.values[node] = value
+end
+
+
+
+--- Removes the element with the minimum priority from the queue
+--
+-- @return The element with the minimum priority
+
+function PriorityQueue:dequeue()
+ local node = self.heap:extractMinimum()
+
+ if node then
+ local value = self.values[node]
+ self.nodes[value] = nil
+ self.values[node] = nil
+ return value
+ else
+ return nil
+ end
+end
+
+
+
+--- Lower the priority of an element of a queue
+--
+-- @param value An object
+-- @param priority A new priority, which must be lower than the old priority
+
+function PriorityQueue:updatePriority(value, priority)
+ local node = self.nodes[value]
+ assert(node, 'updating the priority of ' .. tostring(value) .. ' failed because it is not in the priority queue')
+ self.heap:updateValue(node, priority)
+end
+
+
+
+--- Tests, whether the queue is empty
+--
+-- @return True, if the queue is empty
+
+function PriorityQueue:isEmpty()
+ return #self.heap.trees == 0
+end
+
+
+
+
+
+
+-- Internals: An implementation of Fibonacci heaps.
+FibonacciHeap.__index = FibonacciHeap
+
+
+function FibonacciHeap.new()
+ local heap = {
+ trees = trees or {},
+ minimum = nil,
+ }
+ setmetatable(heap, FibonacciHeap)
+ return heap
+end
+
+
+
+function FibonacciHeap:insert(value)
+ local node = FibonacciHeapNode.new(value)
+ local heap = FibonacciHeap.new()
+ table.insert(heap.trees, node)
+ self:merge(heap)
+ return node
+end
+
+
+
+function FibonacciHeap:merge(other)
+ for _, tree in ipairs(other.trees) do
+ table.insert(self.trees, tree)
+ end
+ self:updateMinimum()
+end
+
+
+
+function FibonacciHeap:extractMinimum()
+ if self.minimum then
+ local minimum = self:removeTableElement(self.trees, self.minimum)
+
+ for _, child in ipairs(minimum.children) do
+ child.root = child
+ table.insert(self.trees, child)
+ end
+
+ local same_degrees_found = true
+ while same_degrees_found do
+ same_degrees_found = false
+
+ local degrees = {}
+
+ for _, root in ipairs(self.trees) do
+ local degree = root:getDegree()
+
+ if degrees[degree] then
+ if root.value < degrees[degree].value then
+ self:linkRoots(root, degrees[degree])
+ else
+ self:linkRoots(degrees[degree], root)
+ end
+
+ degrees[degree] = nil
+ same_degrees_found = true
+ break
+ else
+ degrees[degree] = root
+ end
+ end
+ end
+
+ self:updateMinimum()
+
+ return minimum
+ end
+end
+
+
+
+function FibonacciHeap:updateValue(node, value)
+ local old_value = node.value
+ local new_value = value
+
+ if new_value <= old_value then
+ self:decreaseValue(node, value)
+ else
+ assert(false, 'FibonacciHeap:increaseValue is not implemented yet')
+ end
+end
+
+
+
+function FibonacciHeap:decreaseValue(node, value)
+ assert(value <= node.value)
+
+ node.value = value
+
+ if node.value < node.parent.value then
+ local parent = node.parent
+ self:cutFromParent(node)
+
+ if not parent:isRoot() then
+ if parent.marked then
+ self:cutFromParent(parent)
+ else
+ parent.marked = true
+ end
+ end
+ end
+
+ if node.value < self.minimum.value then
+ self.minimum = node
+ end
+end
+
+
+
+function FibonacciHeap:delete(node)
+ self:decreaseValue(node, -math.huge)
+ self:extractMinimum()
+end
+
+
+
+function FibonacciHeap:linkRoots(root, child)
+ child.root = root
+ child.parent = root
+
+ child = self:removeTableElement(self.trees, child)
+ table.insert(root.children, child)
+
+ return root
+end
+
+
+
+function FibonacciHeap:cutFromParent(node)
+ local parent = node.parent
+
+ node.root = node
+ node.parent = node
+ node.marked = false
+
+ node = self:removeTableElement(parent.children, node)
+ table.insert(self.trees, node)
+end
+
+
+
+function FibonacciHeap:updateMinimum()
+ self.minimum = self.trees[1]
+
+ for _, root in ipairs(self.trees) do
+ if root.value < self.minimum.value then
+ self.minimum = root
+ end
+ end
+end
+
+
+
+function FibonacciHeap:removeTableElement(input_table, element)
+ for i = 1, #input_table do
+ if input_table[i] == element then
+ return table.remove(input_table, i)
+ end
+ end
+end
+
+
+
+
+-- Now come the nodes
+
+FibonacciHeapNode.__index = FibonacciHeapNode
+
+function FibonacciHeapNode.new(value, root, parent)
+ local node = {
+ value = value,
+ children = {},
+ marked = false,
+ root = nil,
+ parent = nil,
+ }
+ setmetatable(node, FibonacciHeapNode)
+
+ if root then
+ node.root = root
+ node.parent = parent
+ else
+ node.root = node
+ node.parent = node
+ end
+
+ return node
+end
+
+function FibonacciHeapNode:addChild(value)
+ local child = FibonacciHeapNode.new(value, self.root, self)
+ table.insert(self.children, child)
+end
+
+function FibonacciHeapNode:getDegree()
+ return #self.children
+end
+
+
+
+function FibonacciHeapNode:setRoot(root)
+ self.root = root
+
+ if root == self then
+ self.parent = root
+ end
+
+ if #self.children > 0 then
+ for _, child in ipairs(self.children) do
+ child.root = root
+ end
+ end
+end
+
+
+
+function FibonacciHeapNode:isRoot()
+ return self.root == self
+end
+
+
+
+
+
+
+-- done
+
+return PriorityQueue \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua
new file mode 100644
index 0000000000..bcb7276190
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua
@@ -0,0 +1,279 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+--- The Simplifiers class is a singleton object.
+-- Its methods allow implement methods for simplifying graphs, for instance
+-- for removing loops or multiedges or computing spanning trees.
+
+local Simplifiers = {}
+
+-- Namespace
+local lib = require "pgf.gd.lib"
+lib.Simplifiers = Simplifiers
+
+
+
+
+-- Imports
+
+local Edge = require "pgf.gd.deprecated.Edge"
+local Node = require "pgf.gd.deprecated.Node"
+
+
+
+
+
+--- Algorithm to classify edges of a DFS search tree.
+--
+-- TODO Jannis: document this algorithm as soon as it is completed and bug-free.
+-- TT: Replace this algorithm by something else, perhaps?
+--
+function Simplifiers:classifyEdges(graph)
+ local discovered = {}
+ local visited = {}
+ local recursed = {}
+ local completed = {}
+
+ local tree_and_forward_edges = {}
+ local cross_edges = {}
+ local back_edges = {}
+
+ local stack = {}
+
+ local function push(node)
+ table.insert(stack, node)
+ end
+
+ local function peek()
+ return stack[#stack]
+ end
+
+ local function pop()
+ return table.remove(stack)
+ end
+
+ local initial_nodes = graph.nodes
+
+ for i=#initial_nodes,1,-1 do
+ local node = initial_nodes[i]
+ push(node)
+ discovered[node] = true
+ end
+
+ while #stack > 0 do
+ local node = peek()
+ local edges_to_traverse = {}
+
+ visited[node] = true
+
+ if not recursed[node] then
+ recursed[node] = true
+
+ local out_edges = node:getOutgoingEdges()
+ for _,edge in ipairs(out_edges) do
+ local neighbour = edge:getNeighbour(node)
+
+ if not discovered[neighbour] then
+ table.insert(tree_and_forward_edges, edge)
+ table.insert(edges_to_traverse, edge)
+ else
+ if not completed[neighbour] then
+ if not visited[neighbour] then
+ table.insert(tree_and_forward_edges, edge)
+ table.insert(edges_to_traverse, edge)
+ else
+ table.insert(back_edges, edge)
+ end
+ else
+ table.insert(cross_edges, edge)
+ end
+ end
+ end
+
+ if #edges_to_traverse == 0 then
+ completed[node] = true
+ pop()
+ else
+ for i=#edges_to_traverse,1,-1 do
+ local neighbour = edges_to_traverse[i]:getNeighbour(node)
+ discovered[neighbour] = true
+ push(neighbour)
+ end
+ end
+ else
+ completed[node] = true
+ pop()
+ end
+ end
+
+ return tree_and_forward_edges, cross_edges, back_edges
+end
+
+
+
+
+
+--
+--
+-- Loops and Multiedges
+--
+--
+
+
+--- Remove all loops from a graph
+--
+-- This method will remove all loops from a graph.
+--
+-- @param algorithm An algorithm object
+
+function Simplifiers:removeLoopsOldModel(algorithm)
+ local graph = algorithm.graph
+ local loops = {}
+
+ for _,edge in ipairs(graph.edges) do
+ if edge:getHead() == edge:getTail() then
+ loops[#loops+1] = edge
+ end
+ end
+
+ for i=1,#loops do
+ graph:deleteEdge(loops[i])
+ end
+
+ graph[algorithm].loops = loops
+end
+
+
+
+--- Restore loops that were previously removed.
+--
+-- @param algorithm An algorithm object
+
+function Simplifiers:restoreLoopsOldModel(algorithm)
+ local graph = algorithm.graph
+
+ for _,edge in ipairs(graph[algorithm].loops) do
+ graph:addEdge(edge)
+ edge:getTail():addEdge(edge)
+ end
+
+ graph[algorithm].loops = nil
+end
+
+
+
+
+--- Remove all multiedges.
+--
+-- Every multiedge of the graph will be replaced by a single edge.
+--
+-- @param algorithm An algorithm object
+
+function Simplifiers:collapseMultiedgesOldModel(algorithm, collapse_action)
+ local graph = algorithm.graph
+ local collapsed_edges = {}
+ local node_processed = {}
+
+ for _,node in ipairs(graph.nodes) do
+ node_processed[node] = true
+
+ local multiedge = {}
+
+ local function handle_edge (edge)
+
+ local neighbour = edge:getNeighbour(node)
+
+ if not node_processed[neighbour] then
+ if not multiedge[neighbour] then
+ multiedge[neighbour] = Edge.new{ direction = Edge.RIGHT }
+ collapsed_edges[multiedge[neighbour]] = {}
+ end
+
+ if collapse_action then
+ collapse_action(multiedge[neighbour], edge, graph)
+ end
+
+ table.insert(collapsed_edges[multiedge[neighbour]], edge)
+ end
+ end
+
+ for _,edge in ipairs(node:getIncomingEdges()) do
+ handle_edge(edge)
+ end
+
+ for _,edge in ipairs(node:getOutgoingEdges()) do
+ handle_edge(edge)
+ end
+
+ for neighbour, multiedge in pairs(multiedge) do
+
+ if #collapsed_edges[multiedge] <= 1 then
+ collapsed_edges[multiedge] = nil
+ else
+ for _,subedge in ipairs(collapsed_edges[multiedge]) do
+ graph:deleteEdge(subedge)
+ end
+
+ multiedge:addNode(node)
+ multiedge:addNode(neighbour)
+
+ graph:addEdge(multiedge)
+ end
+ end
+ end
+
+ graph[algorithm].collapsed_edges = collapsed_edges
+end
+
+
+--- Expand multiedges that were previously collapsed
+--
+-- @param algorithm An algorithm object
+
+function Simplifiers:expandMultiedgesOldModel(algorithm)
+ local graph = algorithm.graph
+ for multiedge, subedges in pairs(graph[algorithm].collapsed_edges) do
+ assert(#subedges >= 2)
+
+ graph:deleteEdge(multiedge)
+
+ for _,edge in ipairs(subedges) do
+
+ -- Copy bend points
+ for _,p in ipairs(multiedge.bend_points) do
+ edge.bend_points[#edge.bend_points+1] = p:copy()
+ end
+
+ -- Copy options
+ for k,v in pairs(multiedge.algorithmically_generated_options) do
+ edge.algorithmically_generated_options[k] = v
+ end
+
+ for _,node in ipairs(edge.nodes) do
+ node:addEdge(edge)
+ end
+
+ graph:addEdge(edge)
+ end
+ end
+
+ graph[algorithm].collapsed_edges = nil
+end
+
+
+
+
+
+-- Done
+
+return Simplifiers
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Stack.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Stack.lua
new file mode 100644
index 0000000000..75084b6e38
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Stack.lua
@@ -0,0 +1,61 @@
+-- Copyright 2011 by Jannis Pohlmann
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+--- A Stack is a very simple wrapper around an array
+--
+--
+
+local Stack = {}
+Stack.__index = Stack
+
+
+-- Namespace
+require("pgf.gd.lib").Stack = Stack
+
+
+--- Create a new stack
+function Stack.new()
+ local stack = {}
+ setmetatable(stack, Stack)
+ return stack
+end
+
+
+--- Push an element on top of the stack
+function Stack:push(data)
+ self[#self+1] = data
+end
+
+
+--- Inspect (but not pop) the top element of a stack
+function Stack:peek()
+ return self[#self]
+end
+
+
+--- Pop an element from the top of the stack
+function Stack:pop()
+ return table.remove(self, #self)
+end
+
+
+--- Get the height of the stack
+function Stack:getSize()
+ return #self
+end
+
+
+
+-- done
+
+return Stack \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Storage.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Storage.lua
new file mode 100644
index 0000000000..e029fdf7ff
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Storage.lua
@@ -0,0 +1,110 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- A storage is an object that, as the name suggests, allows you to
+-- ``store stuff concerning objects.'' Basically, it behaves like
+-- table having weak keys, which means that once the objects for which
+-- you ``store stuff'' go out of scope, they are also removed from the
+-- storage. Also, you can specify that for each object of the storage
+-- you store a table. In this case, there is no need to initialize
+-- this table for each object; rather, when you write into such a
+-- table and it does not yet exist, it is created ``on the fly''.
+--
+-- The typical way you use storages is best explained with the
+-- following example: Suppose you want to write a depth-first search
+-- algorithm for a graph. This algorithm might wish to mark all nodes
+-- it has visited. It could just say |v.marked = true|, but this might
+-- clash with someone else also using the |marked| key. The solution is
+-- to create a |marked| storage. The algorithm can first say
+--\begin{codeexample}[code only, tikz syntax=false]
+--local marked = Storage.new()
+--\end{codeexample}
+-- and then say
+--\begin{codeexample}[code only, tikz syntax=false]
+--marked[v] = true
+--\end{codeexample}
+-- to mark its objects. The |marked| storage object does not need to
+-- be created locally inside a function, you can declare it as a local
+-- variable of the whole file; nevertheless, the entries for vertices
+-- no longer in use get removed automatically. You can also make it a
+-- member variable of the algorithm class, which allows you make the
+-- information about which objects are marked globally
+-- accessible.
+--
+-- Now suppose the algorithm would like to store even more stuff in
+-- the storage. For this, we might use a table and can use the fact
+-- that a storage will automatically create a table when necessary:
+--\begin{codeexample}[code only, tikz syntax=false]
+--local info = Storage.newTableStorage()
+--
+--info[v].marked = true -- the "info[v]" table is
+-- -- created automatically here
+--
+--info[v].foo = "bar"
+--\end{codeexample}
+-- Again, once |v| goes out of scope, both it and the info table will
+-- removed.
+
+local Storage = {}
+
+-- Namespace
+require("pgf.gd.lib").Storage = Storage
+
+
+-- The simple metatable
+
+local SimpleStorageMetaTable = { __mode = "k" }
+
+-- The advanced metatable for table storages:
+
+local TableStorageMetaTable = {
+ __mode = "k",
+ __index =
+ function(t, k)
+ local new = {}
+ rawset(t, k, new)
+ return new
+ end
+}
+
+
+---
+-- Create a new storage object.
+--
+-- @return A new |Storage| instance.
+
+function Storage.new()
+ return setmetatable({}, SimpleStorageMetaTable)
+end
+
+
+---
+-- Create a new storage object which will install a table for every
+-- entry automatically.
+--
+-- @return A new |Storage| instance.
+
+function Storage.newTableStorage()
+ return setmetatable({}, TableStorageMetaTable)
+end
+
+
+
+
+
+
+
+-- Done
+
+return Storage
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Transform.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Transform.lua
new file mode 100644
index 0000000000..7695b1b239
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/lib/Transform.lua
@@ -0,0 +1,120 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- The |Transform| table provides a set of static methods for
+-- creating and handling canvas transformation matrices. Such a matrix
+-- is actually just an array of six numbers. The idea is that
+-- ``applying'' an array { a, b, c, d, e, f } a vector $(x,y)$ will
+-- yield the new vector $(ax+by+e,cx+dy+f)$. For details on how such
+-- matrices work, see Section~\ref{section-transform-cm}
+--
+local Transform = {}
+
+
+-- Namespace
+
+require("pgf.gd.model").Transform = Transform
+
+
+--- Creates a new transformation array.
+--
+-- @param a First component
+-- @param b Second component
+-- @param c Third component
+-- @param d Fourth component
+-- @param x The x shift
+-- @param y The y shift
+--
+-- @return A transformation object.
+--
+function Transform.new(a,b,c,d,x,y)
+ return { a, b, c, d, x, y }
+end
+
+
+--- Creates a new transformation object that represents a shift.
+--
+-- @param x An x-shift
+-- @param y A y-shift
+--
+-- @return A transformation object
+--
+function Transform.new_shift(x,y)
+ return { 1, 0, 0, 1, x, y }
+end
+
+
+--- Creates a new transformation object that represents a rotation.
+--
+-- @param angle An angle
+--
+-- @return A transformation object
+--
+function Transform.new_rotation(angle)
+ local c = math.cos(angle)
+ local s = math.sin(angle)
+ return { c, -s, s, c, 0, 0 }
+end
+
+
+--- Creates a new transformation object that represents a scaling.
+--
+-- @param x The horizontal scaling
+-- @param y The vertical scaling (if missing, the horizontal scaling is used)
+--
+-- @return A transformation object
+--
+function Transform.new_scaling(x_scale, y_scale)
+ return { x_scale, 0, 0, y_scale or x_scale, 0, 0 }
+end
+
+
+
+
+---
+-- Concatenate two transformation matrices, returning the new one.
+--
+-- @param a The first transformation
+-- @param b The second transformation
+--
+-- @return The transformation representing first applying |b| and then
+-- applying |a|.
+--
+function Transform.concat(a,b)
+ local a1, a2, a3, a4, a5, a6, b1, b2, b3, b4, b5, b6 =
+ a[1], a[2], a[3], a[4], a[5], a[6], b[1], b[2], b[3], b[4], b[5], b[6]
+ return { a1*b1 + a2*b3, a1*b2 + a2*b4,
+ a3*b1 + a4*b3, a3*b2 + a4*b4,
+ a1*b5 + a2*b6 + a5, a3*b5 + a4*b6 + a6 }
+end
+
+
+
+---
+-- Inverts a transformation matrix.
+--
+-- @param t The transformation.
+--
+-- @return The inverted transformation
+--
+function Transform.invert(t)
+ local t1, t2, t3, t4 = t[1], t[2], t[3], t[4]
+ local idet = 1/(t1*t4 - t2*t3)
+
+ return { t4*idet, -t2*idet, -t3*idet, t1*idet, -t[5], -t[6] }
+end
+
+
+-- Done
+
+return Transform
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model.lua
new file mode 100644
index 0000000000..4a0130488b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model.lua
@@ -0,0 +1,26 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+-- Imports
+
+require "pgf"
+require "pgf.gd"
+
+
+-- Declare namespace
+pgf.gd.model = {}
+
+
+-- Done
+
+return pgf.gd.model \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Arc.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Arc.lua
new file mode 100644
index 0000000000..e007e9b59b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Arc.lua
@@ -0,0 +1,653 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- An arc is a light-weight object representing an arc from a vertex
+-- in a graph to another vertex. You may not create an |Arc| by
+-- yourself, which is why there is no |new| method, arc creation is
+-- done by the Digraph class.
+--
+-- Every arc belongs to exactly one graph. If you want the same arc in
+-- another graph, you need to newly connect two vertices in the other graph.
+--
+-- You may read the |head| and |tail| fields, but you may not write
+-- them. In order to store data for an arc, use |Storage| objects.
+--
+-- Between any two vertices of a graph there can be only one arc, so
+-- all digraphs are always simple graphs. However, in the
+-- specification of a graph (the syntactic digraph), there might
+-- be multiple edges between two vertices. This means, in particular,
+-- that an arc has no |options| field. Rather, it has several
+-- |optionsXxxx| functions, that will search for options in all of the
+-- syntactic edges that ``belong'' to an edge.
+--
+-- In order to \emph{set} options of the edges, you can set the
+-- |generated_options| field of an arc (which is |nil| by default), see
+-- the |declare_parameter_sequence| function for the syntax. Similar
+-- to the |path| field below, the options set in this table are
+-- written back to the syntactic edges during a sync.
+--
+-- Finally, there is also an |animations| field, which, similarly to
+-- the |generated_options|, gets written back during a sync when it is
+-- not |nil|.
+--
+-- In detail, the following happens: Even though an arc has a |path|,
+-- |generated_options|, and |animations| fields, setting these fields does
+-- not immediately set the paths of the syntactic edges nor does it
+-- generate options. Indeed, you will normally want to setup and
+-- modify the |path| field of an arc during your algorithm and only at
+-- the very end, ``write it back'' to the multiple syntactic edges
+-- underlying the graph. For this purpose, the method |sync| is used,
+-- which is called automatically for the |ugraph| and |digraph| of a
+-- scope as well as for spanning trees.
+--
+-- The bottom line concerning the |path| field is the following: If
+-- you just want a straight line along an arc, just leave the field as
+-- it is (namely, |nil|). If you want to have all edges along a path
+-- to follow a certain path, set the |path| field of the arc to the
+-- path you desire (typically, using the |setPolylinePath| or a
+-- similar method). This will cause all syntactic edges underlying the
+-- arc to be set to the specified path. In the event that you want to
+-- set different paths for the edges underlying a single arc
+-- differently, set the |path| fields of these edges and set the
+-- |path| field of the arc to |nil|. This will disable the syncing for
+-- the arc and will cause the edge |paths| to remain untouched.
+--
+-- @field tail The tail vertex of the arc.
+-- @field head The head vertex of the arc. May be the same as the tail
+-- in case of a loop.
+-- @field path If non-nil, the path of the arc. See the description
+-- above.
+-- @field generated_options If non-nil, some options to be passed back
+-- to the original syntactic edges, see the description above.
+-- @field animations If non-nil, some animations to be passed back
+-- to the original syntactic edges. See the description of the
+-- |animations| field for |Vertex| for details on the syntax.
+-- @field syntactic_edges In case this arc is an arc in the syntactic
+-- digraph (and only then), this field contains an array containing
+-- syntactic edges (``real'' edges in the syntactic digraph) that
+-- underly this arc. Otherwise, the field will be empty or |nil|.
+--
+local Arc = {}
+Arc.__index = Arc
+
+
+-- Namespace
+
+require("pgf.gd.model").Arc = Arc
+
+
+-- Imports
+
+local Path = require 'pgf.gd.model.Path'
+local lib = require 'pgf.gd.lib'
+
+
+---
+-- Get an array of options of the syntactic edges corresponding to an arc.
+--
+-- An arc in a digraph is typically (but not always) present because
+-- there are one or more edges in the syntactic digraph between the
+-- tail and the head of the arc or between the head and the tail.
+--
+-- Since for every arc there can be several edges present in the
+-- syntactic digraph, an option like |length| may have
+-- been given multiple times for the edges corresponding to the arc.
+--
+-- If your algorithm gets confused by multiple edges, try saying
+-- |a:options(your_option)|. This will always give the ``most
+-- sensible'' choice of the option if there are multiple edges
+-- corresponding to the same arc.
+--
+-- @param option A string option like |"length"|.
+--
+-- @return A table with the following contents:
+-- %
+-- \begin{enumerate}
+-- \item It is an array of all values the option has for edges
+-- corresponding to |self| in the syntactic digraph. Suppose, for
+-- instance, you write the following:
+-- %
+--\begin{codeexample}[code only]
+--graph {
+-- tail -- [length=1] head, % multi edge 1
+-- tail -- [length=3] head, % mulit edge 2
+-- head -- [length=8] tail, % multi edge 3
+-- tail -- head, % multi edge 4
+-- head -- [length=7] tail, % multi edge 5
+-- tail -- [length=2] head, % multi edge 6
+--}
+--\end{codeexample}
+-- %
+-- Suppose, furthermore, that |length| has been setup as an edge
+-- option. Now suppose that |a| is the arc from the vertex |tail| to
+-- the vertex |head|. Calling |a:optionsArray('length')| will
+-- yield the array part |{1,3,2,8,7}|. The reason for the ordering is
+-- as follows: First come all values |length| had for syntactic edges
+-- going from |self.tail| to |self.head| in the order they appear in the
+-- graph description. Then come all values the options has for syntactic
+-- edges going from |self.head| to |self.tail|. The reason for this
+-- slightly strange behavior is that many algorithms do not really
+-- care whether someone writes |a --[length=1] b| or
+-- |b --[length=1] a|; in both cases they would ``just'' like to know
+-- that the length is~|1|.
+--
+-- \item There is field called |aligned|, which is an array storing
+-- the actual syntactic edge objects whose values can be found in the
+-- array part of the returned table. However, |aligned| contains only
+-- the syntactic edges pointing ``in the same direction'' as the arc,
+-- that is, the tail and head of the syntactic edge are the same as
+-- those of the arc. In the above example, this array would contain
+-- the edges with the comment numbers |1|, |2|, and |6|.
+--
+-- Using the length of this array and the fact that the ``aligned''
+-- values come first in the table, you can easily iterate over the
+-- |option|'s values of only those edges that are aligned with the arc:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local a = g:arc(tail.head) -- some arc
+--local opt = a:optionsArray('length')
+--local sum = 0
+--for i=1,#opt.aligned do
+-- sum = sum + opt[i]
+--end
+--\end{codeexample}
+-- %
+-- \item There is a field called |anti_aligned|, which is an array
+-- containing exactly the edges in the array part of the table not
+-- aligned with the arc. The numbering start at |1| as usual, so the
+-- $i$th entry of this table corresponds to the entry at position $i +
+-- \verb!#opt.aligned!$ of the table.
+-- \end{enumerate}
+--
+function Arc:optionsArray(option)
+
+ local cache = self.option_cache
+ local t = cache[option]
+ if t then
+ return t
+ end
+
+ -- Accumulate the edges for which the option is set:
+ local tail = self.tail
+ local head = self.head
+ local s_graph = self.syntactic_digraph
+
+ local arc = s_graph:arc(tail, head)
+ local aligned = {}
+ if arc then
+ for _,m in ipairs(arc.syntactic_edges) do
+ if m.options[option] ~= nil then
+ aligned[#aligned + 1] = m
+ end
+ end
+ table.sort(aligned, function (a,b) return a.event.index < b.event.index end)
+ end
+
+ local arc = head ~= tail and s_graph:arc(head, tail)
+ local anti_aligned = {}
+ if arc then
+ for _,m in ipairs(arc.syntactic_edges) do
+ if m.options[option] ~= nil then
+ anti_aligned[#anti_aligned + 1] = m
+ end
+ end
+ table.sort(anti_aligned, function (a,b) return a.event.index < b.event.index end)
+ end
+
+ -- Now merge them together
+ local t = { aligned = aligned, anti_aligned = anti_aligned }
+ for i=1,#aligned do
+ t[i] = aligned[i].options[option]
+ end
+ for i=1,#anti_aligned do
+ t[#t+1] = anti_aligned[i].options[option]
+ end
+ cache[option] = t
+
+ return t
+end
+
+
+
+---
+-- Returns the first option, that is, the first entry of
+-- |Arc:optionsArray(option)|. However, if the |only_aligned|
+-- parameter is set to true and there is no option with any aligned
+-- syntactic edge, |nil| is returned.
+--
+-- @param option An option
+-- @param only_aligned If true, only aligned syntactic edges will be
+-- considered.
+-- @return The first entry of the |optionsArray|
+function Arc:options(option, only_aligned)
+ if only_aligned then
+ local opt = self:optionsArray(option)
+ if #opt.aligned > 0 then
+ return opt[1]
+ end
+ else
+ return self:optionsArray(option)[1]
+ end
+end
+
+
+
+
+---
+-- Get an accumulated value of an option of the syntactic edges
+-- corresponding to an arc.
+--
+-- @param option The option of interest
+-- @param accumulator A function taking two values. When there are
+-- more than one syntactic edges corresponding to |self| for which the
+-- |option| is set, this function will be called repeatedly for the
+-- different values. The first time it will be called for the first
+-- two values. Next, it will be called for the result of this call and
+-- the third value, and so on.
+-- @param only_aligned A boolean. If true, only the aligned syntactic
+-- edges will be considered.
+--
+-- @return If the option is not set for any (aligned) syntactic edges
+-- corresponding to |self|, |nil| is returned. If there is exactly one
+-- edge, the value of this edge is returned. Otherwise, the result of
+-- repeatedly applying the |accumulator| function as described
+-- above.
+--
+-- The result is cached, repeated calls will not invoke the
+-- |accumulator| function again.
+--
+-- @usage Here is typical usage:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local total_length = a:optionsAccumulated('length', function (a,b) return a+b end) or 0
+--\end{codeexample}
+--
+function Arc:optionsAccumulated(option, accumulator, only_aligned)
+ local opt = self:options(option)
+ if only_aligned then
+ local aligned = opt.aligned
+ local v = aligned[accumulator]
+ if v == nil then
+ v = opt[1]
+ for i=2,#aligned do
+ v = accumulator(v, opt[i])
+ end
+ align[accumulator] = v
+ end
+ return v
+ else
+ local v = opt[accumulator]
+ if v == nil then
+ v = opt[1]
+ for i=2,#opt do
+ v = accumulator(v, opt[i])
+ end
+ opt[accumulator] = v
+ end
+ return v
+ end
+end
+
+
+
+---
+-- Compute the syntactic head and tail of an arc. For this, we have a
+-- look at the syntactic digraph underlying the arc. If there is at
+-- least once syntactic edge going from the arc's tail to the arc's
+-- head, the arc's tail and head are returned. Otherwise, we test
+-- whether there is a syntactic edge in the other direction and, if
+-- so, return head and tail in reverse order. Finally, if there is no
+-- syntactic edge at all corresponding to the arc in either direction,
+-- |nil| is returned.
+--
+-- @return The syntactic tail
+-- @return The syntactic head
+
+function Arc:syntacticTailAndHead ()
+ local s_graph = self.syntactic_digraph
+ local tail = self.tail
+ local head = self.head
+ if s_graph:arc(tail, head) then
+ return tail, head
+ elseif s_graph:arc(head, tail) then
+ return head, tail
+ end
+end
+
+
+---
+-- Compute the point cloud.
+--
+-- @return This method will return the ``point cloud'' of an arc,
+-- which is an array of all points that must be rotated and shifted
+-- along with the endpoints of an edge.
+--
+function Arc:pointCloud ()
+ if self.cached_point_cloud then
+ return self.cached_point_cloud -- cached
+ end
+ local cloud = {}
+ local a = self.syntactic_digraph:arc(self.tail,self.head)
+ if a then
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,p in ipairs(e.path) do
+ if type(p) == "table" then
+ cloud[#cloud + 1] = p
+ end
+ end
+ end
+ end
+ self.cached_point_cloud = cloud
+ return cloud
+end
+
+
+
+---
+-- Compute an event index for the arc.
+--
+-- @return The lowest event index of any edge involved
+-- in the arc (or nil, if there is no syntactic edge).
+--
+function Arc:eventIndex ()
+ if self.cached_event_index then
+ return self.cached_event_index
+ end
+ local head = self.head
+ local tail = self.tail
+ local e = math.huge
+ local a = self.syntactic_digraph:arc(tail,head)
+ if a then
+ for _,m in ipairs(a.syntactic_edges) do
+ e = math.min(e, m.event.index)
+ end
+ end
+ local a = head ~= tail and self.syntactic_digraph:arc(head,tail)
+ if a then
+ for _,m in ipairs(a.syntactic_edges) do
+ e = math.min(e, m.event.index)
+ end
+ end
+ self.cached_event_index = e
+ return e
+end
+
+
+
+
+---
+-- The span collector
+--
+-- This method returns the top (that is, smallest) priority of any
+-- edge involved in the arc.
+--
+-- The priority of an edge is computed as follows:
+-- %
+-- \begin{enumerate}
+-- \item If the option |"span priority"| is set, this number
+-- will be used.
+-- \item If the edge has the same head as the arc, we lookup the key\\
+-- |"span priority " .. edge.direction|. If set, we use this value.
+-- \item If the edge has a different head from the arc (the arc is
+-- ``reversed'' with respect to the syntactic edge), we lookup the key
+-- |"span priority reversed " .. edge.direction|. If set, we use this value.
+-- \item Otherwise, we use priority 5.
+-- \end{enumerate}
+--
+-- @return The priority of the arc, as described above.
+--
+function Arc:spanPriority()
+ if self.cached_span_priority then
+ return self.cached_span_priority
+ end
+
+ local head = self.head
+ local tail = self.tail
+ local min
+ local g = self.syntactic_digraph
+
+ local a = g:arc(tail,head)
+ if a then
+ for _,m in ipairs(a.syntactic_edges) do
+ local p =
+ m.options["span priority"] or
+ lib.lookup_option("span priority " .. m.direction, m, g)
+
+ min = math.min(p or 5, min or math.huge)
+ end
+ end
+
+ local a = head ~= tail and g:arc(head,tail)
+ if a then
+ for _,m in ipairs(a.syntactic_edges) do
+ local p =
+ m.options["span priority"] or
+ lib.lookup_option("span priority reversed " .. m.direction, m, g)
+
+ min = math.min(p or 5, min or math.huge)
+ end
+ end
+
+ self.cached_span_priority = min or 5
+
+ return min or 5
+end
+
+
+
+
+
+
+---
+-- Sync an |Arc| with its syntactic edges with respect to the path and
+-- generated options. It causes the following to happen:
+-- If the |path| field of the arc is |nil|, nothing
+-- happens with respect to the path. Otherwise, a copy of the |path|
+-- is created. However, for every path element that is a function,
+-- this function is invoked with the syntactic edge as its
+-- parameter. The result of this call should now be a |Coordinate|,
+-- which will replace the function in the |Path|.
+--
+-- You use this method like this:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--...
+--local arc = g:connect(s,t)
+--arc:setPolylinePath { Coordinate.new(x,y), Coordinate.new(x1,y1) }
+--...
+--arc:sync()
+--\end{codeexample}
+--
+-- Next, similar to the path, the field |generated_options| is
+-- considered. If it is not |nil|, then all options listed in this
+-- field are appended to all syntactic edges underlying the arc.
+--
+-- Note that this function will automatically be called for all arcs
+-- of the |ugraph|, the |digraph|, and the |spanning_tree| of an
+-- algorithm by the rendering pipeline.
+--
+function Arc:sync()
+ if self.path then
+ local path = self.path
+ local head = self.head
+ local tail = self.tail
+ local a = self.syntactic_digraph:arc(tail,head)
+ if a and #a.syntactic_edges>0 then
+ for _,e in ipairs(a.syntactic_edges) do
+ local clone = path:clone()
+ for i=1,#clone do
+ local p = clone[i]
+ if type(p) == "function" then
+ clone[i] = p(e)
+ if type(clone[i]) == "table" then
+ clone[i] = clone[i]:clone()
+ end
+ end
+ end
+ e.path = clone
+ end
+ end
+ local a = head ~= tail and self.syntactic_digraph:arc(head,tail)
+ if a and #a.syntactic_edges>0 then
+ for _,e in ipairs(a.syntactic_edges) do
+ local clone = path:reversed()
+ for i=1,#clone do
+ local p = clone[i]
+ if type(p) == "function" then
+ clone[i] = p(e)
+ if type(clone[i]) == "table" then
+ clone[i] = clone[i]:clone()
+ end
+ end
+ end
+ e.path = clone
+ end
+ end
+ end
+ if self.generated_options then
+ local head = self.head
+ local tail = self.tail
+ local a = self.syntactic_digraph:arc(tail,head)
+ if a and #a.syntactic_edges>0 then
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,o in ipairs(self.generated_options) do
+ e.generated_options[#e.generated_options+1] = o
+ end
+ end
+ end
+ local a = head ~= tail and self.syntactic_digraph:arc(head,tail)
+ if a and #a.syntactic_edges>0 then
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,o in ipairs(self.generated_options) do
+ e.generated_options[#e.generated_options+1] = o
+ end
+ end
+ end
+ end
+ if self.animations then
+ local head = self.head
+ local tail = self.tail
+ local a = self.syntactic_digraph:arc(tail,head)
+ if a and #a.syntactic_edges>0 then
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,o in ipairs(self.animations) do
+ e.animations[#e.animations+1] = o
+ end
+ end
+ end
+ local a = head ~= tail and self.syntactic_digraph:arc(head,tail)
+ if a and #a.syntactic_edges>0 then
+ for _,e in ipairs(a.syntactic_edges) do
+ for _,o in ipairs(self.animations) do
+ e.animations[#e.animations+1] = o
+ end
+ end
+ end
+ end
+end
+
+
+---
+-- This method returns a ``coordinate factory'' that can be used as
+-- the coordinate of a |moveto| at the beginning of a path starting at
+-- the |tail| of the arc. Suppose you want to create a path starting
+-- at the tail vertex, going to the coordinate $(10,10)$ and ending at
+-- the head vertex. The trouble is that when you create the path
+-- corresponding to this route, you typically do not know where the
+-- tail vertex is going to be. Even if that \emph{has} already been
+-- settled, you will still have the problem that different edges
+-- underlying the arc may wish to start their paths at different
+-- anchors inside the tail vertex. In such cases, you use this
+-- method to get a function that will, later on, compute the correct
+-- position of the anchor as needed.
+--
+-- Here is the code you would use to create the above-mentioned path:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local a = g:connect(tail,head)
+--...
+--arc.path = Path.new()
+--arc.path:appendMoveto(arc:tailAnchorForArcPath())
+--arc.path:appendLineto(10, 10)
+--arc.path:appendLineto(arc:headAnchorForArcPath())
+--\end{codeexample}
+--
+-- Normally, however, you will not write code as detailed as the above
+-- and you would just write instead of the last three lines:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--arc:setPolylinePath { Coordinate.new (10, 10) }
+--\end{codeexample}
+
+function Arc:tailAnchorForArcPath()
+ return function (edge)
+ local a = edge.options['tail anchor']
+ if a == "" then
+ a = "center"
+ end
+ return self.tail:anchor(a) + self.tail.pos
+ end
+end
+
+---
+-- See |Arc:tailAnchorForArcPath|.
+
+function Arc:headAnchorForArcPath()
+ return function (edge)
+ local a = edge.options['head anchor']
+ if a == "" then
+ a = "center"
+ end
+ return self.head:anchor(a) + self.head.pos
+ end
+end
+
+
+
+---
+-- Setup the |path| field of an arc in such a way that it corresponds
+-- to a sequence of straight line segments starting at the tail's
+-- anchor and ending at the head's anchor.
+--
+-- @param coordinates An array of |Coordinates| through which the line
+-- will go through.
+
+function Arc:setPolylinePath(coordinates)
+ local p = Path.new ()
+
+ p:appendMoveto(self:tailAnchorForArcPath())
+
+ for _,c in ipairs(coordinates) do
+ p:appendLineto(c)
+ end
+
+ p:appendLineto(self:headAnchorForArcPath())
+
+ self.path = p
+end
+
+
+
+
+-- Returns a string representation of an arc. This is mainly for debugging
+--
+-- @return The Arc as string.
+--
+function Arc:__tostring()
+ return tostring(self.tail) .. "->" .. tostring(self.head)
+end
+
+
+-- Done
+
+return Arc
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Collection.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Collection.lua
new file mode 100644
index 0000000000..abc454b7db
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Collection.lua
@@ -0,0 +1,208 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- A collection is essentially a subgraph of a graph, that is, a
+-- ``collection'' of some nodes and some edges of the graph. The name
+-- ``collection'' was chosen over ``subgraph'' since the latter are
+-- often thought of as parts of a graph that are rendered in a special
+-- way (such as being surrounded by a rectangle), while collections
+-- are used to model such diverse things as hyperedges, sets of
+-- vertices that should be on the same level in a layered algorithm,
+-- or, indeed, subgraphs that are rendered in a special way.
+--
+-- Collections are grouped into ``kinds''. All collections of a given
+-- kind can be accessed by algorithms through an array whose elements
+-- are the collections. On the display layer, for each kind a separate
+-- key is available to indicate that a node or an edge belongs to a
+-- collection.
+--
+-- Collections serve two purposes: First, they can be seen as ``hints''
+-- to graph drawing algorithms that certain nodes and/or edges ``belong
+-- together''. For instance, collections of kind |same layer| are used
+-- by the Sugiyama algorithm to group together nodes that should appear
+-- at the same height of the output. Second, since collections are also
+-- passed back to the display layer in a postprocessing step, they can be
+-- used to render complicated concepts such as hyperedges (which are
+-- just collections of nodes, after all) or subgraphs.
+--
+-- @field kind The ``kind'' of the collection.
+--
+-- @field vertices A lookup table of vertices (that is, both an array
+-- with the vertices in the order in which they appear as well as a
+-- table such that |vertices[vertex] == true| whenever |vertex| is
+-- present in the table.
+--
+-- @field edges A lookup table of edges (not arcs!).
+--
+-- @field options An options table. This is the table of options that
+-- was in force when the collection was created.
+--
+-- @field child_collections An array of all collections that are
+-- direct children of this collection (that is,
+-- they were defined while the current collection was the most
+-- recently defined collection on the options stack). However, you
+-- should use the methods |children|, |descendants|, and so to access
+-- this field.
+--
+-- @field parent_collection The parent collection of the current
+-- collection. This field may be |nil| in case a collection has no parent.
+--
+-- @field event An |Event| object that was create for this
+-- collection. Its |kind| will be |"collection"| while its |parameter|
+-- will be the collection kind.
+
+local Collection = {}
+Collection.__index = Collection
+
+
+-- Namespace
+
+require("pgf.gd.model").Collection = Collection
+
+
+-- Imports
+local Storage = require "pgf.gd.lib.Storage"
+
+
+
+---
+-- Creates a new collection. You should not call this function
+-- directly, it is called by the interface classes.
+--
+-- @param t A table of initial values. The field |t.kind| must be a
+-- nonempty string.
+--
+-- @return The new collection
+--
+function Collection.new(t)
+ assert (type(t.kind) == "string" and t.kind ~= "", "collection kind not set")
+
+ return setmetatable(
+ {
+ vertices = t.vertices or {},
+ edges = t.edges or {},
+ options = t.options or {},
+ generated_options = t.generated_options or {},
+ kind = t.kind,
+ event = t.event,
+ child_collections = t.child_collections or {},
+ }, Collection)
+end
+
+
+
+
+--
+-- An internal function for registering a collection as child of
+-- another collection. The collection |self| will be made a child
+-- collection of |parent|.
+--
+-- @param parent A collection.
+
+function Collection:registerAsChildOf(parent)
+ self.parent = parent
+ if parent then
+ assert (getmetatable(parent) == Collection, "parent must be a collection")
+ parent.child_collections[#parent.child_collections+1] = self
+ end
+end
+
+
+
+---
+-- A collection can have any number of \emph{child collections}, which
+-- are collections nested inside the collection. You can access the
+-- array of these children through this method. You may not modify
+-- the array returned by this function.
+--
+-- @return The array of children of |self|.
+--
+function Collection:children()
+ return self.child_collections
+end
+
+
+---
+-- This method works like the |children| method. However, the tree of
+-- collections is, conceptually, contracted by considering only these
+-- collections that have the |kind| given as parameter. For instance,
+-- if |self| has a child collection of a kind different from |kind|,
+-- but this child collection has, in turn, a child collection of kind
+-- |kind|, this latter child collection will be included in the array
+-- -- but not any of its child collections.
+--
+-- @param kind The collection kind to which the tree of collections
+-- should be restricted.
+--
+-- @return The array of children of |self| in this contracted tree.
+--
+function Collection:childrenOfKind(kind)
+ local function rec (c, a)
+ for _,d in ipairs(c.child_collections) do
+ if d.kind == kind then
+ a[#a + 1] = d
+ else
+ rec (d, a)
+ end
+ end
+ return a
+ end
+ return rec(self, {})
+end
+
+
+---
+-- The descendants of a collection are its children, plus their
+-- children, plus their children, and so on.
+--
+-- @return An array of all descendants of |self|. It will be in
+-- preorder.
+
+function Collection:descendants()
+ local function rec (c, a)
+ for _,d in ipairs(c.child_collections) do
+ a[#a + 1] = d
+ rec (d, a)
+ end
+ return a
+ end
+ return rec(self, {})
+end
+
+
+
+---
+-- The descendants of a collection of the given |kind|.
+--
+-- @param kind A collection kind.
+--
+-- @return An array of all descendants of |self| of the given |kind|.
+
+function Collection:descendantsOfKind(kind)
+ local function rec (c, a)
+ for _,d in ipairs(c.child_collections) do
+ if d.kind == kind then
+ a[#a + 1] = d
+ end
+ rec (d, a)
+ end
+ return a
+ end
+ return rec(self, {})
+end
+
+
+
+-- Done
+
+return Collection
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Coordinate.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Coordinate.lua
new file mode 100644
index 0000000000..3a4448ab08
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Coordinate.lua
@@ -0,0 +1,306 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- A Coordinate models a position on the drawing canvas.
+--
+-- It has an |x| field and a |y| field, which are numbers that will be
+-- interpreted as \TeX\ points (1/72.27th of an inch). The $x$-axis goes
+-- right and the $y$-axis goes up.
+--
+-- @field x
+-- @field y
+--
+-- There is also a static field called |origin| that is always equal to the origin.
+
+local Coordinate = {}
+Coordinate.__index = Coordinate
+
+
+-- Namespace
+
+require("pgf.gd.model").Coordinate = Coordinate
+
+
+
+
+--- Creates a new coordinate.
+--
+-- @param x The $x$ value
+-- @param y The $y$ value
+--
+-- @return A coordinate
+--
+function Coordinate.new(x,y)
+ return setmetatable( {x=x, y=y}, Coordinate)
+end
+
+
+Coordinate.origin = Coordinate.new(0,0)
+
+
+--- Creates a new coordinate that is a copy of an existing one.
+--
+-- @return A new coordinate at the same location as |self|
+--
+function Coordinate:clone()
+ return setmetatable( { x = self.x, y = self.y }, Coordinate)
+end
+
+
+
+--- Apply a transformation matrix to a coordinate,
+-- see |pgf.gd.lib.Transform| for details.
+--
+-- @param t A transformation.
+
+function Coordinate:apply(t)
+ local x = self.x
+ local y = self.y
+ self.x = t[1]*x + t[2]*y + t[5]
+ self.y = t[3]*x + t[4]*y + t[6]
+end
+
+
+--- Shift a coordinate
+--
+-- @param a An $x$ offset
+-- @param b A $y$ offset
+
+function Coordinate:shift(a,b)
+ self.x = self.x + a
+ self.y = self.y + b
+end
+
+
+---
+-- ``Unshift'' a coordinate (which is the same as shifting by the
+-- inversed coordinate; only faster).
+--
+-- @param a An $x$ offset
+-- @param b A $y$ offset
+
+function Coordinate:unshift(a,b)
+ self.x = self.x - a
+ self.y = self.y - b
+end
+
+
+---
+-- Like |shift|, only for coordinate parameters.
+--
+-- @param c Another coordinate. The $x$- and $y$-values of |self| are
+-- increased by the $x$- and $y$-values of this coordinate.
+
+function Coordinate:shiftByCoordinate(c)
+ self.x = self.x + c.x
+ self.y = self.y + c.y
+end
+
+
+---
+-- Like |unshift|, only for coordinate parameters.
+--
+-- @param c Another coordinate.
+
+function Coordinate:unshiftByCoordinate(c)
+ self.x = self.x - c.x
+ self.y = self.y - c.y
+end
+
+
+---
+-- Moves the coordinate a fraction of |f| along a straight line to |c|.
+--
+-- @param c Another coordinate
+-- @param f A fraction
+
+function Coordinate:moveTowards(c,f)
+ self.x = self.x + f*(c.x-self.x)
+ self.y = self.y + f*(c.y-self.y)
+end
+
+
+
+--- Scale a coordinate by a factor
+--
+-- @param s A factor.
+
+function Coordinate:scale(s)
+ self.x = s*self.x
+ self.y = s*self.y
+end
+
+
+
+
+---
+-- Add two coordinates, yielding a new coordinate. Note that it will
+-- be a lot faster to call shift, whenever this is possible.
+--
+-- @param a A coordinate
+-- @param b A coordinate
+
+function Coordinate.__add(a,b)
+ return setmetatable({ x = a.x + b.x, y = a.y + b.y }, Coordinate)
+end
+
+
+---
+-- Subtract two coordinates, yielding a new coordinate. Note that it will
+-- be a lot faster to call unshift, whenever this is possible.
+--
+-- @param a A coordinate
+-- @param b A coordinate
+
+function Coordinate.__sub(a,b)
+ return setmetatable({ x = a.x - b.x, y = a.y - b.y }, Coordinate)
+end
+
+
+---
+-- The unary minus (mirror the coordinate against the origin).
+--
+-- @param a A coordinate
+
+function Coordinate.__unm(a)
+ return setmetatable({ x = - a.x, y = - a.y }, Coordinate)
+end
+
+
+---
+-- The multiplication operator. Its effect depends on the parameters:
+-- If both are coordinates, their dot-product is returned. If exactly
+-- one of them is a coordinate and the other is a number, the scalar
+-- multiple of this coordinate is returned.
+--
+-- @param a A coordinate or a scalar
+-- @param b A coordinate or a scalar
+-- @return The dot product or scalar product.
+
+function Coordinate.__mul(a,b)
+ if getmetatable(a) == Coordinate then
+ if getmetatable(b) == Coordinate then
+ return a.x * b.x + a.y * b.y
+ else
+ return setmetatable({ x = a.x * b, y = a.y *b }, Coordinate)
+ end
+ else
+ return setmetatable({ x = a * b.x, y = a * b.y }, Coordinate)
+ end
+end
+
+---
+-- The division operator. Returns the scalar division of a coordinate
+-- by a scalar.
+--
+-- @param a A coordinate
+-- @param b A scalar (not equal to zero).
+-- @return The scalar product or a * (1/b).
+
+function Coordinate.__div(a,b)
+ return setmetatable({ x = a.x / b, y = a.y / b }, Coordinate)
+end
+
+
+---
+-- The norm function. Returns the norm of a coordinate.
+--
+-- @param a A coordinate
+-- @return The norm of the coordinate
+
+function Coordinate:norm()
+ return math.sqrt(self.x * self.x + self.y * self.y)
+end
+
+
+---
+-- Normalize a vector: Ensure that it has length 1. If the vector used
+-- to be the 0-vector, it gets replaced by (1,0).
+--
+
+function Coordinate:normalize()
+ local x, y = self.x, self.y
+ if x == 0 and y == 0 then
+ self.x = 1
+ else
+ local norm = math.sqrt(x*x+y*y)
+ self.x = x / norm
+ self.y = y / norm
+ end
+end
+
+
+---
+-- Normalized version of a vector: Like |normalize|, only the result is
+-- returned in a new vector.
+--
+-- @return Normalized version of |self|
+
+function Coordinate:normalized()
+ local x, y = self.x, self.y
+ if x == 0 and y == 0 then
+ return setmetatable({ x = 1, y = 0 }, Coordinate)
+ else
+ local norm = math.sqrt(x*x+y*y)
+ return setmetatable({ x = x/norm, y = y/norm }, Coordinate)
+ end
+end
+
+
+
+---
+-- Compute a bounding box around an array of coordinates
+--
+-- @param array An array of coordinates
+--
+-- @return |min_x| The minimum $x$ value of the bounding box of the array
+-- @return |min_y| The minimum $y$ value
+-- @return |max_x|
+-- @return |max_y|
+-- @return |center_x| The center of the bounding box
+-- @return |center_y|
+
+function Coordinate.boundingBox(array)
+ if #array > 0 then
+ local min_x, min_y = math.huge, math.huge
+ local max_x, max_y = -math.huge, -math.huge
+
+ for i=1,#array do
+ local c = array[i]
+ local x = c.x
+ local y = c.y
+ if x < min_x then min_x = x end
+ if y < min_y then min_y = y end
+ if x > max_x then max_x = x end
+ if y > max_y then max_y = y end
+ end
+
+ return min_x, min_y, max_x, max_y, (min_x+max_x) / 2, (min_y+max_y) / 2
+ end
+end
+
+
+
+
+-- Returns a string representation of an arc. This is mainly for debugging
+--
+-- @return The Arc as string.
+--
+function Coordinate:__tostring()
+ return "(" .. self.x .. "pt," .. self.y .. "pt)"
+end
+
+
+-- Done
+
+return Coordinate \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Digraph.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Digraph.lua
new file mode 100644
index 0000000000..30b600e308
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Digraph.lua
@@ -0,0 +1,849 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+---
+-- Each |Digraph| instance models a \emph{directed, simple}
+-- graph. ``Directed'' means that all edges ``point'' from a head node
+-- to a tail node. ``Simple'' means that between any nodes there can be
+-- (at most) one edge. Since these properties are a bit at odds with
+-- the normal behavior of ``nodes'' and ``edges'' in \tikzname,
+-- different names are used for them inside the |model| namespace:
+-- The class modeling ``edges'' is actually called |Arc| to stress
+-- that an arc has a specific ``start'' (the tail) and a specific
+-- ``end'' (the head). The class modeling ``nodes'' is actually called
+-- |Vertex|, just to stress that this is not a direct model of a
+-- \tikzname\ |node|, but can represent a arbitrary vertex of a graph,
+-- independently of whether it is an actual |node| in \tikzname.
+--
+-- \medskip
+-- \noindent\emph{Time Bounds.}
+-- Since digraphs are constantly created and modified inside the graph
+-- drawing engine, some care was taken to ensure that all operations
+-- work as quickly as possible. In particular:
+-- %
+-- \begin{itemize}
+-- \item Adding an array of $k$ vertices using the |add| method needs
+-- time $O(k)$.
+-- \item Adding an arc between two vertices needs time $O(1)$.
+-- \item Accessing both the |vertices| and the |arcs| fields takes time
+-- $O(1)$, provided only the above operations are used.
+-- \end{itemize}
+-- %
+-- Deleting vertices and arcs takes more time:
+-- %
+-- \begin{itemize}
+-- \item Deleting the vertices given in an array of $k$ vertices from a
+-- graph with $n$ vertices takes time $O(\max\{n,c\})$ where $c$ is the
+-- number of arcs between the to-be-deleted nodes and the remaining
+-- nodes. Note that this time bound in independent of~$k$. In
+-- particular, it will be much faster to delete many vertices by once
+-- calling the |remove| function instead of calling it repeatedly.
+-- \item Deleting an arc takes time $O(t_o+h_i)$ where $t_o$ is the
+-- number of outgoing arcs at the arc's tail and $h_i$ is the number
+-- of incoming arcs at the arc's head. After a call to |disconnect|,
+-- the next use of the |arcs| field will take time $O(|V| + |E|)$,
+-- while subsequent accesses take time $O(1)$ -- till the
+-- next use of |disconnect|. This means that once you start deleting
+-- arcs using |disconnect|, you should perform as many additional
+-- |disconnect|s as possible before accessing |arcs| one more.
+-- \end{itemize}
+--
+-- \medskip
+-- \noindent\emph{Stability.} The |vertices| field and the array
+-- returned by |Digraph:incoming| and |Digraph:outgoing| are
+-- \emph{stable} in the following sense: The ordering of the elements
+-- when you use |ipairs| on the will be the ordering in which the
+-- vertices or arcs were added to the graph. Even when you remove a
+-- vertex or an arc, the ordering of the remaining elements stays the
+-- same.
+--
+-- @field vertices This array contains the vertices that are part of
+-- the digraph. Internally, this array
+-- is an object of type |LookupTable|, but you can mostly treat it as
+-- if it were an array. In particular, you can iterate over its
+-- elements using |ipairs|, but you may not modify the array; use the
+-- |add| and |remove| methods, instead.
+--
+-- \begin{codeexample}[code only, tikz syntax=false]
+-- local g = Digraph.new {}
+--
+-- g:add { v1, v2 } -- Add vertices v1 and v2
+-- g:remove { v2 } -- Get rid of v2.
+--
+-- assert (g:contains(v1))
+-- assert (not g:contains(v2))
+-- \end{codeexample}
+--
+-- It is important to note that although each digraph stores a
+-- |vertices| array, the elements in this array are not exclusive to
+-- the digraph: A vertex can be an element of any number of
+-- digraphs. Whether or not a vertex is an element of digraph is not
+-- stored in the vertex, only in the |vertices| array of the
+-- digraph. To test whether a digraph contains a specific node, use the
+-- |contains| method, which takes time $O(1)$ to perform the test (this
+-- is because, as mentioned earlier, the |vertices| array is actually a
+-- |LookupTable| and for each vertex |v| the field |vertices[v]| will
+-- be true if, and only if, |v| is an element of the |vertices| array).
+--
+-- Do not use |pairs(g.vertices)| because this may cause your graph
+-- drawing algorithm to produce different outputs on different runs.
+--
+-- A slightly annoying effect of vertices being able to belong to
+-- several graphs at the same time is that the set of arcs incident to
+-- a vertex is not a property of the vertex, but rather of the
+-- graph. In other words, to get a list of all arcs whose tail is a
+-- given vertex |v|, you cannot say something like |v.outgoings| or
+-- perhaps |v:getOutgoings()|. Rather, you have to say |g:outgoing(v)|
+-- to get this list:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--for _,a in ipairs(g:outgoing(v)) do -- g is a Digraph object.
+-- pgf.debug ("There is an arc leaving " .. tostring(v) ..
+-- " heading to " .. tostring(a.head))
+--end
+--\end{codeexample}
+-- %
+-- Naturally, there is also a method |g:incoming()|.
+--
+-- To iterate over all arcs of a graph you can say:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--for _,v in ipairs(g.vertices) do
+-- for _,a in ipairs(g:outgoing(v)) do
+-- ...
+-- end
+--end
+--\end{codeexample}
+--
+-- However, it will often be more convenient and, in case the there
+-- are far less arcs than vertices, also faster to write
+--
+--\begin{codeexample}[code only, tikz syntax=false]
+--for _,a in ipairs(g.arcs) do
+-- ...
+--end
+--\end{codeexample}
+--
+-- @field arcs For any two vertices |t| and |h| of a graph, there may
+-- or may not be
+-- an arc from |t| to |h|. If this is the case, there is an |Arc|
+-- object that represents this arc. Note that, since |Digraph|s are
+-- always simple graphs, there can be at most one such object for every
+-- pair of vertices. However, you can store any information you like for
+-- an |Arc| through a |Storage|, see the |Storage| class for
+-- details. Each |Arc| for an edge of the syntactic digraph stores
+-- an array called |syntactic_edges| of all the multiple edges that
+-- are present in the user's input.
+--
+-- Unlike vertices, the arc objects of a graph are always local to a
+-- graph; an |Arc| object can never be part of two digraphs at the same
+-- time. For this reason, while for vertices it makes sense to create
+-- |Vertex| objects independently of any |Digraph| objects, it is not
+-- possible to instantiate an |Arc| directly: only the |Digraph| method
+-- |connect| is allowed to create new |Arc| objects and it will return
+-- any existing arcs instead of creating new ones, if there is already
+-- an arc present between two nodes.
+--
+-- The |arcs| field of a digraph contains a |LookupTable| of all arc
+-- objects present in the |Digraph|. Although you can access this field
+-- normally and use it in |ipairs| to iterate over all arcs of a graph,
+-- note that this array is actually ``reconstructed lazily'' whenever
+-- an arc is deleted from the graph. What happens is the following: As
+-- long as you just add arcs to a graph, the |arcs| array gets updated
+-- normally. However, when you remove an arc from a graph, the arc does
+-- not get removed from the |arcs| array (which would be an expensive
+-- operation). Instead, the |arcs| array is invalidated (internally set
+-- to |nil|), allowing us to perform a |disconnect| in time
+-- $O(1)$. The |arcs| array is then ignored until the next time it is
+-- accessed, for instance when a user says |ipairs(g.arcs)|. At this
+-- point, the |arcs| array is reconstructed by adding all arcs of all
+-- nodes to it.
+--
+-- The bottom line of the behavior of the |arcs| field is that (a) the
+-- ordering of the elements may change abruptly whenever you remove an
+-- arc from a graph and (b) performing $k$ |disconnect| operations in
+-- sequence takes time $O(k)$, provided you do not access the |arcs|
+-- field between calls.
+--
+-- @field syntactic_digraph is a reference to the syntactic digraph
+-- from which this graph stems ultimately. This may be a cyclic
+-- reference to the graph itself.
+-- @field options If present, it will be a table storing
+-- the options set for the syntactic digraph.
+--
+local Digraph = {}
+
+local function recalc_arcs (digraph)
+ local arcs = {}
+ local vertices = digraph.vertices
+ for i=1,#vertices do
+ local out = vertices[i].outgoings[digraph]
+ for j=1,#out do
+ arcs[#arcs + 1] = out[j]
+ end
+ end
+ digraph.arcs = arcs
+ return arcs
+end
+
+Digraph.__index =
+ function (t, k)
+ if k == "arcs" then
+ return recalc_arcs(t)
+ else
+ return rawget(Digraph,k)
+ end
+ end
+
+
+
+-- Namespace
+require("pgf.gd.model").Digraph = Digraph
+
+-- Imports
+local Arc = require "pgf.gd.model.Arc"
+local LookupTable = require "pgf.gd.lib.LookupTable"
+local Vertex = require "pgf.gd.model.Vertex"
+
+
+
+
+
+---
+-- Graphs are created using the |new| method, which takes a table of
+-- |initial| values as input (like most |new| methods in the graph
+-- drawing system). It is permissible that this table of initial values
+-- has a |vertices| field, in which case this array will be copied. In
+-- contrast, an |arcs| field in the table will be ignored -- newly
+-- created graphs always have an empty arcs set. This means that
+-- writing |Digraph.new(g)| where |g| is a graph creates a new graph
+-- whose vertex set is the same as |g|'s, but where there are no edges:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local g = Digraph.new {}
+--g:add { v1, v2, v3 }
+--g:connect (v1, v2)
+--
+--local h = Digraph.new (g)
+--assert (h:contains(v1))
+--assert (not h:arc(v1, v2))
+--\end{codeexample}
+--
+-- To completely copy a graph, including all arcs, you have to write:
+--\begin{codeexample}[code only, tikz syntax=false]
+--local h = Digraph.new (g)
+--for _,a in ipairs(g.arcs) do h:connect(a.tail, a.head) end
+--\end{codeexample}
+--
+-- This operation takes time $O(1)$.
+--
+-- @param initial A table of initial values. It is permissible that
+-- this array contains a |vertices| field. In this
+-- case, this field must be an array and its entries
+-- must be nodes, which will be inserted. If initial
+-- has an |arcs| field, this field will be ignored.
+-- The table must contain a field |syntactic_digraph|,
+-- which should normally be the syntactic digraph of
+-- the graph, but may also be the string |"self"|, in
+-- which case it will be set to the newly created
+-- (syntactic) digraph.
+-- @return A newly-allocated digraph.
+--
+function Digraph.new(initial)
+ local digraph = {}
+ setmetatable(digraph, Digraph)
+
+ if initial then
+ for k,v in pairs(initial or {}) do
+ digraph [k] = v
+ end
+ end
+
+ local vertices = digraph.vertices
+ digraph.vertices = {}
+ digraph.arcs = {}
+
+ if vertices then
+ digraph:add(vertices)
+ end
+ return digraph
+end
+
+
+--- Add vertices to a digraph.
+--
+-- This operation takes time $O(|\verb!array!|)$.
+--
+-- @param array An array of to-be-added vertices.
+--
+function Digraph:add(array)
+ local vertices = self.vertices
+ for i=1,#array do
+ local v = array[i]
+ if not vertices[v] then
+ vertices[v] = true
+ vertices[#vertices + 1] = v
+ v.incomings[self] = {}
+ v.outgoings[self] = {}
+ end
+ end
+end
+
+
+--- Remove vertices from a digraph.
+--
+-- This operation removes an array of vertices from a graph. The
+-- operation takes time linear in the number of vertices, regardless of
+-- how many vertices are to be removed. Thus, it will be (much) faster
+-- to delete many vertices by first compiling them in an array and to
+-- then delete them using one call to this method.
+--
+-- This operation takes time $O(\max\{|\verb!array!|, |\verb!self.vertices!|\})$.
+--
+-- @param array The to-be-removed vertices.
+--
+function Digraph:remove(array)
+ local vertices = self.vertices
+
+ -- Mark all to-be-deleted nodes
+ for i=1,#array do
+ local v = array[i]
+ assert(vertices[v], "to-be-deleted node is not in graph")
+ vertices[v] = false
+ end
+
+ -- Disconnect them
+ for i=1,#array do
+ self:disconnect(array[i])
+ end
+
+ LookupTable.remove(self.vertices, array)
+end
+
+
+
+--- Test, whether a graph contains a given vertex.
+--
+-- This operation takes time $O(1)$.
+--
+-- @param v The vertex to be tested.
+--
+function Digraph:contains(v)
+ return v and self.vertices[v] == true
+end
+
+
+
+
+---
+-- Returns the arc between two nodes, provided it exists. Otherwise,
+-- |nil| is returned.
+--
+-- This operation takes time $O(1)$.
+--
+-- @param tail The tail vertex
+-- @param head The head vertex
+--
+-- @return The arc object connecting them
+--
+function Digraph:arc(tail, head)
+ local out = tail.outgoings[self]
+ if out then
+ return out[head]
+ end
+end
+
+
+
+---
+-- Returns an array containing the outgoing arcs of a vertex. You may
+-- only iterate over his array using ipairs, not using pairs.
+--
+-- This operation takes time $O(1)$.
+--
+-- @param v The vertex
+--
+-- @return An array of all outgoing arcs of this vertex (all arcs
+-- whose tail is the vertex)
+--
+function Digraph:outgoing(v)
+ return assert(v.outgoings[self], "vertex not in graph")
+end
+
+
+
+---
+-- Sorts the array of outgoing arcs of a vertex. This allows you to
+-- later iterate over the outgoing arcs in a specific order.
+--
+-- This operation takes time $O(|\verb!outgoing!| \log |\verb!outgoings!|)$.
+--
+-- @param v The vertex
+-- @param f A comparison function that is passed to |table.sort|
+--
+function Digraph:sortOutgoing(v, f)
+ table.sort(assert(v.outgoings[self], "vertex not in graph"), f)
+end
+
+
+---
+-- Reorders the array of outgoing arcs of a vertex. The parameter array
+-- \emph{must} contain the same set of vertices as the outgoing array,
+-- but possibly in a different order.
+--
+-- This operation takes time $O(|\verb!outgoing!|)$, where |outgoing|
+-- is the array of |v|'s outgoing arcs in |self|.
+--
+-- @param v The vertex
+-- @param vertices An array containing the outgoing vertices in some order.
+--
+function Digraph:orderOutgoing(v, vertices)
+ local outgoing = assert (v.outgoings[self], "vertex not in graph")
+ assert (#outgoing == #vertices)
+
+ -- Create back hash
+ local lookup = {}
+ for i=1,#vertices do
+ lookup[vertices[i]] = i
+ end
+
+ -- Compute ordering of the arcs
+ local reordered = {}
+ for _,arc in ipairs(outgoing) do
+ reordered [lookup[arc.head]] = arc
+ end
+
+ -- Copy back
+ for i=1,#outgoing do
+ outgoing[i] = assert(reordered[i], "illegal vertex order")
+ end
+end
+
+
+
+--- See |outgoing|.
+--
+function Digraph:incoming(v)
+ return assert(v.incomings[self], "vertex not in graph")
+end
+
+
+---
+-- See |sortOutgoing|.
+--
+function Digraph:sortIncoming(v, f)
+ table.sort(assert(v.incomings[self], "vertex not in graph"), f)
+end
+
+
+---
+-- See |orderOutgoing|.
+--
+function Digraph:orderIncoming(v, vertices)
+ local incoming = assert (v.incomings[self], "vertex not in graph")
+ assert (#incoming == #vertices)
+
+ -- Create back hash
+ local lookup = {}
+ for i=1,#vertices do
+ lookup[vertices[i]] = i
+ end
+
+ -- Compute ordering of the arcs
+ local reordered = {}
+ for _,arc in ipairs(incoming) do
+ reordered [lookup[arc.head]] = arc
+ end
+
+ -- Copy back
+ for i=1,#incoming do
+ incoming[i] = assert(reordered[i], "illegal vertex order")
+ end
+end
+
+
+
+
+
+---
+-- Connects two nodes by an arc and returns the newly created arc
+-- object. If they are already connected, the existing arc is returned.
+--
+-- This operation takes time $O(1)$.
+--
+-- @param s The tail vertex
+-- @param t The head vertex (may be identical to |tail| in case of a
+-- loop)
+--
+-- @return The arc object connecting them (either newly created or
+-- already existing)
+--
+function Digraph:connect(s, t)
+ assert (s and t and self.vertices[s] and self.vertices[t], "trying connect nodes not in graph")
+
+ local s_outgoings = s.outgoings[self]
+ local arc = s_outgoings[t]
+
+ if not arc then
+ -- Ok, create and insert new arc object
+ arc = {
+ tail = s,
+ head = t,
+ option_cache = {},
+ syntactic_digraph = self.syntactic_digraph,
+ syntactic_edges = {}
+ }
+ setmetatable(arc, Arc)
+
+ -- Insert into outgoings:
+ s_outgoings [#s_outgoings + 1] = arc
+ s_outgoings [t] = arc
+
+ local t_incomings = t.incomings[self]
+ -- Insert into incomings:
+ t_incomings [#t_incomings + 1] = arc
+ t_incomings [s] = arc
+
+ -- Insert into arcs field, if it exists:
+ local arcs = rawget(self, "arcs")
+ if arcs then
+ arcs[#arcs + 1] = arc
+ end
+ end
+
+ return arc
+end
+
+
+
+
+---
+-- Disconnect either a single vertex |v| from all its neighbors (remove all
+-- incoming and outgoing arcs of this vertex) or, in case two nodes
+-- are given as parameter, remove the arc between them, if it exists.
+--
+-- This operation takes time $O(|I_v| + |I_t|)$, where $I_x$ is the set
+-- of vertices incident to $x$, to remove the single arc between $v$ and
+-- $v$. For a single vertex $v$, it takes time $O(\sum_{y: \text{there is some
+-- arc between $v$ and $y$ or $y$ and $v$}} |I_y|)$.
+--
+-- @param v The single vertex or the tail vertex
+-- @param t The head vertex
+--
+function Digraph:disconnect(v, t)
+ if t then
+ -- Case 2: Remove a single arc.
+ local s_outgoings = assert(v.outgoings[self], "tail node not in graph")
+ local t_incomings = assert(t.incomings[self], "head node not in graph")
+
+ if s_outgoings[t] then
+ -- Remove:
+ s_outgoings[t] = nil
+ for i=1,#s_outgoings do
+ if s_outgoings[i].head == t then
+ table.remove (s_outgoings, i)
+ break
+ end
+ end
+ t_incomings[v] = nil
+ for i=1,#t_incomings do
+ if t_incomings[i].tail == v then
+ table.remove (t_incomings, i)
+ break
+ end
+ end
+ self.arcs = nil -- invalidate arcs field
+ end
+ else
+ -- Case 1: Remove all arcs incident to v:
+
+ -- Step 1: Delete all incomings arcs:
+ local incomings = assert(v.incomings[self], "node not in graph")
+ local vertices = self.vertices
+
+ for i=1,#incomings do
+ local s = incomings[i].tail
+ if s ~= v and vertices[s] then -- skip self-loop and to-be-deleted nodes
+ -- Remove this arc from s:
+ local s_outgoings = s.outgoings[self]
+ s_outgoings[v] = nil
+ for i=1,#s_outgoings do
+ if s_outgoings[i].head == v then
+ table.remove (s_outgoings, i)
+ break
+ end
+ end
+ end
+ end
+
+ -- Step 2: Delete all outgoings arcs:
+ local outgoings = v.outgoings[self]
+ for i=1,#outgoings do
+ local t = outgoings[i].head
+ if t ~= v and vertices[t] then
+ local t_incomings = t.incomings[self]
+ t_incomings[v] = nil
+ for i=1,#t_incomings do
+ if t_incomings[i].tail == v then
+ table.remove (t_incomings, i)
+ break
+ end
+ end
+ end
+ end
+
+ if #incomings > 0 or #outgoings > 0 then
+ self.arcs = nil -- invalidate arcs field
+ end
+
+ -- Step 3: Reset incomings and outgoings fields
+ v.incomings[self] = {}
+ v.outgoings[self] = {}
+ end
+end
+
+
+
+
+---
+-- An arc is changed so that instead of connecting |self.tail|
+-- and |self.head|, it now connects a new |head| and |tail|. The
+-- difference to first disconnecting and then reconnecting is that all
+-- fields of the arc (other than |head| and |tail|, of course), will
+-- be ``moved along''. Reconnecting an arc in the same way as before has no
+-- effect.
+--
+-- If there is already an arc at the new position, fields of the
+-- to-be-reconnected arc overwrite fields of the original arc. This is
+-- especially dangerous with a syntactic digraph, so do not reconnect
+-- arcs of the syntactic digraph (which you should not do anyway).
+--
+-- The |arc| object may no longer be valid after a reconnect, but the
+-- operation returns the new arc object.
+--
+-- This operation needs the time of a disconnect (if necessary).
+--
+-- @param arc The original arc object
+-- @param tail The new tail vertex
+-- @param head The new head vertex
+--
+-- @return The new arc object connecting them (either newly created or
+-- already existing)
+--
+function Digraph:reconnect(arc, tail, head)
+ assert (arc and tail and head, "connect with nil parameters")
+
+ if arc.head == head and arc.tail == tail then
+ -- Nothing to be done
+ return arc
+ else
+ local new_arc = self:connect(tail, head)
+
+ for k,v in pairs(arc) do
+ if k ~= "head" and k ~= "tail" then
+ new_arc[k] = v
+ end
+ end
+
+ -- Remove old arc:
+ self:disconnect(arc.tail, arc.head)
+
+ return new_arc
+ end
+end
+
+
+
+---
+-- Collapse a set of vertices into a single vertex
+--
+-- Often, algorithms will wish to treat a whole set of vertices ``as a
+-- single vertex''. The idea is that a new vertex is then inserted
+-- into the graph, and this vertex is connected to all vertices to
+-- which any of the original vertices used to be connected.
+--
+-- The |collapse| method takes an array of to-be-collapsed vertices as
+-- well as a vertex. First, it will store references to the
+-- to-be-collapsed vertices inside the vertex. Second, we iterate over
+-- all arcs of the to-be-collapsed vertices. If this arc connects a
+-- to-be-collapsed vertex with a not-to-be-collapsed vertex, the
+-- not-to-be-collapsed vertex is connected to the collapse
+-- vertex. Additionally, the arc is stored at the vertex.
+--
+-- Note that the collapse vertex will be added to the graph if it is
+-- not already an element. The collapsed vertices will not be removed
+-- from the graph, so you must remove them yourself, if necessary.
+--
+-- A collapse vertex will store the collapsed vertices so that you can
+-- call |expand| later on to ``restore'' the vertices and arcs that
+-- were saved during a collapse. This storage is \emph{not} local to
+-- the graph in which the collapse occurred.
+--
+-- @param collapse_vertices An array of to-be-collapsed vertices
+-- @param collapse_vertex The vertex that represents the collapse. If
+-- missing, a vertex will be created automatically and added to the graph.
+-- @param vertex_fun This function is called for each to-be-collapsed
+-- vertex. The parameters are the collapse vertex and the
+-- to-be-collapsed vertex. May be |nil|.
+-- @param arc_fun This function is called whenever a new arc is added
+-- between |rep| and some other vertex. The arguments are the new arc
+-- and the original arc. May be |nil|.
+--
+-- @return The new vertex that represents the collapsed vertices.
+
+function Digraph:collapse(collapse_vertices, collapse_vertex, vertex_fun, arc_fun)
+
+
+ -- Create and add node, if necessary.
+ if not collapse_vertex then
+ collapse_vertex = Vertex.new {}
+ end
+ self:add {collapse_vertex}
+
+ -- Copy the collapse_vertices and create lookup
+ local cvs = {}
+ for i=1,#collapse_vertices do
+ local v = collapse_vertices[i]
+ cvs[i] = v
+ cvs[v] = true
+ end
+ assert (cvs[collapse_vertex] ~= true, "collapse_vertex is in collapse_vertices")
+
+ -- Connected collapse_vertex appropriately
+ local collapsed_arcs = {}
+
+ if not arc_fun then
+ arc_fun = function () end
+ end
+
+ for _,v in ipairs(cvs) do
+ if vertex_fun then
+ vertex_fun (collapse_vertex, v)
+ end
+ for _,a in ipairs(v.outgoings[self]) do
+ if cvs[a.head] ~= true then
+ arc_fun (self:connect(collapse_vertex, a.head), a)
+ collapsed_arcs[#collapsed_arcs + 1] = a
+ end
+ end
+ for _,a in ipairs(v.incomings[self]) do
+ if cvs[a.tail] ~= true then
+ arc_fun (self:connect(a.tail, collapse_vertex), a)
+ end
+ collapsed_arcs[#collapsed_arcs + 1] = a
+ end
+ end
+
+ -- Remember the old vertices.
+ collapse_vertex.collapsed_vertices = cvs
+ collapse_vertex.collapsed_arcs = collapsed_arcs
+
+ return collapse_vertex
+end
+
+
+
+---
+-- Expand a previously collapsed vertex.
+--
+-- If you have collapsed a set of vertices in a graph using
+-- |collapse|, you can expand this set once more using this method. It
+-- will add all vertices that were previously removed from the graph
+-- and will also reinstall the deleted arcs. The collapse vertex is
+-- not removed.
+--
+-- @param vertex A to-be-expanded vertex that was previously returned
+-- by |collapse|.
+-- @param vertex_fun A function that is called once for each
+-- reinserted vertex. The parameters are the collapse vertex and the
+-- reinstalled vertex. May be |nil|.
+-- @param arc_fun A function that is called once for each
+-- reinserted arc. The parameter is the arc and the |vertex|. May be |nil|.
+--
+function Digraph:expand(vertex, vertex_fun, arc_fun)
+ local cvs = assert(vertex.collapsed_vertices, "no expand information stored")
+
+ -- Add all vertices:
+ self:add(cvs)
+ if vertex_fun then
+ for _,v in ipairs(cvs) do
+ vertex_fun(vertex, v)
+ end
+ end
+
+ -- Add all arcs:
+ for _,arc in ipairs(vertex.collapsed_arcs) do
+ local new_arc = self:connect(arc.tail, arc.head)
+
+ for k,v in pairs(arc) do
+ if k ~= "head" and k ~= "tail" then
+ new_arc[k] = v
+ end
+ end
+
+ if arc_fun then
+ arc_fun(new_arc, vertex)
+ end
+ end
+end
+
+
+
+
+
+---
+-- Invokes the |sync| method for all arcs of the graph.
+--
+-- @see Arc:sync()
+--
+function Digraph:sync()
+ for _,a in ipairs(self.arcs) do
+ a:sync()
+ end
+end
+
+
+
+---
+-- Computes a string representation of this graph including all nodes
+-- and edges. The syntax of this representation is such that it can be
+-- used directly in \tikzname's |graph| syntax.
+--
+-- @return |self| as string.
+--
+function Digraph:__tostring()
+ local vstrings = {}
+ local astrings = {}
+ for i,v in ipairs(self.vertices) do
+ vstrings[i] = " " .. tostring(v) .. "[x=" .. math.floor(v.pos.x) .. "pt,y=" .. math.floor(v.pos.y) .. "pt]"
+ local out_arcs = v.outgoings[self]
+ if #out_arcs > 0 then
+ local t = {}
+ for j,a in ipairs(out_arcs) do
+ t[j] = tostring(a.head)
+ end
+ astrings[#astrings + 1] = " " .. tostring(v) .. " -> { " .. table.concat(t,", ") .. " }"
+ end
+ end
+ return "graph [id=" .. tostring(self.vertices) .. "] {\n {\n" ..
+ table.concat(vstrings, ",\n") .. "\n }; \n" ..
+ table.concat(astrings, ";\n") .. "\n}";
+end
+
+
+
+
+-- Done
+
+return Digraph
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Edge.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Edge.lua
new file mode 100644
index 0000000000..45cbc60f9f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Edge.lua
@@ -0,0 +1,209 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- An |Edge| is a ``syntactic'' connection between two
+-- vertices that represents a connection present in the syntactic
+-- digraph. Unlike an |Arc|, |Edge| objects are not controlled by the
+-- |Digraph| class. Also unlike |Arc| objects, there can be several
+-- edges between the same vertices, namely whenever several such edges
+-- are present in the syntactic digraph.
+--
+-- In detail, the relationship between arcs and edges is as follows:
+-- If there is an |Edge| between two vertices $u$ and $v$ in the
+-- syntactic digraph, there will be an |Arc| from $u$ to $v$ and the
+-- array |syntactic_edges| of this |Arc| object will contain the
+-- |Edge| object. In particular, if there are several edges between
+-- the same vertices, all of these edges will be part of the array in
+-- a single |Arc| object.
+--
+-- Edges, like arcs, are always directed from a |tail| vertex to a
+-- |head| vertex; this is true even for undirected vertices. The
+-- |tail| vertex will always be the vertex that came first in the
+-- syntactic specification of the edge, the |head| vertex is the
+-- second one. Whether
+-- an edge is directed or not depends on the |direction| of the edge, which
+-- may be one of the following:
+-- %
+-- \begin{enumerate}
+-- \item |"->"|
+-- \item |"--"|
+-- \item |"<-"|
+-- \item |"<->"|
+-- \item |"-!-"|
+-- \end{enumerate}
+--
+--
+-- @field head The head vertex of this edge.
+--
+-- @field tail The tail vertex of this edge.
+--
+-- @field event The creation |Event| of this edge.
+--
+-- @field options A table of options that contains user-defined options.
+--
+-- @field direction One of the directions named above.
+--
+-- @field path A |Path| object that describes the path of the
+-- edge. The path's coordinates are interpreted \emph{absolutely}.
+--
+-- @field generated_options This is an options array that is generated
+-- by the algorithm. When the edge is rendered later on, this array
+-- will be passed back to the display layer. The syntax is the same as
+-- for the |declare_parameter_sequence| function, see
+-- |InterfaceToAlgorithms|.
+--
+-- @field animations An array of animations, see the |animations|
+-- field of the |Vertex| class for the syntax.
+
+local Edge = {}
+Edge.__index = Edge
+
+
+-- Namespace
+
+require("pgf.gd.model").Edge = Edge
+
+
+-- Imports
+
+local Path = require "pgf.gd.model.Path"
+
+
+---
+-- Create a new edge. The |initial| parameter allows you to setup
+-- some initial values.
+--
+-- @usage
+--\begin{codeexample}[code only, tikz syntax=false]
+--local v = Edge.new { tail = v1, head = v2 }
+--\end{codeexample}
+--
+-- @param initial Values to override defaults. --
+-- @return A new edge object.
+--
+function Edge.new(values)
+ local new = {}
+ for k,v in pairs(values) do
+ new[k] = v
+ end
+ new.generated_options = new.generated_options or {}
+ new.animations = new.animations or {}
+ if not new.path then
+ local p = Path.new ()
+ p:appendMoveto(Edge.tailAnchorForEdgePath(new))
+ p:appendLineto(Edge.headAnchorForEdgePath(new))
+ new.path = p
+ end
+
+ return setmetatable(new, Edge)
+end
+
+
+
+
+---
+-- This method returns a ``coordinate factory'' that can be used as
+-- the coordinate of a |moveto| at the beginning of a path starting at
+-- the |tail| of the arc. Suppose you want to create a path starting
+-- at the tail vertex, going to the coordinate $(10,10)$ and ending at
+-- the head vertex. The trouble is that when you create the path
+-- corresponding to this route, you typically do not know where the
+-- tail vertex is going to be. In this case, you use this
+-- method to get a function that will, later on, compute the correct
+-- position of the anchor as needed.
+--
+-- Note that you typically do not use this function, but use the
+-- corresponding function of the |Arc| class. Use this function only
+-- if there are multiple edges between two vertices that need to be
+-- routed differently.
+--
+-- Here is the code you would use to create the above-mentioned path:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--local a = g:connect(tail,head)
+--local e = a.syntactic_edges[1]
+--...
+--e.path = Path.new()
+--e.path:appendMoveto(e:tailAnchorForEdgePath())
+--e.path:appendLineto(10, 10)
+--e.path:appendLineto(e:headAnchorForEdgePath())
+--\end{codeexample}
+--
+-- As for the |Arc| class, you can also setup a polyline more easily:
+-- %
+--\begin{codeexample}[code only, tikz syntax=false]
+--e:setPolylinePath { Coordinate.new (10, 10) }
+--\end{codeexample}
+
+function Edge:tailAnchorForEdgePath()
+ return function ()
+ local a = self.options['tail anchor']
+ if a == "" then
+ a = "center"
+ end
+ return self.tail:anchor(a) + self.tail.pos
+ end
+end
+
+---
+-- See |Arc:tailAnchorForArcPath|.
+
+function Edge:headAnchorForEdgePath()
+ return function ()
+ local a = self.options['head anchor']
+ if a == "" then
+ a = "center"
+ end
+ return self.head:anchor(a) + self.head.pos
+ end
+end
+
+
+
+---
+-- Setup the |path| field of an edge in such a way that it corresponds
+-- to a sequence of straight line segments starting at the tail's
+-- anchor and ending at the head's anchor.
+--
+-- @param coordinates An array of |Coordinates| through which the line
+-- will go through.
+
+function Edge:setPolylinePath(coordinates)
+ local p = Path.new ()
+
+ p:appendMoveto(self:tailAnchorForEdgePath())
+
+ for _,c in ipairs(coordinates) do
+ p:appendLineto(c)
+ end
+
+ p:appendLineto(self:headAnchorForEdgePath())
+
+ self.path = p
+end
+
+
+
+--
+-- Returns a string representation of an edge. This is mainly for debugging.
+--
+-- @return The Edge as a string.
+--
+function Edge:__tostring()
+ return tostring(self.tail) .. self.direction .. tostring(self.head)
+end
+
+
+-- Done
+
+return Edge
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Hyperedge.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Hyperedge.lua
new file mode 100644
index 0000000000..cc265023fa
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Hyperedge.lua
@@ -0,0 +1,56 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Hyperedges}
+--
+-- @end
+
+
+-- Includes
+
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+
+---
+
+declare {
+ key = "hyper",
+ layer = -10,
+
+ summary = [["
+ A \emph{hyperedge} of a graph does not connect just two nodes, but
+ is any subset of the node set (although a normal edge is also a
+ hyperedge that happens to contain just two nodes). Internally, a
+ collection of kind |hyper| is created. Currently, there is
+ no default renderer for hyper edges.
+ "]],
+ documentation = [["
+\begin{codeexample}[code only]
+\graph {
+ % The nodes:
+ a, b, c, d;
+
+ % The edges:
+ {[hyper] a,b,c};
+ {[hyper] b,c,d};
+ {[hyper] a,c};
+ {[hyper] d}
+};
+\end{codeexample}
+ "]]
+}
+
+-- Done
+
+return Hyperedge \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path.lua
new file mode 100644
index 0000000000..cbd0f079bf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path.lua
@@ -0,0 +1,1278 @@
+-- Copyright 2014 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- A Path models a path in the plane.
+--
+-- Following the PostScript/\textsc{pdf}/\textsc{svg} convention, a
+-- path consists of a series of path segments, each of which can be
+-- closed or not. Each path segment, in turn, consists of a series of
+-- Bézier curves and straight line segments; see
+-- Section~\ref{section-paths} for an introduction to paths in
+-- general.
+--
+-- A |Path| object is a table whose array part stores
+-- |Coordinate| objects, |strings|, and |function|s that
+-- describe the path of the edge. The following strings are allowed in
+-- this array:
+-- %
+-- \begin{itemize}
+-- \item |"moveto"| The line's path should stop at the current
+-- position and then start anew at the next coordinate in the array.
+-- \item |"lineto"| The line should continue from the current position
+-- to the next coordinate in the array.
+-- \item |"curveto"| The line should continue form the current
+-- position with a Bézier curve that is specified by the next three
+-- |Coordinate| objects (in the usual manner).
+-- \item |"closepath"| The line's path should be ``closed'' in the sense
+-- that the current subpath that was started with the most recent
+-- moveto operation should now form a closed curve.
+-- \end{itemize}
+--
+-- Instead of a |Coordinate|, a |Path| may also contain a function. In
+-- this case, the function, when called, must return the |Coordinate|
+-- that is ``meant'' by the position. This allows algorithms to
+-- add coordinates to a path that are still not fixed at the moment
+-- they are added to the path.
+
+local Path = {}
+Path.__index = Path
+
+
+-- Namespace
+
+require("pgf.gd.model").Path = Path
+
+
+-- Imports
+
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Bezier = require "pgf.gd.lib.Bezier"
+
+local lib = require "pgf.gd.lib"
+
+
+-- Private function
+
+function Path.rigid (x)
+ if type(x) == "function" then
+ return x()
+ else
+ return x
+ end
+end
+
+local rigid = Path.rigid
+
+
+---
+-- Creates an empty path.
+--
+-- @param initial A table containing an array of strings and
+-- coordinates that constitute the path. Coordinates may be given as
+-- tables or as a pair of numbers. In this case, each pair of numbers
+-- is converted into one coordinate. If omitted, a new empty path
+-- is created.
+--
+-- @return A empty Path
+--
+function Path.new(initial)
+ if initial then
+ local new = {}
+ local i = 1
+ local count = 0
+ while i <= #initial do
+ local e = initial[i]
+ if type(e) == "string" then
+ assert (count == 0, "illformed path")
+ if e == "moveto" then
+ count = 1
+ elseif e == "lineto" then
+ count = 1
+ elseif e == "closepath" then
+ count = 0
+ elseif e == "curveto" then
+ count = 3
+ else
+ error ("unknown path command " .. e)
+ end
+ new[#new+1] = e
+ elseif type(e) == "number" then
+ if count == 0 then
+ new[#new+1] = "lineto"
+ else
+ count = count - 1
+ end
+ new[#new+1] = Coordinate.new(e,initial[i+1])
+ i = i + 1
+ elseif type(e) == "table" or type(e) == "function" then
+ if count == 0 then
+ new[#new+1] = "lineto"
+ else
+ count = count - 1
+ end
+ new[#new+1] = e
+ else
+ error ("invalid object on path")
+ end
+ i = i + 1
+ end
+ return setmetatable(new, Path)
+ else
+ return setmetatable({}, Path)
+ end
+end
+
+
+---
+-- Creates a copy of a path.
+--
+-- @return A copy of the path
+
+function Path:clone()
+ local new = {}
+ for _,x in ipairs(self) do
+ if type(x) == "table" then
+ new[#new+1] = x:clone()
+ else
+ new[#new+1] = x
+ end
+ end
+ return setmetatable(new, Path)
+end
+
+
+
+---
+-- Returns the path in reverse order.
+--
+-- @return A copy of the reversed path
+
+function Path:reversed()
+
+ -- First, build segments
+ local subpaths = {}
+ local subpath = {}
+
+ local function closepath ()
+ if subpath.start then
+ subpaths [#subpaths + 1] = subpath
+ subpath = {}
+ end
+ end
+
+ local prev
+ local start
+
+ local i = 1
+ while i <= #self do
+ local x = self[i]
+ if x == "lineto" then
+ subpath[#subpath+1] = {
+ action = 'lineto',
+ from = prev,
+ to = self[i+1]
+ }
+ prev = self[i+1]
+ i = i + 2
+ elseif x == "moveto" then
+ closepath()
+ prev = self[i+1]
+ start = prev
+ subpath.start = prev
+ i = i + 2
+ elseif x == "closepath" then
+ subpath [#subpath + 1] = {
+ action = "closepath",
+ from = prev,
+ to = start,
+ }
+ prev = nil
+ start = nil
+ closepath()
+ i = i + 1
+ elseif x == "curveto" then
+ local s1, s2, to = self[i+1], self[i+2], self[i+3]
+ subpath [#subpath + 1] = {
+ action = "curveto",
+ from = prev,
+ to = to,
+ support_1 = s1,
+ support_2 = s2,
+ }
+ prev = self[i+3]
+ i = i + 4
+ else
+ error ("illegal path command '" .. x .. "'")
+ end
+ end
+ closepath ()
+
+ local new = Path.new ()
+
+ for _,subpath in ipairs(subpaths) do
+ if #subpath == 0 then
+ -- A subpath that consists only of a moveto:
+ new:appendMoveto(subpath.start)
+ else
+ -- We start with a moveto to the end point:
+ new:appendMoveto(subpath[#subpath].to)
+
+ -- Now walk backwards:
+ for i=#subpath,1,-1 do
+ if subpath[i].action == "lineto" then
+ new:appendLineto(subpath[i].from)
+ elseif subpath[i].action == "closepath" then
+ new:appendLineto(subpath[i].from)
+ elseif subpath[i].action == "curveto" then
+ new:appendCurveto(subpath[i].support_2,
+ subpath[i].support_1,
+ subpath[i].from)
+ else
+ error("illegal path command")
+ end
+ end
+
+ -- Append a closepath, if necessary
+ if subpath[#subpath].action == "closepath" then
+ new:appendClosepath()
+ end
+ end
+ end
+
+ return new
+end
+
+
+---
+-- Transform all points on a path.
+--
+-- @param t A transformation, see |pgf.gd.lib.Transform|. It is
+-- applied to all |Coordinate| objects on the path.
+
+function Path:transform(t)
+ for _,c in ipairs(self) do
+ if type(c) == "table" then
+ c:apply(t)
+ end
+ end
+end
+
+
+---
+-- Shift all points on a path.
+--
+-- @param x An $x$-shift
+-- @param y A $y$-shift
+
+function Path:shift(x,y)
+ for _,c in ipairs(self) do
+ if type(c) == "table" then
+ c.x = c.x + x
+ c.y = c.y + y
+ end
+ end
+end
+
+
+---
+-- Shift by all points on a path.
+--
+-- @param x A coordinate
+
+function Path:shiftByCoordinate(x)
+ for _,c in ipairs(self) do
+ if type(c) == "table" then
+ c.x = c.x + x.x
+ c.y = c.y + x.y
+ end
+ end
+end
+
+
+---
+-- Makes the path empty.
+--
+
+function Path:clear()
+ for i=1,#self do
+ self[i] = nil
+ end
+end
+
+
+---
+-- Appends a |moveto| to the path.
+--
+-- @param x A |Coordinate| or |function| or, if the |y| parameter is
+-- not |nil|, a number that is the $x$-part of a coordinate.
+-- @param y The $y$-part of the coordinate.
+
+function Path:appendMoveto(x,y)
+ self[#self + 1] = "moveto"
+ self[#self + 1] = y and Coordinate.new(x,y) or x
+end
+
+
+---
+-- Appends a |lineto| to the path.
+--
+-- @param x A |Coordinate| or |function|, if the |y| parameter is not
+-- |nil|, a number that is the $x$-part of a coordinate.
+-- @param y The $y$-part of the coordinate.
+
+function Path:appendLineto(x,y)
+ self[#self + 1] = "lineto"
+ self[#self + 1] = y and Coordinate.new(x,y) or x
+end
+
+
+
+---
+-- Appends a |closepath| to the path.
+
+function Path:appendClosepath()
+ self[#self + 1] = "closepath"
+end
+
+
+---
+-- Appends a |curveto| to the path. There can be either three
+-- coordinates (or functions) as parameters (the two support points
+-- and the target) or six numbers, where two consecutive numbers form a
+-- |Coordinate|. Which case is meant is detected by the presence of a
+-- sixth non-nil parameter.
+
+function Path:appendCurveto(a,b,c,d,e,f)
+ self[#self + 1] = "curveto"
+ if f then
+ self[#self + 1] = Coordinate.new(a,b)
+ self[#self + 1] = Coordinate.new(c,d)
+ self[#self + 1] = Coordinate.new(e,f)
+ else
+ self[#self + 1] = a
+ self[#self + 1] = b
+ self[#self + 1] = c
+ end
+end
+
+
+
+
+
+
+---
+-- Makes a path ``rigid'', meaning that all coordinates that are only
+-- given as functions are replaced by the values these functions
+-- yield.
+
+function Path:makeRigid()
+ for i=1,#self do
+ self[i] = rigid(self[i])
+ end
+end
+
+
+---
+-- Returns an array of all coordinates that are present in a
+-- path. This means, essentially, that all strings are filtered out.
+--
+-- @return An array of all coordinate objects on the path.
+
+function Path:coordinates()
+ local cloud = {}
+ for i=1,#self do
+ local p = self[i]
+ if type(p) == "table" then
+ cloud[#cloud + 1] = p
+ elseif type(p) == "function" then
+ cloud[#cloud + 1] = p()
+ end
+ end
+ return cloud
+end
+
+
+---
+-- Returns a bounding box of the path. This will not necessarily be
+-- the minimal bounding box in case the path contains curves because,
+-- then, the support points of the curve are used for the computation
+-- rather than the actual bounding box of the path.
+--
+-- If the path contains no coordinates, all return values are 0.
+--
+-- @return |min_x| The minimum $x$ value of the bounding box of the path
+-- @return |min_y| The minimum $y$ value
+-- @return |max_x|
+-- @return |max_y|
+-- @return |center_x| The center of the bounding box
+-- @return |center_y|
+
+function Path:boundingBox()
+ if #self > 0 then
+ local min_x, min_y = math.huge, math.huge
+ local max_x, max_y = -math.huge, -math.huge
+
+ for i=1,#self do
+ local c = rigid(self[i])
+ if type(c) == "table" then
+ local x = c.x
+ local y = c.y
+ if x < min_x then min_x = x end
+ if y < min_y then min_y = y end
+ if x > max_x then max_x = x end
+ if y > max_y then max_y = y end
+ end
+ end
+
+ if min_x ~= math.huge then
+ return min_x, min_y, max_x, max_y, (min_x+max_x) / 2, (min_y+max_y) / 2
+ end
+ end
+ return 0, 0, 0, 0, 0, 0
+end
+
+
+-- Forwards
+
+local segmentize, bb, boxes_intersect, intersect_curves
+
+local eps = 0.0001
+
+
+
+---
+-- Computes all intersections of a path with another path and returns
+-- them as an array of coordinates. The intersections will be sorted
+-- ``along the path |self|''. The implementation uses a
+-- divide-and-conquer approach that should be reasonably fast in
+-- practice.
+--
+-- @param path Another path
+--
+-- @return Array of all intersections of |path| with |self| in the
+-- order they appear on |self|. Each entry of this array is a table
+-- with the following fields:
+-- %
+-- \begin{itemize}
+-- \item |index| The index of the segment in |self| where
+-- the intersection occurs.
+-- \item |time| The ``time'' at which a point traveling along the
+-- segment from its start point to its end point.
+-- \item |point| The point itself.
+-- \end{itemize}
+
+function Path:intersectionsWith(path)
+
+ local p1 = segmentize(self)
+ local memo1 = prepare_memo(p1)
+ local p2 = segmentize(path)
+ local memo2 = prepare_memo(p2)
+
+ local intersections = {}
+
+ local function intersect_segments(i1, i2)
+
+ local s1 = p1[i1]
+ local s2 = p2[i2]
+ local r = {}
+
+ if s1.action == 'lineto' and s2.action == 'lineto' then
+ local a = s2.to.x - s2.from.x
+ local b = s1.from.x - s1.to.x
+ local c = s2.from.x - s1.from.x
+ local d = s2.to.y - s2.from.y
+ local e = s1.from.y - s1.to.y
+ local f = s2.from.y - s1.from.y
+
+ local det = a*e - b*d
+
+ if math.abs(det) > eps*eps then
+ local t, s = (c*d - a*f)/det, (b*f - e*c)/det
+
+ if t >= 0 and t<=1 and s>=0 and s <= 1 then
+ local p = s1.from:clone()
+ p:moveTowards(s1.to, t)
+ return { { time = t, point = p } }
+ end
+ end
+ elseif s1.action == 'lineto' and s2.action == 'curveto' then
+ intersect_curves (0, 1,
+ s1.from.x, s1.from.y,
+ s1.from.x*2/3+s1.to.x*1/3, s1.from.y*2/3+s1.to.y*1/3,
+ s1.from.x*1/3+s1.to.x*2/3, s1.from.y*1/3+s1.to.y*2/3,
+ s1.to.x, s1.to.y,
+ s2.from.x, s2.from.y,
+ s2.support_1.x, s2.support_1.y,
+ s2.support_2.x, s2.support_2.y,
+ s2.to.x, s2.to.y,
+ r)
+ elseif s1.action == 'curveto' and s2.action == 'lineto' then
+ intersect_curves (0, 1,
+ s1.from.x, s1.from.y,
+ s1.support_1.x, s1.support_1.y,
+ s1.support_2.x, s1.support_2.y,
+ s1.to.x, s1.to.y,
+ s2.from.x, s2.from.y,
+ s2.from.x*2/3+s2.to.x*1/3, s2.from.y*2/3+s2.to.y*1/3,
+ s2.from.x*1/3+s2.to.x*2/3, s2.from.y*1/3+s2.to.y*2/3,
+ s2.to.x, s2.to.y,
+ r)
+ else
+ intersect_curves (0, 1,
+ s1.from.x, s1.from.y,
+ s1.support_1.x, s1.support_1.y,
+ s1.support_2.x, s1.support_2.y,
+ s1.to.x, s1.to.y,
+ s2.from.x, s2.from.y,
+ s2.support_1.x, s2.support_1.y,
+ s2.support_2.x, s2.support_2.y,
+ s2.to.x, s2.to.y,
+ r)
+ end
+ return r
+ end
+
+ local function intersect (i1, j1, i2, j2)
+
+ if i1 > j1 or i2 > j2 then
+ return
+ end
+
+ local bb1 = bb(i1, j1, memo1)
+ local bb2 = bb(i2, j2, memo2)
+
+ if boxes_intersect(bb1, bb2) then
+ -- Ok, need to do something
+ if i1 == j1 and i2 == j2 then
+ local intersects = intersect_segments (i1, i2)
+ for _,t in ipairs(intersects) do
+ intersections[#intersections+1] = {
+ time = t.time,
+ index = p1[i1].path_pos,
+ point = t.point
+ }
+ end
+ elseif i1 == j1 then
+ local m2 = math.floor((i2 + j2) / 2)
+ intersect(i1, j1, i2, m2)
+ intersect(i1, j1, m2+1, j2)
+ elseif i2 == j2 then
+ local m1 = math.floor((i1 + j1) / 2)
+ intersect(i1, m1, i2, j2)
+ intersect(m1+1, j1, i2, j2)
+ else
+ local m1 = math.floor((i1 + j1) / 2)
+ local m2 = math.floor((i2 + j2) / 2)
+ intersect(i1, m1, i2, m2)
+ intersect(m1+1, j1, i2, m2)
+ intersect(i1, m1, m2+1, j2)
+ intersect(m1+1, j1, m2+1, j2)
+ end
+ end
+ end
+
+ -- Run the recursion
+ intersect(1, #p1, 1, #p2)
+
+ -- Sort
+ table.sort(intersections, function(a,b)
+ return a.index < b.index or
+ a.index == b.index and a.time < b.time
+ end)
+
+ -- Remove duplicates
+ local remains = {}
+ remains[1] = intersections[1]
+ for i=2,#intersections do
+ local next = intersections[i]
+ local prev = remains[#remains]
+ if math.abs(next.point.x - prev.point.x) + math.abs(next.point.y - prev.point.y) > eps then
+ remains[#remains+1] = next
+ end
+ end
+
+ return remains
+end
+
+
+-- Returns true if two bounding boxes intersection
+
+function boxes_intersect (bb1, bb2)
+ return (bb1.max_x >= bb2.min_x - eps*eps and
+ bb1.min_x <= bb2.max_x + eps*eps and
+ bb1.max_y >= bb2.min_y - eps*eps and
+ bb1.min_y <= bb2.max_y + eps*eps)
+end
+
+
+-- Turns a path into a sequence of segments, each being either a
+-- lineto or a curveto from some point to another point. It also sets
+-- up a memorization array for the bounding boxes.
+
+function segmentize (path)
+
+ local prev
+ local start
+ local s = {}
+
+ local i = 1
+ while i <= #path do
+ local x = path[i]
+
+ if x == "lineto" then
+ x = rigid(path[i+1])
+ s [#s + 1] = {
+ path_pos = i,
+ action = "lineto",
+ from = prev,
+ to = x,
+ bb = {
+ min_x = math.min(prev.x, x.x),
+ max_x = math.max(prev.x, x.x),
+ min_y = math.min(prev.y, x.y),
+ max_y = math.max(prev.y, x.y),
+ }
+ }
+ prev = x
+ i = i + 2
+ elseif x == "moveto" then
+ prev = rigid(path[i+1])
+ start = prev
+ i = i + 2
+ elseif x == "closepath" then
+ s [#s + 1] = {
+ path_pos = i,
+ action = "lineto",
+ from = prev,
+ to = start,
+ bb = {
+ min_x = math.min(prev.x, start.x),
+ max_x = math.max(prev.x, start.x),
+ min_y = math.min(prev.y, start.y),
+ max_y = math.max(prev.y, start.y),
+ }
+ }
+ prev = nil
+ start = nil
+ i = i + 1
+ elseif x == "curveto" then
+ local s1, s2, to = rigid(path[i+1]), rigid(path[i+2]), rigid(path[i+3])
+ s [#s + 1] = {
+ action = "curveto",
+ path_pos = i,
+ from = prev,
+ to = to,
+ support_1 = s1,
+ support_2 = s2,
+ bb = {
+ min_x = math.min(prev.x, s1.x, s2.x, to.x),
+ max_x = math.max(prev.x, s1.x, s2.x, to.x),
+ min_y = math.min(prev.y, s1.y, s2.y, to.y),
+ max_y = math.max(prev.y, s1.y, s2.y, to.y),
+ }
+ }
+ prev = path[i+3]
+ i = i + 4
+ else
+ error ("illegal path command '" .. x .. "'")
+ end
+ end
+
+ return s
+end
+
+
+function prepare_memo (s)
+
+ local memo = {}
+
+ memo.base = #s
+
+ -- Fill memo table
+ for i,e in ipairs (s) do
+ memo[i*#s + i] = e.bb
+ end
+
+ return memo
+end
+
+
+-- This function computes the bounding box of all segments between i
+-- and j (inclusively)
+
+function bb (i, j, memo)
+ local b = memo[memo.base*i + j]
+ if not b then
+ assert (i < j, "memorization table filled incorrectly")
+
+ local mid = math.floor((i+j)/2)
+ local bb1 = bb (i, mid, memo)
+ local bb2 = bb (mid+1, j, memo)
+ b = {
+ min_x = math.min(bb1.min_x, bb2.min_x),
+ max_x = math.max(bb1.max_x, bb2.max_x),
+ min_y = math.min(bb1.min_y, bb2.min_y),
+ max_y = math.max(bb1.max_y, bb2.max_y)
+ }
+ memo[memo.base*i + j] = b
+ end
+
+ return b
+end
+
+
+
+-- Intersect two Bézier curves.
+
+function intersect_curves(t0, t1,
+ c1_ax, c1_ay, c1_bx, c1_by,
+ c1_cx, c1_cy, c1_dx, c1_dy,
+ c2_ax, c2_ay, c2_bx, c2_by,
+ c2_cx, c2_cy, c2_dx, c2_dy,
+ intersections)
+
+ -- Only do something, if the bounding boxes intersect:
+ local c1_min_x = math.min(c1_ax, c1_bx, c1_cx, c1_dx)
+ local c1_max_x = math.max(c1_ax, c1_bx, c1_cx, c1_dx)
+ local c1_min_y = math.min(c1_ay, c1_by, c1_cy, c1_dy)
+ local c1_max_y = math.max(c1_ay, c1_by, c1_cy, c1_dy)
+ local c2_min_x = math.min(c2_ax, c2_bx, c2_cx, c2_dx)
+ local c2_max_x = math.max(c2_ax, c2_bx, c2_cx, c2_dx)
+ local c2_min_y = math.min(c2_ay, c2_by, c2_cy, c2_dy)
+ local c2_max_y = math.max(c2_ay, c2_by, c2_cy, c2_dy)
+
+ if c1_max_x >= c2_min_x and
+ c1_min_x <= c2_max_x and
+ c1_max_y >= c2_min_y and
+ c1_min_y <= c2_max_y then
+
+ -- Everything "near together"?
+ if c1_max_x - c1_min_x < eps and c1_max_y - c1_min_y < eps then
+
+ -- Compute intersection of lines c1_a to c1_d and c2_a to c2_d
+ local a = c2_dx - c2_ax
+ local b = c1_ax - c1_dx
+ local c = c2_ax - c1_ax
+ local d = c2_dy - c2_ay
+ local e = c1_ay - c1_dy
+ local f = c2_ay - c1_ay
+
+ local det = a*e - b*d
+ local t
+
+ t = (c*d - a*f)/det
+ if t<0 then
+ t=0
+ elseif t>1 then
+ t=1
+ end
+
+ intersections [#intersections + 1] = {
+ time = t0 + t*(t1-t0),
+ point = Coordinate.new(c1_ax + t*(c1_dx-c1_ax), c1_ay+t*(c1_dy-c1_ay))
+ }
+ else
+ -- Cut 'em in half!
+ local c1_ex, c1_ey = (c1_ax + c1_bx)/2, (c1_ay + c1_by)/2
+ local c1_fx, c1_fy = (c1_bx + c1_cx)/2, (c1_by + c1_cy)/2
+ local c1_gx, c1_gy = (c1_cx + c1_dx)/2, (c1_cy + c1_dy)/2
+
+ local c1_hx, c1_hy = (c1_ex + c1_fx)/2, (c1_ey + c1_fy)/2
+ local c1_ix, c1_iy = (c1_fx + c1_gx)/2, (c1_fy + c1_gy)/2
+
+ local c1_jx, c1_jy = (c1_hx + c1_ix)/2, (c1_hy + c1_iy)/2
+
+ local c2_ex, c2_ey = (c2_ax + c2_bx)/2, (c2_ay + c2_by)/2
+ local c2_fx, c2_fy = (c2_bx + c2_cx)/2, (c2_by + c2_cy)/2
+ local c2_gx, c2_gy = (c2_cx + c2_dx)/2, (c2_cy + c2_dy)/2
+
+ local c2_hx, c2_hy = (c2_ex + c2_fx)/2, (c2_ey + c2_fy)/2
+ local c2_ix, c2_iy = (c2_fx + c2_gx)/2, (c2_fy + c2_gy)/2
+
+ local c2_jx, c2_jy = (c2_hx + c2_ix)/2, (c2_hy + c2_iy)/2
+
+ intersect_curves (t0, (t0+t1)/2,
+ c1_ax, c1_ay, c1_ex, c1_ey, c1_hx, c1_hy, c1_jx, c1_jy,
+ c2_ax, c2_ay, c2_ex, c2_ey, c2_hx, c2_hy, c2_jx, c2_jy,
+ intersections)
+ intersect_curves (t0, (t0+t1)/2,
+ c1_ax, c1_ay, c1_ex, c1_ey, c1_hx, c1_hy, c1_jx, c1_jy,
+ c2_jx, c2_jy, c2_ix, c2_iy, c2_gx, c2_gy, c2_dx, c2_dy,
+ intersections)
+ intersect_curves ((t0+t1)/2, t1,
+ c1_jx, c1_jy, c1_ix, c1_iy, c1_gx, c1_gy, c1_dx, c1_dy,
+ c2_ax, c2_ay, c2_ex, c2_ey, c2_hx, c2_hy, c2_jx, c2_jy,
+ intersections)
+ intersect_curves ((t0+t1)/2, t1,
+ c1_jx, c1_jy, c1_ix, c1_iy, c1_gx, c1_gy, c1_dx, c1_dy,
+ c2_jx, c2_jy, c2_ix, c2_iy, c2_gx, c2_gy, c2_dx, c2_dy,
+ intersections)
+ end
+ end
+end
+
+
+---
+-- Shorten a path at the beginning. We are given the index of a
+-- segment inside the path as well as a point in time along this
+-- segment. The path is now shortened so that everything before this
+-- segment and everything in the segment before the given time is
+-- removed from the path.
+--
+-- @param index The index of a path segment.
+-- @param time A time along the specified path segment.
+
+function Path:cutAtBeginning(index, time)
+
+ local cut_path = Path:new ()
+
+ -- Ok, first, we need to find the segment *before* the current
+ -- one. Usually, this will be a moveto or a lineto, but things could
+ -- be different.
+ assert (type(self[index-1]) == "table" or type(self[index-1]) == "function",
+ "segment before intersection does not end with a coordinate")
+
+ local from = rigid(self[index-1])
+ local action = self[index]
+
+ -- Now, depending on the type of segment, we do different things:
+ if action == "lineto" then
+
+ -- Ok, compute point:
+ local to = rigid(self[index+1])
+
+ from:moveTowards(to, time)
+
+ -- Ok, this is easy: We start with a fresh moveto ...
+ cut_path[1] = "moveto"
+ cut_path[2] = from
+
+ -- ... and copy the rest
+ for i=index,#self do
+ cut_path[#cut_path+1] = self[i]
+ end
+ elseif action == "curveto" then
+
+ local to = rigid(self[index+3])
+ local s1 = rigid(self[index+1])
+ local s2 = rigid(self[index+2])
+
+ -- Now, compute the support vectors and the point at time:
+ from:moveTowards(s1, time)
+ s1:moveTowards(s2, time)
+ s2:moveTowards(to, time)
+
+ from:moveTowards(s1, time)
+ s1:moveTowards(s2, time)
+
+ from:moveTowards(s1, time)
+
+ -- Ok, this is easy: We start with a fresh moveto ...
+ cut_path[1] = "moveto"
+ cut_path[2] = from
+ cut_path[3] = "curveto"
+ cut_path[4] = s1
+ cut_path[5] = s2
+ cut_path[6] = to
+
+ -- ... and copy the rest
+ for i=index+4,#self do
+ cut_path[#cut_path+1] = self[i]
+ end
+
+ elseif action == "closepath" then
+ -- Let us find the start point:
+ local found
+ for i=index,1,-1 do
+ if self[i] == "moveto" then
+ -- Bingo:
+ found = i
+ break
+ end
+ end
+
+ assert(found, "no moveto found in path")
+
+ local to = rigid(self[found+1])
+ from:moveTowards(to,time)
+
+ cut_path[1] = "moveto"
+ cut_path[2] = from
+ cut_path[3] = "lineto"
+ cut_path[4] = to
+
+ -- ... and copy the rest
+ for i=index+1,#self do
+ cut_path[#cut_path+1] = self[i]
+ end
+ else
+ error ("wrong path operation")
+ end
+
+ -- Move cut_path back:
+ for i=1,#cut_path do
+ self[i] = cut_path[i]
+ end
+ for i=#cut_path+1,#self do
+ self[i] = nil
+ end
+end
+
+
+
+
+---
+-- Shorten a path at the end. This method works like |cutAtBeginning|,
+-- only the path is cut at the end.
+--
+-- @param index The index of a path segment.
+-- @param time A time along the specified path segment.
+
+function Path:cutAtEnd(index, time)
+
+ local cut_path = Path:new ()
+
+ -- Ok, first, we need to find the segment *before* the current
+ -- one. Usually, this will be a moveto or a lineto, but things could
+ -- be different.
+ assert (type(self[index-1]) == "table" or type(self[index-1]) == "function",
+ "segment before intersection does not end with a coordinate")
+
+ local from = rigid(self[index-1])
+ local action = self[index]
+
+ -- Now, depending on the type of segment, we do different things:
+ if action == "lineto" then
+
+ -- Ok, compute point:
+ local to = rigid(self[index+1])
+ to:moveTowards(from, 1-time)
+
+ for i=1,index do
+ cut_path[i] = self[i]
+ end
+ cut_path[index+1] = to
+
+ elseif action == "curveto" then
+
+ local s1 = rigid(self[index+1])
+ local s2 = rigid(self[index+2])
+ local to = rigid(self[index+3])
+
+ -- Now, compute the support vectors and the point at time:
+ to:moveTowards(s2, 1-time)
+ s2:moveTowards(s1, 1-time)
+ s1:moveTowards(from, 1-time)
+
+ to:moveTowards(s2, 1-time)
+ s2:moveTowards(s1, 1-time)
+
+ to:moveTowards(s2, 1-time)
+
+ -- ... and copy the rest
+ for i=1,index do
+ cut_path[i] = self[i]
+ end
+
+ cut_path[index+1] = s1
+ cut_path[index+2] = s2
+ cut_path[index+3] = to
+
+ elseif action == "closepath" then
+ -- Let us find the start point:
+ local found
+ for i=index,1,-1 do
+ if self[i] == "moveto" then
+ -- Bingo:
+ found = i
+ break
+ end
+ end
+
+ assert(found, "no moveto found in path")
+
+ local to = rigid(self[found+1]:clone())
+ to:moveTowards(from,1-time)
+
+ for i=1,index-1 do
+ cut_path[i] = self[i]
+ end
+ cut_path[index] = 'lineto'
+ cut_path[index+1] = to
+ else
+ error ("wrong path operation")
+ end
+
+ -- Move cut_path back:
+ for i=1,#cut_path do
+ self[i] = cut_path[i]
+ end
+ for i=#cut_path+1,#self do
+ self[i] = nil
+ end
+end
+
+
+
+
+---
+-- ``Pads'' the path. The idea is the following: Suppose we stroke the
+-- path with a pen whose width is twice the value |padding|. The outer
+-- edge of this stroked drawing is now a path by itself. The path will
+-- be a bit longer and ``larger''. The present function tries to
+-- compute an approximation to this resulting path.
+--
+-- The algorithm used to compute the enlarged part does not necessarily
+-- compute the precise new path. It should work correctly for polyline
+-- paths, but not for curved paths.
+--
+-- @param padding A padding distance.
+-- @return The padded path.
+--
+
+function Path:pad(padding)
+
+ local padded = self:clone()
+ padded:makeRigid()
+
+ if padding == 0 then
+ return padded
+ end
+
+ -- First, decompose the path into subpaths:
+ local subpaths = {}
+ local subpath = {}
+ local start_index = 1
+
+ local function closepath(end_index)
+ if #subpath >= 1 then
+ subpath.start_index = start_index
+ subpath.end_index = end_index
+ start_index = end_index + 1
+
+ local start = 1
+ if (subpath[#subpath] - subpath[1]):norm() < 0.01 and subpath[2] then
+ start = 2
+ subpath.skipped = subpath[1]
+ end
+ subpath[#subpath + 1] = subpath[start]
+ subpath[#subpath + 1] = subpath[start+1]
+ subpaths[#subpaths + 1] = subpath
+ subpath = {}
+ end
+ end
+
+ for i,p in ipairs(padded) do
+ if p ~= "closepath" then
+ if type(p) == "table" then
+ subpath[#subpath + 1] = p
+ end
+ else
+ closepath (i)
+ end
+ end
+ closepath(#padded)
+
+ -- Second, iterate over the subpaths:
+ for _,subpath in ipairs(subpaths) do
+ local new_coordinates = {}
+ local _,_,_,_,c_x,c_y = Coordinate.boundingBox(subpath)
+ local c = Coordinate.new(c_x,c_y)
+
+ -- Find out the orientation of the path
+ local count = 0
+ for i=1,#subpath-2 do
+ local d2 = subpath[i+1] - subpath[i]
+ local d1 = subpath[i+2] - subpath[i+1]
+
+ local diff = math.atan2(d2.y,d2.x) - math.atan2(d1.y,d1.x)
+
+ if diff < -math.pi then
+ count = count + 1
+ elseif diff > math.pi then
+ count = count - 1
+ end
+ end
+
+ for i=2,#subpath-1 do
+ local p = subpath[i]
+ local d1 = subpath[i] - subpath[i-1]
+ local d2 = subpath[i+1] - subpath[i]
+
+ local orth1 = Coordinate.new(-d1.y, d1.x)
+ local orth2 = Coordinate.new(-d2.y, d2.x)
+
+ orth1:normalize()
+ orth2:normalize()
+
+ if count < 0 then
+ orth1:scale(-1)
+ orth2:scale(-1)
+ end
+
+ -- Ok, now we want to compute the intersection of the lines
+ -- perpendicular to p + padding*orth1 and p + padding*orth2:
+
+ local det = orth1.x * orth2.y - orth1.y * orth2.x
+
+ local c
+ if math.abs(det) < 0.1 then
+ c = orth1 + orth2
+ c:scale(padding/2)
+ else
+ c = Coordinate.new (padding*(orth2.y-orth1.y)/det, padding*(orth1.x-orth2.x)/det)
+ end
+
+ new_coordinates[i] = c+p
+ end
+
+ for i=2,#subpath-1 do
+ local p = subpath[i]
+ local new_p = new_coordinates[i]
+ p.x = new_p.x
+ p.y = new_p.y
+ end
+
+ if subpath.skipped then
+ local p = subpath[1]
+ local new_p = new_coordinates[#subpath-2]
+ p.x = new_p.x
+ p.y = new_p.y
+ end
+
+ -- Now, we need to correct the curveto fields:
+ for i=subpath.start_index,subpath.end_index do
+ if self[i] == 'curveto' then
+ local from = rigid(self[i-1])
+ local s1 = rigid(self[i+1])
+ local s2 = rigid(self[i+2])
+ local to = rigid(self[i+3])
+
+ local p1x, p1y, _, _, h1x, h1y =
+ Bezier.atTime(from.x, from.y, s1.x, s1.y, s2.x, s2.y,
+ to.x, to.y, 1/3)
+
+ local p2x, p2y, _, _, _, _, h2x, h2y =
+ Bezier.atTime(from.x, from.y, s1.x, s1.y, s2.x, s2.y,
+ to.x, to.y, 2/3)
+
+ local orth1 = Coordinate.new (p1y - h1y, -(p1x - h1x))
+ orth1:normalize()
+ orth1:scale(-padding)
+
+ local orth2 = Coordinate.new (p2y - h2y, -(p2x - h2x))
+ orth2:normalize()
+ orth2:scale(padding)
+
+ if count < 0 then
+ orth1:scale(-1)
+ orth2:scale(-1)
+ end
+
+ local new_s1, new_s2 =
+ Bezier.supportsForPointsAtTime(padded[i-1],
+ Coordinate.new(p1x+orth1.x,p1y+orth1.y), 1/3,
+ Coordinate.new(p2x+orth2.x,p2y+orth2.y), 2/3,
+ padded[i+3])
+
+ padded[i+1] = new_s1
+ padded[i+2] = new_s2
+ end
+ end
+ end
+
+ return padded
+end
+
+
+
+---
+-- Appends an arc (as in the sense of ``a part of the circumference of
+-- a circle'') to the path. You may optionally provide a
+-- transformation matrix, which will be applied to the arc. In detail,
+-- the following happens: We first invert the transformation
+-- and apply it to the start point. Then we compute the arc
+-- ``normally'', as if no transformation matrix were present. Then we
+-- apply the transformation matrix to all computed points.
+--
+-- @function Path:appendArc(start_angle,end_angle,radius,trans)
+--
+-- @param start_angle The start angle of the arc. Must be specified in
+-- degrees.
+-- @param end_angle the end angle of the arc.
+-- @param radius The radius of the circle on which this arc lies.
+-- @param trans A transformation matrix. If |nil|, the identity
+-- matrix will be assumed.
+
+Path.appendArc = lib.ondemand("Path_arced", Path, "appendArc")
+
+
+
+---
+-- Appends a clockwise arc (as in the sense of ``a part of the circumference of
+-- a circle'') to the path such that it ends at a given point. If a
+-- transformation matrix is given, both start and end point are first
+-- transformed according to the inverted transformation, then the arc
+-- is computed and then transformed back.
+--
+-- @function Path:appendArcTo(target,radius_or_center,clockwise,trans)
+--
+-- @param target The point where the arc should end.
+-- @param radius_or_center If a number, it is the radius of the circle
+-- on which this arc lies. If it is a |Coordinate|, this is the center
+-- of the circle.
+-- @param clockwise If true, the arc will be clockwise. Otherwise (the
+-- default, if nothing or |nil| is given), the arc will be counter
+-- clockwise.
+-- @param trans A transformation matrix. If missing,
+-- the identity matrix is assumed.
+
+Path.appendArcTo = lib.ondemand("Path_arced", Path, "appendArcTo")
+
+
+
+
+--
+-- @return The Path as string.
+--
+function Path:__tostring()
+ local r = {}
+ local i = 1
+ while i <= #self do
+ local p = self[i]
+
+ if p == "lineto" then
+ r [#r+1] = " -- " .. tostring(rigid(self[i+1]))
+ i = i + 1
+ elseif p == "moveto" then
+ r [#r+1] = " " .. tostring(rigid(self[i+1]) )
+ i = i + 1
+ elseif p == "curveto" then
+ r [#r+1] = " .. controls " .. tostring(rigid(self[i+1])) .. " and " ..
+ tostring(rigid(self[i+2])) .. " .. " .. tostring(rigid(self[i+3]))
+ i = i + 3
+ elseif p == "closepath" then
+ r [#r+1] = " -- cycle"
+ else
+ error("illegal path command")
+ end
+ i = i + 1
+ end
+ return table.concat(r)
+end
+
+
+
+-- Done
+
+return Path
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path_arced.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path_arced.lua
new file mode 100644
index 0000000000..1875b8d1a5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Path_arced.lua
@@ -0,0 +1,316 @@
+-- Copyright 2014 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local Path = require 'pgf.gd.model.Path'
+
+-- Imports
+
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Transform = require "pgf.gd.lib.Transform"
+
+
+
+-- Locals
+
+local rigid = Path.rigid
+
+local tan = math.tan
+local sin = math.sin
+local cos = math.cos
+local sqrt = math.sqrt
+local atan2 = math.atan2
+local abs = math.abs
+
+local to_rad = math.pi/180
+local to_deg = 180/math.pi
+local pi_half = math.pi/2
+
+local function sin_quarter(x)
+ x = x % 360
+ if x == 0 then
+ return 0
+ elseif x == 90 then
+ return 1
+ elseif x == 180 then
+ return 0
+ else
+ return -1
+ end
+end
+
+local function cos_quarter(x)
+ x = x % 360
+ if x == 0 then
+ return 1
+ elseif x == 90 then
+ return 0
+ elseif x == 180 then
+ return -1
+ else
+ return 0
+ end
+end
+
+local function atan2deg(y,x)
+
+ -- Works like atan2, but returns the angle in degrees and, returns
+ -- exactly a multiple of 90 if x or y are zero
+
+ if x == 0 then
+ if y < 0 then
+ return -90
+ else
+ return 90
+ end
+ elseif y == 0 then
+ if x < 0 then
+ return 180
+ else
+ return 0
+ end
+ else
+ return atan2(y,x) * to_deg
+ end
+
+end
+
+local function subarc (path, startx, starty, start_angle, delta, radius, trans, center_x, center_y)
+
+ local end_angle = start_angle + delta
+ local factor = tan (delta*to_rad/4) * 1.333333333333333333333 * radius
+
+ local s1, c1, s190, c190, s2, c2, s290, c290
+
+ if start_angle % 90 == 0 then
+ s1, c1, s190, c190 = sin_quarter(start_angle), cos_quarter(start_angle), sin_quarter(start_angle+90), cos_quarter(start_angle+90)
+ else
+ local a1 = start_angle*to_rad
+ s1, c1, s190, c190 = sin(a1), cos(a1), sin(a1+pi_half), cos(a1+pi_half)
+ end
+
+ if end_angle % 90 == 0 then
+ s2, c2, s290, c290 = sin_quarter(end_angle), cos_quarter(end_angle), sin_quarter(end_angle-90), cos_quarter(end_angle-90)
+ else
+ local a2 = end_angle * to_rad
+ s2, c2, s290, c290 = sin(a2), cos(a2), sin(a2-pi_half), cos(a2-pi_half)
+ end
+
+ local lastx, lasty = center_x + c2*radius, center_y + s2*radius
+
+ path[#path + 1] = "curveto"
+ path[#path + 1] = Coordinate.new (startx + c190*factor, starty + s190*factor)
+ path[#path + 1] = Coordinate.new (lastx + c290*factor, lasty + s290*factor)
+ path[#path + 1] = Coordinate.new (lastx, lasty)
+
+ if trans then
+ path[#path-2]:apply(trans)
+ path[#path-1]:apply(trans)
+ path[#path ]:apply(trans)
+ end
+
+ return lastx, lasty, end_angle
+end
+
+
+
+local function arc (path, start, start_angle, end_angle, radius, trans, centerx, centery)
+
+ -- @param path is the path object
+ -- @param start is the start coordinate
+ -- @param start_angle is given in degrees
+ -- @param end_angle is given in degrees
+ -- @param radius is the radius
+ -- @param trans is an optional transformation matrix that gets applied to all computed points
+ -- @param centerx optionally: x-part of the center of the circle
+ -- @param centery optionally: y-part of the center of the circle
+
+ local startx, starty = start.x, start.y
+
+ -- Compute center:
+ centerx = centerx or startx - cos(start_angle*to_rad)*radius
+ centery = centery or starty - sin(start_angle*to_rad)*radius
+
+ if start_angle < end_angle then
+ -- First, ensure that the angles are in a reasonable range:
+ start_angle = start_angle % 360
+ end_angle = end_angle % 360
+
+ if end_angle <= start_angle then
+ -- In case the modulo has inadvertently moved the end angle
+ -- before the start angle:
+ end_angle = end_angle + 360
+ end
+
+ -- Ok, now create a series of arcs that are at most quarter-cycles:
+ while start_angle < end_angle do
+ if start_angle + 179 < end_angle then
+ -- Add a quarter cycle:
+ startx, starty, start_angle = subarc(path, startx, starty, start_angle, 90, radius, trans, centerx, centery)
+ elseif start_angle + 90 < end_angle then
+ -- Add 60 degrees to ensure that there are no small segments
+ -- at the end
+ startx, starty, start_angle = subarc(path, startx, starty, start_angle, (end_angle-start_angle)/2, radius, trans, centerx, centery)
+ else
+ subarc(path, startx, starty, start_angle, end_angle - start_angle, radius, trans, centerx, centery)
+ break
+ end
+ end
+
+ elseif start_angle > end_angle then
+ -- First, ensure that the angles are in a reasonable range:
+ start_angle = start_angle % 360
+ end_angle = end_angle % 360
+
+ if end_angle >= start_angle then
+ -- In case the modulo has inadvertedly moved the end angle
+ -- before the start angle:
+ end_angle = end_angle - 360
+ end
+
+ -- Ok, now create a series of arcs that are at most quarter-cycles:
+ while start_angle > end_angle do
+ if start_angle - 179 > end_angle then
+ -- Add a quarter cycle:
+ startx, starty, start_angle = subarc(path, startx, starty, start_angle, -90, radius, trans, centerx, centery)
+ elseif start_angle - 90 > end_angle then
+ -- Add 60 degrees to ensure that there are no small segments
+ -- at the end
+ startx, starty, start_angle = subarc(path, startx, starty, start_angle, (end_angle-start_angle)/2, radius, trans, centerx, centery)
+ else
+ subarc(path, startx, starty, start_angle, end_angle - start_angle, radius, trans, centerx, centery)
+ break
+ end
+ end
+
+ -- else, do nothing
+ end
+end
+
+
+-- Doc see Path.lua
+
+function Path:appendArc(start_angle,end_angle,radius, trans)
+
+ local start = rigid(self[#self])
+ assert(type(start) == "table", "trying to append an arc to a path that does not end with a coordinate")
+
+ if trans then
+ start = start:clone()
+ start:apply(Transform.invert(trans))
+ end
+
+ arc (self, start, start_angle, end_angle, radius, trans)
+end
+
+
+
+
+-- Doc see Path.lua
+
+function Path:appendArcTo (target, radius_or_center, clockwise, trans)
+
+ local start = rigid(self[#self])
+ assert(type(start) == "table", "trying to append an arc to a path that does not end with a coordinate")
+
+ local trans_target = target
+ local centerx, centery, radius
+
+ if type(radius_or_center) == "number" then
+ radius = radius_or_center
+ else
+ centerx, centery = radius_or_center.x, radius_or_center.y
+ end
+
+ if trans then
+ start = start:clone()
+ trans_target = target:clone()
+ local itrans = Transform.invert(trans)
+ start:apply(itrans)
+ trans_target:apply(itrans)
+ if centerx then
+ local t = radius_or_center:clone()
+ t:apply(itrans)
+ centerx, centery = t.x, t.y
+ end
+ end
+
+ if not centerx then
+ -- Compute center
+ local dx, dy = target.x - start.x, target.y - start.y
+
+ if abs(dx) == abs(dy) and abs(dx) == radius then
+ if (dx < 0 and dy < 0) or (dx > 0 and dy > 0) then
+ centerx = start.x
+ centery = trans_target.y
+ else
+ centerx = trans_target.x
+ centery = start.y
+ end
+ else
+ local l_sq = dx*dx + dy*dy
+ if l_sq >= radius*radius*4*0.999999 then
+ centerx = (start.x+trans_target.x) / 2
+ centery = (start.y+trans_target.y) / 2
+ assert(l_sq <= radius*radius*4/0.999999, "radius too small for arc")
+ else
+ -- Normalize
+ local l = sqrt(l_sq)
+ local nx = dx / l
+ local ny = dy / l
+
+ local e = sqrt(radius*radius - 0.25*l_sq)
+
+ centerx = start.x + 0.5*dx - ny*e
+ centery = start.y + 0.5*dy + nx*e
+ end
+ end
+ end
+
+ local start_dx, start_dy, target_dx, target_dy =
+ start.x - centerx, start.y - centery,
+ trans_target.x - centerx, trans_target.y - centery
+
+ if not radius then
+ -- Center is given, compute radius:
+ radius_sq = start_dx^2 + start_dy^2
+
+ -- Ensure that the circle is, indeed, centered:
+ assert (abs(target_dx^2 + target_dy^2 - radius_sq)/radius_sq < 1e-5, "attempting to add an arc with incorrect center")
+
+ radius = sqrt(radius_sq)
+ end
+
+ -- Compute start and end angle:
+ local start_angle = atan2deg(start_dy, start_dx)
+ local end_angle = atan2deg(target_dy, target_dx)
+
+ if clockwise then
+ if end_angle > start_angle then
+ end_angle = end_angle - 360
+ end
+ else
+ if end_angle < start_angle then
+ end_angle = end_angle + 360
+ end
+ end
+
+ arc (self, start, start_angle, end_angle, radius, trans, centerx, centery)
+
+ -- Patch last point to avoid rounding problems:
+ self[#self] = target
+end
+
+
+
+-- Done
+
+return true
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Vertex.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Vertex.lua
new file mode 100644
index 0000000000..677ea4fbd0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/Vertex.lua
@@ -0,0 +1,296 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- A |Vertex| instance models a node of graphs. Each |Vertex| object can be an
+-- element of any number of graphs (whereas an |Arc| object can only be an
+-- element of a single graph).
+--
+-- When a vertex is added to a digraph |g|, two tables are created in
+-- the vertex' storage: An array of incoming arcs (with respect to
+-- |g|) and an array of outgoing arcs (again, with respect to
+-- |g|). The fields are managed by the |Digraph| class and should not
+-- be modified directly.
+--
+-- Note that a |Vertex| is an abstraction of \tikzname\ nodes; indeed
+-- the objective is to ensure that, in principle, we can use them
+-- independently of \TeX. For this reason, you will not find any
+-- references to |tex| inside a |Vertex|; this information is only
+-- available in the syntactic digraph.
+--
+-- One important aspect of vertices are its anchors -- a concept well
+-- familiar for users of \tikzname, but since we need to abstract from
+-- \tikzname, a separate anchor management is available inside the
+-- graph drawing system. It works as follows:
+--
+-- First of all, every vertex has a path, which is a (typically
+-- closed) line around the vertex. The display system will pass down
+-- the vertex' path to the graph drawing system and this path will be
+-- stored as a |Path| object in the |path| field of the vertex. This
+-- path lives in a special ``local'' coordinate system, that is, all
+-- coordinates of this path should actually be considered relative to
+-- the vertex' |pos| field. Note that the path is typically, but not
+-- always, ``centered'' on the origin. A graph drawing algorithm
+-- should arrange the vertices in such a way that the origins in the
+-- path coordinate systems are aligned.
+--
+-- To illustrate the difference between the origin and the vertex
+-- center, consider a tree drawing algorithm in which a node |root| has
+-- three children |a|, |b|, and |g|. Now, if we were to simply center
+-- these three letters vertically and arrange them in a line, the
+-- letters would appear to ``jump up and down'' since the height of
+-- the three letters are quite different. A solution is to shift the
+-- letters (and, thus, the paths of the vertices) in such a way that
+-- in all three letters the baseline of the letters is exactly at the
+-- origin. Now, when a graph drawing algorithm aligns these vertices
+-- along the origins, the letters will all have the same baseline.
+--
+-- Apart from the origin, there may be other positions in the path
+-- coordinate system that are of interest -- such as the center of
+-- the vertex. As mentioned above, this need not be the origin and
+-- although a graph drawing algorithm should align the origins,
+-- \emph{edges} between vertices should head toward these vertex
+-- centers rather that toward the origins. Other points of interest
+-- might be the ``top'' of the node.
+--
+-- All points of special interest are called ``anchors''. The |anchor|
+-- method allows you to retrieve them. By default, you always have
+-- access to the |center| anchor, but other anchors may or may not be
+-- available also, see the |anchor| method for details.
+--
+-- @field pos A coordinate object that stores the position where the
+-- vertex should be placed on the canvas. The main objective of graph drawing
+-- algorithms is to update this coordinate.
+--
+-- @field name An optional string that is used as a textual representation
+-- of the node.
+--
+-- @field path The path of the vertex's shape. This is a path along
+-- the outer line resulting from stroking the vertex's original
+-- shape. For instance, if you have a quadratic shape of size 1cm and
+-- you stroke the path with a pen of 2mm thickness, this |path| field
+-- would store a path of a square of edge length 12mm.
+--
+-- @field anchors A table of anchors (in the TikZ sense). The table is
+-- indexed by the anchor names (strings) and the values are
+-- |Coordinate|s. Currently, it is only guaranteed that the |center|
+-- anchor is present. Note that the |center| anchor need not lie at
+-- the origin: A graph drawing system should align nodes relative to
+-- the origin of the path's coordinate system. However, lines going to
+-- and from the node will head towards the |center| anchor. See
+-- Section~\ref{section-gd-anchors} for details.
+--
+-- @field options A table of options that contains user-defined options.
+--
+-- @field animations An array of attribute animations for the
+-- node. When an algorithm adds entries to this array, the display
+-- layer should try to render these. The syntax is as follows: Each
+-- element in the array is a table with a field |attribute|, which must
+-- be a string like |"opacity"| or |"translate"|, a field |entries|,
+-- which must be an array to be explained in a moment, and field
+-- |options|, which must be a table of the same syntax as the
+-- |options| field. For the |entries| array, each element must be
+-- table with two field: |t| must be set to a number, representing a
+-- time in seconds, and |value|, which must be set to a value that
+-- the |attribute| should have at the given time. The entries and the
+-- options will then be interpreted as described in \pgfname's basic
+-- layer animation system, except that where a |\pgfpoint| is expected
+-- you provide a |Coordinate| and a where a path is expected you
+-- provide a |Path|.
+--
+-- @field shape A string describing the shape of the node (like |rectangle|
+-- or |circle|). Note, however, that this is more ``informative''; the
+-- actual information that is used by the graph drawing system for
+-- determining the extent of a node, its bounding box, convex hull,
+-- and line intersections is the |path| field.
+--
+-- @field kind A string describing the kind of the node. For instance, a
+-- node of type |"dummy"| does not correspond to any real node in
+-- the graph but is used by the graph drawing algorithm.
+--
+-- @field event The |Event| when this vertex was created (may be |nil|
+-- if the vertex is not part of the syntactic digraph).
+--
+-- @field incomings A table indexed by |Digraph| objects. For each
+-- digraph, the table entry is an array of all vertices from which
+-- there is an |Arc| to this vertex. This field is internal and may
+-- not only be accessed by the |Digraph| class.
+--
+-- @field outgoings Like |incomings|, but for outgoing arcs.
+--
+local Vertex = {}
+Vertex.__index = Vertex
+
+
+-- Namespace
+
+require("pgf.gd.model").Vertex = Vertex
+
+
+-- Imports
+
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Path = require "pgf.gd.model.Path"
+local Storage = require "pgf.gd.lib.Storage"
+
+
+---
+-- Create a new vertex. The |initial| parameter allows you to setup
+-- some initial values.
+--
+-- @usage
+--\begin{codeexample}[code only, tikz syntax=false]
+--local v = Vertex.new { name = "hello", pos = Coordinate.new(1,1) }
+--\end{codeexample}
+--
+-- @param initial Values to override default node settings. The
+-- following are permissible:
+-- \begin{description}
+-- \item[|pos|] Initial position of the node.
+-- \item[|name|] The name of the node. It is optional to define this.
+-- \item[|path|] A |Path| object representing the vertex's hull.
+-- \item[|anchors|] A table of anchors.
+-- \item[|options|] An options table for the vertex.
+-- \item[|animations|] An array of generated animation attributes.
+-- \item[|shape|] A string describing the shape. If not given, |"none"| is used.
+-- \item[|kind|] A kind like |"node"| or |"dummy"|. If not given, |"dummy"| is used.
+-- \end{description}
+--
+-- @return A newly allocated node.
+--
+function Vertex.new(values)
+ local new = {
+ incomings = Storage.new(),
+ outgoings = Storage.new()
+ }
+ for k,v in pairs(values) do
+ new[k] = v
+ end
+ new.path = new.path or Path.new { 0, 0 }
+ new.shape = new.shape or "none"
+ new.kind = new.kind or "dummy"
+ new.pos = new.pos or Coordinate.new(0,0)
+ new.anchors = new.anchors or { center = Coordinate.new(0,0) }
+ new.animations = new.animations or {}
+ return setmetatable (new, Vertex)
+end
+
+
+
+
+---
+-- Returns a bounding box of a vertex.
+--
+-- @return |min_x| The minimum $x$ value of the bounding box of the path
+-- @return |min_y| The minimum $y$ value
+-- @return |max_x|
+-- @return |max_y|
+-- @return |center_x| The center of the bounding box
+-- @return |center_y|
+
+function Vertex:boundingBox()
+ return self.path:boundingBox()
+end
+
+
+
+local anchor_cache = Storage.new ()
+
+local directions = {
+ north = function(min_x, min_y, max_x, max_y)
+ return (min_x+max_x)/2, max_y
+ end,
+ south = function(min_x, min_y, max_x, max_y)
+ return (min_x+max_x)/2, min_y
+ end,
+ east = function(min_x, min_y, max_x, max_y)
+ return max_x, (min_y+max_y)/2
+ end,
+ west = function(min_x, min_y, max_x, max_y)
+ return min_x, (min_y+max_y)/2
+ end,
+ ["north west"] = function(min_x, min_y, max_x, max_y)
+ return min_x, max_y
+ end,
+ ["north east"] = function(min_x, min_y, max_x, max_y)
+ return max_x, max_y
+ end,
+ ["south west"] = function(min_x, min_y, max_x, max_y)
+ return min_x, min_y
+ end,
+ ["south east"] = function(min_x, min_y, max_x, max_y)
+ return max_x, min_y
+ end,
+}
+
+---
+-- Returns an anchor position in a vertex. First, we try to look
+-- the anchor up in the vertex's |anchors| table. If it is not found
+-- there, we test whether it is one of the direction strings |north|,
+-- |south east|, and so on. If so, we consider a line from the center
+-- of the node to the position on the bounding box that corresponds to
+-- the given direction (so |south east| would be the lower right
+-- corner). We intersect this line with the vertex's path and return
+-- the result. Finally, if the above fails, we try to consider the
+-- anchor as a number and return the intersection of a line starting
+-- at the vertex's center with the number as its angle and the path of
+-- the vertex.
+--
+-- @param anchor An anchor as detailed above
+-- @return A coordinate in the vertex's local coordinate system (so
+-- add the |pos| field to arrive at the actual position). If the
+-- anchor was not found, |nil| is returned
+
+function Vertex:anchor(anchor)
+ local c = self.anchors[anchor]
+ if not c then
+ local b
+ local d = directions [anchor]
+ if d then
+ b = Coordinate.new(d(self:boundingBox()))
+ else
+ local n = tonumber(anchor)
+ if n then
+ local x1, y1, x2, y2 = self:boundingBox()
+ local r = math.max(x2-x1, y2-y1)
+ b = Coordinate.new(r*math.cos(n/180*math.pi),r*math.sin(n/180*math.pi))
+ b:shiftByCoordinate(self.anchors.center)
+ end
+ end
+ if not b then
+ return
+ end
+ local p = Path.new {'moveto', self.anchors.center, 'lineto', b}
+ local intersections = p:intersectionsWith(self.path)
+ if #intersections > 0 then
+ c = intersections[1].point
+ end
+ end
+ self.anchors[anchor] = c
+ return c
+end
+
+
+
+--
+-- Returns a string representation of a vertex. This is mainly for debugging
+--
+-- @return The Arc as string.
+--
+function Vertex:__tostring()
+ return self.name or tostring(self.anchors)
+end
+
+
+-- Done
+
+return Vertex
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/library.lua
new file mode 100644
index 0000000000..ad62faa0f3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/model/library.lua
@@ -0,0 +1,15 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+-- Load declarations from:
+require "pgf.gd.model.Hyperedge"
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf.lua
new file mode 100644
index 0000000000..f7905f2418
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf.lua
@@ -0,0 +1,26 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+-- Imports
+
+require "pgf"
+require "pgf.gd"
+
+
+-- Declare namespace
+pgf.gd.ogdf = {}
+
+
+-- Done
+
+return pgf.gd.ogdf \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf/library.lua
new file mode 100644
index 0000000000..f91c75a4d6
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/ogdf/library.lua
@@ -0,0 +1,33 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- The Open Graph Drawing Framework (\textsc{ogdf}) is a large,
+-- powerful graph drawing system written in C++. This library enables
+-- its use inside \tikzname's graph drawing system by translating
+-- back-and-forth between Lua and C++.
+--
+-- Since C++ code is compiled and not interpreted (like Lua), in order
+-- to use the present library, you need a compiled version of the
+-- \pgfname\ interface code for the \textsc{ogdf} library
+-- (|pgf/gd/ogdf/c/ogdf_script.so|) installed correctly for your particular
+-- architecture. This is by no means trivial\dots
+--
+-- @library
+
+local ogdf
+
+
+-- Load the C++ code:
+
+require "pgf_gd_ogdf_c_ogdf_script"
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees.lua
new file mode 100644
index 0000000000..95689e6379
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees.lua
@@ -0,0 +1,21 @@
+-- Copyright 2015 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+local pedigrees = {}
+
+-- Declare namespace
+require("pgf.gd").pedigrees = tree
+
+
+-- Done
+
+return pedigrees \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/Koerner2015.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/Koerner2015.lua
new file mode 100644
index 0000000000..32927530a2
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/Koerner2015.lua
@@ -0,0 +1,163 @@
+-- Copyright 2015 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local Koerner2015 = {}
+
+
+-- Namespace
+require("pgf.gd.pedigrees").Koerner2015 = Koerner2015
+
+-- Imports
+local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms"
+local Storage = require "pgf.gd.lib.Storage"
+local Direct = require "pgf.gd.lib.Direct"
+
+-- Shorthand:
+local declare = InterfaceToAlgorithms.declare
+
+
+---
+declare {
+ key = "mate",
+ type = "boolean",
+
+ summary = [["
+ Edges of type |mate| join mates.
+ "]],
+}
+
+
+---
+declare {
+ key = "child",
+ type = "boolean",
+
+ summary = [["
+ Edges of type |child| join a parent to a child. The parent is the tail
+ of the edge, the child is the head.
+ "]],
+}
+
+---
+declare {
+ key = "sibling",
+ type = "boolean",
+
+ summary = [["
+ Edges of type |sibling| join a siblings (persons with identical parents).
+ "]],
+}
+
+
+---
+declare {
+ key = "simple pedigree layout",
+ algorithm = Koerner2015,
+
+ postconditions = {
+ upward_oriented = true
+ },
+
+ summary = [["
+ A simple algorithm for drawing a pedigree.
+ "]],
+ documentation = [["
+ ...
+ "]],
+ examples = [["
+ \tikz \graph [simple pedigree layout, default edge operator=complete bipartite]
+ {
+ Eve -- [mate] Felix;
+ { Eve, Felix } -> [child] { George, Hank };
+
+ Alice -- [mate] Bob;
+ { Alice, Bob } -> [child] { Charly, Dave, Eve };
+ };
+ "]]
+}
+
+
+function Koerner2015:run()
+
+ local g = self.digraph
+
+ -- Compute ranks:
+
+ local visited = {}
+ local ranks = {}
+
+ local queue = { { g.vertices[1], 1 } }
+
+ local queue_start = 1
+ local queue_end = 1
+
+ local function put(v, r)
+ queue_end = queue_end + 1
+ queue [queue_end] = { v, r }
+ end
+
+ local function get()
+ local v = queue[queue_start][1]
+ local r = queue[queue_start][2]
+ queue_start = queue_start + 1
+ return v,r
+ end
+
+ while queue_start <= queue_end do
+
+ -- Pop
+ local v, rank = get()
+ ranks[v] = rank
+
+ visited [v] = true
+
+ -- Follow mates:
+ for _,a in ipairs(g:outgoing(v)) do
+ if a:options("sibling") then
+ if not visited[a.head] then
+ put(a.head, rank)
+ end
+ end
+ end
+ for _,a in ipairs(g:incoming(v)) do
+ if a:options("child") then
+ if not visited[a.tail] then
+ put(a.tail, rank-1)
+ end
+ end
+ end
+ for _,a in ipairs(g:outgoing(v)) do
+ if a:options("child") then
+ if not visited[a.head] then
+ put(a.head, rank+1)
+ end
+ end
+ end
+ for _,a in ipairs(g:outgoing(v)) do
+ if a:options("mate") then
+ if not visited[a.head] then
+ put(a.head, rank)
+ end
+ end
+ end
+ end
+
+ for i,v in ipairs(g.vertices) do
+ v.pos.x = i*50
+ v.pos.y = ranks[v] * 50
+ end
+
+end
+
+return Koerner2015
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/library.lua
new file mode 100644
index 0000000000..db3d4f9cf7
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/pedigrees/library.lua
@@ -0,0 +1,21 @@
+-- Copyright 2015 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- A pedigree depicts parent--mate--sibling relationships between individuals.
+--
+-- @library
+
+local pedigrees -- Library name
+
+require "pgf.gd.pedigrees.Koerner2015"
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics.lua
new file mode 100644
index 0000000000..77c66de5b2
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics.lua
@@ -0,0 +1,21 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+local phylogenetics = {}
+
+-- Declare namespace
+require("pgf.gd").phylogenetics = tree
+
+
+-- Done
+
+return phylogenetics \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua
new file mode 100644
index 0000000000..04e1ca49f1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua
@@ -0,0 +1,77 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+local AuthorDefinedPhylogeny = {}
+
+
+-- Namespace
+require("pgf.gd.phylogenetics").AuthorDefinedPhylogeny = AuthorDefinedPhylogeny
+
+-- Imports
+local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms"
+local Direct = require "pgf.gd.lib.Direct"
+
+-- Shorthand:
+local declare = InterfaceToAlgorithms.declare
+
+
+---
+declare {
+ key = "phylogenetic tree by author",
+ algorithm = AuthorDefinedPhylogeny,
+ phase = "phylogenetic tree generation",
+ phase_default = true,
+
+ summary = [["
+ When this key is used, the phylogenetic tree must be specified
+ by the author (rather than being generated algorithmically).
+ "]],
+ documentation = [["
+ A spanning tree of the input graph will be computed first (it
+ must be connected, otherwise errors will result).
+ The evolutionary length of the edges must be specified through
+ the use of the |length| key for each edge.
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout] {
+ a -- {
+ b [>length=2] --[length=1] { c, d },
+ e [>length=3]
+ }
+ };
+ "]]
+}
+
+
+
+function AuthorDefinedPhylogeny:run()
+
+ local spanning_tree = self.main_algorithm.digraph.options.algorithm_phases["spanning tree computation"].new {
+ ugraph = self.main_algorithm.ugraph,
+ events = {} -- no events
+ }:run()
+
+ local phylogenetic_tree = Direct.ugraphFromDigraph(spanning_tree)
+ local lengths = self.lengths
+
+ for _,a in ipairs(phylogenetic_tree.arcs) do
+ lengths[a.tail][a.head] = a:options('length')
+ end
+
+ return phylogenetic_tree
+end
+
+
+
+return AuthorDefinedPhylogeny
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua
new file mode 100644
index 0000000000..ef40f0ee60
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua
@@ -0,0 +1,593 @@
+-- Copyright 2013 by Sarah Mäusle and Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+local BalancedMinimumEvolution = {}
+
+
+-- Namespace
+require("pgf.gd.phylogenetics").BalancedMinimumEvolution = BalancedMinimumEvolution
+
+-- Imports
+local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms")
+local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix")
+local Storage = require("pgf.gd.lib.Storage")
+local Digraph = require("pgf.gd.model.Digraph")
+local lib = require("pgf.gd.lib")
+
+-- Shorthand:
+local declare = InterfaceToAlgorithms.declare
+
+
+---
+declare {
+ key = "balanced minimum evolution",
+ algorithm = BalancedMinimumEvolution,
+ phase = "phylogenetic tree generation",
+
+ summary = [["
+ The BME (Balanced Minimum Evolution) algorithm tries to minimize
+ the total tree length.
+ "]],
+ documentation = [["
+ This algorithm is from Desper and Gascuel, \emph{Fast and
+ Accurate Phylogeny Reconstruction Algorithms Based on the
+ Minimum-Evolution Principle}, 2002. The tree is built in a way
+ that minimizes the total tree length. The leaves are inserted
+ into the tree one after another, creating new edges and new
+ nodes. After every insertion the distance matrix has to be
+ updated.
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout,
+ balanced minimum evolution,
+ grow'=right, sibling distance=0pt,
+ distance matrix={
+ 0 4 9 9 9 9 9
+ 4 0 9 9 9 9 9
+ 9 9 0 2 7 7 7
+ 9 9 2 0 7 7 7
+ 9 9 7 7 0 3 5
+ 9 9 7 7 3 0 5
+ 9 9 7 7 5 5 0}]
+ { a, b, c, d, e, f, g };
+ "]]
+}
+
+
+
+
+function BalancedMinimumEvolution:run()
+
+ self.tree = Digraph.new(self.main_algorithm.digraph)
+
+ self.distances = Storage.newTableStorage()
+
+ local vertices = self.tree.vertices
+
+ -- Sanity checks:
+ if #vertices == 2 then
+ self.tree:connect(vertices[1],vertices[2])
+ return self.tree
+ elseif #vertices > 2 then
+
+ -- Setup storages:
+ self.is_leaf = Storage.new()
+
+ -- First, build the initial distance matrix:
+ local matrix = DistanceMatrix.graphDistanceMatrix(self.tree)
+
+ -- Store distance information in the distance fields of the storages:
+ for _,u in ipairs(vertices) do
+ for _,v in ipairs(vertices) do
+ self.distances[u][v] = matrix[u][v]
+ end
+ end
+
+ -- Run BME
+ self:runBME()
+
+ -- Run postoptimizations
+ local optimization_class = self.tree.options.algorithm_phases['phylogenetic tree optimization']
+ optimization_class.new {
+ main_algorithm = self.main_algorithm,
+ tree = self.tree,
+ matrix = self.matrix,
+ distances = self.distances,
+ is_leaf = self.is_leaf,
+ }:run()
+ end
+
+ -- Finish
+ self:computeFinalLengths()
+ self:createFinalEdges()
+
+ return self.tree
+end
+
+
+
+
+-- the BME (Balanced Minimum Evolution) algorithm
+-- [DESPER and GASCUEL: Fast and Accurate Phylogeny Reconstruction
+-- Algorithms Based on the Minimum-Evolution Principle, 2002]
+--
+-- The tree is built in a way that minimizes the total tree length.
+-- The leaves are inserted into the tree one after another, creating new edges and new nodes.
+-- After every insertion the distance matrix has to be updated.
+function BalancedMinimumEvolution:runBME()
+ local g = self.tree
+ local leaves = {}
+ local is_leaf = self.is_leaf
+ local distances = self.distances
+
+ -- get user input
+ for i, vertex in ipairs (g.vertices) do
+ leaves[i] = vertex
+ is_leaf[vertex] = true
+ end
+
+ -- create the new node which will be connected to the first three leaves
+ local new_node = InterfaceToAlgorithms.createVertex(
+ self.main_algorithm,
+ {
+ name = "BMEnode"..#g.vertices+1,
+ generated_options = { { key = "phylogenetic inner node" } }
+ }
+ )
+ g:add {new_node}
+ -- set the distances of new_node to subtrees
+ local distance_1_2 = self:distance(leaves[1],leaves[2])
+ local distance_1_3 = self:distance(leaves[1],leaves[3])
+ local distance_2_3 = self:distance(leaves[2],leaves[3])
+ distances[new_node][leaves[1]] = 0.5*(distance_1_2 + distance_1_3)
+ distances[new_node][leaves[2]] = 0.5*(distance_1_2 + distance_2_3)
+ distances[new_node][leaves[3]] = 0.5*(distance_1_3 + distance_2_3)
+
+ --connect the first three leaves to the new node
+ for i = 1,3 do
+ g:connect(new_node, leaves[i])
+ g:connect(leaves[i], new_node)
+ end
+
+ for k = 4,#leaves do
+ -- compute distance from k to any subtree
+ local k_dists = Storage.newTableStorage()
+ for i = 1,k-1 do
+ -- note that the function called stores the k_dists before they are overwritten
+ self:computeAverageDistancesToAllSubtreesForK(g.vertices[i], { }, k,k_dists)
+ end
+
+ -- find the best insertion point
+ local best_arc = self:findBestEdge(g.vertices[1],nil,k_dists)
+ local head = best_arc.head
+ local tail = best_arc.tail
+
+ -- remove the old arc
+ g:disconnect(tail, head)
+ g:disconnect(head, tail)
+
+ -- create the new node
+ local new_node = InterfaceToAlgorithms.createVertex(
+ self.main_algorithm,
+ {
+ name = "BMEnode"..#g.vertices+1,
+ generated_options = {
+ { key = "phylogenetic inner node" }
+ }
+ }
+ )
+ g:add{new_node}
+
+ -- gather the vertices that will be connected to the new node...
+ local vertices_to_connect = { head, tail, leaves[k] }
+
+ -- ...and connect them
+ for _, vertex in pairs (vertices_to_connect) do
+ g:connect(new_node, vertex)
+ g:connect(vertex, new_node)
+ end
+
+ if not is_leaf[tail] then
+ distances[leaves[k]][tail] = k_dists[head][tail]
+ end
+ if not is_leaf[head] then
+ distances[leaves[k]][head] = k_dists[tail][head]
+ end
+ -- insert distances from k to subtrees into actual matrix...
+ self:setAccurateDistancesForK(new_node,nil,k,k_dists,leaves)
+
+ -- set the distance from k to the new node, which was created by inserting k into the graph
+ distances[leaves[k]][new_node] = 0.5*( self:distance(leaves[k], head) + self:distance(leaves[k],tail))
+
+ -- update the average distances
+ local values = {}
+ values.s = head -- s--u is the arc into which k has been inserted
+ values.u = tail
+ values.new_node = new_node -- the new node created by inserting k
+ self:updateAverageDistances(new_node, values,k,leaves)
+ end
+end
+
+--
+-- Updates the average distances from k to all subtrees
+--
+-- @param vertex The starting point of the recursion
+-- @param values The values needed for the recursion
+-- - s, u The nodes which span the edge into which k has been
+-- inserted
+-- - new_node The new_node which has been created to insert k
+-- - l (l-1) is the number of edges between the
+-- new_node and the current subtree Y
+--
+-- values.new_node, values.u and values.s must be set
+-- the depth first search must begin at the new node, thus vertex
+-- must be set to the newly created node
+function BalancedMinimumEvolution:updateAverageDistances(vertex, values, k, leaves)
+ local g = self.tree
+ local leaf_k = leaves[k]
+ local y, z, x
+ if not values.visited then
+ values.visited = {}
+ values.visited[leaf_k] = leaf_k -- we don't want to visit k!
+ end
+ -- there are (l-1) edges between new_node and y
+ if not values.l then values.l = 1 end
+ if not values.new_node then values.new_node = g:outgoing(leaf_k)[1].head end
+ --values.s and values.u must be set
+
+ -- the two nodes which connect the edge on which k was inserted: s,u
+
+ local new_node = values.new_node
+ local l = values.l
+ local visited = values.visited
+
+ visited[vertex] = vertex
+
+ -- computes the distances to Y{k} for all subtrees X of Z
+ function loop_over_x( x, y, values )
+ local l = values.l
+ local y1= values.y1
+
+ -- calculate distance between Y{k} and X
+ local old_distance -- the distance between Y{/k} and X needed for calculating the new distance
+ if y == new_node then -- this y didn't exist in the former tree; so use y1 (see below)
+ old_distance = self:distance(x,y1)
+ else
+ old_distance = self:distance(x,y)
+ end
+
+ local new_distance = old_distance + math.pow(2,-l) * ( self:distance(leaf_k,x) - self:distance(x,y1) )
+ self.distances[x][y] = new_distance
+ self.distances[y][x] = new_distance -- symmetric matrix
+
+ values.x_visited[x] = x
+ --go deeper to next x
+ for _, x_arc in ipairs (self.tree:outgoing(x)) do
+ if not values.x_visited[x_arc.head] then
+ local new_x = x_arc.head
+ loop_over_x( new_x, y, values )
+ end
+ end
+ end
+
+ --loop over Z's
+ for _, arc in ipairs (self.tree:outgoing(vertex)) do
+ if not visited[arc.head] then
+ -- set y1, which is the node which was pushed further away from
+ -- subtree Z by inserting k
+ if arc.head == values.s then
+ values.y1 = values.u
+ elseif arc.head == values.u then
+ values.y1 = values.s
+ else
+ assert(values.y1,"no y1 set!")
+ end
+
+ z = arc.head -- root of the subtree we're looking at
+ y = arc.tail -- the root of the subtree-complement of Z
+
+ x = z -- the first subtree of Z is Z itself
+ values.x_visited = {}
+ values.x_visited[y] = y -- we don't want to go there, as we want to stay within Z
+ loop_over_x( z,y, values ) -- visit all possible subtrees of Z
+
+ -- go to next Z
+ values.l = values.l+1 -- moving further away from the new_node
+ self:updateAverageDistances(z,values,k,leaves)
+ values.l = values.l-1 -- moving back to the new_node
+ end
+ end
+end
+
+
+--
+-- Computes the average distances of a node, which does not yet belong
+-- to the graph, to all subtrees. This is done using a depth first
+-- search
+--
+-- @param vertex The starting point of the depth first search
+-- @param values The values for the recursion
+-- - distances The table in which the distances are to be
+-- stored
+-- - outgoing_arcs The table containing the outgoing arcs
+-- of the current vertex
+--
+-- @return The average distance of the new node #k to any subtree
+-- The distances are stored as follows:
+-- example: distances[center][a]
+-- center is any vertex, thus if center is an inner vertex
+-- it has 3 neighbors a,b and c, which can all be seen as the
+-- roots of subtrees A,B,C.
+-- distances[center][a] gives us the distance of the new
+-- node k to the subtree A.
+-- if center is a leaf, it has only one neighbor, which
+-- can also be seen as the root of the subtree T\{center}
+--
+function BalancedMinimumEvolution:computeAverageDistancesToAllSubtreesForK(vertex, values, k, k_dists)
+ local is_leaf = self.is_leaf
+ local arcs = self.tree.arcs
+ local vertices = self.tree.vertices
+ local center_vertex = vertex
+ -- for every vertex a table is created, in which the distances to all
+ -- its subtrees will be stored
+
+ values.outgoing_arcs = values.outgoing_arcs or self.tree:outgoing(center_vertex)
+ for _, arc in ipairs (values.outgoing_arcs) do
+ local root = arc.head -- this vertex can be seen as the root of a subtree
+ if is_leaf[root] then -- we know the distance of k to the leaf!
+ k_dists[center_vertex][root] = self:distance(vertices[k], root)
+ else -- to compute the distance we need the root's neighboring vertices, which we can access by its outgoing arcs
+ local arc1, arc2
+ local arc_back -- the arc we came from
+ for _, next_arc in ipairs (self.tree:outgoing(root)) do
+ if next_arc.head ~= center_vertex then
+ arc1 = arc1 or next_arc
+ arc2 = next_arc
+ else
+ arc_back = next_arc
+ end
+ end
+
+ values.outgoing_arcs = { arc1, arc2, arc_back }
+
+ -- go deeper, if the distances for the next center node haven't been set yet
+ if not (k_dists[root][arc1.head] and k_dists[root][arc2.head]) then
+ self:computeAverageDistancesToAllSubtreesForK(root, values, k,k_dists)
+ end
+
+ -- set the distance between k and subtree
+ k_dists[center_vertex][root] = 1/2 * (k_dists[root][arc1.head] + k_dists[root][arc2.head])
+ end
+ end
+end
+
+
+--
+-- Sets the distances from k to subtrees
+-- In computeAverageDistancesToAllSubtreesForK the distances to ALL possible
+-- subtrees are computed. Once k is inserted many of those subtrees don't
+-- exist for k, as k is now part of them. In this function all
+-- still accurate subtrees and their distances to k are
+-- extracted.
+--
+-- @param center The vertex serving as the starting point of the depth-first search;
+-- should be the new_node
+
+function BalancedMinimumEvolution:setAccurateDistancesForK(center,visited,k,k_dists,leaves)
+ local visited = visited or {}
+ local distances = self.distances
+
+ visited[center] = center
+ local outgoings = self.tree:outgoing(center)
+ for _,arc in ipairs (outgoings) do
+ local vertex = arc.head
+ if vertex ~= leaves[k] then
+ local distance
+ -- set the distance
+ if not distances[leaves[k]][vertex] and k_dists[center] then
+ distance = k_dists[center][vertex] -- use previously calculated distance
+ distances[leaves[k]][vertex] = distance
+ distances[vertex][leaves[k]] = distance
+ end
+ -- go deeper
+ if not visited[vertex] then
+ self:setAccurateDistancesForK(vertex,visited,k,k_dists,leaves)
+ end
+ end
+ end
+end
+
+
+--
+-- Find the best edge for the insertion of leaf #k, such that the
+-- total tree length is minimized. This function uses a depth first
+-- search.
+--
+-- @param vertex The vertex where the depth first search is
+-- started; must be a leaf
+-- @param values The values needed for the recursion
+-- - visited: The vertices that already have been visited
+-- - tree_length: The current tree_length
+-- - best_arc: The current best_arc, such that the tree
+-- length is minimized
+-- - min_length: The smallest tree_length found so far
+function BalancedMinimumEvolution:findBestEdge(vertex, values, k_dists)
+ local arcs = self.tree.arcs
+ local vertices = self.tree.vertices
+ values = values or { visited = {} }
+ values.visited[vertex] = vertex
+
+ local c -- the arc we came from
+ local unvisited_arcs = {} --unvisited arcs
+ --identify arcs
+ for _, arc in ipairs (self.tree:outgoing(vertex)) do
+ if not values.visited[arc.head] then
+ unvisited_arcs[#unvisited_arcs+1] = arc
+ else
+ c = arc.head --last visited arc
+ end
+ end
+
+ for i, arc in ipairs (unvisited_arcs) do
+ local change_in_tree_length = 0
+ -- set tree length to 0 for first insertion arc
+ if not values.tree_length then
+ values.tree_length = 0
+ values.best_arc = arc
+ values.min_length = 0
+ else -- compute new tree length for the case that k is inserted into this arc
+ local b = arc.head --current arc
+ local a = unvisited_arcs[i%2+1].head -- the remaining arc
+ local k_v = vertices[k] -- the leaf to be inserted
+ change_in_tree_length = 1/4 * ( ( self:distance(a,c)
+ + k_dists[vertex][b])
+ - (self:distance(a,b)
+ + k_dists[vertex][c]) )
+ values.tree_length = values.tree_length + change_in_tree_length
+ end
+ -- if the tree length becomes shorter, this is the new best arc
+ -- for the insertion of leaf k
+ if values.tree_length < values.min_length then
+ values.best_arc = arc
+ values.min_length = values.tree_length
+ end
+
+ -- go deeper
+ self:findBestEdge(arc.head, values, k_dists)
+
+ values.tree_length = values.tree_length - change_in_tree_length
+ end
+ return values.best_arc
+end
+
+-- Calculates the total tree length
+-- This is done by adding up all the edge lengths
+--
+-- @return the tree length
+function BalancedMinimumEvolution:calculateTreeLength()
+ local vertices = self.tree.vertices
+ local sum = 0
+
+ for index, v1 in ipairs(vertices) do
+ for i = index+1,#vertices do
+ local v2 = vertices[i]
+ local dist = self.lengths[v1][v2]
+ if dist then
+ sum = sum + dist
+ end
+ end
+ end
+ return sum
+end
+
+-- generates edges for the final graph
+--
+-- throughout the process of creating the tree, arcs have been
+-- disconnected and connected, without truly creating edges. this is
+-- done in this function
+function BalancedMinimumEvolution:createFinalEdges()
+ local g = self.tree
+ local o_arcs = {} -- copy arcs since createEdge is going to modify the arcs array...
+ for _,arc in ipairs(g.arcs) do
+ if arc.tail.event.index < arc.head.event.index then
+ o_arcs[#o_arcs+1] = arc
+ end
+ end
+ for _,arc in ipairs(o_arcs) do
+ InterfaceToAlgorithms.createEdge(
+ self.main_algorithm, arc.tail, arc.head,
+ { generated_options = {
+ { key = "phylogenetic edge", value = tostring(self.lengths[arc.tail][arc.head]) }
+ }})
+ end
+end
+
+
+-- Gets the distance between two nodes as specified in their options
+-- or storage fields.
+-- Note: this function implies that the distance from a to b is the
+-- same as the distance from b to a.
+--
+-- @param a,b The nodes
+-- @return The distance between the two nodes
+
+function BalancedMinimumEvolution:distance(a, b)
+ if a == b then
+ return 0
+ else
+ local distances = self.distances
+ return distances[a][b] or distances[b][a]
+ end
+end
+
+
+--
+-- computes the final branch lengths
+--
+-- goes over all arcs and computes the final branch lengths,
+-- as neither the BME nor the BNNI main_algorithm does so.
+function BalancedMinimumEvolution:computeFinalLengths()
+ local is_leaf = self.is_leaf
+ local lengths = self.lengths
+ local g = self.tree
+ for _, arc in ipairs(g.arcs) do
+ local head = arc.head
+ local tail = arc.tail
+ local distance
+ local a,b,c,d
+ -- assert, that the length hasn't already been computed for this arc
+ if not lengths[head][tail] then
+ if not is_leaf[head] then
+ -- define subtrees a and b
+ for _, arc in ipairs (g:outgoing(head)) do
+ local subtree = arc.head
+ if subtree ~= tail then
+ a = a or subtree
+ b = subtree
+ end
+ end
+ end
+ if not is_leaf[tail] then
+ -- define subtrees c and d
+ for _, arc in ipairs (g:outgoing(tail)) do
+ local subtree = arc.head
+ if subtree ~= head then
+ c = c or subtree
+ d = subtree
+ end
+ end
+ end
+ -- compute the distance using the formula for outer or inner edges, respectively
+ if is_leaf[head] then
+ distance = 1/2 * ( self:distance(head,c)
+ + self:distance(head,d)
+ - self:distance(c,d) )
+ elseif is_leaf[tail] then
+ distance = 1/2 * ( self:distance(tail,a)
+ + self:distance(tail,b)
+ - self:distance(a,b) )
+ else --inner edge
+ distance = self:distance(head, tail)
+ -1/2 * ( self:distance(a,b)
+ + self:distance(c,d) )
+ end
+ lengths[head][tail] = distance
+ lengths[tail][head] = distance
+ end
+ end
+
+end
+
+
+
+return BalancedMinimumEvolution
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua
new file mode 100644
index 0000000000..1980afe7ad
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua
@@ -0,0 +1,372 @@
+-- Copyright 2013 by Sarah Mäusle and Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+local BalancedNearestNeighbourInterchange = {}
+
+
+-- Namespace
+require("pgf.gd.phylogenetics").BalancedNearestNeighbourInterchange = BalancedNearestNeighbourInterchange
+
+-- Imports
+local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms")
+local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix")
+local lib = require("pgf.gd.lib")
+
+-- Shorthand:
+local declare = InterfaceToAlgorithms.declare
+
+
+---
+declare {
+ key = "balanced nearest neighbour interchange",
+ algorithm = BalancedNearestNeighbourInterchange,
+ phase = "phylogenetic tree optimization",
+ phase_default = true,
+
+ summary = [["
+ The BNNI (Balanced Nearest Neighbor Interchange) is a
+ postprocessing algorithm for phylogenetic trees. It swaps two
+ distant 3-subtrees if the total tree length is reduced by doing
+ so, until no such swaps are left.
+ "]],
+ documentation = [["
+ This algorithm is from Desper and Gascuel, \emph{Fast and
+ Accurate Phylogeny Reconstruction Algorithms Based on the
+ Minimum-Evolution Principle}, 2002.
+ "]]
+}
+
+
+---
+declare {
+ key = "no phylogenetic tree optimization",
+ algorithm = { run = function(self) end },
+ phase = "phylogenetic tree optimization",
+
+ summary = [["
+ Switches off any phylogenetic tree optimization.
+ "]],
+}
+
+
+
+-- creates a binary heap, implementation as an array as described in
+-- the respective wikipedia article
+local function new_heap()
+ local heap = {}
+
+ function heap:insert(element, value)
+ local object = { element = element, value = value }
+ heap[#heap+1]= object
+
+ local i = #heap
+ local parent = math.floor(i/2)
+
+ -- sort the new object into its correct place
+ while heap[parent] and heap[parent].value < heap[i].value do
+ heap[i] = heap[parent]
+ heap[parent] = object
+ i = parent
+ parent = math.floor(i/2)
+ end
+ end
+
+ -- deletes the top element from the heap
+ function heap:remove_top_element()
+ -- replace first element with last and delete the last element
+ local element = heap[1].element
+ heap[1] = heap[#heap]
+ heap[#heap] = nil
+
+ local i = 1
+ local left_child = 2*i
+ local right_child = 2*i +1
+
+ -- sort the new top element into its correct place by swapping it
+ -- against its largest child
+ while heap[left_child] do
+ local largest_child = left_child
+ if heap[right_child] and heap[left_child].value < heap[right_child].value then
+ largest_child = right_child
+ end
+
+ if heap[largest_child].value > heap[i].value then
+ heap[largest_child], heap[i] = heap[i], heap[largest_child]
+ i = largest_child
+ left_child = 2*i
+ right_child = 2*i +1
+ else
+ return element
+ end
+ end
+ return element
+ end
+
+ return heap
+end
+
+
+-- BNNI (Balanced Nearest Neighbor Interchange)
+-- [DESPER and GASCUEL: Fast and Accurate Phylogeny Reconstruction Algorithms Based on the Minimum-Evolution Principle, 2002]
+-- swaps two distant-3 subtrees if the total tree length is reduced by doing so, until no such swaps are left
+--
+-- step 1: precomputation of all average distances between non-intersecting subtrees (already done by BME)
+-- step 2: create heap of possible swaps
+-- step 3: ( current tree with subtrees a,b,c,d: a--v-- {b, w -- {c, d}} )
+-- (a): edge (v,w) is the best swap on the heap. Remove (v,c) and (w,b)
+-- (b), (c), (d) : update the distance matrix
+-- (e): remove the edge (v,w) from the heap; check the four edges adjacent to it for new possible swaps
+-- (d): if the heap is non-empty, return to (a)
+
+function BalancedNearestNeighbourInterchange:run()
+ local g = self.tree
+ -- create a heap of possible swaps
+ local possible_swaps = new_heap()
+ -- go over all arcs, look for possible swaps and add them to the heap [step 2]
+ for _, arc in ipairs (g.arcs) do
+ self:getBestSwap(arc, possible_swaps)
+ end
+
+ -- achieve best swap and update the distance matrix, until there is
+ -- no more swap to perform
+
+ while #possible_swaps > 0 do
+ -- get the best swap and delete it from the heap
+ local swap = possible_swaps:remove_top_element() --[part of step 3 (a)]
+
+ -- Check if the indicated swap is still possible. Another swap may
+ -- have interfered.
+ if g:arc(swap.v, swap.subtree1) and g:arc(swap.w, swap.subtree2) and g:arc(swap.v, swap.w) and g:arc(swap.a, swap.v) and g:arc(swap.d, swap.w) then
+ -- insert new arcs and delete the old ones to perform the swap [part of step 3 (a)]
+
+ -- disconnect old arcs
+ g:disconnect(swap.v, swap.subtree1)
+ g:disconnect(swap.subtree1, swap.v)
+ g:disconnect(swap.w, swap.subtree2)
+ g:disconnect(swap.subtree2, swap.w)
+
+ -- connect new arcs
+ g:connect(swap.v, swap.subtree2)
+ g:connect(swap.subtree2, swap.v)
+ g:connect(swap.w, swap.subtree1)
+ g:connect(swap.subtree1, swap.w)
+
+ --update distance matrix
+ self:updateBNNI(swap)
+
+ -- update heap: check neighboring arcs for new possible swaps
+ -- [step 3 (e)]
+ self:getBestSwap(g:arc(swap.a,swap.v), possible_swaps)
+ self:getBestSwap(g:arc(swap.subtree2, swap.v), possible_swaps)
+ self:getBestSwap(g:arc(swap.d,swap.w), possible_swaps)
+ self:getBestSwap(g:arc(swap.subtree1, swap.w), possible_swaps)
+ end
+ end
+
+end
+
+
+--
+-- Gets the distance between two nodes as specified in the distances
+-- fields. Note: this function assumes that the distance from a to b
+-- is the
+-- same as the distance from b to a.
+--
+-- @param a,b The nodes
+-- @return The distance between the two nodes
+function BalancedNearestNeighbourInterchange:distance(a, b)
+ if a == b then
+ return 0
+ else
+ local distances = self.distances
+ return distances[a][b] or distances[b][a]
+ end
+end
+
+-- updates the distance matrix after a swap has been performed [step3(b),(c),(d)]
+--
+-- @param swap A table containing the information on the performed swap
+-- subtree1, subtree2: the two subtrees, which
+-- were swapped
+-- a, d: The other two subtrees bordering the
+-- swapping edge
+-- v, w : the two nodes connecting the swapping edge
+
+function BalancedNearestNeighbourInterchange:updateBNNI(swap)
+ local g = self.tree
+ local b = swap.subtree1
+ local c = swap.subtree2
+ local a = swap.a
+ local d = swap.d
+ local v = swap.v
+ local w = swap.w
+ local distances = self.distances
+
+ -- updates the distances in one of the four subtrees adjacent to the
+ -- swapping edge
+ function update_BNNI_subtree(swap, values)
+ local g = self.tree
+ local b = swap.farther
+ local c = swap.nearer
+ local a = swap.subtree
+ local v = swap.v
+ local d = swap.same
+ local w = swap.w
+
+ if not values then
+ values = {
+ visited = {[v] = v},
+ possible_ys = {v},
+ x = a,
+ y = v
+ }
+ -- if we're looking at subtrees in one of the swapped subtrees,
+ -- then need the old root (w) for the calculations
+ if swap.swapped_branch then values.possible_ys = {w} end
+ end
+ local visited = values.visited
+ local x = values.x
+ local y = values.y
+ local ys = values.possible_ys
+ local l = 0 -- number of edges between y and v
+
+ local dist_x_b = self:distance(x,b)
+ local dist_x_c = self:distance(x,c)
+ visited[x] = x --mark current x as visited
+
+ -- loop over possible y's:
+ for _, y in ipairs (ys) do
+ -- update distance [step 3(b)]
+ local distance = self:distance(x,y) - 2^(-l-2)*dist_x_b + 2^(-l-2)*dist_x_c
+
+ if y == w then y = v end -- the old distance w,x was used for the new distance calculation, but it needs to be
+ -- saved under its appropriate new name according to its new root. this case only arises when looking at x's
+ -- in one of the swapped subtrees (b or c)
+
+ distances[x][y] = distance
+ distances[y][x] = distance
+ l = l+1 -- length + 1, as the next y will be further away from v
+ end
+
+ -- update the distance between x and w (root of subtree c and d)
+ -- [step 3(c)]
+ local distance = 1/2 * (self:distance(x,b) + self:distance(x,d))
+ distances[x][w] = distance
+ distances[w][x] = distance
+
+ -- go to next possible x's
+ table.insert(ys, x) -- when we're at the next possible x, y can also be the current x
+ for _,arc in ipairs (g:outgoing(x)) do
+ if not visited[arc.head] then
+ values.x = arc.head
+ --go deeper
+ update_BNNI_subtree(swap, values)
+ end
+ end
+ end
+
+ -- name the nodes/subtrees in a general way that allows the use of the function update_BNNI_subtree
+ local update_a = {subtree = a, farther = b, nearer = c, v = v, same = d, w = w}
+ local update_b = {subtree = b, farther = a, nearer = d, v = w, same = c, w = v, swapped_branch = true}
+ local update_c = {subtree = c, farther = d, nearer = a, v = v, same = b, w = w, swapped_branch = true}
+ local update_d = {subtree = d, farther = c, nearer = b, v = w, same = a, w = v}
+
+ -- update the distances within the subtrees a,b,c,d respectively
+ update_BNNI_subtree(update_a)
+ update_BNNI_subtree(update_b)
+ update_BNNI_subtree(update_c)
+ update_BNNI_subtree(update_d)
+
+ -- update the distance between subtrees v and w [step 3 (d)]:
+ local distance = 1/4*( self:distance(a,b) + self:distance(a,d) + self:distance(c,b) + self:distance(c,d) )
+ distances[v][w] = distance
+ distances[w][v] = distance
+end
+
+
+
+-- finds the best swap across an arc and inserts it into the heap of
+-- possible swaps
+--
+-- @param arc The arc, which is to be checked for possible swaps
+-- @param heap_of_swaps The heap, containing all swaps, which
+-- improve the total tree length
+--
+-- the following data of the swap are saved:
+-- v,w = the nodes connecting the arc, across which the swap is
+-- performed
+-- subtree1,2 = the roots of the subtrees that are to be swapped
+-- a,d = the roots of the two remaining subtrees adjacent to the arc
+
+function BalancedNearestNeighbourInterchange:getBestSwap(arc, heap_of_swaps)
+ local g = self.tree
+ local possible_swaps = heap_of_swaps
+ local v = arc.tail
+ local w = arc.head
+ local is_leaf = self.is_leaf
+
+ -- only look at inner edges:
+ if not is_leaf[v] and not is_leaf[w] then
+ -- get the roots of the adjacent subtrees
+ local a, b, c, d
+ for _,outgoing in ipairs (g:outgoing(v)) do
+ local head = outgoing.head
+ if head ~= w then
+ a = a or head
+ b = head
+ end
+ end
+
+ for _,outgoing in ipairs (g:outgoing(w)) do
+ local head = outgoing.head
+ if head ~= v then
+ c = c or head
+ d = head
+ end
+ end
+
+ -- get the distances between the four subtrees
+ local a_b = self:distance(a,b)
+ local a_c = self:distance(a,c)
+ local a_d = self:distance(a,d)
+ local b_c = self:distance(b,c)
+ local b_d = self:distance(b,d)
+ local c_d = self:distance(c,d)
+
+ -- difference in total tree length between old tree (T) and new tree (T')
+ -- when nodes b and c are swapped
+ local swap1 = 1/4*(a_b + c_d - a_c - b_d )
+
+ -- difference in total tree length between old tree and new tree when nodes b and d are swapped
+ local swap2 = 1/4*(a_b + c_d - a_d - b_c)
+
+ -- choose the best swap that reduces the total tree length most (T-T' > 0)
+ if swap1 > swap2 and swap1 > 0 then
+ -- v,w = the nodes connecting the edge across which the swap is performed
+ -- subtree1 = one of the nodes to be swapped; connected to v
+ -- subtree2 = the other node to be swapped; connected to w
+ -- a = other node connected to v
+ -- d = other node connected to w
+ local swap = { v = v, w = w, subtree1 = b, subtree2 = c, a = a, d = d }
+ -- insert the swap into the heap
+ possible_swaps:insert(swap, swap1)
+ elseif swap2 > 0 then
+ local swap = { v = v, w = w, subtree1 = b, subtree2 = d, d = c, a = a }
+ possible_swaps:insert(swap, swap2)
+ end
+ end
+end
+
+
+
+return BalancedNearestNeighbourInterchange
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua
new file mode 100644
index 0000000000..a65a83da17
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua
@@ -0,0 +1,451 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+local DistanceMatrix = {}
+
+
+-- Imports
+local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms")
+local declare = InterfaceToAlgorithms.declare
+
+
+---
+
+declare {
+ key = "distance matrix vertices",
+ type = "string",
+
+ summary = [["
+ A list of vertices that are used in the parsing of the
+ |distance matrix| key. If this key is not used at all, all
+ vertices of the graph will be used for the computation of a
+ distance matrix.
+ "]],
+
+ documentation = [["
+ The vertices must be separated by spaces and/or
+ commas. For vertices containing spaces or commas, the vertex
+ names may be surrounded by single or double quotes (as in
+ Lua). Typical examples are |a, b, c| or |"hello world", 'foo'|.
+ "]]
+}
+
+
+
+---
+
+declare {
+ key = "distance matrix",
+ type = "string",
+
+ summary = [["
+ A distance matrix specifies ``desired distances'' between
+ vertices in a graph. These distances are used, in particular, in
+ algorithms for computing phylogenetic trees.
+ "]],
+
+ documentation = [["
+ When this key is parsed, the key |distance matrix vertices| is
+ considered first. It is used to determine a list of vertices
+ for which a distance matrix is computed, see that key for
+ details. Let $n$ be the number of vertices derived from that
+ key.
+
+ The string passed to the |distance matrix| key is basically
+ a sequence of numbers that are used to fill an $n \times n$
+ matrix. This works as follows: We keep track of a \emph{current
+ position $p$} in the matrix, starting at the upper left corner
+ of the matrix. We read the numbers in the string
+ one by one, write it to the current position of the matrix, and
+ advance the current position by going right one step; if we go
+ past the right end of the matrix, we ``wrap around'' by going
+ back to the left border of the matrix, but one line down. If we
+ go past the bottom of the matrix, we start at the beginning once
+ more.
+
+ This basic behavior can be modified in different ways. First,
+ when a number is followed by a semicolon instead of a comma or a
+ space (which are the ``usual'' ways of indicating the end of a
+ number), we immediately go down to the next line. Second,
+ instead of a number you can directly provide a \emph{position}
+ in the matrix and the current position will be set to this
+ position. Such a position information is detected by a
+ greater-than sign (|>|). It must be followed by
+ %
+ \begin{itemize}
+ \item a number or a vertex name or
+ \item a number or a vertex name, a comma, and another number or
+ vertex name or
+ \item a comma and a number and a vertex name.
+ \end{itemize}
+ %
+ Examples of the respective cases are |>1|, |>a,b|, and
+ |>,5|. The semantics is as follows: In all cases, if a vertex
+ name rather than a number is given, it is converted into a
+ number (namely the index of the vertex inside the matrix). Then,
+ in the first case, the column of the current position is set to
+ the given number; in the second case, the columns is set to the
+ first number and the column is set to the second number; and in
+ the third case only the row is set to the given number. (This
+ idea is that following the |>|-sign comes a ``coordinate pair''
+ whose components are separated by a comma, but part of that pair
+ may be missing.) If a vertex name contains special symbols like
+ a space or a comma, you must surround it by single or double
+ quotation marks (as in Lua).
+
+ Once the string has been parsed completely, the matrix may be
+ filled only partially. In this case, for each missing entry
+ $(x,y)$, we try to set it to the value of the entry $(y,x)$,
+ provided that entry is set. If neither are set, the entry is set
+ to $0$.
+
+ Let us now have a look at several examples that all produce the
+ same matrix. The vertices are |a|, |b|, |c|.
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+0, 1, 2
+1, 0, 3
+2, 3, 0
+\end{codeexample}
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+0 1 2 1 0 3 2 3 0
+\end{codeexample}
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+;
+1;
+2 3
+\end{codeexample}
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+>,b 1; 2 3
+\end{codeexample}
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+>b 1 2 >c 3
+\end{codeexample}
+ "]]
+}
+
+
+---
+
+declare {
+ key = "distances",
+ type = "string",
+
+ summary = [["
+ This key is used to specify the ``desired distances'' between
+ a vertex and the other vertices in a graph.
+ "]],
+
+ documentation = [["
+ This key works similar to the |distance matrix| key, only it is
+ passed to a vertex instead of to a whole graph. The syntax is
+ the same, only the notion of different ``rows'' is not
+ used. Here are some examples that all have the same effect,
+ provided the nodes are |a|, |b|, and |c|.
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+0, 1, 2
+\end{codeexample}
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+0 1 2
+\end{codeexample}
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+>b 1 2
+\end{codeexample}
+ %
+\begin{codeexample}[code only, tikz syntax=false]
+>c 2, >b 1
+\end{codeexample}
+ "]]
+}
+
+
+
+local function to_index(s, indices)
+ if s and s ~= "" then
+ if s:sub(1,1) == '"' then
+ local _, _, m = s:find('"(.*)"')
+ return indices[InterfaceToAlgorithms.findVertexByName(m)]
+ elseif s:sub(1,1) == "'" then
+ local _, _, m = s:find("'(.*)'")
+ return indices[InterfaceToAlgorithms.findVertexByName(m)]
+ else
+ local num = tonumber(s)
+ if not num then
+ return indices[InterfaceToAlgorithms.findVertexByName(s)]
+ else
+ return num
+ end
+ end
+ end
+end
+
+local function compute_indices(vertex_string, vertices)
+ local indices = {}
+
+ if not vertex_string then
+ for i,v in ipairs(vertices) do
+ indices[i] = v
+ indices[v] = i
+ end
+ else
+ -- Ok, need to parse the vertex_string. Sigh.
+ local pos = 1
+ while pos <= #vertex_string do
+ local start = vertex_string:sub(pos,pos)
+ if not start:find("[%s,]") then
+ local _, vertex
+ if start == '"' then
+ _, pos, vertex = vertex_string:find('"(.-)"', pos)
+ elseif start == "'" then
+ _, pos, vertex = vertex_string:find("'(.-)'", pos)
+ else
+ _, pos, vertex = vertex_string:find("([^,%s'\"]*)", pos)
+ end
+ local v = assert(InterfaceToAlgorithms.findVertexByName(vertex), "unknown vertex name '" .. vertex .. "'")
+ indices [#indices + 1] = v
+ indices [v] = #indices
+ end
+ pos = pos + 1
+ end
+ end
+
+ return indices
+end
+
+
+---
+-- Compute a distance matrix based on the values of a
+-- |distance matrix| and a |distance matrix vertices|.
+--
+-- @param matrix_string A distance matrix string
+-- @param vertex_string A distance matrix vertex string
+-- @param vertices An array of all vertices in the graph.
+--
+-- @return A distance matrix. This matrix will contain both a
+-- two-dimensional array (accessed through numbers) and also a
+-- two-dimensional hash table (accessed through vertex indices). Thus,
+-- you can write both |m[1][1]| and also |m[v][v]| to access the first
+-- entry of this matrix, provided |v == vertices[1]|.
+-- @return An index vector. This is an array of the vertices
+-- identified for the |vertex_string| parameter.
+
+function DistanceMatrix.computeDistanceMatrix(matrix_string, vertex_string, vertices)
+ -- First, we create a table of the vertices we need to consider:
+ local indices = compute_indices(vertex_string, vertices)
+
+ -- Second, build matrix.
+ local n = #indices
+ local m = {}
+ for i=1,n do
+ m[i] = {}
+ end
+
+ local x = 1
+ local y = 1
+ local pos = 1
+ -- Start scanning the matrix_string
+ while pos <= #matrix_string do
+ local start = matrix_string:sub(pos,pos)
+ if not start:find("[%s,]") then
+ if start == '>' then
+ local _, parse
+ _, pos, parse = matrix_string:find(">([^%s>;]*)", pos)
+ local a, b
+ if parse:find(",") then
+ _,_,a,b = parse:find("(.*),(.*)")
+ else
+ a = parse
+ end
+ x = to_index(a, indices) or x
+ y = to_index(b, indices) or y
+ elseif start == ';' then
+ x = 1
+ y = y + 1
+ elseif start == ',' then
+ x = x + 1
+ else
+ local _, n
+ _, pos, n = matrix_string:find("([^,;%s>]*)", pos)
+ local num = assert(tonumber(n), "number expected in distance matrix")
+ m[x][y] = num
+ x = x + 1
+ -- Skip everything up to first comma:
+ _, pos = matrix_string:find("(%s*,?)", pos+1)
+ end
+ end
+ pos = pos + 1
+ if x > n then
+ x = 1
+ y = y + 1
+ end
+ if y > n then
+ y = 1
+ end
+ end
+
+ -- Fill up
+ for x=1,n do
+ for y=1,n do
+ if not m[x][y] then
+ m[x][y] = m[y][x] or 0
+ end
+ end
+ end
+
+ -- Copy to index version
+ for x=1,n do
+ local v = indices[x]
+ m[v] = {}
+ for y=1,n do
+ local u = indices[y]
+ m[v][u] = m[x][y]
+ end
+ end
+
+ return m, indices
+end
+
+
+
+
+---
+-- Compute a distance vector. See the key |distances| for details.
+--
+-- @param vector_string A distance vector string
+-- @param vertex_string A distance matrix vertex string
+-- @param vertices An array of all vertices in the graph.
+--
+-- @return A distance vector. Like a distance matrix, this vector will
+-- double indexed, once by numbers and once be vertex objects.
+-- @return An index vector. This is an array of the vertices
+-- identified for the |vertex_string| parameter.
+
+function DistanceMatrix.computeDistanceVector(vector_string, vertex_string, vertices)
+ -- First, we create a table of the vertices we need to consider:
+ local indices = compute_indices(vertex_string, vertices)
+
+ -- Second, build matrix.
+ local n = #indices
+ local m = {}
+ local x = 1
+ local pos = 1
+ -- Start scanning the vector_string
+ while pos <= #vector_string do
+ local start = vector_string:sub(pos,pos)
+ if not start:find("[%s,]") then
+ if start == '>' then
+ local _, parse
+ _, pos, parse = vector_string:find(">([^%s>;]*)", pos)
+ x = to_index(parse, indices) or x
+ elseif start == ',' then
+ x = x + 1
+ else
+ local _, n
+ _, pos, n = vector_string:find("([^,;%s>]*)", pos)
+ local num = assert(tonumber(n), "number expected in distance matrix")
+ m[x] = num
+ x = x + 1
+ -- Skip everything up to first comma:
+ _, pos = vector_string:find("(%s*,?)", pos+1)
+ end
+ end
+ pos = pos + 1
+ if x > n then
+ x = 1
+ end
+ end
+
+ -- Fill up
+ for x=1,n do
+ m[x] = m[x] or 0
+ m[indices[x]] = m[x]
+ end
+
+ return m, indices
+end
+
+
+
+---
+-- Compute a distance matrix for a graph that incorporates all
+-- information stored in the different options of the graph and the
+-- vertices.
+--
+-- @param graph A digraph object.
+--
+-- @return A distance matrix for all vertices of the graph.
+
+function DistanceMatrix.graphDistanceMatrix(digraph)
+ local vertices = digraph.vertices
+ local n = #vertices
+ local m = {}
+ for i,v in ipairs(vertices) do
+ m[i] = {}
+ m[v] = {}
+ end
+
+ local indices = {}
+ for i,v in ipairs(vertices) do
+ indices[i] = v
+ indices[v] = i
+ end
+
+ if digraph.options['distance matrix'] then
+ local sub, vers = DistanceMatrix.computeDistanceMatrix(
+ digraph.options['distance matrix'],
+ digraph.options['distance matrix vertices'],
+ vertices
+ )
+
+ for x=1,#vers do
+ for y=1,#vers do
+ m[vers[x]][vers[y]] = sub[x][y]
+ end
+ end
+ end
+
+ for i,v in ipairs(vertices) do
+ if v.options['distances'] then
+ local sub, vers = DistanceMatrix.computeDistanceVector(
+ v.options['distances'],
+ v.options['distance matrix vertices'],
+ vertices
+ )
+
+ for x=1,#vers do
+ m[vers[x]][v] = sub[x]
+ end
+ end
+ end
+
+ -- Fill up number versions:
+ for x,vx in ipairs(vertices) do
+ for y,vy in ipairs(vertices) do
+ m[x][y] = m[vx][vy]
+ end
+ end
+
+ return m
+end
+
+
+
+return DistanceMatrix
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua
new file mode 100644
index 0000000000..a9acc48865
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua
@@ -0,0 +1,778 @@
+-- Copyright 2013 by Sarah Mäusle and Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local Digraph = require 'pgf.gd.model.Digraph'
+local Coordinate = require 'pgf.gd.model.Coordinate'
+local Path = require 'pgf.gd.model.Path'
+
+local layered = require 'pgf.gd.layered'
+
+local lib = require 'pgf.gd.lib'
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+-- Main class of this file:
+
+local Maeusle2012 = lib.class {}
+
+-- Namespace
+require("pgf.gd.phylogenetics").Maeusle2012 = Maeusle2012
+
+
+
+
+---
+declare {
+ key = "rooted rectangular phylogram",
+ algorithm = {
+ base_class = Maeusle2012,
+ run = function (self)
+ local root = self:getRoot()
+ self:setPosForRectangularLayout(root)
+ end
+ },
+ phase = "phylogenetic tree layout",
+ phase_default = true,
+
+ summary = [["
+ A rooted rectangular phylogram is...
+ "]],
+ documentation = [["
+ ...
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout,
+ rooted rectangular phylogram,
+ balanced minimum evolution,
+ distance matrix={
+ 0 4 9 9 9 9 9
+ 4 0 9 9 9 9 9
+ 9 9 0 2 7 7 7
+ 9 9 2 0 7 7 7
+ 9 9 7 7 0 3 5
+ 9 9 7 7 3 0 5
+ 9 9 7 7 5 5 0}]
+ { a, b, c, d, e, f, g };
+ "]]
+}
+
+---
+declare {
+ key = "rectangular phylogram",
+ use = { { key = "rooted rectangular phylogram" } },
+ summary = "An alias for |rooted rectangular phylogram|"
+}
+
+---
+declare {
+ key = "rooted straight phylogram",
+ algorithm = {
+ base_class = Maeusle2012,
+ run = function (self)
+ local root = self:getRoot()
+ self:setXPos(root)
+ self:setYPosForStraightLayout(root)
+ end
+ },
+ phase = "phylogenetic tree layout",
+
+ summary = [["
+ A rooted straight phylogram is...
+ "]],
+ documentation = [["
+ ...
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout,
+ rooted straight phylogram,
+ balanced minimum evolution, grow=right,
+ distance matrix={
+ 0 4 9 9 9 9 9
+ 4 0 9 9 9 9 9
+ 9 9 0 2 7 7 7
+ 9 9 2 0 7 7 7
+ 9 9 7 7 0 3 5
+ 9 9 7 7 3 0 5
+ 9 9 7 7 5 5 0}]
+ { a, b, c, d, e, f, g };
+ "]]}
+
+---
+declare {
+ key = "straight phylogram",
+ use = { { key = "rooted straight phylogram" } },
+ summary = "An alias for |rooted straight phylogram|"
+}
+
+---
+declare {
+ key = "unrooted rectangular phylogram",
+ algorithm = {
+ base_class = Maeusle2012,
+ run = function (self)
+ local root1, root2 = self:getRoot()
+ self:setPosForUnrootedRectangular(root2, root1)
+ end
+ },
+ phase = "phylogenetic tree layout",
+
+ summary = [["
+ A unrooted rectangular phylogram is...
+ "]],
+ documentation = [["
+ ...
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout,
+ unrooted rectangular phylogram,
+ balanced minimum evolution, grow=right,
+ distance matrix={
+ 0 4 9 9 9 9 9
+ 4 0 9 9 9 9 9
+ 9 9 0 2 7 7 7
+ 9 9 2 0 7 7 7
+ 9 9 7 7 0 3 5
+ 9 9 7 7 3 0 5
+ 9 9 7 7 5 5 0}]
+ { a, b, c, d, e, f, g };
+ "]]
+}
+
+---
+declare {
+ key = "unrooted straight phylogram",
+ algorithm = {
+ base_class = Maeusle2012,
+ run = function (self)
+ local root1, root2 = self:getRoot()
+ self:setPosForUnrootedStraight(root2, root1)
+ end
+ },
+ phase = "phylogenetic tree layout",
+
+ summary = [["
+ A unrooted straight phylogram is...
+ "]],
+ documentation = [["
+ ...
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout,
+ unrooted straight phylogram,
+ balanced minimum evolution, grow=right,
+ distance matrix={
+ 0 4 9 9 9 9 9
+ 4 0 9 9 9 9 9
+ 9 9 0 2 7 7 7
+ 9 9 2 0 7 7 7
+ 9 9 7 7 0 3 5
+ 9 9 7 7 3 0 5
+ 9 9 7 7 5 5 0}]
+ { a, b, c, d, e, f, g };
+ "]]
+}
+
+
+---
+declare {
+ key = "evolutionary unit length",
+ type = "length",
+ initial = "1cm",
+
+ summary = [["
+ Specifies how long a ``unit'' of evolutionary time should be on
+ paper. For instance, if two nodes in a phylogenetic tree have an
+ evolutionary distance of 3 and this length is set to |1cm|, then
+ they will be |3cm| apart in a straight-line phylogram.
+ "]],
+ documentation = [["
+ (This key used to be called |distance scaling factor|.)
+ "]],
+}
+
+
+
+--
+-- Gets the edge length between two nodes
+--
+-- @param vertex1, vertex2 The two nodes
+--
+-- @return The length of the edge between the two nodes
+function Maeusle2012:edgeLength(vertex1, vertex2)
+ return self.lengths[vertex1][vertex2]
+end
+
+
+-- Sets the x and y coordinates for all nodes, using a depth first
+-- search
+--
+-- @param vertex The starting point; should usually be the root
+-- @param values Values needed for the recursion
+-- @param vertex2 A node that will not be visited; this parameter should only be set
+-- for an unrooted layout to ensure that only the half of the tree is set.
+function Maeusle2012:setPosForRectangularLayout(vertex, values, vertex2)
+ local arcs = self.tree.arcs
+ local vertices = self.tree.vertices
+ local adjusted_bb = self.main_algorithm.adjusted_bb
+
+ values = values or {
+ length = 0, -- current path length
+ visited = {}, -- all nodes that have already been visited
+ leaves = {}, -- all leaves from left to right
+ }
+
+ local vertex_is_leaf = true
+ values.visited[vertex] = true
+
+ local children = {} -- a table containing all children of the
+ -- current vertex (for the later determination of inner vertices
+ -- x-positions)
+
+
+ for _, arc in ipairs (self.tree:outgoing(vertex)) do
+ if not values.visited[arc.head] and arc.head ~= vertex2 then
+ -- if arc.head hasn't been visited, the current vertex cannot be a leaf
+ vertex_is_leaf = false
+ local arc_length = self:edgeLength(vertex, arc.head)
+
+ values.length = values.length + arc_length
+
+ -- go deeper
+ self:setPosForRectangularLayout(arc.head, values, vertex2)
+
+ -- get the children of the current vertex
+ children[#children+1] = arc.head
+
+ values.length = values.length - arc_length
+ end
+ end
+
+ if vertex_is_leaf then
+ -- subtract layer_pre, thus the leaf itself is NOT part of the
+ -- edge length
+ vertex.pos.y = - adjusted_bb[vertex].layer_pre
+
+ values.leaves[#values.leaves+1] = vertex
+
+ -- x coordinate:
+ -- the x coordinates of the leaves are the first to be set; the
+ -- first leave stays at x = 0, the x coordinates for the other
+ -- leaves is computed with help of the ideal_sibling_distance
+ -- function
+ if #values.leaves > 1 then
+ local left_sibling = values.leaves[#values.leaves-1]
+ local ideal_distance = layered.ideal_sibling_distance(adjusted_bb, self.tree, vertex, left_sibling )
+ vertex.pos.x = left_sibling.pos.x + ideal_distance
+ end
+
+ else -- the vertex is an inner node
+ -- the x position of an inner vertex is at the center of its children.
+
+ -- determine the outer children
+ local left_child = children[1]
+ local right_child = left_child
+ for _, child in ipairs(children) do
+ if child.pos.x < left_child.pos.x then left_child = child end
+ if child.pos.x > right_child.pos.x then right_child = child end
+ end
+
+ -- position between child with highest and child with lowest x-value,
+ -- if number of children is even
+ local index_of_middle_child = math.ceil(#children/2)
+ local even = #children/2 == index_of_middle_child
+
+ if even then
+ vertex.pos.x = (left_child.pos.x + right_child.pos.x) / 2
+ index_of_middle_child = 0
+ else -- if number of children is odd, position above the middle child
+ vertex.pos.x = children[index_of_middle_child].pos.x
+ table.remove(children, index_of_middle_child) -- don't bend the edge to this node, as it it above it anyway
+ end
+ end
+
+ -- set the node's y-coordinate, using the calculated length
+ -- and a scaling factor
+ vertex.pos.y = vertex.pos.y + (values.length * self.tree.options['evolutionary unit length'])
+
+ -- if this is the second subtree to be set of an unrooted tree, have
+ -- it grow in the other direction
+ if values.second_subtree then
+ vertex.pos.y = -vertex.pos.y
+ end
+
+ -- bend the edges for the rectangular layout
+ for i,child in ipairs(children) do
+ self:bendEdge90Degree(child, vertex)
+ end
+
+ return values
+end
+
+
+-- Sets only the x-positions of all nodes using a depth-first search.
+-- This is necessary for straight-edge layouts.
+--
+-- @param vertex The starting point of the depth-first search; should usually be the root
+-- @param values Values needed for the recursion
+-- @param vertex2 A node that will not be visited; this parameter should only be set
+-- for an unrooted layout to ensure that only the half of the tree is set.
+function Maeusle2012:setXPos(vertex, values, vertex2)
+ local arcs = self.tree.arcs
+ local vertices = self.tree.vertices
+ if not values then
+ values = {
+ visited = {}, -- all nodes that have already been visited
+ leaves = {}, -- all leaves from left to right
+ }
+ end
+
+ local vertex_is_leaf = true
+ values.visited[vertex] = true
+ local children = {} -- a table containing all children of the current vertex (for the later determination of inner vertices x-positions)
+
+ for _, arc in ipairs (self.tree:outgoing(vertex)) do
+ if not values.visited[arc.head] and arc.head ~= vertex2 then
+ -- if arc.head hasn't been visited, the current vertex cannot be a leaf
+ vertex_is_leaf = false
+
+ -- go deeper
+ self:setXPos(arc.head, values, vertex2)
+
+ -- get the children of the current vertex
+ table.insert(children, arc.head)
+ end
+ end
+
+ -- set the x-position of a leaf
+ if vertex_is_leaf then
+
+ table.insert(values.leaves, vertex)
+
+ if #values.leaves > 1 then
+ local left_sibling = values.leaves[#values.leaves-1]
+ local ideal_distance = layered.ideal_sibling_distance(self.main_algorithm.adjusted_bb, self.tree, vertex, left_sibling )
+ vertex.pos.x = left_sibling.pos.x + ideal_distance
+ end
+
+ -- set x position of an inner node, which is at the center of its
+ -- children
+ else
+ -- determine the outer children
+ local left_child = children[1]
+ local right_child = left_child
+ for _, child in ipairs(children) do
+ if child.pos.x < left_child.pos.x then left_child = child end
+ if child.pos.x > right_child.pos.x then right_child = child end
+ end
+
+ -- position between child with highest and child with lowest x-value,
+ -- if number of children is even
+ local index_of_middle_child = math.ceil(#children/2)
+ local even = #children/2 == index_of_middle_child
+
+ if even then
+ vertex.pos.x = (left_child.pos.x + right_child.pos.x) / 2
+ else -- if number of children is odd, position above the middle child
+ vertex.pos.x = children[index_of_middle_child].pos.x
+ end
+ end
+ return values
+end
+
+
+--
+-- Sets only the y-positions of all nodes using a depth-first search.
+-- This is needed for a straight-edge layout, as the x-positions have
+-- to bet first so that the y-coordinates can be calculated correctly
+-- here.
+--
+-- @param vertex1 The starting point of the depth-first search
+-- @param values Values needed for the recursion
+-- @param vertex2 For unrooted layout only: The root of the second subtree.
+-- This node and all its children will not be visited.
+function Maeusle2012:setYPosForStraightLayout(vertex, values, vertex2)
+ local arcs = self.tree.arcs
+ local vertices = self.tree.vertices
+ local adjusted_bb = self.main_algorithm.adjusted_bb
+
+ values = values or {
+ length = 0, -- current path length
+ visited = {}, -- all nodes that have already been visited
+ leaves = {}, -- all leaves from left to right
+ }
+
+ local vertex_is_leaf = true
+ values.visited[vertex] = true
+ local children = {} -- a table containing all children of the current vertex (for the later determination of inner vertices x-positions)
+
+ for _, arc in ipairs (self.tree:outgoing(vertex)) do
+ if not values.visited[arc.head] and arc.head ~= vertex2 then
+ -- if arc.head hasn't been visited, the current vertex cannot be a leaf
+ vertex_is_leaf = false
+
+ -- calculate the arc length with the help of the Pythagorean
+ -- theorem
+ local a
+ local l = self:edgeLength(vertex, arc.head) * self.tree.options['evolutionary unit length']
+ local b = math.abs(vertex.pos.x - arc.head.pos.x)
+ if b > l then
+ a = 0
+ else
+ a = math.sqrt(l^2-b^2)
+ end
+ local arc_length = a
+
+
+ values.length = values.length + arc_length
+
+ -- go deeper
+ self:setYPosForStraightLayout(arc.head, values, vertex2)
+
+ -- get the children of the current vertex
+ table.insert(children, arc.head)
+
+ values.length = values.length - arc_length
+ end
+ end
+
+ if vertex_is_leaf then
+ -- subtract layer_pre, thus the leaf itself is NOT part of the
+ -- edge length
+ vertex.pos.y = - adjusted_bb[vertex].layer_pre
+
+ table.insert(values.leaves, vertex)
+ end
+
+ -- set the node's y-coordinate, using the calculated length
+ vertex.pos.y = vertex.pos.y + values.length
+
+ -- if this is the second subtree to be set of an unrooted tree, have
+ -- it grow in the other direction
+ if values.second_subtree then vertex.pos.y = -vertex.pos.y end
+end
+
+--
+-- Correct the x-positions in the unrooted layout for a more aesthetic result
+--
+-- If the roots of the two subtrees have different x-positions, this is corrected
+-- by shifting the x-positions of all nodes in one subtree by that difference.
+--
+-- @param vertex1 The root of the first subtree
+-- @param vertex2 The root of the second subtree.
+function Maeusle2012:correctXPos(vertex1, vertex2, straight)
+
+ -- correct the x-positions
+ --
+ -- @param vertex Starting point of the depth-first search
+ -- @param values Values needed for the recursion
+ -- @param vertex2 The root of the subtree that will not be visited
+ local function x_correction(vertex, values, vertex2)
+ values.visited[vertex] = true
+ local children = {}
+
+ for _, arc in ipairs (self.tree:outgoing(vertex)) do
+ if not values.visited[arc.head] and arc.head ~= vertex2 then
+
+ table.insert(children, arc.head)
+ x_correction(arc.head, values, vertex2)
+ end
+ end
+
+ vertex.pos.x = vertex.pos.x + values.diff
+ if not straight then
+ for i,child in ipairs(children) do
+ self:bendEdge90Degree(child, vertex)
+ end
+ end
+
+ return values
+ end
+
+ -- compute the difference of the x-positions of the two subtrees'
+ -- roots
+ local diff = vertex1.pos.x - vertex2.pos.x
+ local values = { visited = {} }
+ if diff < 0 then
+ values.diff = - diff
+ x_correction(vertex1, values, vertex2)
+ elseif diff > 0 then
+ values.diff = diff
+ x_correction(vertex2, values, vertex1)
+ end
+end
+
+
+--
+-- Sets the x- and y-positions of the vertices in an unrooted layout
+--
+-- This is done using the function for setting the positions for a rooted layout:
+-- Two neighboring vertices are chosen as roots; one half of the tree
+-- is drawn in one direction, the other half 180° to the other
+-- direction.
+--
+-- @param vertex1, vertex2: The vertices functioning as roots
+function Maeusle2012:setPosForUnrootedRectangular(vertex1, vertex2)
+ -- set positions for first half of the tree...
+ self:setPosForRectangularLayout(vertex2,false,vertex1)
+ local vals={
+ length = self:edgeLength(vertex1, vertex2), -- the length between the two roots
+ visited={},
+ leaves={},
+ path={},
+ second_subtree = true
+ }
+ -- ... and for the second half.
+ self:setPosForRectangularLayout(vertex1,vals,vertex2)
+ -- if the two roots have different x-values, correct the x-positions for nicer layout
+ self:correctXPos(vertex1, vertex2, false)
+end
+
+
+--
+-- Sets the x- and y-positions of the vertices in an unrooted straight layout
+--
+-- This is done using the function for setting the positions for a rooted straight layout:
+-- Two neighboring vertices are chosen as roots; one half of the tree
+-- is drawn in one direction, the other half 180° to the other
+-- direction.
+--
+-- @param vertex1, vertex2: The vertices functioning as roots
+function Maeusle2012:setPosForUnrootedStraight(vertex1, vertex2)
+ -- first set the x-positions of the two subtrees...
+ local vals = {visited = {}, leaves = {} }
+ self:setXPos(vertex2, vals, vertex1)
+ self:setXPos(vertex1, vals, vertex2)
+
+ -- ... and then the y-positions
+ self:setYPosForStraightLayout(vertex2, false, vertex1)
+ local vals={
+ length = self:edgeLength(vertex1, vertex2) * self.tree.options['evolutionary unit length'],
+ visited={},
+ leaves={},
+ path={},
+ second_subtree = true
+ }
+ self:setYPosForStraightLayout(vertex1, vals, vertex2)
+
+ -- if the two roots have different x-values, correct the x-positions for nicer layout
+ -- as the length between the roots of the two subtrees is set to the calculated value,
+ -- this step is mandatory for the unrooted, straight layout
+ self:correctXPos(vertex1, vertex2, true)
+end
+
+
+
+-- Bends the arc between two nodes by 90 degree by updating the arc's
+-- path
+--
+-- @param head The head of the arc
+-- @param tail The tail of the arc
+function Maeusle2012:bendEdge90Degree(head, tail)
+ local arc = self.tree:arc(tail,head)
+ local syntactic_tail = arc:syntacticTailAndHead()
+ arc:setPolylinePath { Coordinate.new(head.pos.x, tail.pos.y) }
+end
+
+
+
+-- Finds the longest path in a graph
+--
+-- @ return A table containing the path (an array of nodes) and the
+-- path length
+function Maeusle2012:findLongestPath()
+ local starting_point = self.tree.vertices[1] -- begin at any vertex
+ -- get the path lengths from the starting point to all leaves:
+ local paths_to_leaves = self:getPathLengthsToLeaves(starting_point)
+ local path_lengths = paths_to_leaves.path_lengths
+ local paths = paths_to_leaves.paths
+
+ -- looks for the longest path and identifies its end-point
+ local function find_head_of_longest_path(path_lengths, paths)
+ local longest_path
+ local node
+ -- to make sure that the same path is chosen every time, we go over all vertices with "ipairs"; if we would go over path_lengths directly, we could only use "pairs"
+ for _, vertex in ipairs(self.tree.vertices) do
+ local path_length = path_lengths[vertex]
+ if path_length then
+ -- choose longest path. if two paths have the same length, take the path with more nodes
+ if not longest_path or path_length > longest_path or (path_length == longest_path and #paths[vertex]>#paths[node]) then
+ longest_path = path_length
+ node = vertex
+ end
+ end
+ end
+ return node
+ end
+
+ -- find the longest path leading away from the starting point and identify
+ -- the leaf it leads to. Use that leaf as the tail for the next path
+ -- search
+ local tail = find_head_of_longest_path(path_lengths, paths)
+ paths_to_leaves = self:getPathLengthsToLeaves(tail) -- gets new path information
+ -- paths_to leaves now has all paths starting at vertex "tail"; one of these paths is the
+ -- longest (globally)
+ path_lengths = paths_to_leaves.path_lengths
+ paths = paths_to_leaves.paths
+ local head = find_head_of_longest_path(path_lengths, paths)
+
+ local path_information =
+ { path = paths_to_leaves.paths[head], -- longest path
+ length = path_lengths[head] } -- length of that path
+
+ return path_information
+end
+
+
+-- a depth first search for getting all path lengths from a
+-- starting point to all leaves
+--
+-- @param vertex The vertex where the search is to start
+-- @param values Table of values needed for the recursive computation
+--
+-- @return A table containing:
+-- a table of the leaves with corresponding path lengths
+-- and a table containing the path to each leaf (an array of
+-- nodes)
+function Maeusle2012:getPathLengthsToLeaves(vertex, values)
+ local arcs = self.tree.arcs
+ local vertices = self.tree.vertices
+ if not values then
+ values = {
+ paths = {}, -- all paths we've found so far
+ path_lengths = {}, -- all path lengths that have so far been computed
+ length = 0, -- current path length
+ visited = {}, -- all nodes that have already been visited
+ path = {}, -- the current path we're on
+ leaves = {} -- all leaves from left to right
+ }
+ table.insert(values.path,vertex)
+ end
+
+ local vertex_is_leaf = true
+ values.visited[vertex] = true
+
+ for _, arc in ipairs (self.tree:outgoing(vertex)) do
+ if not values.visited[arc.head] then
+ -- the current vertex is not a leaf! note: if the starting vertex is a leaf, vertex_is_leaf
+ -- will be set to 'false' for it anyway. as we're not interested in the distance
+ -- of the starting vertex to itself, this is fine.
+ vertex_is_leaf = false
+ local arc_length = self.lengths[vertex][arc.head]
+ values.length = values.length + arc_length
+
+ -- add arc.head to path...
+ table.insert(values.path,arc.head)
+
+ -- ... and go down that path
+ self:getPathLengthsToLeaves(arc.head, values)
+
+ -- remove arc.head again to go a different path
+ table.remove(values.path)
+ values.length = values.length - arc_length
+ end
+ end
+
+ if vertex_is_leaf then -- we store the information gained on the path to this leaf
+ values.path_lengths[vertex] = values.length
+ values.paths[vertex] = {}
+ table.insert(values.leaves, vertex)
+ for i,k in pairs(values.path) do
+ values.paths[vertex][i] = k
+ end
+ end
+ -- the path_lengths and the paths are stored in one table and
+ -- returned together
+ local path_information =
+ { path_lengths = values.path_lengths,
+ paths = values.paths,
+ leaves = values.leaves }
+ return path_information
+end
+
+
+-- Gets the root of a tree
+-- checks whether a tree is already rooted, if not, computeCenterOfPath() is
+-- called, which defines a node in the center of the graph as the root
+--
+-- @return The root
+function Maeusle2012:getRoot()
+ -- check whether a root exists (vertex with degree 2)
+ local root = lib.find (self.tree.vertices, function(v) return #self.tree:outgoing(v) == 2 end)
+ if root then
+ return root, self.tree:outgoing(root)[1].head
+ else
+ return self:computeCenterOfPath()
+ end
+end
+
+
+--
+-- @return The newly computed root and its nearest neighbor
+function Maeusle2012:computeCenterOfPath()
+ local longest_path = self:findLongestPath()
+ local path = longest_path.path
+ local root, neighbor_of_root
+
+ local length = 0 --length between first vertex on the path and the current vertex we're looking at
+ for i = 1, #path-1 do
+ local node1 = path[i]
+ local node2 = path[i+1]
+ local node3 = path[i+2]
+
+ local dist_node_1_2, dist_node_2_3 --distances between node1 and node2, and node2 and node3
+ dist_node_1_2 = self:edgeLength(node1, node2)
+ if node3 then dist_node_2_3 = self:edgeLength(node2, node3) end
+ length = length + dist_node_1_2 -- length between first vertex on the path and current node2
+
+ if length == longest_path.length/2 then
+ root = node2 -- if there is a node exactly at the half of the path, use this node as root
+
+ -- and find nearest neighbor of the root
+ if node3 == nil or dist_node_1_2 < dist_node_2_3 then -- neu 3.8
+ neighbor_of_root = node1
+ else
+ neighbor_of_root = node3
+ end
+ break
+
+ elseif length > longest_path.length/2 then
+ -- else find node closest to the center of the path and use it as the root;
+ local node2_length = math.abs(longest_path.length/2 - length)
+ local node1_length = math.abs(longest_path.length/2 - (length - dist_node_1_2))
+ if node2_length < node1_length then
+ root = node2
+ neighbor_of_root = node1
+ -- if node3 is closer to node2 than node1 is, use node3 as neighbor!
+ if node3 and dist_node_2_3 < dist_node_1_2 then neighbor_of_root = node3 end
+ else
+ root = node1
+ neighbor_of_root = node2
+ --check if node i-1 is closer to node1
+ local dist_node_0_1
+ if i>1 then
+ node0 = path[i-1]
+ dist_node_0_1 = self:edgeLength(node0, node1)
+ if dist_node_0_1 < dist_node_1_2 then neighbor_of_root = node0 end
+ end
+ end
+ break
+ end
+ end
+
+ return root, neighbor_of_root
+end
+
+
+return Maeusle2012
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua
new file mode 100644
index 0000000000..242ccf183f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua
@@ -0,0 +1,91 @@
+-- Copyright 2013 by Sarah Mäusle and Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local PhylogeneticTree = {}
+
+
+-- Namespace
+require("pgf.gd.phylogenetics").PhylogeneticTree = PhylogeneticTree
+
+-- Imports
+local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms"
+local Storage = require "pgf.gd.lib.Storage"
+local Direct = require "pgf.gd.lib.Direct"
+
+-- Shorthand:
+local declare = InterfaceToAlgorithms.declare
+
+
+---
+declare {
+ key = "phylogenetic tree layout",
+ algorithm = PhylogeneticTree,
+
+ postconditions = {
+ upward_oriented = true
+ },
+
+ summary = [["
+ Layout for drawing phylogenetic trees.
+ "]],
+ documentation = [["
+ ...
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout, upgma,
+ distance matrix={
+ 0 4 9 9 9 9 9
+ 4 0 9 9 9 9 9
+ 9 9 0 2 7 7 7
+ 9 9 2 0 7 7 7
+ 9 9 7 7 0 3 5
+ 9 9 7 7 3 0 5
+ 9 9 7 7 5 5 0}]
+ { a, b, c, d, e, f, g };
+ "]]
+}
+
+
+-- Computes a phylogenetic tree and/or visualizes it
+-- - computes a phylogenetic tree according to what the "phylogenetic
+-- algorithm" key is set to
+-- - invokes a graph drawing algorithm according to what the
+-- "phylogenetic layout" key is set to
+function PhylogeneticTree:run()
+
+ local options = self.digraph.options
+
+ -- Two storages for some information computed by the phylogenetic
+ -- tree generation algorithm
+ local lengths = Storage.newTableStorage()
+
+ -- First, compute the phylogenetic tree
+ local tree = options.algorithm_phases['phylogenetic tree generation'].new {
+ main_algorithm = self,
+ lengths = lengths
+ }:run()
+
+ tree = Direct.ugraphFromDigraph(tree)
+
+ -- Second, layout the tree
+ local layout_class = options.algorithm_phases['phylogenetic tree layout']
+ layout_class.new {
+ main_algorithm = self,
+ distances = distances,
+ lengths = lengths,
+ tree = tree
+ }:run()
+
+ tree:sync()
+end
+
+return PhylogeneticTree
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua
new file mode 100644
index 0000000000..6a665b6732
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua
@@ -0,0 +1,261 @@
+-- Copyright 2013 by Sarah Mäusle and Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+
+local SokalMichener1958 = {}
+
+
+-- Namespace
+require("pgf.gd.phylogenetics").SokalMichener1958 = SokalMichener1958
+
+-- Imports
+local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms")
+local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix")
+local lib = require("pgf.gd.lib")
+local Storage = require("pgf.gd.lib.Storage")
+local Digraph = require("pgf.gd.model.Digraph")
+
+-- Shorthand:
+local declare = InterfaceToAlgorithms.declare
+
+
+---
+declare {
+ key = "unweighted pair group method using arithmetic averages",
+ algorithm = SokalMichener1958,
+ phase = "phylogenetic tree generation",
+
+ summary = [["
+ The UPGMA (Unweighted Pair Group Method using arithmetic
+ Averages) algorithm of Sokal and Michener, 1958. It generates a
+ graph on the basis of such a distance matrix by generating nodes
+ and computing the edge lengths.
+ "]],
+ documentation = [["
+ This algorithm uses a distance matrix, ideally an ultrametric
+ one, to compute the graph.
+ "]],
+ examples = [["
+ \tikz \graph [phylogenetic tree layout, sibling distance=0pt, sibling sep=2pt,
+ unweighted pair group method using arithmetic averages,
+ distance matrix={
+ 0 4 9 9 9 9 9
+ 4 0 9 9 9 9 9
+ 9 9 0 2 7 7 7
+ 9 9 2 0 7 7 7
+ 9 9 7 7 0 3 5
+ 9 9 7 7 3 0 5
+ 9 9 7 7 5 5 0}]
+ { a, b, c, d, e, f, g };
+ "]]
+}
+
+
+---
+declare {
+ key = "upgma",
+ use = { { key = "unweighted pair group method using arithmetic averages" } },
+ summary = "An shorthand for |unweighted pair group method using arithmetic averages|"
+}
+
+
+
+
+--
+-- The run function of the upgma algorithm.
+--
+-- You must setup the following fields: The |main_algorithm| must
+-- store the main algorithm object (for phase |main|). The |distances|
+-- field must be a |Storage| object that will get filled with the
+-- distances computed by this algorithm. The |lengths| field must also
+-- be a |Storage| for the computed distances.
+--
+
+function SokalMichener1958:run()
+ self.distances = Storage.newTableStorage()
+
+ self.tree = Digraph.new(self.main_algorithm.digraph)
+
+ -- store the phylogenetic tree object, containing all user-specified
+ -- graph information
+ self:runUPGMA()
+ self:createFinalEdges()
+
+ return self.tree
+end
+
+
+
+-- UPGMA (Unweighted Pair Group Method using arithmetic Averages) algorithm
+-- (Sokal and Michener, 1958)
+--
+-- this function generates a graph on the basis of such a distance
+-- matrix by generating nodes and computing the edge lengths; the x-
+-- and y-positions of the nodes must be set separately
+--
+-- requirement: a distance matrix, ideally an ultrametric
+function SokalMichener1958:runUPGMA()
+ local matrix = DistanceMatrix.graphDistanceMatrix(self.tree)
+
+ local g = self.tree
+ local clusters = {}
+
+ -- create the clusters
+ for _,v in ipairs(g.vertices) do
+ clusters[#clusters+1] = self:newCluster(v)
+ end
+
+ -- Initialize the distances of these clusters:
+ for _,cx in ipairs(clusters) do
+ for _,cy in ipairs(clusters) do
+ cx.distances[cy] = matrix[cx.root][cy.root]
+ end
+ end
+
+ -- search for clusters with smallest distance and merge them
+ while #clusters > 1 do
+ local minimum_distance = math.huge
+ local min_cluster1
+ local min_cluster2
+ for i, cluster in ipairs (clusters) do
+ for j = i+1,#clusters do
+ local cluster2 = clusters[j]
+ local cluster_distance = self:getClusterDistance(cluster, cluster2)
+ if cluster_distance < minimum_distance then
+ minimum_distance, min_cluster1, min_cluster2 = cluster_distance, i, j
+ end
+ end
+ end
+ self:mergeClusters(clusters, min_cluster1, min_cluster2, minimum_distance)
+ end
+end
+
+
+-- a new cluster is created
+--
+-- @param vertex The vertex the cluster is initialized with
+--
+-- @return The new cluster
+function SokalMichener1958:newCluster(vertex)
+ return {
+ root = vertex, -- the root of the cluster
+ size = 1, -- the number of vertices in the cluster,
+ distances = {}, -- cached cluster distances to all other clusters
+ cluster_height = 0 -- this value is equivalent to half the distance of the last two clusters
+ -- that have been merged to form the current cluster;
+ -- necessary for determining the distances of newly generated nodes to their children.
+ }
+end
+
+
+-- gets the distance between two clusters
+--
+-- @param cluster1, cluster2 The two clusters
+--
+-- @return the distance between the clusters
+function SokalMichener1958:getClusterDistance(c,d)
+ return c.distances[d] or d.distances[c] or 0
+end
+
+
+-- merges two clusters by doing the following:
+-- - deletes cluster2 from the clusters table
+-- - adds all vertices from cluster2 to the vertices table of cluster1
+-- - updates the distances of the new cluster to all remaining clusters
+-- - generates a new node, as the new root of the cluster
+-- - computes the distance of the new node to the former roots (for
+-- later computation of the y-positions)
+-- - generates edges, connecting the new node to the former roots
+-- - updates the cluster height
+--
+-- @param clusters The array of clusters
+-- @param index_of_first_cluster The index of the first cluster
+-- @param index_of_second_cluster The index of the second cluster
+-- @param distance The distance between the two clusters
+
+function SokalMichener1958:mergeClusters(clusters, index_of_first_cluster, index_of_second_cluster, distance)
+
+ local g = self.tree
+ local cluster1 = clusters[index_of_first_cluster]
+ local cluster2 = clusters[index_of_second_cluster]
+
+ --update cluster distances
+ for i,cluster in ipairs (clusters) do
+ if cluster ~= cluster1 and cluster ~= cluster2 then
+ local dist1 = self:getClusterDistance (cluster1, cluster)
+ local dist2 = self:getClusterDistance (cluster2, cluster)
+ local dist = (dist1*cluster1.size + dist2*cluster2.size)/ (cluster1.size+cluster2.size)
+ cluster1.distances[cluster] = dist
+ cluster.distances[cluster1] = dist
+ end
+ end
+
+ -- delete cluster2
+ table.remove(clusters, index_of_second_cluster)
+
+ --add node and connect last vertex of each cluster with new node
+ local new_node = InterfaceToAlgorithms.createVertex(
+ self.main_algorithm,
+ {
+ name = "UPGMA-node ".. #self.tree.vertices+1,
+ generated_options = { { key = "phylogenetic inner node" } },
+ }
+ )
+ g:add{new_node}
+ -- the distance of the new node ( = the new root of the cluster) to its children (= the former roots) is
+ -- equivalent to half the distance between the two former clusters
+ -- minus the respective cluster height
+ local distance1 = distance/2-cluster1.cluster_height
+ self.distances[new_node][cluster1.root] = distance1
+ local distance2 = distance/2-cluster2.cluster_height
+ self.distances[new_node][cluster2.root] = distance2
+
+ -- these distances are also the final edge lengths, thus:
+ self.lengths[new_node][cluster1.root] = distance1
+ self.lengths[cluster1.root][new_node] = distance1
+
+ self.lengths[new_node][cluster2.root] = distance2
+ self.lengths[cluster2.root][new_node] = distance2
+
+ g:connect(new_node, cluster1.root)
+ g:connect(new_node, cluster2.root)
+
+ cluster1.root = new_node
+ cluster1.size = cluster1.size + cluster2.size
+ cluster1.cluster_height = distance/2 -- set new height of the cluster
+end
+
+
+
+-- generates edges for the final graph
+--
+-- throughout the process of creating the tree, arcs have been
+-- disconnected and connected, without truly creating edges. this is
+-- done in this function
+function SokalMichener1958:createFinalEdges()
+ local g = self.tree
+ local o_arcs = {} -- copy arcs since createEdge is going to modify the arcs array...
+ for _,arc in ipairs(g.arcs) do
+ o_arcs[#o_arcs+1] = arc
+ end
+ for _,arc in ipairs(o_arcs) do
+ InterfaceToAlgorithms.createEdge(
+ self.main_algorithm, arc.tail, arc.head,
+ { generated_options = {
+ { key = "phylogenetic edge", value = tostring(self.lengths[arc.tail][arc.head]) }
+ }})
+ end
+end
+
+
+return SokalMichener1958
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/library.lua
new file mode 100644
index 0000000000..5ab821c4a8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/phylogenetics/library.lua
@@ -0,0 +1,35 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- A phylogenetic tree (or network) depicts the evolutionary history
+-- of species or, more generally, so called taxa. The present library
+-- includes a number of algorithms for drawing phylogenetic trees.
+--
+-- @library
+
+local phylogenetics -- Library name
+
+-- Main layout:
+require "pgf.gd.phylogenetics.PhylogeneticTree"
+
+-- Phylogenetic tree drawing:
+require "pgf.gd.phylogenetics.Maeusle2012"
+
+-- Phylogenetic tree generation:
+require "pgf.gd.phylogenetics.SokalMichener1958"
+require "pgf.gd.phylogenetics.BalancedMinimumEvolution"
+require "pgf.gd.phylogenetics.BalancedNearestNeighbourInterchange"
+require "pgf.gd.phylogenetics.AuthorDefinedPhylogeny"
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar.lua
new file mode 100644
index 0000000000..5d80de77cd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar.lua
@@ -0,0 +1,6 @@
+require "pgf"
+require "pgf.gd"
+
+pgf.gd.planar = {}
+
+return pgf.gd.planar
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/BoyerMyrvold2004.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/BoyerMyrvold2004.lua
new file mode 100644
index 0000000000..f587861d79
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/BoyerMyrvold2004.lua
@@ -0,0 +1,678 @@
+
+--[[
+---Data structures---
+
+Vertices from the original ugraph are referred to as input vertices.
+The tables that contain vertex data relevant to the algorithm
+are referred to as vertices.
+A vertex table may have the following keys:
+
+-sign
+1 or -1, indicates whether this and all in the depth-first search
+following vertices must be considered flipped
+(i. e. adjacency lists reversed) in respect to the dfs parent
+
+-childlist
+A linked list containing all dfs children of the vertex whose virtual roots
+have not yet been merged into the vertex, sorted by lowpoint
+
+-adjlistlinks
+A table with two fields with keys 0 and 1, containing the two half edges
+of the vertex which lie on the external face of the graph
+(if the vertex lies on the external face).
+The half edge with key 0 lies in the 0-direction of the other half edge
+and vice-versa
+The two fields may hold the same half edge, if the vertex has degree one
+
+-pertinentroots
+A linked list containing all virtual roots of this vertex that are
+pertinent during the current step
+
+-inputvertex
+The input vertex that corresponds to the vertex
+
+-dfi
+The depth-first search index (number of the step in the dfs at which
+the vertex was discovered)
+
+-dfsparent
+The depth-first search parent (vertex from which the vertex was discovered
+first in the dfs)
+
+-leastancestor
+Dfi of the vertex with lowest dfi that can be reached using one back edge
+(non-tree edge)
+
+-lowpoint
+Dfi of the vertex with lowest dfi that can be reached using any number of
+tree edges plus one back edge
+
+
+A root vertex is a virtual vertex not contained in the original ugraph.
+The root vertex represents another vertex in a biconnected component (block)
+which is a child of the biconnected component the represented vertex is in.
+The only field that it has in common with other vertices is the
+adjacency list links array:
+
+-isroot
+always true, indicates that this vertex is a virtual root
+
+-rootparent
+The vertex which this root represents
+
+-rootchild
+The only dfs child of the original vertex which is contained in the
+root verticis biconnected component
+
+-adjlistlinks
+See adjlistlinks of a normal vertex
+
+
+A half edge is a table with the following fields:
+
+-links
+A table with two fields with keys 0 and 1, containing the neighboring
+half edges in the adjacency list of the vertex these edges originate from.
+
+-target
+The vertex the half edge leads to
+
+-twin
+The twin half edge which connects the two vertices in the opposite direction
+
+-shortcircuit
+True if the half edge was inserted in order to make a short circuit for the
+algorithm. The edge will be removed at the end.
+
+The BoyerMyrvold2004 class has the following fields:
+
+-inputgraph
+The original ugraph given to the algorithm
+
+-numvertices
+The number of vertices of the graph
+
+-vertices
+The vertex table with depth-first search indices as keys
+
+-verticesbyinputvertex
+The vertex table with input vertices as keys
+
+-verticesbylowpoint
+The vertex table with low points as keys
+
+-shortcircuitedges
+An array of all short circuit half edges
+(which may not be in the original graph and will be removed at the end)
+
+--]]
+
+local BM = {}
+require("pgf.gd.planar").BoyerMyrvold2004 = BM
+
+-- imports
+local Storage = require "pgf.gd.lib.Storage"
+local LinkedList = require "pgf.gd.planar.LinkedList"
+local Embedding = require "pgf.gd.planar.Embedding"
+
+-- create class properties
+BM.__index = BM
+
+function BM.new()
+ local t = {}
+ setmetatable(t, BM)
+ return t
+end
+
+-- initializes some data structures at the beginning
+-- takes the ugraph of the layout algorithm as input
+function BM:init(g)
+ self.inputgraph = g
+ self.numvertices = #g.vertices
+ self.vertices = {}
+ self.verticesbyinputvertex = Storage.new()
+ self.verticesbylowpoint = Storage.newTableStorage()
+ self.shortcircuitedges = {}
+ for _, inputvertex in ipairs(self.inputgraph.vertices) do
+ local vertex = {
+ sign = 1,
+ childlist = LinkedList.new(),
+ adjlistlinks = {},
+ pertinentroots = LinkedList.new(),
+ inputvertex = inputvertex,
+ }
+ setmetatable(vertex, Embedding.vertexmetatable)
+ self.verticesbyinputvertex[inputvertex] = vertex
+ end
+end
+
+--[[
+local function nilmax(a, b)
+ if a == nil then return b end
+ if b == nil then return a end
+ return math.max(a, b)
+end
+
+local function nilmin(a, b)
+ if a == nil then return b end
+ if b == nil then return a end
+ return math.min(a, b)
+end
+--]]
+
+-- the depth-first search of the preprocessing
+function BM:predfs(inputvertex, parent)
+ local dfi = #self.vertices + 1
+ local vertex = self.verticesbyinputvertex[inputvertex]
+ self.vertices[dfi] = vertex
+ -- set the dfs infos in the vertex
+ vertex.dfi = dfi
+ vertex.dfsparent = parent
+ vertex.leastancestor = dfi
+ vertex.lowpoint = dfi
+ -- find neighbors
+ for _, arc in ipairs(self.inputgraph:outgoing(inputvertex)) do
+ local ninputvertex = arc.head
+ assert(ninputvertex ~= inputvertex, "Self-loop detected!")
+ local nvertex = self.verticesbyinputvertex[ninputvertex]
+ if nvertex.dfi == nil then
+ -- new vertex discovered
+ self:predfs(ninputvertex, vertex) -- recursive call
+ vertex.lowpoint = math.min(vertex.lowpoint, nvertex.lowpoint)
+ elseif parent and ninputvertex ~= parent.inputvertex then
+ -- back edge found
+ vertex.leastancestor = math.min(vertex.leastancestor, nvertex.dfi)
+ vertex.lowpoint = math.min(vertex.lowpoint, nvertex.dfi)
+ end
+ end
+ -- put vertex into lowpoint sort bucket
+ table.insert(self.verticesbylowpoint[vertex.lowpoint], vertex)
+end
+
+-- the preprocessing at the beginning of the algorithm
+-- does the depth-first search and the bucket sort for the child lists
+function BM:preprocess()
+ -- make dfs starting at an arbitrary vertex
+ self:predfs(self.inputgraph.vertices[1])
+ -- create separated child lists with bucket sort
+ for i = 1, self.numvertices do
+ for _, vertex in ipairs(self.verticesbylowpoint[i]) do
+ if vertex.dfsparent then
+ vertex.childlistelement
+ = vertex.dfsparent.childlist:addback(vertex)
+ end
+ end
+ end
+end
+
+-- adds tree edges and the corresponding virtual root vertices
+-- of the currentvertex
+function BM:add_trivial_edges(vertex)
+ -- find all dfs children
+ for _, arc in ipairs(self.inputgraph:outgoing(vertex.inputvertex)) do
+ local nvertex = self.verticesbyinputvertex[arc.head]
+ if nvertex.dfsparent == vertex then
+ -- create root vertex
+ local rootvertex = {
+ isroot = true,
+ rootparent = vertex,
+ rootchild = nvertex,
+ adjlistlinks = {},
+ name = tostring(vertex) .. "^" .. tostring(nvertex)
+ }
+ setmetatable(rootvertex, Embedding.vertexmetatable)
+ nvertex.parentroot = rootvertex
+ -- create half edges
+ local halfedge1 = {target = nvertex, links = {}}
+ local halfedge2 = {target = rootvertex, links = {}}
+ halfedge1.twin = halfedge2
+ halfedge2.twin = halfedge1
+ -- create circular adjacency lists
+ halfedge1.links[0] = halfedge1
+ halfedge1.links[1] = halfedge1
+ halfedge2.links[0] = halfedge2
+ halfedge2.links[1] = halfedge2
+ -- create links to adjacency lists
+ rootvertex.adjlistlinks[0] = halfedge1
+ rootvertex.adjlistlinks[1] = halfedge1
+ nvertex.adjlistlinks[0] = halfedge2
+ nvertex.adjlistlinks[1] = halfedge2
+ end
+ end
+end
+
+-- for the external face vertex which was entered through link vin
+-- returns the successor on the external face and the link through
+-- which it was entered
+local function get_successor_on_external_face(vertex, vin)
+ local halfedge = vertex.adjlistlinks[1 - vin]
+ local svertex = halfedge.target
+ local sin
+ if vertex.adjlistlinks[0] == vertex.adjlistlinks[1] then
+ sin = vin
+ elseif svertex.adjlistlinks[0].twin == halfedge then
+ sin = 0
+ else
+ sin = 1
+ end
+ return svertex, sin
+end
+
+-- the "walkup", used to identify the pertinent subgraph,
+-- i. e. the subgraph that contains end points of backedges
+-- for one backedge this function will mark all virtual roots
+-- as pertinent that lie on the path between the backedge and the current vertex
+-- backvertex: a vertex that is an endpoint of a backedge to the current vertex
+-- currentvertex: the vertex of the current step
+-- returns a root vertex of the current step, if one was found
+local function walkup(backvertex, currentvertex)
+ local currentindex = currentvertex.dfi
+ -- set the backedgeflag
+ backvertex.backedgeindex = currentindex
+ -- initialize traversal variables for both directions
+ local x, xin, y, yin = backvertex, 1, backvertex, 0
+ while x ~= currentvertex do
+ if x.visited == currentindex or y.visited == currentindex then
+ -- we found a path that already has the pertinent roots marked
+ return nil
+ end
+ -- mark vertices as visited for later calls
+ x.visited = currentindex
+ y.visited = currentindex
+
+ -- check for rootvertex
+ local rootvertex
+ if x.isroot then
+ rootvertex = x
+ elseif y.isroot then
+ rootvertex = y
+ end
+ if rootvertex then
+ local rootchild = rootvertex.rootchild
+ local rootparent = rootvertex.rootparent
+ if rootvertex.rootparent == currentvertex then
+ -- we found the other end of the back edge
+ return rootvertex
+ elseif rootchild.lowpoint < currentindex then
+ -- the block we just traversed is externally active
+ rootvertex.pertinentrootselement
+ = rootparent.pertinentroots:addback(rootvertex)
+ else
+ -- the block we just traversed is internally active
+ rootvertex.pertinentrootselement
+ = rootparent.pertinentroots:addfront(rootvertex)
+ end
+ -- jump to parent block
+ x, xin, y, yin = rootvertex.rootparent, 1, rootvertex.rootparent, 0
+ else
+ -- just continue on the external face
+ x, xin = get_successor_on_external_face(x, xin)
+ y, yin = get_successor_on_external_face(y, yin)
+ end
+ end
+end
+
+-- inverts the adjacency of a vertex
+-- i. e. reverses the order of the adjacency list and flips the links
+local function invert_adjacency(vertex)
+ -- reverse the list
+ for halfedge in Embedding.adjacency_iterator(vertex.adjlistlinks[0]) do
+ halfedge.links[0], halfedge.links[1]
+ = halfedge.links[1], halfedge.links[0]
+ end
+ -- flip links
+ vertex.adjlistlinks[0], vertex.adjlistlinks[1]
+ = vertex.adjlistlinks[1], vertex.adjlistlinks[0]
+end
+
+-- merges two blocks by merging the virtual root of the child block
+-- into it's parent, while making sure the external face stays consistent
+-- by flipping the root block if needed
+-- mergeinfo contains four fields:
+-- root - the virtual root vertex
+-- parent - it's parent
+-- rout - the link of the root through which we have exited it
+-- during the walkdown
+-- pin - the link of the parent through which we have entered it
+-- during the walkdown
+local function mergeblocks(mergeinfo)
+ local root = mergeinfo.root
+ local parent = mergeinfo.parent
+ local rout = mergeinfo.rootout
+ local pin = mergeinfo.parentin
+ if pin == rout then
+ -- flip required
+ invert_adjacency(root)
+ root.rootchild.sign = -1
+ --rout = 1 - rout -- not needed
+ end
+
+ -- redirect edges of the root vertex
+ for halfedge in Embedding.adjacency_iterator(root.adjlistlinks[0]) do
+ halfedge.twin.target = parent
+ end
+
+ -- remove block from data structures
+ root.rootchild.parentroot = nil
+ parent.pertinentroots:remove(root.pertinentrootselement)
+ parent.childlist:remove(root.rootchild.childlistelement)
+
+ -- merge adjacency lists
+ parent.adjlistlinks[0].links[1] = root.adjlistlinks[1]
+ parent.adjlistlinks[1].links[0] = root.adjlistlinks[0]
+ root.adjlistlinks[0].links[1] = parent.adjlistlinks[1]
+ root.adjlistlinks[1].links[0] = parent.adjlistlinks[0]
+ parent.adjlistlinks[pin] = root.adjlistlinks[pin]
+end
+
+-- inserts a half edge pointing to "to" into the adjacency list of "from",
+-- replacing the link "linkindex"
+local function insert_half_edge(from, linkindex, to)
+ local halfedge = {target = to, links = {}}
+ halfedge.links[ linkindex] = from.adjlistlinks[ linkindex]
+ halfedge.links[1 - linkindex] = from.adjlistlinks[1 - linkindex]
+ from.adjlistlinks[ linkindex].links[1 - linkindex] = halfedge
+ from.adjlistlinks[1 - linkindex].links[ linkindex] = halfedge
+ from.adjlistlinks[linkindex] = halfedge
+ return halfedge
+end
+
+-- connect the vertices x and y through the links xout and yin
+-- if shortcircuit is true, the edge will be marked as a short circuit edge
+-- and removed at the end of the algorithm
+function BM:embed_edge(x, xout, y, yin, shortcircuit)
+ -- create half edges
+ local halfedgex = insert_half_edge(x, xout, y)
+ local halfedgey = insert_half_edge(y, yin, x)
+ halfedgex.twin = halfedgey
+ halfedgey.twin = halfedgex
+ -- short circuit handling
+ if shortcircuit then
+ halfedgex.shortcircuit = true
+ halfedgey.shortcircuit = true
+ table.insert(self.shortcircuitedges, halfedgex)
+ table.insert(self.shortcircuitedges, halfedgey)
+ end
+end
+
+-- returns true if the given vertex is pertinent at the current step
+local function pertinent(vertex, currentindex)
+ return vertex.backedgeindex == currentindex
+ or not vertex.pertinentroots:empty()
+end
+
+-- returns true if the given vertex is externally active at the current step
+local function externally_active(vertex, currentindex)
+ return vertex.leastancestor < currentindex
+ or (not vertex.childlist:empty()
+ and vertex.childlist:first().lowpoint < currentindex)
+end
+
+-- the "walkdown", which merges the pertinent subgraph and embeds
+-- back and short circuit edges
+-- childrootvertex - a root vertex of the current vertex
+-- which the walkdown will start at
+-- currentvertex - the vertex of the current step
+function BM:walkdown(childrootvertex, currentvertex)
+ local currentindex = currentvertex.dfi
+ local mergestack = {}
+ local numinsertededges = 0 -- to return the number for count check
+ -- two walkdowns into both directions
+ for vout = 0,1 do
+ -- initialize the traversal variables
+ local w, win = get_successor_on_external_face(childrootvertex, 1 - vout)
+ while w ~= childrootvertex do
+ if w.backedgeindex == currentindex then
+ -- we found a backedge endpoint
+ -- merge all pertinent roots we found
+ while #mergestack > 0 do
+ mergeblocks(table.remove(mergestack))
+ end
+ -- embed the back edge
+ self:embed_edge(childrootvertex, vout, w, win)
+ numinsertededges = numinsertededges + 1
+ w.backedgeindex = 0 -- this shouldn't be necessary
+ end
+ if not w.pertinentroots:empty() then
+ -- we found a pertinent vertex with child blocks
+ -- create merge info for the later merge
+ local mergeinfo = {}
+ mergeinfo.parent = w
+ mergeinfo.parentin = win
+ local rootvertex = w.pertinentroots:first()
+ mergeinfo.root = rootvertex
+ -- check both directions for active vertices
+ local x, xin = get_successor_on_external_face(rootvertex, 1)
+ local y, yin = get_successor_on_external_face(rootvertex, 0)
+ local xpertinent = pertinent(x, currentindex)
+ local xexternallyactive = externally_active(x, currentindex)
+ local ypertinent = pertinent(y, currentindex)
+ local yexternallyactive = externally_active(y, currentindex)
+ -- chose the direction with the best vertex
+ if xpertinent and not xexternallyactive then
+ w, win = x, xin
+ mergeinfo.rootout = 0
+ elseif ypertinent and not yexternallyactive then
+ w, win = y, yin
+ mergeinfo.rootout = 1
+ elseif xpertinent then
+ w, win = x, xin
+ mergeinfo.rootout = 0
+ else
+ w, win = y, yin
+ mergeinfo.rootout = 1
+ end
+ -- this is what the paper says, but it might cause problems
+ -- not sure though...
+ --[[if w == x then
+ mergeinfo.rootout = 0
+ else
+ mergeinfo.rootout = 1
+ end--]]
+ table.insert(mergestack, mergeinfo)
+ elseif not pertinent(w, currentindex)
+ and not externally_active(w, currentindex) then
+ -- nothing to see here, just continue on the external face
+ w, win = get_successor_on_external_face(w, win)
+ else
+ -- this is a stopping vertex, walkdown will end here
+ -- paper puts this into the if,
+ -- but this should always be the case, i think
+ assert(childrootvertex.rootchild.lowpoint < currentindex)
+ if #mergestack == 0 then
+ -- we're in the block we started at, so we embed a back edge
+ self:embed_edge(childrootvertex, vout, w, win, true)
+ end
+ break
+ end
+ end
+ if #mergestack > 0 then
+ -- this means, there is a pertinent vertex blocked by stop vertices,
+ -- so the graph is not planar and we can skip the second walkdown
+ break
+ end
+ end
+ return numinsertededges
+end
+
+-- embeds the back edges for the current vertex
+-- walkup and walkdown are called from here
+-- returns true, if all back edges could be embedded
+function BM:add_back_edges(vertex)
+ local pertinentroots = {} -- not in the paper
+ local numbackedges = 0
+ -- find all back edges to vertices with lower dfi
+ for _, arc in ipairs(self.inputgraph:outgoing(vertex.inputvertex)) do
+ local nvertex = self.verticesbyinputvertex[arc.head]
+ if nvertex.dfi > vertex.dfi
+ and nvertex.dfsparent ~= vertex
+ and nvertex ~= vertex.dfsparent then
+ numbackedges = numbackedges + 1
+ -- do the walkup
+ local rootvertex = walkup(nvertex, vertex)
+ if rootvertex then
+ -- remember the root vertex the walkup found, so we don't
+ -- have to call the walkdown for all root vertices
+ -- (or even know what the root vertices are)
+ table.insert(pertinentroots, rootvertex)
+ end
+ end
+ end
+ -- for all root vertices the walkup found
+ local insertededges = 0
+ while #pertinentroots > 0 do
+ -- do the walkdown
+ insertededges = insertededges
+ + self:walkdown(table.remove(pertinentroots), vertex)
+ end
+ if insertededges ~= numbackedges then
+ -- not all back edges could be embedded -> graph is not planar
+ return false
+ end
+ return true
+end
+
+-- the depth-first search of the postprocessing
+-- flips the blocks according to the sign field
+function BM:postdfs(vertex, sign)
+ sign = sign or 1
+ local root = vertex.parentroot
+ if root then
+ sign = 1
+ else
+ sign = sign * vertex.sign
+ end
+
+ if sign == -1 then
+ -- number of flips is odd, so we need to flip here
+ invert_adjacency(vertex)
+ end
+
+ -- for all dfs children
+ for _, arc in ipairs(self.inputgraph:outgoing(vertex.inputvertex)) do
+ local nvertex = self.verticesbyinputvertex[arc.head]
+ if nvertex.dfsparent == vertex then
+ -- recursive call
+ self:postdfs(nvertex, sign)
+ end
+ end
+end
+
+-- the postprocessing at the end of the algorithm
+-- calls the post depth-first search,
+-- removes the short circuit edges from the adjacency lists,
+-- adjusts the links of the vertices,
+-- merges root vertices
+-- and cleans up the vertices
+function BM:postprocess()
+ -- flip components
+ self:postdfs(self.vertices[1])
+
+ -- unlink the short circuit edges
+ for _, halfedge in ipairs(self.shortcircuitedges) do
+ halfedge.links[0].links[1] = halfedge.links[1]
+ halfedge.links[1].links[0] = halfedge.links[0]
+ end
+
+ -- vertex loop
+ local rootvertices = {}
+ local edgetoface = {}
+ for _, vertex in ipairs(self.vertices) do
+ -- check for root vertex and save it
+ local root = vertex.parentroot
+ if root then
+ table.insert(rootvertices, root)
+ end
+
+ -- clean up links and create adjacency matrix
+ local link = vertex.adjlistlinks[0]
+ local adjmat = {}
+ vertex.adjmat = adjmat
+ if link then
+ -- make sure the link points to a half edge
+ -- that is no short circuit edge
+ while link.shortcircuit do
+ link = link.links[0]
+ end
+ -- create link
+ vertex.link = link
+
+ -- create adjacency matrix
+ for halfedge in Embedding.adjacency_iterator(link) do
+ setmetatable(halfedge, Embedding.halfedgemetatable)
+ local target = halfedge.target
+ if target.isroot then
+ target = target.rootparent
+ end
+ adjmat[target] = halfedge
+ end
+ end
+
+ -- clean up vertex
+ vertex.sign = nil
+ vertex.childlist = nil
+ vertex.adjlistlinks = nil
+ vertex.pertinentroots = nil
+ vertex.dfi = nil
+ vertex.dfsparent = nil
+ vertex.leastancestor = nil
+ vertex.lowpoint = nil
+ vertex.parentroot = nil
+ end
+
+ -- root vertex loop
+ for _, root in ipairs(rootvertices) do
+ -- make sure the links point to a half edges
+ -- that are no short circuit edge
+ local link = root.adjlistlinks[0]
+ while link.shortcircuit do
+ link = link.links[0]
+ end
+
+ -- merge into parent
+ local rootparent = root.rootparent
+ local parentlink = rootparent.link
+ local adjmat = rootparent.adjmat
+ for halfedge in Embedding.adjacency_iterator(link) do
+ setmetatable(halfedge, Embedding.halfedgemetatable)
+ halfedge.twin.target = rootparent
+ adjmat[halfedge.target] = halfedge
+ end
+ if parentlink == nil then
+ assert(rootparent.link == nil)
+ rootparent.link = link
+ else
+ -- merge adjacency lists
+ parentlink.links[0].links[1] = link
+ link.links[0].links[1] = parentlink
+ local tmp = link.links[0]
+ link.links[0] = parentlink.links[0]
+ parentlink.links[0] = tmp
+ end
+ end
+end
+
+-- the entry point of the algorithm
+-- returns the array of vertices
+-- the vertices now only contain the inputvertex field
+-- and a field named "link" which contains an arbitrary half edge
+-- from the respective adjacency list
+-- the adjacency lists are in a circular order in respect to the plane graph
+function BM:run()
+ self:preprocess()
+ -- main loop over all vertices from lowest dfi to highest
+ for i = self.numvertices, 1, -1 do
+ local vertex = self.vertices[i]
+ self:add_trivial_edges(vertex)
+ if not self:add_back_edges(vertex) then
+ -- graph not planar
+ return nil
+ end
+ end
+ self:postprocess()
+ local embedding = Embedding.new()
+ embedding.vertices = self.vertices
+ return embedding
+end
+
+return BM
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/Embedding.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/Embedding.lua
new file mode 100644
index 0000000000..8d9d3b53b1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/Embedding.lua
@@ -0,0 +1,788 @@
+local E = {}
+
+require("pgf.gd.planar").Embedding = E
+
+-- includes
+local LinkedList = require("pgf.gd.planar.LinkedList")
+
+E.vertexmetatable = {
+ __tostring = function(v)
+ if v.name then
+ return v.name
+ elseif v.inputvertex then
+ return v.inputvertex.name
+ else
+ return tostring(v)
+ end
+ end
+}
+
+E.halfedgemetatable = {
+ __tostring = function(e)
+ return tostring(e.twin.target)
+ .. " -> "
+ .. tostring(e.target)
+ end
+}
+
+-- create class properties
+E.__index = E
+
+function E.new()
+ local t = {
+ vertices = {},
+ }
+ setmetatable(t, E)
+ return t
+end
+
+function E:add_vertex(name, inputvertex, virtual)
+ virtual = virtual or nil
+ local vertex = {
+ adjmat = {},
+ name = name,
+ inputvertex = inputvertex,
+ virtual = virtual,
+ }
+ setmetatable(vertex, E.vertexmetatable)
+ table.insert(self.vertices, vertex)
+ return vertex
+end
+
+function E:add_edge(v1, v2, after1, after2, virtual)
+ assert(v1.link == nil or v1 == after1.twin.target)
+ assert(v2.link == nil or v2 == after2.twin.target)
+ assert(v1.adjmat[v2] == nil)
+ assert(v2.adjmat[v1] == nil)
+
+ virtual = virtual or nil
+
+ local halfedge1 = {
+ target = v2,
+ virtual = virtual,
+ links = {},
+ }
+ local halfedge2 = {
+ target = v1,
+ virtual = virtual,
+ links = {},
+ }
+ halfedge1.twin = halfedge2
+ halfedge2.twin = halfedge1
+
+ setmetatable(halfedge1, E.halfedgemetatable)
+ setmetatable(halfedge2, E.halfedgemetatable)
+
+ if v1.link == nil then
+ v1.link = halfedge1
+ halfedge1.links[0] = halfedge1
+ halfedge1.links[1] = halfedge1
+ else
+ halfedge1.links[0] = after1.links[0]
+ after1.links[0].links[1] = halfedge1
+ halfedge1.links[1] = after1
+ after1.links[0] = halfedge1
+ end
+
+ if v2.link == nil then
+ v2.link = halfedge2
+ halfedge2.links[0] = halfedge2
+ halfedge2.links[1] = halfedge2
+ else
+ halfedge2.links[0] = after2.links[0]
+ after2.links[0].links[1] = halfedge2
+ halfedge2.links[1] = after2
+ after2.links[0] = halfedge2
+ end
+
+ v1.adjmat[v2] = halfedge1
+ v2.adjmat[v1] = halfedge2
+
+ return halfedge1, halfedge2
+end
+
+function E:remove_virtual()
+ local virtuals = {}
+ for i, v in ipairs(self.vertices) do
+ if v.virtual then
+ table.insert(virtuals, i)
+ else
+ local start = v.link
+ local current = start
+ repeat
+ current = current.links[0]
+ if current.virtual then
+ current.links[0].links[1] = current.links[1]
+ current.links[1].links[0] = current.links[0]
+ v.adjmat[current.target] = nil
+ current.target.adjmat[v] = nil
+ end
+ until current == start
+ end
+ end
+ for i = #virtuals, 1, -1 do
+ self.vertices[virtuals[i]] = self.vertices[#self.vertices]
+ table.remove(self.vertices)
+ end
+end
+
+-- for the use in for-loops
+-- iterates over the adjacency list of a vertex
+-- given a half edge to start and a direction (0 or 1, default 0)
+function E.adjacency_iterator(halfedge, direction)
+ direction = direction or 0
+ local function next_edge(startedge, prevedge)
+ if prevedge == nil then
+ return startedge
+ else
+ local nextedge = prevedge.links[direction]
+ if nextedge ~= startedge then
+ return nextedge
+ else
+ return nil
+ end
+ end
+ end
+ return next_edge, halfedge, nil
+end
+
+function E.face_iterator(halfedge, direction)
+ direction = direction or 0
+ local function next_edge(startedge, prevedge)
+ if prevedge == nil then
+ return startedge
+ else
+ local nextedge = prevedge.twin.links[1 - direction]
+ if nextedge ~= startedge then
+ return nextedge
+ else
+ return nil
+ end
+ end
+ end
+ return next_edge, halfedge, nil
+end
+
+function E:triangulate()
+ local visited = {}
+ for _, vertex in ipairs(self.vertices) do
+ for start in E.adjacency_iterator(vertex.link) do
+ if not visited[start] then
+ local prev = start
+ local beforestart = start.links[0].twin
+ local current = start.twin.links[1]
+ local next = current.twin.links[1]
+ visited[start] = true
+ visited[current] = true
+ visited[next] = true
+ while next ~= beforestart do
+ local halfedge1, halfedge2
+ if vertex ~= current.target
+ and not vertex.adjmat[current.target] then
+ halfedge1, halfedge2 = self:add_edge(
+ vertex, current.target,
+ prev, next,
+ true
+ )
+
+ prev = halfedge1
+ current = next
+ next = next.twin.links[1]
+ elseif not prev.target.adjmat[next.target] then
+ halfedge1, halfedge2 = self:add_edge(
+ prev.target, next.target,
+ current, next.twin.links[1],
+ true
+ )
+
+ current = halfedge1
+ next = halfedge2.links[1]
+ else
+ local helper = next.twin.links[1]
+ halfedge1, halfedge2 = self:add_edge(
+ current.target, helper.target,
+ next, helper.twin.links[1],
+ true
+ )
+
+ next = halfedge1
+ end
+
+ visited[next] = true
+ visited[halfedge1] = true
+ visited[halfedge2] = true
+ end
+ end
+ end
+ end
+end
+
+function E:canonical_order(v1, v2, vn)
+ local n = #self.vertices
+ local order = { v1 }
+ local marks = { [v1] = "ordered", [v2] = 0 }
+ local visited = {}
+ local vk = v1
+ local candidates = LinkedList.new()
+ local listelements = {}
+ for k = 1, n-2 do
+ for halfedge in E.adjacency_iterator(vk.link) do
+ local vertex = halfedge.target
+ if vertex ~= vn then
+ local twin = halfedge.twin
+ visited[twin] = true
+ if marks[vertex] == nil then
+ marks[vertex] = "visited"
+ elseif marks[vertex] ~= "ordered" then
+ local neighbor1 = visited[twin.links[0]]
+ local neighbor2 = visited[twin.links[1]]
+ if marks[vertex] == "visited" then
+ if neighbor1 or neighbor2 then
+ marks[vertex] = 1
+ listelements[vertex] = candidates:addback(vertex)
+ else
+ marks[vertex] = 2
+ end
+ else
+ if neighbor1 == neighbor2 then
+ if neighbor1 and neighbor2 then
+ marks[vertex] = marks[vertex] - 1
+ else
+ marks[vertex] = marks[vertex] + 1
+ end
+ if marks[vertex] == 1 then
+ listelements[vertex]
+ = candidates:addback(vertex)
+ elseif listelements[vertex] then
+ candidates:remove(listelements[vertex])
+ listelements[vertex] = nil
+ end
+ end
+ end
+ end
+ end
+ end
+ vk = candidates:popfirst()
+ order[k+1] = vk
+ marks[vk] = "ordered"
+ end
+ order[n] = vn
+ return order
+end
+
+function E:get_biggest_face()
+ local number = 0
+ local edge
+ local visited = {}
+ for _, vertex in ipairs(self.vertices) do
+ for start in E.adjacency_iterator(vertex.link) do
+ local count = 0
+ if not visited[start] then
+ visited[start] = true
+ local current = start
+ repeat
+ count = count + 1
+ current = current.twin.links[1]
+ until current == start
+ if count > number then
+ number = count
+ edge = start
+ end
+ end
+ end
+ end
+ return edge, number
+end
+
+function E:surround_by_triangle(faceedge, facesize)
+ local divisor = 3
+ if facesize > 3 then
+ divisor = 4
+ end
+ local basenodes = math.floor(facesize / divisor)
+ local extranodes = facesize % divisor
+ local attachnodes = { basenodes, basenodes, basenodes }
+ if facesize > 3 then
+ attachnodes[2] = basenodes * 2
+ end
+ for i = 1,extranodes do
+ attachnodes[i] = attachnodes[i] + 1
+ end
+
+ local v = {
+ self:add_vertex("$v_1$", nil, true),
+ self:add_vertex("$v_n$", nil, true),
+ self:add_vertex("$v_2$", nil, true)
+ }
+ for i = 1,3 do
+ local currentv = v[i]
+ local nextv = v[i % 3 + 1]
+ self:add_edge(currentv, nextv, currentv.link, nextv.link, true)
+ end
+
+ local current = faceedge
+ local next = current.twin.links[1]
+ for i = 1,3 do
+ local vertex = v[i]
+ local otheredge = vertex.adjmat[v[i % 3 + 1]]
+ local previnserted = otheredge.links[1]
+ for count = 1, attachnodes[i] do
+ if not vertex.adjmat[current.target] then
+ previnserted, _ = self:add_edge(
+ vertex, current.target,
+ previnserted, next,
+ true
+ )
+ end
+
+ current = next
+ next = next.twin.links[1]
+ end
+ if not vertex.adjmat[current.target] then
+ previnserted, _ = self:add_edge(
+ vertex, current.target,
+ previnserted, next,
+ true
+ )
+ current = previnserted
+ end
+ end
+ return v[1], v[3], v[2]
+end
+
+function E:improve()
+ local pairdata = {}
+ local inpair = {}
+ for i, v1 in ipairs(self.vertices) do
+ for j = i + 1, #self.vertices do
+ local v2 = self.vertices[j]
+ local pd = self:find_pair_components(v1, v2)
+ if pd then
+ inpair[v1] = true
+ inpair[v2] = true
+ table.insert(pairdata, pd)
+ end
+ end
+ if not inpair[v1] then
+ local pd = self:find_pair_components(v1, nil)
+ if pd then
+ inpair[v1] = true
+ table.insert(pairdata, pd)
+ end
+ end
+ end
+
+ local changed
+ local runs = 1
+ local edgepositions = {}
+ repeat
+ changed = false
+ for i, pd in ipairs(pairdata) do
+ self:improve_separation_pair(pd)
+ end
+ -- check for changes
+ for i, v in ipairs(self.vertices) do
+ local start = v.link
+ local current = start
+ local counter = 1
+ repeat
+ if counter ~= edgepositions[current] then
+ changed = true
+ edgepositions[current] = counter
+ end
+ counter = counter + 1
+ current = current.links[0]
+ until current == start
+ end
+ runs = runs + 1
+ until changed == false or runs > 100
+end
+
+function E:find_pair_components(v1, v2)
+ local visited = {}
+ local companchors = {}
+ local edgecomps = {}
+ local compvertices = {}
+ local islinear = {}
+ local edgeindices = {}
+
+ local pair = { v1, v2 }
+ local start = v1.link
+ local current = start
+ local edgeindex = 1
+ -- start searches from v1
+ repeat
+ edgeindices[current] = edgeindex
+ edgeindex = edgeindex + 1
+ if not edgecomps[current] then
+ local compindex = #companchors + 1
+ local ca, il
+ edgecomps[current] = compindex
+ compvertices[compindex] = {}
+ local target = current.target
+ if target == v2 then
+ edgecomps[current.twin] = compindex
+ ca = 3
+ il = true
+ else
+ ca, il = self:component_dfs(
+ target,
+ pair,
+ visited,
+ edgecomps,
+ compvertices[compindex],
+ compindex
+ )
+ end
+ companchors[compindex] = ca
+ islinear[compindex] = il
+ end
+ current = current.links[0]
+ until current == start
+
+ if v2 then
+ start = v2.link
+ current = start
+ local lastincomp = true
+ local edgeindex = 1
+ -- now find the remaining blocks at v2
+ repeat
+ edgeindices[current] = edgeindex
+ edgeindex = edgeindex + 1
+ if not edgecomps[current] then
+ local compindex = #companchors + 1
+ edgecomps[current] = compindex
+ compvertices[compindex] = {}
+ self:component_dfs(
+ current.target,
+ pair,
+ visited,
+ edgecomps,
+ compvertices[compindex],
+ compindex
+ )
+ companchors[compindex] = 2
+ end
+ current = current.links[0]
+ until current == start
+ end
+
+ -- init compedges, tricomps, twocomps
+ local tricomps = {}
+ local twocomps = {{}, {}}
+ for i, anchors in ipairs(companchors) do
+ if anchors == 3 then
+ table.insert(tricomps, i)
+ else
+ table.insert(twocomps[anchors], i)
+ end
+ end
+
+ local flipimmune = #tricomps == 2
+ and (islinear[tricomps[1]] or islinear[tricomps[2]])
+ if (#tricomps < 2 or flipimmune)
+ and (v2 ~= nil or #twocomps[1] < 2) then
+ return nil
+ end
+
+ -- order tri comps cyclic
+ local function sorter(a, b)
+ return #compvertices[a] < #compvertices[b]
+ end
+
+ table.sort(tricomps, sorter)
+
+ -- determine order of comps
+ local numtricomps = #tricomps
+ local comporder = { {}, {} }
+ local bottom = math.ceil(numtricomps / 2)
+ local top = bottom + 1
+ for i, comp in ipairs(tricomps) do
+ if i % 2 == 1 then
+ comporder[1][bottom] = comp
+ comporder[2][numtricomps - bottom + 1] = comp
+ bottom = bottom - 1
+ else
+ comporder[1][top] = comp
+ comporder[2][numtricomps - top + 1] = comp
+ top = top + 1
+ end
+ end
+
+ local pairdata = {
+ pair = pair,
+ companchors = companchors,
+ edgecomps = edgecomps,
+ edgeindices = edgeindices,
+ compvertices = compvertices,
+ tricomps = tricomps,
+ twocomps = twocomps,
+ comporder = comporder,
+ }
+ return pairdata
+end
+
+function E:component_dfs(v, pair, visited, edgecomps, compvertices, compindex)
+ visited[v] = true
+ local start = v.link
+ local current = start
+ local companchors = 1
+ local numedges = 0
+ local islinear = true
+ table.insert(compvertices, v)
+ repeat
+ numedges = numedges + 1
+ local target = current.target
+ if target == pair[1] or target == pair[2] then
+ edgecomps[current.twin] = compindex
+ if target == pair[2] then
+ companchors = 3
+ end
+ elseif not visited[target] then
+ local ca, il = self:component_dfs(
+ target,
+ pair,
+ visited,
+ edgecomps,
+ compvertices,
+ compindex
+ )
+ if ca == 3 then
+ companchors = 3
+ end
+ islinear = islinear and il
+ end
+ current = current.links[0]
+ until current == start
+ return companchors, islinear and numedges == 2
+end
+
+function E:improve_separation_pair(pairdata)
+ local pair = pairdata.pair
+ local companchors = pairdata.companchors
+ local edgecomps = pairdata.edgecomps
+ local edgeindices = pairdata.edgeindices
+ local compvertices = pairdata.compvertices
+ local tricomps = pairdata.tricomps
+ local twocomps = pairdata.twocomps
+ local comporder = pairdata.comporder
+ local v1 = pair[1]
+ local v2 = pair[2]
+
+ local compedges = {}
+ for i = 1, #companchors do
+ compedges[i] = {{}, {}}
+ end
+
+ local numtricomps = #tricomps
+ local numtwocomps = { #twocomps[1], #twocomps[2] }
+
+ -- find compedges
+ for i = 1, #pair do
+ -- first find an edge that is the first of a triconnected component
+ local start2
+ if v2 then
+ start = pair[i].link
+ current = start
+ local last
+ repeat
+ local comp = edgecomps[current]
+ if companchors[comp] == 3 then
+ if last == nil then
+ last = comp
+ elseif last ~= comp then
+ start2 = current
+ break
+ end
+ end
+ current = current.links[0]
+ until current == start
+ else
+ start2 = pair[i].link
+ end
+ -- now list the edges by components
+ current = start2
+ repeat
+ table.insert(compedges[edgecomps[current]][i], current)
+ current = current.links[0]
+ until current == start2
+ end
+
+ -- count edges on each side of tri comps
+ local edgecount = {}
+ for _, comp in ipairs(tricomps) do
+ edgecount[comp] = {}
+ for i = 1, #pair do
+ local count = 1
+ local current = compedges[comp][i][1]
+ local other = pair[3 - i]
+ while current.target ~= other do
+ count = count + 1
+ current = current.twin.links[0]
+ end
+ edgecount[comp][i] = count
+ end
+ end
+
+ -- determine which comps have to be flipped
+ local flips = {}
+ local numflips = 0
+ local allflipped = true
+ for i, comp in ipairs(comporder[1]) do
+ local side1, side2
+ if i > numtricomps / 2 then
+ side1 = edgecount[comp][1]
+ side2 = edgecount[comp][2]
+ else
+ side1 = edgecount[comp][2]
+ side2 = edgecount[comp][1]
+ end
+ if side1 > side2 then
+ numflips = numflips + 1
+ flips[comp] = true
+ elseif side1 < side2 then
+ allflipped = false
+ end
+ end
+
+ if allflipped then
+ for i, comp in ipairs(tricomps) do
+ flips[comp] = false
+ end
+ else
+ for i, comp in ipairs(tricomps) do
+ if flips[comp] then
+ for _, v in ipairs(compvertices[comp]) do
+ local start = v.link
+ local current = start
+ repeat
+ current.links[0], current.links[1]
+ = current.links[1], current.links[0]
+ current = current.links[1]
+ until current == start
+ end
+ end
+ end
+ end
+
+ -- order edges cyclic per component (one cycle for all tri comps)
+ for i = 1, #pair do
+ if v2 then
+ local co
+ if allflipped then
+ co = comporder[3 - i]
+ else
+ co = comporder[i]
+ end
+
+ local id = co[numtricomps]
+ lastedges = compedges[id][i]
+ if flips[id] then
+ lastedge = lastedges[1]
+ else
+ lastedge = lastedges[#lastedges]
+ end
+
+ -- tri comps
+ for _, id in ipairs(co) do
+ local edges = compedges[id][i]
+ local from
+ local to
+ local step
+ if flips[id] then
+ from = #edges
+ to = 1
+ step = -1
+ else
+ from = 1
+ to = #edges
+ step = 1
+ end
+ for k = from, to, step do
+ local edge = edges[k]
+ lastedge.links[0] = edge
+ edge.links[1] = lastedge
+ lastedge = edge
+ end
+ end
+ end
+
+ -- two comps
+ for _, id in ipairs(twocomps[i]) do
+ lastedges = compedges[id][i]
+ lastedge = lastedges[#lastedges]
+ for _, edge in ipairs(compedges[id][i]) do
+ lastedge.links[0] = edge
+ edge.links[1] = lastedge
+ lastedge = edge
+ end
+ end
+ end
+
+ -- now merge the cycles
+ for i = 1, #pair do
+ local outeredges = {}
+ -- find the biggest face of the tri comps
+ if v2 then
+ local biggestedge
+ local biggestsize
+ local biggestindex
+ local start = compedges[tricomps[1]][i][1]
+ local current = start
+ repeat
+ local size = self:get_face_size(current)
+ if not biggestedge or size > biggestsize
+ or (size == biggestsize
+ and edgeindices[current] > biggestindex) then
+ biggestedge = current
+ biggestsize = size
+ biggestindex = edgeindices[current]
+ end
+ current = current.links[0]
+ until current == start
+ outeredges[1] = biggestedge
+ end
+
+ -- now for every two comp
+ for _, id in ipairs(twocomps[i]) do
+ local biggestedge
+ local biggestsize
+ local biggestindex
+ local start = compedges[id][i][1]
+ local current = start
+ repeat
+ local size = self:get_face_size(current)
+ if not biggestedge or size > biggestsize
+ or (size == biggestsize
+ and edgeindices[current] > biggestindex) then
+ biggestedge = current
+ biggestsize = size
+ biggestindex = edgeindices[current]
+ end
+ current = current.links[0]
+ until current == start
+ table.insert(outeredges, biggestedge)
+ end
+
+ -- now merge all comps at the outer edges
+ local lastedge = outeredges[#outeredges].links[0]
+ for _, edge in ipairs(outeredges) do
+ local nextlastedge = edge.links[0]
+ lastedge.links[1] = edge
+ edge.links[0] = lastedge
+ lastedge = nextlastedge
+ end
+ end
+end
+
+function E:get_face_size(halfedge)
+ local size = 0
+ local current = halfedge
+ repeat
+ size = size + 1
+ current = current.twin.links[1]
+ until current == halfedge
+ return size
+end
+
+return E
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/LinkedList.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/LinkedList.lua
new file mode 100644
index 0000000000..35f8418fdf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/LinkedList.lua
@@ -0,0 +1,88 @@
+local LinkedList = {}
+
+LinkedList.__index = LinkedList
+
+function LinkedList.new()
+ local list = {elements = {}}
+ setmetatable(list, LinkedList)
+ return list
+end
+
+function LinkedList:addback(payload)
+ if payload == nil then
+ error("Need a payload!", 2)
+ end
+ local element = { payload = payload }
+ if self.head then
+ local tail = self.head.prev
+ self.head.prev = element
+ tail.next = element
+ element.next = self.head
+ element.prev = tail
+ else
+ self.head = element
+ element.next = element
+ element.prev = element
+ end
+ self.elements[element] = true
+ return element
+end
+
+function LinkedList:addfront(payload)
+ self.head = self:addback(payload)
+ return self.head
+end
+
+function LinkedList:remove(element)
+ if self.elements[element] == nil then
+ error("Element not in list!", 2)
+ end
+ if self.head == element then
+ if element.next == element then
+ self.head = nil
+ else
+ self.head = element.next
+ end
+ end
+ element.prev.next = element.next
+ element.next.prev = element.prev
+ self.elements[element] = nil
+end
+
+function LinkedList:popfirst()
+ if self.head == nil then
+ return nil
+ end
+ local element = self.head
+ if element.next == element then
+ self.head = nil
+ else
+ self.head = element.next
+ element.next.prev = element.prev
+ element.prev.next = element.next
+ end
+ self.elements[element] = nil
+ return element.payload
+end
+
+function LinkedList:poplast()
+ if self.head == nil then
+ return nil
+ end
+ self.head = self.head.prev
+ return self:popfirst()
+end
+
+function LinkedList:first()
+ return self.head and self.head.payload
+end
+
+function LinkedList:last()
+ return self.head and self.head.prev.payload
+end
+
+function LinkedList:empty()
+ return self.head == nil
+end
+
+return LinkedList
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/List.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/List.lua
new file mode 100644
index 0000000000..22a91e6571
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/List.lua
@@ -0,0 +1,49 @@
+local List = {}
+
+List.__index = List
+
+function List.new()
+ local t = {first = 0, last = -1}
+ setmetatable(t, List)
+ return t
+end
+
+function List:pushleft(value)
+ local first = self.first - 1
+ self.first = first
+ self[first] = value
+end
+
+function List:pushright(value)
+ local last = self.last + 1
+ self.last = last
+ self[last] = value
+end
+
+function List:popleft()
+ local first = self.first
+ if first > self.last then error("List is empty") end
+ local value = self[first]
+ self[first] = nil
+ self.first = first + 1
+ return value
+end
+
+function List:popright()
+ local last = self.last
+ if self.first > last then error("List is empty") end
+ local value = self[last]
+ self[last] = nil
+ self.last = last - 1
+ return value
+end
+
+function List:size()
+ return self.last - self.first + 1
+end
+
+function List:empty()
+ return self.last < self.first
+end
+
+return List
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PDP.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PDP.lua
new file mode 100644
index 0000000000..8c159cf61d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PDP.lua
@@ -0,0 +1,576 @@
+
+local PDP = {}
+require("pgf.gd.planar").PDP = PDP
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+local Storage = require "pgf.gd.lib.Storage"
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Path = require "pgf.gd.model.Path"
+---
+PDP.__index = PDP
+
+function PDP.new(ugraph, embedding,
+ delta, gamma, coolingfactor,
+ expiterations,
+ startrepexp, endrepexp,
+ startattexp, endattexp,
+ appthreshold, stretchthreshold,
+ stresscounterthreshold,
+ numdivisions)
+ local t = {
+ ugraph = ugraph,
+ embedding = embedding,
+ delta = delta ,
+ gamma = gamma,
+ coolingfactor = coolingfactor,
+ expiterations = expiterations,
+ startrepexp = startrepexp,
+ endrepexp = endrepexp,
+ startattexp = startattexp,
+ endattexp = endattexp,
+ appthreshold = appthreshold,
+ stretchthreshold = stretchthreshold,
+ stresscounterthreshold = stresscounterthreshold,
+ numdivisions = numdivisions,
+ posxs = {},
+ posys = {},
+ cvsxs = {},
+ cvsys = {},
+ embeddingedges = {},
+ edgeids = {},
+ numedgeids = 0,
+ vertexids = {},
+ numvertexids = 0,
+ vertexpairs1 = {},
+ vertexpairs2 = {},
+ pairconnected = {},
+ edgepairsvertex = {},
+ edgepairsedge = {},
+ edgevertex1 = {},
+ edgevertex2 = {},
+ edgedeprecated = {},
+ subdivisionedges = {},
+ subdivisionvertices = {},
+ temperature = 1,
+ }
+
+ setmetatable(t, PDP)
+ return t
+end
+
+function PDP:run()
+ self:normalize_size()
+ self:find_force_pairs()
+
+ local delta = self.delta
+ local gamma = self.gamma
+ local coolingfactor = self.coolingfactor
+ local expiterations = self.expiterations
+ local startrepexp = self.startrepexp
+ local endattexp = self.endattexp
+ local startattexp = self.startattexp
+ local endrepexp = self.endrepexp
+
+ local vertexpairs1 = self.vertexpairs1
+ local vertexpairs2 = self.vertexpairs2
+ local pairconnected = self.pairconnected
+ local edgepairsvertex = self.edgepairsvertex
+ local edgepairsedge = self.edgepairsedge
+ local edgevertex1 = self.edgevertex1
+ local edgevertex2 = self.edgevertex2
+ local edgedeprecated = self.edgedeprecated
+
+ local forcexs = {}
+ local forceys = {}
+ local posxs = self.posxs
+ local posys = self.posys
+ local cvsxs = self.cvsxs
+ local cvsys = self.cvsys
+ local numcvs = {}
+ for i, v in ipairs(self.embedding.vertices) do
+ cvsxs[i] = {}
+ cvsys[i] = {}
+ posxs[i] = v.inputvertex.pos.x
+ posys[i] = v.inputvertex.pos.y
+ end
+
+ local numorigvertices = self.numvertexids
+ local numorigedges = self.numedgeids
+ local numdivisions = self.numdivisions
+ local divdelta = delta / (numdivisions + 1)
+ local stresscounter = {}
+ for i = 1, self.numedgeids do
+ stresscounter[i] = 0
+ end
+
+ local appthreshold = self.appthreshold
+ local stretchthreshold = self.stretchthreshold
+ local stresscounterthreshold = self.stresscounterthreshold
+
+ for i = 1, numorigedges do
+ local iv1 = self.embedding.vertices[edgevertex1[i]].inputvertex
+ local iv2 = self.embedding.vertices[edgevertex2[i]].inputvertex
+ local arc = self.ugraph:arc(iv1, iv2)
+ --TODO subdivide edge if desired
+ --self:subdivide_edge(i)
+ end
+
+ -- main loop
+ local iteration = 0
+ repeat
+ iteration = iteration + 1
+ local temperature = self.temperature
+ local ratio = math.min(1, iteration / expiterations)
+ local repexp = startrepexp + (endrepexp - startrepexp) * ratio
+ local attexp = startattexp + (endattexp - startattexp) * ratio
+ for i = 1, self.numvertexids do
+ forcexs[i] = 0
+ forceys[i] = 0
+ numcvs[i] = 0
+ end
+ -- vertex-vertex forces
+ for i = 1, #vertexpairs1 do
+ local id1 = vertexpairs1[i]
+ local id2 = vertexpairs2[i]
+ local diffx = posxs[id2] - posxs[id1]
+ local diffy = posys[id2] - posys[id1]
+ local dist2 = diffx * diffx + diffy * diffy
+ local dist = math.sqrt(dist2)
+ local dirx = diffx / dist
+ local diry = diffy / dist
+ assert(dist ~= 0)
+
+ local useddelta = delta
+ local hasdivvertex = id1 > numorigvertices or id2 > numorigvertices
+
+ -- calculate attractive force
+ if pairconnected[i] then
+ if hasdivvertex then
+ useddelta = divdelta
+ end
+ local mag = (dist / useddelta) ^ attexp * useddelta
+ local fax = mag * dirx
+ local fay = mag * diry
+ forcexs[id1] = forcexs[id1] + fax
+ forceys[id1] = forceys[id1] + fay
+ forcexs[id2] = forcexs[id2] - fax
+ forceys[id2] = forceys[id2] - fay
+ elseif hasdivvertex then
+ useddelta = gamma
+ end
+
+ -- calculate repulsive force
+ local mag = (useddelta / dist) ^ repexp * useddelta
+ local frx = mag * dirx
+ local fry = mag * diry
+ forcexs[id1] = forcexs[id1] - frx
+ forceys[id1] = forceys[id1] - fry
+ forcexs[id2] = forcexs[id2] + frx
+ forceys[id2] = forceys[id2] + fry
+ end
+
+ -- edge-vertex forces and collisions
+ for i = 1, #edgepairsvertex do
+ local edgeid = edgepairsedge[i]
+ if not edgedeprecated[edgeid] then
+ local id1 = edgepairsvertex[i]
+ local id2 = edgevertex1[edgeid]
+ local id3 = edgevertex2[edgeid]
+ assert(id2 ~= id1 and id3 ~= id1)
+
+ local abx = posxs[id3] - posxs[id2]
+ local aby = posys[id3] - posys[id2]
+ local dab2 = abx * abx + aby * aby
+ local dab = math.sqrt(dab2)
+ assert(dab ~= 0)
+ local abnx = abx / dab
+ local abny = aby / dab
+ local avx = posxs[id1] - posxs[id2]
+ local avy = posys[id1] - posys[id2]
+ local daiv = abnx * avx + abny * avy
+ local ivx = posxs[id2] + abnx * daiv
+ local ivy = posys[id2] + abny * daiv
+ local vivx = ivx - posxs[id1]
+ local vivy = ivy - posys[id1]
+ local dviv2 = vivx * vivx + vivy * vivy
+ local dviv = math.sqrt(dviv2)
+ local afactor, bfactor = 1, 1
+ local cvx
+ local cvy
+ if daiv < 0 then
+ cvx = -avx / 2
+ cvy = -avy / 2
+ local norm2 = cvx * cvx + cvy * cvy
+ bfactor = 1 + (cvx * abx + cvy * aby) / norm2
+ elseif daiv > dab then
+ cvx = (abx - avx) / 2
+ cvy = (aby - avy) / 2
+ local norm2 = cvx * cvx + cvy * cvy
+ afactor = 1 - (cvx * abx + cvy * aby) / norm2
+ else
+ if edgeid < numorigedges
+ and dviv < gamma * appthreshold
+ and dab > delta * stretchthreshold then
+ stresscounter[edgeid] = stresscounter[edgeid] + 1
+ end
+ assert(dviv > 0)
+ cvx = vivx / 2
+ cvy = vivy / 2
+ -- calculate edge repulsive force
+ local dirx = -vivx / dviv
+ local diry = -vivy / dviv
+ local mag = (gamma / dviv) ^ repexp * gamma
+ local fex = mag * dirx
+ local fey = mag * diry
+ local abratio = daiv / dab
+ forcexs[id1] = forcexs[id1] + fex
+ forceys[id1] = forceys[id1] + fey
+ forcexs[id2] = forcexs[id2] - fex * (1 - abratio)
+ forceys[id2] = forceys[id2] - fey * (1 - abratio)
+ forcexs[id3] = forcexs[id3] - fex * abratio
+ forceys[id3] = forceys[id3] - fey * abratio
+ end
+ local nv = numcvs[id1] + 1
+ local na = numcvs[id2] + 1
+ local nb = numcvs[id3] + 1
+ numcvs[id1] = nv
+ numcvs[id2] = na
+ numcvs[id3] = nb
+ cvsxs[id1][nv] = cvx
+ cvsys[id1][nv] = cvy
+ cvsxs[id2][na] = -cvx * afactor
+ cvsys[id2][na] = -cvy * afactor
+ cvsxs[id3][nb] = -cvx * bfactor
+ cvsys[id3][nb] = -cvy * bfactor
+ end
+ end
+
+ -- clamp forces
+ local scalefactor = 1
+ local collision = false
+ for i = 1, self.numvertexids do
+ local forcex = forcexs[i]
+ local forcey = forceys[i]
+ forcex = forcex * temperature
+ forcey = forcey * temperature
+ forcexs[i] = forcex
+ forceys[i] = forcey
+ local forcenorm2 = forcex * forcex + forcey * forcey
+ local forcenorm = math.sqrt(forcenorm2)
+ scalefactor = math.min(scalefactor, delta * 3 * temperature / forcenorm)
+ local cvys = cvsys[i]
+ for j, cvx in ipairs(cvsxs[i]) do
+ local cvy = cvys[j]
+ local cvnorm2 = cvx * cvx + cvy * cvy
+ local cvnorm = math.sqrt(cvnorm2)
+ local projforcenorm = (cvx * forcex + cvy * forcey) / cvnorm
+ if projforcenorm > 0 then
+ local factor = cvnorm * 0.9 / projforcenorm
+ if factor < scalefactor then
+ scalefactor = factor
+ collision = true
+ end
+ end
+ end
+ end
+ local moved = false
+ for i = 1, self.numvertexids do
+ local forcex = forcexs[i] * scalefactor
+ local forcey = forceys[i] * scalefactor
+ posxs[i] = posxs[i] + forcex
+ posys[i] = posys[i] + forcey
+ local forcenorm2 = forcex * forcex + forcey * forcey
+ if forcenorm2 > 0.0001 * delta * delta then moved = true end
+ end
+
+ -- subdivide stressed edges
+ if numdivisions > 0 then
+ for i = 1, numorigedges do
+ if stresscounter[i] > stresscounterthreshold then
+ self:subdivide_edge(i)
+ stresscounter[i] = 0
+ end
+ end
+ end
+ self.temperature = self.temperature * coolingfactor
+ until not collision and not moved
+ print("\nfinished PDP after " .. iteration .. " iterations")
+
+ -- write the positions back
+ for i, v in ipairs(self.embedding.vertices) do
+ v.inputvertex.pos.x = posxs[i]
+ v.inputvertex.pos.y = posys[i]
+ end
+
+ -- route the edges
+ for i = 1, self.numedgeids do
+ if self.subdivisionvertices[i] then
+ local iv1 = self.embedding.vertices[self.edgevertex1[i]].inputvertex
+ local iv2 = self.embedding.vertices[self.edgevertex2[i]].inputvertex
+ local arc = self.ugraph:arc(iv1, iv2)
+ local p = Path.new()
+ p:appendMoveto(arc.tail.pos:clone())
+ for _, vid in ipairs(self.subdivisionvertices[i]) do
+ p:appendLineto(self.posxs[vid], self.posys[vid])
+ end
+ p:appendLineto(arc.head.pos:clone())
+ arc.path = p
+ end
+ end
+end
+
+function PDP:subdivide_edge(edgeid)
+ assert(self.subdivisionedges[edgeid] == nil)
+ local numdivisions = self.numdivisions
+ local subdivisionedges = {}
+ local subdivisionvertices = {}
+ local id1 = self.edgevertex1[edgeid]
+ local id2 = self.edgevertex2[edgeid]
+ local x1 = self.posxs[id1]
+ local y1 = self.posys[id1]
+ local x2 = self.posxs[id2]
+ local y2 = self.posys[id2]
+ local prevvertexid = id1
+ for i = 1, numdivisions do
+ -- create new edge and vertex
+ local newvertexid1 = self.numvertexids + i
+ table.insert(subdivisionvertices, newvertexid1)
+ self.posxs[newvertexid1] = (x1 * (numdivisions + 1 - i) + x2 * i)
+ / (numdivisions + 1)
+ self.posys[newvertexid1] = (y1 * (numdivisions + 1 - i) + y2 * i)
+ / (numdivisions + 1)
+ self.cvsxs[newvertexid1] = {}
+ self.cvsys[newvertexid1] = {}
+
+ local newedgeid = self.numedgeids + i
+ table.insert(subdivisionedges, newedgeid)
+ table.insert(self.edgevertex1, prevvertexid)
+ table.insert(self.edgevertex2, newvertexid1)
+ prevvertexid = newvertexid1
+
+ -- pair the new vertex
+ -- with first vertex of the edge being divided
+ table.insert(self.vertexpairs1, self.edgevertex1[edgeid])
+ table.insert(self.vertexpairs2, newvertexid1)
+ table.insert(self.pairconnected, i == 1)
+
+ -- with second vertex of the edge being divided
+ table.insert(self.vertexpairs1, self.edgevertex2[edgeid])
+ table.insert(self.vertexpairs2, newvertexid1)
+ table.insert(self.pairconnected, i == numdivisions)
+
+ -- with each other
+ for j = i + 1, numdivisions do
+ local newvertexid2 = self.numvertexids + j
+ table.insert(self.vertexpairs1, newvertexid1)
+ table.insert(self.vertexpairs2, newvertexid2)
+ table.insert(self.pairconnected, j == i + 1)
+ end
+
+ -- with new edges
+ -- before vertex
+ for j = 1, i - 1 do
+ local newedgeid = self.numedgeids + j
+ table.insert(self.edgepairsvertex, newvertexid1)
+ table.insert(self.edgepairsedge, newedgeid)
+ end
+ -- after vertex
+ for j = i + 2, numdivisions + 1 do
+ local newedgeid = self.numedgeids + j
+ table.insert(self.edgepairsvertex, newvertexid1)
+ table.insert(self.edgepairsedge, newedgeid)
+ end
+
+ -- pair the new edges with vertices of the edge being divided
+ if i > 1 then
+ table.insert(self.edgepairsvertex, id1)
+ table.insert(self.edgepairsedge, newedgeid)
+ end
+ table.insert(self.edgepairsvertex, id2)
+ table.insert(self.edgepairsedge, newedgeid)
+ end
+ -- create last edge
+ table.insert(subdivisionedges, self.numedgeids + numdivisions + 1)
+ table.insert(self.edgevertex1, prevvertexid)
+ table.insert(self.edgevertex2, id2)
+
+ -- pair last edge with first vertex of the edge being divided
+ table.insert(self.edgepairsvertex, id1)
+ table.insert(self.edgepairsedge, self.numedgeids + numdivisions + 1)
+
+ self.subdivisionedges[edgeid] = subdivisionedges
+ self.subdivisionvertices[edgeid] = subdivisionvertices
+
+ -- pair new edges and vertices with existing edges and vertices
+ local sameface = false
+ local start = self.embeddingedges[edgeid]
+ local twin = start.twin
+ local donevertices = { [start.target] = true, [twin.target] = true }
+ local doneedges = { [start] = true, [twin] = true }
+ local current = start.twin.links[1]
+ for twice = 1, 2 do
+ while current ~= start do
+ if current == twin then
+ sameface = true
+ end
+
+ -- pair edge with the new vertices
+ -- or pair subdivision of edge with new vertices and edges
+ if not doneedges[current] then
+ local currentedgeid = self.edgeids[current]
+ if self.subdivisionvertices[currentedgeid] then
+ for _, vid in ipairs(self.subdivisionvertices[currentedgeid]) do
+ for i = 1, numdivisions do
+ local newvertexid = self.numvertexids + i
+ table.insert(self.vertexpairs1, vid)
+ table.insert(self.vertexpairs2, newvertexid)
+ self.pairconnected[#self.vertexpairs1] = false
+ end
+ for i = 1, numdivisions + 1 do
+ local newedgeid = self.numedgeids + i
+ table.insert(self.edgepairsvertex, vid)
+ table.insert(self.edgepairsedge, newedgeid)
+ end
+ end
+ for _, eid in ipairs(self.subdivisionedges[currentedgeid]) do
+ for i = 1, numdivisions do
+ local newvertexid = self.numvertexids + i
+ table.insert(self.edgepairsvertex, newvertexid)
+ table.insert(self.edgepairsedge, eid)
+ end
+ end
+ else
+ for i = 1, numdivisions do
+ local newvertexid = self.numvertexids + i
+ table.insert(self.edgepairsvertex, newvertexid)
+ table.insert(self.edgepairsedge, currentedgeid)
+ end
+ end
+ doneedges[current] = true
+ end
+
+ -- pair target vertex with the new vertices and edges
+ local vertexid = self.vertexids[current.target]
+ if not donevertices[current.target] then
+ for i = 1, numdivisions do
+ local newvertexid = self.numvertexids + i
+ table.insert(self.vertexpairs1, vertexid)
+ table.insert(self.vertexpairs2, newvertexid)
+ self.pairconnected[#self.vertexpairs1] = false
+ end
+ for i = 1, numdivisions + 1 do
+ local newedgeid = self.numedgeids + i
+ table.insert(self.edgepairsvertex, vertexid)
+ table.insert(self.edgepairsedge, newedgeid)
+ end
+ end
+ current = current.twin.links[1]
+ end
+ start = self.embeddingedges[edgeid].twin
+ current = start.twin.links[1]
+ if sameface then
+ break
+ end
+ end
+
+ self.edgedeprecated[edgeid] = true
+ self.numvertexids = self.numvertexids + numdivisions
+ self.numedgeids = self.numedgeids + numdivisions + 1
+end
+
+function PDP:find_force_pairs()
+ local donevertices = {}
+ -- number all vertices
+ local vertexids = self.vertexids
+ for i, v in ipairs(self.embedding.vertices) do
+ vertexids[v] = i
+ end
+ self.numvertexids = #self.embedding.vertices
+
+ local edgeids = self.edgeids
+ local numedgeids = 0
+ -- number all edges
+ for _, v in ipairs(self.embedding.vertices) do
+ local id = vertexids[v]
+ local start = v.link
+ local current = start
+ repeat
+ local targetid = vertexids[current.target]
+ if edgeids[current] == nil then
+ table.insert(self.edgevertex1, id)
+ table.insert(self.edgevertex2, targetid)
+ numedgeids = numedgeids + 1
+ edgeids[current] = numedgeids
+ edgeids[current.twin] = numedgeids
+ self.embeddingedges[numedgeids] = current
+ end
+ current = current.links[0]
+ until current == start
+ end
+
+ -- find all force pairs
+ for _, v in ipairs(self.embedding.vertices) do
+ local id = vertexids[v]
+ donevertices[id] = true
+ local vertexset = {}
+ local edgeset = {}
+ local start = v.link
+ repeat
+ local targetid = vertexids[start.target]
+ if vertexset[targetid] == nil and not donevertices[targetid] then
+ table.insert(self.pairconnected, true)
+ table.insert(self.vertexpairs1, id)
+ table.insert(self.vertexpairs2, targetid)
+ vertexset[targetid] = true
+ end
+ local current = start.twin.links[1]
+ while current.target ~= v do
+ local targetid = vertexids[current.target]
+ if vertexset[targetid] == nil and not donevertices[targetid] then
+ table.insert(self.pairconnected, self.ugraph:arc(v.inputvertex, current.target.inputvertex) ~= nil)
+ table.insert(self.vertexpairs1, id)
+ table.insert(self.vertexpairs2, targetid)
+ vertexset[targetid] = true
+ end
+ if edgeset[current] == nil then
+ table.insert(self.edgepairsvertex, id)
+ table.insert(self.edgepairsedge, edgeids[current])
+ edgeset[current] = true
+ edgeset[current.twin] = true
+ end
+ current = current.twin.links[1]
+ end
+ start = start.links[0]
+ until start == v.link
+ end
+
+ self.numedgeids = numedgeids
+end
+
+function PDP:normalize_size()
+ local minx = math.huge
+ local maxx = -math.huge
+ local miny = math.huge
+ local maxy = -math.huge
+
+ for _, v in ipairs(self.ugraph.vertices) do
+ minx = math.min(minx, v.pos.x)
+ maxx = math.max(maxx, v.pos.x)
+ miny = math.min(miny, v.pos.y)
+ maxy = math.max(maxy, v.pos.y)
+ end
+
+ local area = (maxx - minx) * (maxy - miny)
+ local gridarea = #self.ugraph.vertices * self.delta * self.delta
+
+ local scale = math.sqrt(gridarea) / math.sqrt(area)
+
+ for _, v in ipairs(self.ugraph.vertices) do
+ v.pos = v.pos * scale
+ end
+end
+
+-- done
+
+return PDP
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PlanarLayout.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PlanarLayout.lua
new file mode 100644
index 0000000000..9e5b8d72ec
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/PlanarLayout.lua
@@ -0,0 +1,159 @@
+
+
+local PlanarLayout = {}
+require("pgf.gd.planar").PlanarLayout = PlanarLayout
+
+-- imports
+local Coordinate = require "pgf.gd.model.Coordinate"
+local Storage = require "pgf.gd.lib.Storage"
+local BoyerMyrvold = require "pgf.gd.planar.BoyerMyrvold2004"
+local ShiftMethod = require "pgf.gd.planar.ShiftMethod"
+local Embedding = require "pgf.gd.planar.Embedding"
+local PDP = require "pgf.gd.planar.PDP"
+local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms")
+local createEdge = InterfaceToAlgorithms.createEdge
+local createVertex = InterfaceToAlgorithms.createVertex
+
+InterfaceToAlgorithms.declare {
+ key = "planar layout",
+ algorithm = PlanarLayout,
+ preconditions = {
+ connected = true,
+ loop_free = true,
+ simple = true,
+ },
+ postconditions = {
+ fixed = true,
+ },
+ summary = [["
+ The planar layout draws planar graphs without edge crossings.
+ "]],
+ documentation = [["
+ The planar layout is a pipeline of algorithms to produce
+ a crossings-free drawing of a planar graph.
+ First a combinatorical embedding of the graph is created using
+ the Algorithm from Boyer and Myrvold.
+ The combinatorical Embedding is then being improved by
+ by the Sort and Flip algorithm and triangulated afterwards.
+ To determine the actual node positions the shift method
+ by de Fraysseix, Pach and Pollack is used.
+ Finally the force based Planar Drawing Postprocessing improves the drawing.
+ "]],
+ examples = {
+ [["
+ \tikz \graph [nodes={draw, circle}] {
+ a -- {
+ b -- {
+ d -- i,
+ e,
+ f
+ },
+ c -- {
+ g,
+ h
+ }
+ },
+ f --[no span edge] a,
+ h --[no span edge] a,
+ i --[no span edge] g,
+ f --[no span edge] g,
+ c --[no span edge] d,
+ e --[no span edge] c
+ }
+ "]]
+ }
+}
+
+function PlanarLayout:run()
+ --local file = io.open("timing.txt", "a")
+
+ local options = self.digraph.options
+
+ -- get embedding
+ local bm = BoyerMyrvold.new()
+ bm:init(self.ugraph)
+ local embedding = bm:run()
+
+ assert(embedding, "Graph is not planar")
+
+ --local start = os.clock()
+ if options["use sf"] then
+ embedding:improve()
+ end
+
+ -- choose external face
+ local exedge, exsize = embedding:get_biggest_face()
+
+ -- surround graph with triangle
+ local v1, v2, vn = embedding:surround_by_triangle(exedge, exsize)
+
+ -- make maximal planar
+ embedding:triangulate()
+
+ if options["show virtual"] then
+ -- add virtual vertices to input graph
+ for _, vertex in ipairs(embedding.vertices) do
+ if vertex.virtual then
+ vertex.inputvertex = createVertex(self, {
+ name = nil,--vertex.name,
+ generated_options = {},
+ text = vertex.name
+ })
+ vertex.virtual = false
+ end
+ end
+
+ -- add virtual edges to input graph
+ for _, vertex in ipairs(embedding.vertices) do
+ for halfedge in Embedding.adjacency_iterator(vertex.link) do
+ if halfedge.virtual then
+ createEdge(
+ self,
+ vertex.inputvertex,
+ halfedge.target.inputvertex
+ )
+ end
+ halfedge.virtual = false
+ end
+ end
+ end
+
+ -- create canonical ordering
+ local order = embedding:canonical_order(v1, v2, vn)
+
+ local sm = ShiftMethod.new()
+ sm:init(order)
+ local gridpos = sm:run()
+
+ local gridspacing = options["grid spacing"]
+ for _, v in ipairs(order) do
+ if not v.virtual then
+ local iv = v.inputvertex
+ iv.pos.x = gridpos[v].x * gridspacing
+ iv.pos.y = gridpos[v].y * gridspacing
+ end
+ end
+
+ embedding:remove_virtual()
+
+ --start = os.clock()
+ if options["use pdp"] then
+ local pdp = PDP.new(
+ self.ugraph, embedding,
+ options["node distance"],
+ options["node distance"],
+ options["pdp cooling factor"],
+ options["exponent change iterations"],
+ options["start repulsive exponent"],
+ options["end repulsive exponent"],
+ options["start attractive exponent"],
+ options["end attractive exponent"],
+ options["edge approach threshold"],
+ options["edge stretch threshold"],
+ options["stress counter threshold"],
+ options["edge divisions"]
+ )
+ pdp:run()
+ end
+
+end
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/ShiftMethod.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/ShiftMethod.lua
new file mode 100644
index 0000000000..c568ca5696
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/ShiftMethod.lua
@@ -0,0 +1,128 @@
+local SM = {}
+require("pgf.gd.planar").ShiftMethod = SM
+
+-- imports
+local Embedding = require("pgf.gd.planar.Embedding")
+
+-- create class properties
+SM.__index = SM
+
+function SM.new()
+ local t = {}
+ setmetatable(t, SM)
+ return t
+end
+
+function SM:init(vertices)
+ self.vertices = vertices
+ self.xoff = {}
+ self.pos = {}
+ for _, v in ipairs(vertices) do
+ self.pos[v] = {}
+ end
+ self.left = {}
+ self.right = {}
+end
+
+function SM:run()
+ local v1 = self.vertices[1]
+ local v2 = self.vertices[2]
+ local v3 = self.vertices[3]
+
+ self.xoff[v1] = 0
+ self.pos[v1].y = 0
+ self.right[v1] = v3
+
+ self.xoff[v3] = 1
+ self.pos[v3].y = 1
+ self.right[v3] = v2
+
+ self.xoff[v2] = 1
+ self.pos[v2].y = 0
+
+ local n = #self.vertices
+ for k = 4, n do
+ local vk = self.vertices[k]
+ local wplink, wqlink, wp1qsum
+ if k ~= n then
+ wplink, wqlink, wp1qsum = self:get_attachments(vk)
+ else
+ wplink, wqlink, wp1qsum = self:get_last_attachments(vk, v1, v2)
+ end
+ local wp, wq = wplink.target, wqlink.target
+ local wp1 = wplink.links[0].target
+ local wq1 = wqlink.links[1 - 0].target
+ self.xoff[wp1] = self.xoff[wp1] + 1
+ self.xoff[wq] = self.xoff[wq] + 1
+ wp1qsum = wp1qsum + 2
+ self.xoff[vk] = (wp1qsum + self.pos[wq].y - self.pos[wp].y) / 2
+ self.pos[vk].y = (wp1qsum + self.pos[wq].y + self.pos[wp].y) / 2
+ -- = self.xoff[vk] + self.pos[wp].y ?
+ self.right[wp] = vk
+ if wp ~= wq1 then
+ self.left[vk] = wp1
+ self.right[wq1] = nil
+ self.xoff[wp1] = self.xoff[wp1] - self.xoff[vk]
+ end
+ self.right[vk] = wq
+ self.xoff[wq] = wp1qsum - self.xoff[vk]
+ end
+ self.pos[v1].x = 0
+ self:accumulate_offset(v1, 0)
+ return self.pos
+end
+
+function SM:get_attachments(vk)
+ local wplink, wqlink
+ local wp1qsum = 0
+ local start = vk.link
+ local startattach = self.xoff[start.target] ~= nil
+ local current = start.links[0]
+ local last = start
+ repeat
+ local currentattach = self.xoff[current.target] ~= nil
+ local lastattach = self.xoff[last.target] ~= nil
+ if currentattach ~= lastattach then
+ if currentattach then
+ wplink = current
+ else
+ wqlink = last
+ end
+ if currentattach == startattach and not startattach then
+ break
+ end
+ currentattach = lastattach
+ elseif currentattach then
+ wp1qsum = wp1qsum + self.xoff[current.target]
+ end
+ last = current
+ current = current.links[0]
+ until last == start
+ return wplink, wqlink, wp1qsum
+end
+
+function SM:get_last_attachments(vn, v1, v2)
+ local wplink, wqlink
+ local wp1qsum = 0
+ for halfedge in Embedding.adjacency_iterator(vn.link, ccwdir) do
+ local target = halfedge.target
+ if target == v1 then
+ wplink = halfedge
+ elseif target == v2 then
+ wqlink = halfedge
+ end
+ wp1qsum = wp1qsum + self.xoff[target]
+ end
+ return wplink, wqlink, wp1qsum
+end
+
+function SM:accumulate_offset(v, x)
+ x = x + self.xoff[v]
+ self.pos[v].x = x
+ local l = self.left[v]
+ local r = self.right[v]
+ if l then self:accumulate_offset(l, x) end
+ if r then self:accumulate_offset(r, x) end
+end
+
+return SM
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/library.lua
new file mode 100644
index 0000000000..68c46898e3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/library.lua
@@ -0,0 +1,2 @@
+require "pgf.gd.planar.PlanarLayout"
+require "pgf.gd.planar.parameters"
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/parameters.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/parameters.lua
new file mode 100644
index 0000000000..603f2ee7cc
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/planar/parameters.lua
@@ -0,0 +1,144 @@
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+declare {
+ key = "use pdp",
+ type = "boolean",
+ initial = "true",
+
+ summary = [["
+ Whether or not to use the Planar Drawing Postprocessing
+ to improve the drawing.
+ "]]
+}
+
+declare {
+ key = "use sf",
+ type = "boolean",
+ initial = "true",
+
+ summary = [["
+ Whether or not to use the Sort and Flip Algorithm
+ to improve the combinatorical embedding.
+ "]]
+}
+
+declare {
+ key = "grid spacing",
+ type = "number",
+ initial = "10",
+
+ summary = [["
+ If the |use pdp| option is not set,
+ this sets the spacing of the grid used by the shift method.
+ A bigger grid spacing will result in a bigger drawing.
+ "]]
+}
+
+declare {
+ key = "pdp cooling factor",
+ type = "number",
+ initial = "0.98",
+
+ summary = [["
+ This sets the cooling factor used by the Planar Drawing Postprocessing.
+ A higher cooling factor can result in better quality of the drawing,
+ but will increase the run time of the algorithm.
+ "]]
+}
+
+declare {
+ key = "start repulsive exponent",
+ type = "number",
+ initial = "2",
+
+ summary = [["
+ Start value of the exponent used in the calculation of all repulsive forces in PDP
+ "]]
+}
+
+declare {
+ key = "end repulsive exponent",
+ type = "number",
+ initial = "2",
+
+ summary = [["
+ End value of the exponent used in the calculation of all repulsive forces in PDP.
+ "]]
+}
+
+declare {
+ key = "start attractive exponent",
+ type = "number",
+ initial = "2",
+
+ summary = [["
+ Start value of the exponent used in PDP's calculation of the attractive force between
+ nodes connected by an edge.
+ "]]
+}
+
+declare {
+ key = "end attractive exponent",
+ type = "number",
+ initial = "2",
+
+ summary = [["
+ End value of the exponent used in PDP's calculation of the attractive force between
+ nodes connected by an edge.
+ "]]
+}
+
+declare {
+ key = "exponent change iterations",
+ type = "number",
+ initial = "1",
+
+ summary = [["
+ The number of iterations over which to modify the force exponents.
+ In iteration one the exponents will have their start value and in iteration
+ |exponent change iterations| they will have their end value.
+ "]]
+}
+
+declare {
+ key = "edge approach threshold",
+ type = "number",
+ initial = "0.3",
+
+ summary = [["
+ The maximum ration between the actual and the desired node-edge distance
+ which is required to count an edge as stressed.
+ "]]
+}
+
+declare {
+ key = "edge stretch threshold",
+ type = "number",
+ initial = "1.5",
+
+ summary = [["
+ The minimum ration between the actual and the desired edge length
+ which is required to count an edge as stressed.
+ "]]
+}
+
+declare {
+ key = "stress counter threshold",
+ type = "number",
+ initial = "30",
+
+ summary = [["
+ The number of iterations an edge has to be under stress before it will be subdivided.
+ "]]
+}
+
+declare {
+ key = "edge divisions",
+ type = "number",
+ initial = "0",
+
+ summary = [["
+ The number of edges in which stressed edges will be subdivided.
+ "]]
+}
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing.lua
new file mode 100644
index 0000000000..77166c5cbf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing.lua
@@ -0,0 +1,22 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+
+local routing = {}
+
+-- Declare namespace
+require("pgf.gd").routing = routing
+
+
+-- Done
+
+return routing \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/Hints.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/Hints.lua
new file mode 100644
index 0000000000..7d34726f47
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/Hints.lua
@@ -0,0 +1,100 @@
+-- Copyright 2014 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+---
+-- The |Hints| class provides a way for graph drawing algorithms to
+-- communicate certain possibilities concerning the routing of edges
+-- to edge routing algorithms. This partly decouples the choice of the
+-- vertex positioning algorithms from the choice of edge routing
+-- algorithm. For instance, for a simple necklace routing, it is
+-- unclear whether the edges on the necklace should be routing ``along
+-- the necklace'' or not. Thus, necklace routing algorithms will
+-- ``hint'' that a necklace is present and only when the
+-- |necklace routing| algorithm is selected will these hints lead to
+-- actual bending of edges.
+--
+-- For each kind of hint, there are methods in this class for creating
+-- the hints and other methods for reading them. Hints are always
+-- local to the ugraph.
+
+local Hints = {}
+
+-- Namespace
+require("pgf.gd.routing").Hints = Hints
+
+-- Imports
+local Storage = require("pgf.gd.lib.Storage")
+local Coordinate = require("pgf.gd.model.Coordinate")
+
+
+
+
+-- The necklace storage
+
+local necklaces = Storage.new()
+
+
+---
+-- Adds a necklace hint. In this case, the hint indicates that the
+-- given sequence of vertices lie on a circle.
+--
+-- The idea is that an algorithm may specify that in a
+-- given graph certain sequences of nodes form a ``necklace'', which
+-- is typically a circle. There may be more than one necklace inside a
+-- given graph. For each necklace,
+-- whenever an arc connects subsequent nodes on the necklace, they get
+-- bend in such a way that they lie follow the path of the
+-- necklace. If an arc lies on more than one necklace, the ``last one
+-- wins''.
+--
+-- @param ugraph The ugraph to which this hint is added
+-- @param necklace The sequence of vertices that form the necklace. If
+-- the necklace is closed, the last vertex must equal the first one.
+-- @param center If provided, must be |Coordinate| that specifies the
+-- center of the circle on which the vertices lie. If not provided,
+-- the origin is assumed.
+-- @param clockwise If |true|, the vertices are in clockwise order,
+-- otherwise in counter-clockwise order.
+
+function Hints.addNecklaceCircleHint(ugraph, necklace, center, clockwise)
+ local a = necklaces[ugraph] or {}
+ necklaces[ugraph] = a
+
+ a[#a+1] = {
+ necklace = necklace,
+ center = center or Coordinate.origin,
+ clockwise = clockwise
+ }
+end
+
+
+---
+-- Gets the necklace hints.
+--
+-- This function will return an array whose entries are necklace
+-- hints. Each entry in the array has a |necklace| field, which is the
+-- field passed to the |addNecklaceXxxx| methods. For a circle
+-- necklace, the |center| and |clockwise| fields will be set. (Other
+-- necklaces are not yet implemented.)
+--
+-- @param ugraph The ugraph for which the necklace hints are
+-- requested.
+-- @return The array of necklaces as described above.
+
+function Hints.getNecklaceHints(ugraph)
+ return necklaces[ugraph] or {}
+end
+
+-- done
+
+return Hints
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/NecklaceRouting.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/NecklaceRouting.lua
new file mode 100644
index 0000000000..defcf9f8c6
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/NecklaceRouting.lua
@@ -0,0 +1,90 @@
+-- Copyright 2014 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- The class; it processes necklace hints.
+
+local NecklaceRouting = {}
+
+
+-- Namespace
+require("pgf.gd.routing").NecklaceRouting = NecklaceRouting
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+local Hints = require "pgf.gd.routing.Hints"
+local Path = require "pgf.gd.model.Path"
+
+
+---
+declare {
+ key = "necklace routing",
+ algorithm = NecklaceRouting,
+
+ phase = "edge routing",
+
+ summary = "Bends all edges of a graph that lie on ``necklaces'' along these necklaces.",
+
+ documentation = [["
+ Some graph drawing algorithms lay out some or all nodes along a
+ path, which is then called a \emph{necklace}. For instance, the
+ |simple necklace layout| places all nodes on a circle and that
+ circle is the ``necklace''. When the |necklace routing| edge
+ routing algorithm is selected, all edges that connect subsequent
+ nodes on such a necklace are bend in such a way that the
+ ``follow the necklace path''. In the example case, this will
+ cause all edges that connect adjacent nodes to become arcs on
+ of the circle on which the nodes lie.
+
+ Note that local edge routing options for an edge may overrule
+ the edge routing computed by the algorithm as in the edge from 6
+ to 7 in the example.
+ "]],
+
+ examples = [["
+ \tikz \graph [simple necklace layout, node distance=1.5cm,
+ necklace routing,
+ nodes={draw,circle}, edges={>={Stealth[round,sep,bend]}}]
+ { 1 -> 2 [minimum size=30pt] <- 3 <-> 4 --
+ 5 -- 6 -- [bend left] 7 -- 1 -- 4 };
+ "]]
+}
+
+
+
+-- The implementation
+
+function NecklaceRouting:run()
+ local ugraph = self.ugraph
+
+ for _,entry in ipairs(Hints.getNecklaceHints(ugraph)) do
+ assert (entry.center) -- no other necklace types, yet
+ local prev
+ for _,vertex in ipairs(entry.necklace) do
+ if prev then
+ local a = ugraph:arc(prev, vertex)
+ if a then
+ local p = Path.new()
+ p:appendMoveto(a.tail.pos:clone())
+ p:appendArcTo(a.head.pos:clone(), entry.center, entry.clockwise)
+ a.path = p
+ end
+ end
+ prev = vertex
+ end
+ end
+end
+
+
+-- done
+
+return NecklaceRouting
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/library.lua
new file mode 100644
index 0000000000..17c959d685
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/routing/library.lua
@@ -0,0 +1,29 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+-- Imports
+local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare
+
+---
+-- This library contains algorithms for routing edges through a graph.
+--
+-- @library
+
+local routing -- Library name
+
+-- Load declarations from:
+
+-- Load algorithms from:
+require "pgf.gd.routing.NecklaceRouting"
+
+
+-- General declarations
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua
new file mode 100644
index 0000000000..a0aee6501c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua
@@ -0,0 +1,183 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This program generates a C wrap file around graph drawing
+-- algorithms. The idea is that when you have a graph drawing
+-- algorithm implemented in C and wish to invoke it from Lua, you need
+-- a wrapper that manages the translation between Lua and C. This
+-- program is intended to make it (reasonably) easy to produce such a
+-- wrapper.
+
+
+
+-- Sufficient number of arguments?
+
+if #arg < 4 or arg[1] == "-h" or arg[1] == "-?" or arg[1] == "--help" then
+ print([["
+Usage: make_gd_wrap library1 library2 ... libraryn template library_name target_c_file
+
+This program will read all of the graph drawing library files using
+Lua's require. Then, it will iterate over all declared algorithm keys
+(declared using declare { algorithm_written_in_c = ... }) and will
+produce the code for library for the required target C files based on
+the template.
+"]])
+ os.exit()
+end
+
+
+-- Imports
+
+local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay"
+local InterfaceCore = require "pgf.gd.interface.InterfaceCore"
+
+
+-- Ok, setup:
+
+InterfaceToDisplay.bind(require "pgf.gd.bindings.Binding")
+
+
+-- Now, read all libraries:
+
+for i=1,#arg-3 do
+ require(arg[i])
+end
+
+
+-- Now, read the template:
+
+local file = io.open(arg[#arg-2])
+local template = file:read("*a")
+file:close()
+
+-- Let us grab the declaration:
+
+local functions_dec = (template:match("%$functions(%b{})") or ""):match("^{(.*)}$")
+local functions_reg_dec = (template:match("%$functions_registry(%b{})") or ""):match("^{(.*)}$")
+local factories_dec = (template:match("%$factories(%b{})") or ""):match("^{(.*)}$")
+local factories_reg_dec = (template:match("%$factories_registry(%b{})") or ""):match("^{(.*)}$")
+
+-- Now, handle all keys with a algorithm_written_in_c field
+
+local keys = InterfaceCore.keys
+local filename = arg[#arg]
+local target = arg[#arg-1]
+
+local includes = {}
+local functions = {}
+local functions_registry = {}
+
+local factories = {}
+local factories_reg = {}
+
+for _,k in ipairs(keys) do
+
+ if k.algorithm_written_in_c and k.code then
+
+ local library, fun_name = k.algorithm_written_in_c:match("(.*)%.(.*)")
+
+ if target == library then
+ -- First, gather the includes:
+ if type(k.includes) == "string" then
+ if not includes[k.includes] then
+ includes[#includes + 1] = k.includes
+ includes[k.includes] = true
+ end
+ elseif type(k.includes) == "table" then
+ for _,i in ipairs(k.includes) do
+ if not includes[i] then
+ includes[#includes + 1] = i
+ includes[i] = true
+ end
+ end
+ end
+
+ -- Second, create a code block:
+ functions[#functions+1] = functions_dec:gsub("%$([%w_]-)%b{}",
+ {
+ function_name = fun_name,
+ function_body = k.code
+ })
+
+ -- Third, create functions_registry entry
+ functions_registry[#functions_registry + 1] = functions_reg_dec:gsub("%$([%w_]-)%b{}",
+ {
+ function_name = fun_name,
+ function_body = k.code
+ })
+ end
+ end
+
+
+ if k.module_class then
+
+ -- First, gather the includes:
+ if type(k.includes) == "string" then
+ if not includes[k.includes] then
+ includes[#includes + 1] = k.includes
+ includes[k.includes] = true
+ end
+ elseif type(k.includes) == "table" then
+ for _,i in ipairs(k.includes) do
+ if not includes[i] then
+ includes[#includes + 1] = i
+ includes[i] = true
+ end
+ end
+ end
+
+ -- Second, create a code block:
+ factories[#factories+1] = factories_dec:gsub(
+ "%$([%w_]-)%b{}",
+ {
+ factory_class = k.module_class,
+ factory_code = k.code,
+ factory_base = k.module_base,
+ factory_name = k.module_class .. '_factory'
+ })
+
+ -- Third, create factories_registry entry
+ factories_reg[#factories_reg + 1] = factories_reg_dec:gsub(
+ "%$([%w_]-)%b{}",
+ {
+ factory_class = k.module_class,
+ factory_code = k.code,
+ factory_base = k.module_base,
+ factory_name = k.module_class .. '_factory'
+ })
+ end
+end
+
+
+local file = io.open(filename, "w")
+
+if not file then
+ print ("failed to open file " .. filename)
+ os.exit(-1)
+end
+
+file:write ((template:gsub(
+ "%$([%w_]-)%b{}",
+ {
+ factories = table.concat(factories, "\n\n"),
+ factories_registry = table.concat(factories_reg, "\n"),
+ functions = table.concat(functions, "\n\n"),
+ functions_registry = table.concat(functions_registry, "\n"),
+ includes = table.concat(includes, "\n"),
+ library_c_name = target:gsub("%.", "_"),
+ library_name = target
+ })))
+file:close()
+
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees.lua
new file mode 100644
index 0000000000..8c45e912dc
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees.lua
@@ -0,0 +1,21 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+--- @release $Header$
+
+
+local trees = {}
+
+-- Declare namespace
+require("pgf.gd").trees = tree
+
+
+-- Done
+
+return trees \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua
new file mode 100644
index 0000000000..cc3c18d12c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua
@@ -0,0 +1,226 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Specifying Missing Children}
+-- \label{section-gd-missing-children}
+--
+-- In the present section we discuss keys for specifying missing children
+-- in a tree. For many certain kind of trees, in particular for binary
+-- trees, there are not just ``a certain number of children'' at each
+-- node, but, rather, there is a designated ``first'' (or ``left'') child
+-- and a ``second'' (or ``right'') child. Even if one of these children
+-- is missing and a node actually has only one child, the single child will
+-- still be a ``first'' or ``second'' child and this information should
+-- be taken into consideration when drawing a tree.
+--
+-- The first useful key for specifying missing children is
+-- |missing number of children| which allows you to state how many
+-- children there are, at minimum.
+--
+-- Once the minimum number of children has been set, we still need a way
+-- of specifying ``missing first children'' or, more generally, missing
+-- children that are not ``at the end'' of the list of children. For
+-- this, there are three methods:
+-- %
+-- \begin{enumerate}
+-- \item When you use the |child| syntax, you can use the |missing| key
+-- with the |child| command to indicate a missing child:
+-- %
+-- \begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+-- \usegdlibrary{trees}}]
+-- \tikz [binary tree layout, level distance=5mm]
+-- \node {a}
+-- child { node {b}
+-- child { node {c}
+-- child { node {d} }
+-- } }
+-- child { node {e}
+-- child [missing]
+-- child { node {f}
+-- child [missing]
+-- child { node {g}
+-- } } };
+-- \end{codeexample}
+-- %
+-- \item When using the |graph| syntax, you can use an ``empty node'',
+-- which really must be completely empty and may not even contain a
+-- slash, to indicate a missing node:
+-- %
+-- \begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+-- \usegdlibrary{trees}}]
+-- \tikz [binary tree layout, level distance=5mm]
+-- \graph { a -> { b -> c -> d, e -> { , f -> { , g} } } };
+-- \end{codeexample}
+-- %
+-- \item You can simply specify the index of a child directly using
+-- the key |desired child index|.
+-- \end{enumerate}
+--
+-- @end
+
+
+-- Imports
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+---
+--
+declare {
+ key = "minimum number of children",
+ type = "number",
+ initial = "0",
+
+ summary = [["
+ Specifies how many children a tree node must have at least. If
+ there are less, ``virtual'' children are added.
+ "]],
+ documentation = [["
+ When this key is set to |2| or more, the following happens: We first
+ compute a spanning tree for the graph, see
+ Section~\ref{subsection-gd-spanning-tree}. Then, whenever a node is
+ not a leaf in this spanning tree (when it has at least one child),
+ we add ``virtual'' or ``dummy'' nodes as children of the node until
+ the total number of real and dummy children is at least
+ \meta{number}. If there where at least \meta{number} children at the
+ beginning, nothing happens.
+
+ The new children are added after the existing children. This means
+ that, for instance, in a tree with \meta{number} set to |2|, for
+ every node with a single child, this child will be the first child
+ and the second child will be missing.
+ "]],
+ examples = [["
+ \tikz \graph [binary tree layout,level distance=5mm]
+ { a -> { b->c->d, e->f->g } };
+ "]]
+}
+
+---
+
+declare {
+ key = "desired child index",
+ type = "number",
+
+ summary = [["
+ Pass this key to a node to tell the graph drawing engine which child
+ number you ``desired'' for the node. Whenever all desires for the
+ children of a node are conflict-free, they will all be met; children
+ for which no desired indices were given will remain at their
+ position, whenever possible, but will ``make way'' for children with
+ a desired position.
+ "]],
+ documentation = [["
+ In detail, the following happens: We first
+ determine the total number of children (real or dummy) needed, which
+ is the maximum of the actual number of children, of the
+ \texttt{minimum number of children}, and of the highest desired
+ child index. Then we go over all children that have a desired child
+ index and put they at this position. If the position is already
+ taken (because some other child had the same desired index), the
+ next free position is used with a wrap-around occurring at the
+ end. Next, all children without a desired index are place using the
+ same mechanism, but they want to be placed at the position they had
+ in the original spanning tree.
+
+ While all of this might sound a bit complicated, the application of
+ the key in a binary tree is pretty straightforward: To indicate that
+ a node is a ``right'' child in a tree, just add \texttt{desired child index=2}
+ to it. This will make it a second child, possibly causing the first
+ child to be missing. If there are two nodes specified as children of
+ a node, by saying \texttt{desired child index=}\meta{number} for one
+ of them, you will cause it be first or second child, depending on
+ \meta{number}, and cause the \emph{other} child to become the other
+ child.
+
+ Since |desired child index=2| is a bit long, the following shortcuts
+ are available: |first|, |second|, |third|, and |fourth|.
+ You might wonder why |second| is used rather than |right|. The
+ reason is that trees may also grow left and right and, additionally,
+ the |right| and |left| keys are already in use for
+ anchoring. Naturally, you can locally redefine them, if you want.
+ "]],
+ examples = {[["
+ \tikz \graph [binary tree layout, level distance=5mm]
+ { a -> b[second] };
+ "]],[["
+ \tikz \graph [binary tree layout, level distance=5mm]
+ { a -> { b[second], c} };
+ "]],[["
+ \tikz \graph [binary tree layout, level distance=5mm]
+ { a -> { b, c[first]} };
+ "]],[["
+ \tikz \graph [binary tree layout, level distance=5mm]
+ { a -> { b[second], c[second]} };
+ "]],[["
+ \tikz \graph [binary tree layout, level distance=5mm]
+ { a -> { b[third], c[first], d} };
+ "]]
+ }
+}
+
+
+---
+
+declare {
+ key = "first",
+ use = {
+ { key = "desired child index", value = 1},
+ },
+
+ summary = [["
+ A shorthand for setting the desired child number to |1|.
+ "]]
+ }
+
+---
+
+declare {
+ key = "second",
+ use = {
+ { key = "desired child index", value = 2},
+ },
+
+ summary = [["
+ A shorthand for setting the desired child number to |2|.
+ "]]
+ }
+
+
+---
+
+declare {
+ key = "third",
+ use = {
+ { key = "desired child index", value = 3},
+ },
+
+ summary = [["
+ A shorthand for setting the desired child number to |3|.
+ "]]
+ }
+
+
+---
+
+declare {
+ key = "fourth",
+ use = {
+ { key = "desired child index", value = 4}
+ },
+
+ summary = [["
+ A shorthand for setting the desired child number to |4|.
+ "]]
+ }
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua
new file mode 100644
index 0000000000..69babd443c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua
@@ -0,0 +1,211 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsubsection {The Reingold--Tilford Layout}
+--
+-- @end
+
+local ReingoldTilford1981 = {}
+
+-- Imports
+local layered = require "pgf.gd.layered"
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+local Storage = require "pgf.gd.lib.Storage"
+
+---
+declare {
+ key = "tree layout",
+ algorithm = ReingoldTilford1981,
+
+ preconditions = {
+ connected = true,
+ tree = true
+ },
+
+ postconditions = {
+ upward_oriented = true
+ },
+
+ documentation_in = "pgf.gd.trees.doc"
+}
+
+
+---
+declare {
+ key = "missing nodes get space",
+ type = "boolean",
+ documentation_in = "pgf.gd.trees.doc"
+}
+
+
+
+---
+declare {
+ key = "significant sep",
+ type = "length",
+ initial = "0",
+ documentation_in = "pgf.gd.trees.doc"
+}
+
+
+---
+declare {
+ key = "binary tree layout",
+ use = {
+ { key = "tree layout" },
+ { key = "minimum number of children" , value=2 },
+ { key = "significant sep", value = 10 },
+ },
+ documentation_in = "pgf.gd.trees.doc"
+}
+
+---
+declare {
+ key = "extended binary tree layout",
+ use = {
+ { key = "tree layout" },
+ { key = "minimum number of children" , value=2 },
+ { key = "missing nodes get space" },
+ { key = "significant sep", value = 0 },
+ },
+ documentation_in = "pgf.gd.trees.doc"
+}
+
+
+
+
+-- Now comes the implementation:
+
+function ReingoldTilford1981:run()
+
+ local root = self.spanning_tree.root
+
+ local layers = Storage.new()
+ local descendants = Storage.new()
+
+ self.extended_version = self.digraph.options['missing nodes get space']
+
+ self:precomputeDescendants(root, 1, layers, descendants)
+ self:computeHorizontalPosition(root, layers, descendants)
+ layered.arrange_layers_by_baselines(layers, self.adjusted_bb, self.ugraph)
+
+end
+
+
+function ReingoldTilford1981:precomputeDescendants(node, depth, layers, descendants)
+ local my_descendants = { node }
+
+ for _,arc in ipairs(self.spanning_tree:outgoing(node)) do
+ local head = arc.head
+ self:precomputeDescendants(head, depth+1, layers, descendants)
+ for _,d in ipairs(descendants[head]) do
+ my_descendants[#my_descendants + 1] = d
+ end
+ end
+
+ layers[node] = depth
+ descendants[node] = my_descendants
+end
+
+
+
+function ReingoldTilford1981:computeHorizontalPosition(node, layers, descendants)
+
+ local children = self.spanning_tree:outgoing(node)
+
+ node.pos.x = 0
+
+ local child_depth = layers[node] + 1
+
+ if #children > 0 then
+ -- First, compute positions for all children:
+ for i=1,#children do
+ self:computeHorizontalPosition(children[i].head, layers, descendants)
+ end
+
+ -- Now, compute minimum distances and shift them
+ local right_borders = {}
+
+ for i=1,#children-1 do
+
+ local local_right_borders = {}
+
+ -- Advance "right border" of the subtree rooted at
+ -- the i-th child
+ for _,d in ipairs(descendants[children[i].head]) do
+ local layer = layers[d]
+ local x = d.pos.x
+ if self.extended_version or not (layer > child_depth and d.kind == "dummy") then
+ if not right_borders[layer] or right_borders[layer].pos.x < x then
+ right_borders[layer] = d
+ end
+ if not local_right_borders[layer] or local_right_borders[layer].pos.x < x then
+ local_right_borders[layer] = d
+ end
+ end
+ end
+
+ local left_borders = {}
+ -- Now left for i+1 st child
+ for _,d in ipairs(descendants[children[i+1].head]) do
+ local layer = layers[d]
+ local x = d.pos.x
+ if self.extended_version or not (layer > child_depth and d.kind == "dummy") then
+ if not left_borders[layer] or left_borders[layer].pos.x > x then
+ left_borders[layer] = d
+ end
+ end
+ end
+
+ -- Now walk down the lines and try to find out what the minimum
+ -- distance needs to be.
+
+ local shift = -math.huge
+ local first_dist = left_borders[child_depth].pos.x - local_right_borders[child_depth].pos.x
+ local is_significant = false
+
+ for layer,n2 in pairs(left_borders) do
+ local n1 = right_borders[layer]
+ if n1 then
+ shift = math.max(
+ shift,
+ layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, n1, n2) + n1.pos.x - n2.pos.x
+ )
+ end
+ if local_right_borders[layer] then
+ if layer > child_depth and
+ (left_borders[layer].pos.x - local_right_borders[layer].pos.x <= first_dist) then
+ is_significant = true
+ end
+ end
+ end
+
+ if is_significant then
+ shift = shift + self.ugraph.options['significant sep']
+ end
+
+ -- Shift all nodes in the subtree by shift:
+ for _,d in ipairs(descendants[children[i+1].head]) do
+ d.pos.x = d.pos.x + shift
+ end
+ end
+
+ -- Finally, position root in the middle:
+ node.pos.x = (children[1].head.pos.x + children[#children].head.pos.x) / 2
+ end
+end
+
+
+
+return ReingoldTilford1981 \ No newline at end of file
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua
new file mode 100644
index 0000000000..dacf634865
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua
@@ -0,0 +1,646 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- @section subsection {Spanning Tree Computation}
+--
+-- \label{subsection-gd-spanning-tree}
+-- Although the algorithms of this library are tailored to layout trees,
+-- they will work for any graph as input. First, if the graph is not
+-- connected, it is decomposed into connected components and these are
+-- laid out individually. Second, for each component, a spanning tree of
+-- the graph is computed first and the layout is computed for this
+-- spanning tree; all other edges will still be drawn, but they have no
+-- impact on the placement of the nodes. If the graph is already a tree,
+-- the spanning tree will be the original graph.
+--
+-- The computation of the spanning tree is a non-trivial process since
+-- a non-tree graph has many different possible spanning trees. You can
+-- choose between different methods for deciding on a spanning tree, it
+-- is even possible to implement new algorithms. (In the future, the
+-- computation of spanning trees and the cycle removal in layered graph
+-- drawing algorithms will be unified, but, currently, they are
+-- implemented differently.)
+--
+-- Selects the (sub)algorithm that is to be used for computing spanning
+-- trees whenever this is requested by a tree layout algorithm. The
+-- default algorithm is |breadth first spanning tree|.
+--%
+--\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+-- \usegdlibrary{trees}}]
+--\tikz \graph [tree layout, breadth first spanning tree]
+--{
+-- 1 -- {2,3,4,5} -- 6;
+--};
+--\end{codeexample}
+--%
+--\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+-- \usegdlibrary{trees}}]
+--\tikz \graph [tree layout, depth first spanning tree]
+--{
+-- 1 --[bend right] {2,3,4,5 [>bend left]} -- 6;
+--};
+--\end{codeexample}
+--
+-- @end
+
+local SpanningTreeComputation = {}
+
+
+
+-- Namespace
+require("pgf.gd.trees").SpanningTreeComputation = SpanningTreeComputation
+
+
+-- Imports
+local lib = require "pgf.gd.lib"
+
+local Vertex = require "pgf.gd.model.Vertex"
+local Digraph = require "pgf.gd.model.Digraph"
+
+
+local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare
+
+
+
+
+-- ------------------------- --
+-- General tree parameters --
+-- ------------------------- --
+
+
+
+
+---
+--
+declare {
+ key = "breadth first spanning tree",
+ algorithm = {
+ run =
+ function (self)
+ return SpanningTreeComputation.computeSpanningTree(self.ugraph, false, self.events)
+ end
+ },
+ phase = "spanning tree computation",
+ phase_default = true,
+
+ summary = [["
+ This key selects ``breadth first'' as the (sub)algorithm for
+ computing spanning trees. Note that this key does not cause a graph
+ drawing scope to start; the key only has an effect in conjunction
+ with keys like |tree layout|.
+"]],
+ documentation = [["
+ The algorithm will be called whenever a graph drawing algorithm
+ needs a spanning tree on which to operate. It works as follows:
+ %
+ \begin{enumerate}
+ \item It looks for a node for which the |root| parameter is
+ set. If there are several such nodes, the first one is used.
+ If there are no such nodes, the first node is used.
+
+ Let call the node determined in this way the \emph{root node}.
+ \item For every edge, a \emph{priority} is determined, which is a
+ number between 1 and 10. How this happens, exactly, will be
+ explained in a moment. Priority 1 means ``most important'' while
+ priority 10 means ``least important''.
+ \item Starting from the root node, we now perform a breadth first
+ search through the tree, thereby implicitly building a spanning
+ tree: Suppose for a moment that all edges have priority~1. Then,
+ the algorithm works just the way that a normal breadth first
+ search is performed: We keep a queue of to-be-visited nodes and
+ while this queue is not empty, we remove its first node. If this
+ node has not yet been visited, we add all its neighbors at the
+ end of the queue. When a node is taken out of the queue, we make
+ it the child of the node whose neighbor it was when it was
+ added. Since the queue follows the ``first in, first out''
+ principle (it is a fifo queue), the children of the root will be
+ all nodes at distance $1$ form the root, their children will be
+ all nodes at distance $2$, and so on.
+ \item Now suppose that some edges have a priority different
+ from~1, in which case things get more complicated. We now keep
+ track of one fifo queue for each of the ten possible
+ priorities. When we consider the neighbors of a node, we actually
+ consider all its incident edges. Each of these edges has a certain
+ priority and the neighbor is put into the queue of the edge's
+ priority. Now, we still remove nodes normally from the queue for
+ priority~1; only if this queue is empty and there is still a node
+ in the queue for priority~2 we remove the first element from this
+ queue (and proceed as before). If the second queue is also empty,
+ we try the third, and so on up to the tenth queue. If all queues
+ are empty, the algorithm stops.
+ \end{enumerate}
+
+ The effect of the ten queues is the following: If the edges of
+ priority $1$ span the whole graph, a spanning tree consisting solely
+ of these edges will be computed. However, if they do not, once we
+ have visited reachable using only priority 1 edges, we will extend
+ the spanning tree using a priority 2 edge; but then we once switch
+ back to using only priority 1 edges. If neither priority~1 nor
+ priority~2 edges suffice to cover the whole graph, priority~3 edges
+ are used, and so on.
+ "]]
+}
+
+---
+
+declare {
+ key = "depth first spanning tree",
+ algorithm = {
+ run =
+ function (self)
+ return SpanningTreeComputation.computeSpanningTree(self.ugraph, true, self.events)
+ end
+ },
+ phase = "spanning tree computation",
+
+ summary = [["
+ Works exactly like |breadth first spanning tree| (same handling of
+ priorities), only the queues are now lifo instead of
+ fifo.
+ "]]
+}
+
+---
+--
+declare {
+ key = "root",
+ type = "boolean",
+ default = true,
+
+ summary = [["
+ This Boolean parameter is used in the computation of spanning
+ trees. When can be set for a node, this node will be used as the
+ root for the spanning tree computation. If several nodes have this
+ option set, the first node will be used.
+ "]]
+}
+
+
+---
+--
+declare {
+ key = "span priority",
+ type = "number",
+
+ summary = [["
+ Explicitly sets the ``span priority'' of an edge to \meta{number}, which must be
+ a number between |1| and |10|. The priority of edges is used by
+ spanning tree computations, see |breadth first spanning tree|.
+ "]]
+}
+
+
+
+---
+-- when it comes to choosing which edges are part of the spanning tree.
+declare {
+ key = "span edge",
+ use = {
+ { key = "span priority", value = 1 },
+ },
+
+ summary = [["
+ An easy-to-remember shorthand for |span priority=1|. When this key
+ is used with an edge, it will always be preferred over other edges
+ "]]
+}
+
+
+
+
+---
+--
+declare {
+ key = "no span edge",
+ use = {
+ { key = "span priority", value = 10 },
+ },
+
+ summary = [["
+ An easy-to-remember shorthand for |span priority=10|. This causes
+ the edge to be used only as a last resort as part of a spanning
+ tree.
+ "]],
+ documentation = [["
+ In the example, we add lots of edges that would normally be
+ preferred in the computation of the spanning tree, but use
+ |no span edge| to cause the algorithm to ignore these edges.
+ "]],
+ examples = [["
+ \tikz \graph [tree layout, nodes={draw}, sibling distance=0pt,
+ every group/.style={
+ default edge kind=->, no span edge,
+ path=source}]
+ {
+ 5 -> {
+ "1,3" -> {0,2,4},
+ 11 -> {
+ "7,9" -> { 6, 8, 10 }
+ }
+ }
+ };
+ "]]
+}
+
+
+
+---
+declare {
+ key = "span priority ->",
+ type = "number",
+ initial = "3",
+
+ summary = [["
+ This key stores the span priority of all edges whose direction is
+ |->|. There are similar keys for all other directions, such as
+ |span priority <-| and so on.
+ "]],
+ documentation = [["
+ When you write
+ %
+\begin{codeexample}[code only]
+graph { a -> b -- c <- [span priority=2] d }
+\end{codeexample}
+ %
+ the priority of the edge from |a| to |b| would be the current
+ value of the key |span priority ->|, the priority of the edge from
+ |b| to |c| would be the current value of |span priority --|, and
+ the priority of the edge from |c| to |d| would be |2|, regardless
+ of the value of |span priority <-|.
+
+ The defaults for the priorities are:
+ %
+ \begin{itemize}
+ \item |span priority -> = 3|
+ \item |span priority -- = 5|
+ \item |span priority <-> = 5|
+ \item |span priority <- = 8|
+ \item |span priority -!- = 10|
+ \end{itemize}
+ "]]
+}
+
+
+
+---
+
+declare {
+ key = "span priority reversed ->",
+ type = "number",
+ initial = "9",
+
+ documentation = [["
+ This key stores the span priority of traveling across reversed
+ edges whose actual direction is |->| (again, there are similar keys
+ for all other directions).
+ "]],
+ documentation = [["
+ When you write
+ %
+\begin{codeexample}[code only]
+graph { a -> b -- c <- [span priority=2] d }
+\end{codeexample}
+ %
+ there are, in addition to the priorities indicated above, also
+ further edge priorities: The priority of the (reversed) edge |b|
+ to |a| is |span priority reversed ->|, the priority of the
+ (reversed) edge |c| to |b| is |span priority reversed --|, and the
+ span priority of the reversed edge |d| to |c| is |2|, regardless
+ of the value of |span priority reversed <-|.
+
+ The defaults for the priorities are:
+ %
+ \begin{itemize}
+ \item |span priority reversed -> = 9|
+ \item |span priority reversed -- = 5|
+ \item |span priority reversed <-> = 5|
+ \item |span priority reversed <- = 7|
+ \item |span priority reversed -!- = 10|
+ \end{itemize}
+
+ The default priorities are set in such a way, that non-reversed |->|
+ edges have top priorities, |--| and |<->| edges have the same
+ priorities in either direction, and |<-| edges have low priority in
+ either direction (but going |a <- b| from |b| to |a| is given higher
+ priority than going from |a| to |b| via this edge and also higher
+ priority than going from |b| to |a| in |a -> b|).
+
+ Keys like |span using directed| change the priorities ``en bloc''.
+ "]]
+}
+
+
+declare {
+ key = "span priority <-",
+ type = "number",
+ initial = "8",
+}
+
+declare {
+ key = "span priority reversed <-",
+ type = "number",
+ initial = "7",
+}
+
+declare {
+ key = "span priority --",
+ type = "number",
+ initial = "5",
+}
+
+declare {
+ key = "span priority reversed --",
+ type = "number",
+ initial = "5",
+}
+
+declare {
+ key = "span priority <->",
+ type = "number",
+ initial = "5",
+}
+
+declare {
+ key = "span priority reversed <->",
+ type = "number",
+ initial = "5",
+}
+
+declare {
+ key = "span priority -!-",
+ type = "number",
+ initial= "10",
+}
+
+declare {
+ key = "span priority reversed -!-",
+ type = "number",
+ initial= "10",
+}
+
+---
+
+declare {
+ key = "span using directed",
+ use = {
+ { key = "span priority reversed <-", value = 3},
+ { key = "span priority <->", value = 3},
+ { key = "span priority reversed <->", value = 3},
+ },
+ summary = [["
+ This style sets a priority of |3| for all edges that are directed
+ and ``go along the arrow direction'', that is, we go from |a| to
+ |b| with a priority of |3| for the cases |a -> b|, |b <- a|,
+ |a <-> b|, and |b <-> a|.
+ This strategy is nice with trees specified with both forward and
+ backward edges.
+ "]],
+ examples = [["
+ \tikz \graph [tree layout, nodes={draw}, sibling distance=0pt,
+ span using directed]
+ {
+ 3 <- 5[root] -> 8,
+ 1 <- 3 -> 4,
+ 7 <- 8 -> 9,
+ 1 -- 4 -- 7 -- 9
+ };
+ "]]
+}
+
+---
+
+declare {
+ key = "span using all",
+ use = {
+ { key = "span priority <-", value = 5},
+ { key = "span priority ->", value = 5},
+ { key = "span priority <->", value = 5},
+ { key = "span priority --", value = 5},
+ { key = "span priority -!-", value = 5},
+ { key = "span priority reversed <-", value = 5},
+ { key = "span priority reversed ->", value = 5},
+ { key = "span priority reversed <->", value = 5},
+ { key = "span priority reversed --", value = 5},
+ { key = "span priority reversed -!-", value = 5},
+ },
+
+ summary = [["
+ Assings a uniform priority of 5 to all edges.
+ "]]
+}
+
+
+-- The implementation
+
+--
+-- Compute a spanning tree of a graph
+--
+-- The algorithm will favor nodes according to their priority. This is
+-- determined through an edge priority function.
+--
+-- @param ugraph An undirected graph for which the spanning tree
+-- should be computed
+-- @param dfs True if depth first should be used, false if breadth
+-- first should be used.
+--
+-- @return A new graph that is a spanning tree.
+
+function SpanningTreeComputation.computeSpanningTree (ugraph, dfs, events)
+
+ local tree = Digraph.new (ugraph) -- copy vertices
+
+ local edge_priorities = ugraph.options['/graph drawing/edge priorities']
+
+ local root = lib.find(ugraph.vertices, function (v) return v.options['root'] end) or ugraph.vertices[1]
+
+ -- Traverse tree, giving preference to directed edges and, that
+ -- failing, to undirected and bidirected edges, and, that failing,
+ -- all other edges.
+ local marked = {}
+
+ local stacks = { -- 10 stacks for 10 priorities, with 1 being the highest
+ { { parent = nil, node = root}, top = 1, bottom = 1 },
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1},
+ { top = 0, bottom = 1}
+ }
+
+ local function stack_is_non_empty (s) return s.top >= s.bottom end
+
+ while lib.find(stacks, stack_is_non_empty) do
+ local parent, node
+
+ for _,stack in ipairs(stacks) do
+ if stack_is_non_empty(stack) then
+ -- Pop
+ parent = stack[stack.top].parent
+ node = stack[stack.top].node
+
+ stack[stack.top] = nil
+ stack.top = stack.top - 1
+
+ break
+ end
+ end
+
+ if not marked[node] then
+
+ -- The node is good!
+ marked[node] = true
+
+ if parent then
+ tree:connect(parent,node)
+ end
+
+ local arcs = ugraph:outgoing(node)
+
+ for j=1,#arcs do
+ local arc = arcs[dfs and j or #arcs - j + 1]
+ local head = arc.head
+
+ if not marked[head] then
+ local priority = arc:spanPriority()
+ local stack = assert(stacks[priority], "illegal edge priority")
+ if dfs then
+ stack.top = stack.top + 1
+ stack[stack.top] = { parent = node, node = head}
+ else
+ stack.bottom = stack.bottom - 1
+ stack[stack.bottom] = { parent = node, node = head}
+ end
+ end
+ end
+ end
+ end
+
+ -- Now, copy vertex list
+ local copy = {}
+ for i,v in ipairs(tree.vertices) do
+ copy[i] = v
+ end
+
+ -- Now, setup child lists
+ for _,v in ipairs(copy) do
+
+ -- Children as they come from the spanning tree computation
+ tree:sortOutgoing(v, function (a,b) return a:eventIndex() < b:eventIndex() end)
+ local outgoings = tree:outgoing(v)
+
+ -- Compute children as they come in the event list:
+ local children = {}
+
+ local i = (v.event.index or 0)+1
+ while i <= #events and events[i].kind == "edge" do
+ i = i + 1
+ end
+
+ if events[i] and events[i].kind == "begin" and events[i].parameters == "descendants" then
+ -- Ok, the node is followed by a descendants group
+ -- Now scan for nodes that are not inside a descendants group
+ local stop = events[i].end_index
+ local j = i+1
+ while j <= stop do
+ if events[j].kind == "node" then
+ children[#children+1] = events[j].parameters
+ elseif events[j].kind == "begin" and events[j].parameters == "descendants" then
+ j = events[j].end_index
+ end
+ j = j + 1
+ end
+
+ -- Test, whether outgoings and children contain the same nodes:
+ local function same_elements()
+ local hash = {}
+ for v,c in ipairs(outgoings) do
+ hash[c.head] = true
+ end
+ local count = 0
+ for _,c in pairs(children) do
+ if c ~= "" then
+ count = count + 1
+ if not hash[c] or count > #outgoings then
+ return false
+ end
+ end
+ end
+ return count == #outgoings
+ end
+
+ if same_elements() and #outgoings > 0 then
+ -- increase number of children, if necessary
+ local needed = math.max(#children, lib.lookup_option('minimum number of children', v, ugraph))
+ for i=1,#children do
+ if children[i] ~= "" then
+ local d = children[i].options['desired child index']
+ needed = d and math.max(needed, d) or needed
+ end
+ end
+
+ local new_children = {}
+ for i=1,#children do
+ if children[i] ~= "" then
+ local d = children[i].options['desired child index']
+ if d then
+ local target = d
+
+ while new_children[target] do
+ target = 1 + (target % #children)
+ end
+ new_children[target] = children[i]
+ end
+ end
+ end
+ for i=1,#children do
+ if children[i] ~= "" then
+ local d = children[i].options['desired child index']
+ if not d then
+ local target = i
+
+ while new_children[target] do
+ target = 1 + (target % #children)
+ end
+ new_children[target] = children[i]
+ end
+ end
+ end
+ for i=1,needed do
+ if not new_children[i] then
+ local new_child = Vertex.new{ kind = "dummy" }
+ new_children[i] = new_child
+ tree:add {new_child}
+ tree:connect(v,new_child)
+ end
+ end
+
+ tree:orderOutgoing(v,new_children)
+ end
+ end
+ end
+
+ tree.root = root
+
+ return tree
+end
+
+
+
+-- Done
+
+return SpanningTreeComputation
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/doc.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/doc.lua
new file mode 100644
index 0000000000..a44fd47031
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/doc.lua
@@ -0,0 +1,340 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+local key = require 'pgf.gd.doc'.key
+local documentation = require 'pgf.gd.doc'.documentation
+local summary = require 'pgf.gd.doc'.summary
+local example = require 'pgf.gd.doc'.example
+
+
+--------------------------------------------------------------------
+key "tree layout"
+
+summary "This layout uses the Reingold--Tilform method for drawing trees."
+
+documentation
+[[
+The Reingold--Tilford method is a standard method for drawing
+trees. It is described in:
+%
+\begin{itemize}
+ \item
+ E.~M.\ Reingold and J.~S.\ Tilford,
+ \newblock Tidier drawings of trees,
+ \newblock \emph{IEEE Transactions on Software Engineering,}
+ 7(2), 223--228, 1981.
+\end{itemize}
+%
+My implementation in |graphdrawing.trees| follows the following paper, which
+introduces some nice extensions of the basic algorithm:
+%
+\begin{itemize}
+ \item
+ A.\ Br\"uggemann-Klein, D.\ Wood,
+ \newblock Drawing trees nicely with \TeX,
+ \emph{Electronic Publishing,} 2(2), 101--115, 1989.
+\end{itemize}
+%
+As a historical remark, Br\"uggemann-Klein and Wood have implemented
+their version of the Reingold--Tilford algorithm directly in \TeX\
+(resulting in the Tree\TeX\ style). With the power of Lua\TeX\ at
+our disposal, the 2012 implementation in the |graphdrawing.tree|
+library is somewhat more powerful and cleaner, but it really was an
+impressive achievement to implement this algorithm back in 1989
+directly in \TeX.
+
+The basic idea of the Reingold--Tilford algorithm is to use the
+following rules to position the nodes of a tree (the following
+description assumes that the tree grows downwards, other growth
+directions are handled by the automatic orientation mechanisms of
+the graph drawing library):
+%
+\begin{enumerate}
+ \item For a node, recursively compute a layout for each of its children.
+ \item Place the tree rooted at the first child somewhere on the page.
+ \item Place the tree rooted at the second child to the right of the
+ first one as near as possible so that no two nodes touch (and such
+ that the |sibling sep| padding is not violated).
+ \item Repeat for all subsequent children.
+ \item Then place the root above the child trees at the middle
+ position, that is, at the half-way point between the left-most and
+ the right-most child of the node.
+\end{enumerate}
+%
+The standard keys |level distance|, |level sep|, |sibling distance|,
+and |sibling sep|, as well as the |pre| and |post| versions of these
+keys, as taken into consideration when nodes are positioned. See also
+Section~\ref{subsection-gd-dist-pad} for details on these keys.
+
+\noindent\textbf{Handling of Missing Children.}
+As described in Section~\ref{section-gd-missing-children}, you can
+specify that some child nodes are ``missing'' in the tree, but some
+space should be reserved for them. This is exactly what happens:
+When the subtrees of the children of a node are arranged, each
+position with a missing child is treated as if a zero-width,
+zero-height subtree were present at that positions:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz [tree layout, nodes={draw,circle}]
+ \node {r}
+ child { node {a}
+ child [missing]
+ child { node {b} }
+ }
+ child[missing];
+\end{codeexample}
+%
+or in |graph| syntax:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+ \tikz \graph [tree layout, nodes={draw,circle}]
+ {
+ r -> {
+ a -> {
+ , %missing
+ b},
+ % missing
+ }
+ };
+\end{codeexample}
+%
+More than one child can go missing:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [tree layout, nodes={draw,circle}, sibling sep=0pt]
+ { r -> { a, , ,b -> {c,d}, ,e} };
+\end{codeexample}
+%
+Although missing children are taken into consideration for the
+computation of the placement of the children of a root node relative
+to one another and also for the computation of the position of the
+root node, they are usually \emph{not} considered as part of the
+``outline'' of a subtree (the \texttt{minimum number of children}
+key ensures that |b|, |c|, |e|, and |f| all have a missing right
+child):
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [tree layout, minimum number of children=2,
+ nodes={draw,circle}]
+ { a -> { b -> c -> d, e -> f -> g } };
+\end{codeexample}
+%
+This behaviour of ``ignoring'' missing children in later stages of
+the recursion can be changed using the key |missing nodes get space|.
+
+\noindent\textbf{Significant Pairs of Siblings.}
+Br\"uggemann-Klein and Wood have proposed an extension of the
+Reingold--Tilford method that is intended to better highlight the
+overall structure of a tree. Consider the following two trees:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz [baseline=(a.base), tree layout, minimum number of children=2,
+ sibling distance=5mm, level distance=5mm]
+ \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{
+ a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] }
+ };\quad
+\tikz [baseline=(a.base), tree layout, minimum number of children=2,
+ sibling distance=5mm, level distance=5mm]
+ \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{
+ a -- { b -- c -- d -- e, i -- j -- { f -- {g,h}, k } }
+ };
+\end{codeexample}
+%
+As observed by Br\"uggemann-Klein and Wood, the two trees are
+structurally quite different, but the Reingold--Tilford method
+places the nodes at exactly the same positions and only one edge
+``switches'' positions. In order to better highlight the differences
+between the trees, they propose to add a little extra separation
+between siblings that form a \emph{significant pair}. They define
+such a pair as follows: Consider the subtrees of two adjacent
+siblings. There will be one or more levels where these subtrees have
+a minimum distance. For instance, the following two trees the
+subtrees of the nodes |a| and |b| have a minimum distance only at
+the top level in the left example, and in all levels in the second
+example. A \emph{significant pair} is a pair of siblings where the
+minimum distance is encountered on any level other than the first
+level. Thus, in the first example there is no significant pair,
+while in the second example |a| and |b| form such a pair.
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,graphdrawing}
+ \usegdlibrary{trees}}]
+\tikz \graph [tree layout, minimum number of children=2,
+ level distance=5mm, nodes={circle,draw}]
+ { / -> { a -> / -> /, b -> /[second] -> /[second] }};
+ \quad
+\tikz \graph [tree layout, minimum number of children=2,
+ level distance=5mm, nodes={circle,draw}]
+ { / -> { a -> / -> /, b -> / -> / }};
+\end{codeexample}
+%
+Whenever the algorithm encounters a significant pair, it adds extra
+space between the siblings as specified by the |significant sep|
+key.
+]]
+
+
+example
+[[
+\tikz [tree layout, sibling distance=8mm]
+ \graph [nodes={circle, draw, inner sep=1.5pt}]{
+ 1 -- { 2 -- 3 -- { 4 -- 5, 6 -- { 7, 8, 9 }}, 10 -- 11 -- { 12, 13 } }
+ };
+]]
+
+
+example
+[[
+\tikz [tree layout, grow=-30,
+ sibling distance=0mm, level distance=0mm,]
+ \graph [nodes={circle, draw, inner sep=1.5pt}]{
+ 1 -- { 2 -- 3 -- { 4 -- 5, 6 -- { 7, 8, 9 }}, 10 -- 11 -- { 12, 13 } }
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "missing nodes get space"
+
+summary
+[[
+When set to true, missing children are treated as if they where
+zero-width, zero-height nodes during the whole tree layout process.
+]]
+
+
+example
+[[
+\tikz \graph [tree layout, missing nodes get space,
+ minimum number of children=2, nodes={draw,circle}]
+{ a -> { b -> c -> d, e -> f -> g } };
+]]
+--------------------------------------------------------------------
+
+
+
+
+
+--------------------------------------------------------------------
+key "significant sep"
+
+summary
+[[
+This space is added to significant pairs by the modified
+Reingold--Tilford algorithm.
+]]
+
+example
+[[
+\tikz [baseline=(a.base), tree layout, significant sep=1em,
+ minimum number of children=2,
+ sibling distance=5mm, level distance=5mm]
+ \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{
+ a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] }
+ };\quad
+\tikz [baseline=(a.base), tree layout, significant sep=1em,
+ minimum number of children=2,
+ sibling distance=5mm, level distance=5mm]
+ \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{
+ a -- { b -- c -- d -- e, i -- j -- { f -- {g,h}, k } }
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "binary tree layout"
+
+summary
+[[
+A layout based on the Reingold--Tilford method for drawing
+binary trees.
+]]
+
+documentation
+[[
+This key executes:
+%
+\begin{enumerate}
+ \item |tree layout|, thereby selecting the Reingold--Tilford method,
+ \item |minimum number of children=2|, thereby ensuring the all nodes
+ have (at least) two children or none at all, and
+ \item |significant sep=10pt| to highlight significant pairs.
+\end{enumerate}
+%
+In the examples, the last one is taken from the paper of
+Br\"uggemann-Klein and Wood. It demonstrates nicely the
+advantages of having the full power of \tikzname's anchoring and the
+graph drawing engine's orientation mechanisms at one's disposal.
+]]
+
+
+example
+[[
+\tikz [grow'=up, binary tree layout, sibling distance=7mm, level distance=7mm]
+ \graph {
+ a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] }
+ };
+]]
+
+--[[
+% TODOsp: codeexamples: the next example needs the library `arrows.meta`
+--]]
+example
+[[
+\tikz \graph [binary tree layout] {
+ Knuth -> {
+ Beeton -> Kellermann [second] -> Carnes,
+ Tobin -> Plass -> { Lamport, Spivak }
+ }
+};\qquad
+\tikz [>={Stealth[round,sep]}]
+ \graph [binary tree layout, grow'=right, level sep=1.5em,
+ nodes={right, fill=blue!50, text=white, chamfered rectangle},
+ edges={decorate,decoration={snake, post length=5pt}}]
+ {
+ Knuth -> {
+ Beeton -> Kellermann [second] -> Carnes,
+ Tobin -> Plass -> { Lamport, Spivak }
+ }
+ };
+]]
+--------------------------------------------------------------------
+
+
+
+--------------------------------------------------------------------
+key "extended binary tree layout"
+
+summary
+[[
+This algorithm is similar to |binary tree layout|, only the
+option \texttt{missing nodes get space} is executed and the
+\texttt{significant sep} is zero.
+]]
+
+example
+[[
+\tikz [grow'=up, extended binary tree layout,
+ sibling distance=7mm, level distance=7mm]
+ \graph {
+ a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] }
+ };
+]]
+--------------------------------------------------------------------
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/library.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/library.lua
new file mode 100644
index 0000000000..a0019666ac
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/trees/library.lua
@@ -0,0 +1,35 @@
+-- Copyright 2012 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- \tikzname\ offers several different syntax to specify trees (see
+-- Sections \ref{section-library-graphs}
+-- and~\ref{section-trees}). The job of the graph drawing algorithms from
+-- this library is to turn the specification of trees into beautiful
+-- layouts.
+--
+-- We start this section with a description of algorithms, then we have a
+-- look at how missing children can be specified and at what happens when
+-- the input graph is not a tree.
+--
+-- @library
+
+local trees -- Library name
+
+-- Load declarations from:
+require "pgf.gd.trees.ChildSpec"
+require "pgf.gd.trees.SpanningTreeComputation"
+
+-- Load algorithms from:
+require "pgf.gd.trees.ReingoldTilford1981"
+
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/experimental/tikzlibrarygraphdrawing.evolving.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/experimental/tikzlibrarygraphdrawing.evolving.code.tex
new file mode 100644
index 0000000000..efa214a12e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/experimental/tikzlibrarygraphdrawing.evolving.code.tex
@@ -0,0 +1,21 @@
+% Copyright 2018 by Malte Skambath
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{graphdrawing}
+
+\usegdlibrary{evolving}
+
+\newcount\mycount
+\tikzgraphsset{
+ nodes = {supernode/.expanded=\tikzgraphnodename},
+ when/.code = {\pgfparsetime{#1}\mycount=\pgftimeresult pt\tikzgraphsset{name/.expanded=\the\mycount,snapshot/.expanded=\the\mycount}}
+}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex
new file mode 100644
index 0000000000..2fec25131d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex
@@ -0,0 +1,16 @@
+% Copyright 2019 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarygraphdrawing.circular.code.tex}
+
+
+\usegdlibrary{circular}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.code.tex
new file mode 100644
index 0000000000..63efd352f1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.code.tex
@@ -0,0 +1,1165 @@
+% Copyright 2018 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarygraphdrawing.code.tex}
+
+
+
+% check if luatex is running
+
+\ifx\directlua\relax%
+ \pgferror{You need to run LuaTeX to use the graph drawing library}
+ \expandafter\endinput
+\fi
+\ifx\directlua\undefined%
+ \pgferror{You need to run LuaTeX to use the graph drawing library}
+ \expandafter\endinput
+\fi
+
+
+
+
+%
+% All graph drawing keys normally live in the following namespace:
+% /graph drawing.
+%
+
+\def\pgfgdset{\pgfqkeys{/graph drawing}}%
+
+
+% Setup a key
+%
+% #1 = key
+%
+% Description:
+%
+% An internal macro that sets up #1 as a graph drawing key.
+
+\def\pgfgd@callbackkey#1{%
+ \pgf@gd@setup@forwards{#1}%
+ \pgfutil@g@addto@macro\pgf@gd@forwards@list{\pgf@gd@setup@forwards{#1}}%
+}%
+\def\pgf@gd@setup@forwards#1{%
+ \let\pgf@temp\pgfutil@empty
+ \foreach \pgf@gd@path in \pgf@gd@forwarding@list {%
+ \ifx\pgf@gd@path\pgfutil@empty\else%
+ \expandafter\pgfutil@g@addto@macro%
+ \expandafter\pgf@temp\expandafter{%
+ \expandafter\pgfkeys\expandafter{\pgf@gd@path#1/.forward to=/graph drawing/#1}}%
+ \fi%
+ }%
+ \pgf@temp
+}%
+
+\let\pgf@gd@forwards@list\pgfutil@empty
+
+
+% Append to the forwarding list:
+%
+% #1 = paths to append to the forwarding list
+%
+% Description:
+%
+% Append the paths in #1 (with trailing slashes) to the forwarding
+% list.
+%
+% If algorithms have already been declared, forwarding will also be
+% setup for them (using a bit of magic...).
+
+\def\pgfgdappendtoforwardinglist#1{%
+ \let\pgf@gd@forwarding@list@orig\pgf@gd@forwarding@list
+ \def\pgf@gd@forwarding@list{#1}%
+ \pgf@gd@forwards@list%
+ \expandafter\def\expandafter\pgf@gd@forwarding@list\expandafter{\pgf@gd@forwarding@list@orig,#1}%
+}%
+\let\pgf@gd@forwarding@list\pgfutil@empty
+
+
+
+%
+%
+% Callbacks
+%
+% The following macros are called *from* the binding layer. You do not
+% call them from the pgf layer.
+%
+%
+
+
+% Callback for declaring a graph parameter key
+%
+% #1 = Parameter key
+% #2 = Parameter type
+%
+% Description:
+%
+% When a graph drawing algorithm starts working, a set of options,
+% called "graph drawing parameters" in the following, can influence the
+% way the algorithm works. For instance, an graph drawing parameter
+% might be the average distance between vertices which the algorithm
+% should take into account. Another example might be the fact the
+% certain nodes are special nodes and that a certain edge should have
+% a large label.
+%
+% These graph drawing parameters are different from "usual" pgf
+% options: An algorithmic parameter influenced the way the algorithm
+% works, while usual options normally only influence how the result
+% looks like. For instance, the fact that a node is red is not an
+% graph drawing parameter (usually, at least), while the shape of a node
+% might be an graph drawing parameter.
+%
+% Graph drawing parameters are declared by the algorithmic layer
+% (since only this layer "knows" which parameters there are). The
+% binding to TeX will call the \pgfgddeclareparameter function
+% internally.
+%
+% Specifying the set of graph drawing parameters for a given graph or
+% node or edge works as follows: When the graph drawing engine is
+% started for a graph (using \pgfgdbeginscope), a snapshot is taken of
+% all graph drawing parameters currently setup at this
+% point. Similarly, when a node is created inside such a scope, a
+% snapshot is taken of the set of all graph drawing parameters in
+% force at this point is taken and stored together with the
+% node. Finally, when an edge is created, a snapshot of the setting of
+% the graph drawing parameters is taken.
+
+\def\pgfgdcallbackdeclareparameter#1#2{%
+ \pgfkeysdef{/graph drawing/#1}{\pgf@gd@handle@parameter{#1}{#2}{##1}}%
+ \pgfgd@callbackkey{#1}%
+}%
+\def\pgf@gd@handle@parameter#1#2#3{%
+ \def\pgf@temp{#3}%
+ \ifx\pgf@temp\pgfkeysnovalue@text%
+ \let\pgfgdresult\pgfgd@niltext%
+ \else%
+ \pgfkeys{/graph drawing/conversions/#2={#3}}%
+ \fi%
+ \advance\pgf@gd@parameter@stack@height by1\relax%
+ \pgf@gd@parameter@stack@height\directlua{%
+ local new, main = pgf.gd.interface.InterfaceToDisplay.pushOption('\pgfutil@luaescapestring{#1}',\pgfgdresult,\the\pgf@gd@parameter@stack@height)
+ tex.print(new..'\pgfutil@luaescapestring{\relax}')
+ if main then
+ tex.print('\pgfutil@luaescapestring{\noexpand\pgfgdtriggerrequest}')
+ end}%
+}%
+\newcount\pgf@gd@parameter@stack@height
+
+\def\pgfgdtriggerrequest{\pgfgdset{@request scope and layout}}%
+
+
+% Conversions are used to adapt the syntactic description of a
+% parameter on the TikZ layer to the one expected by Lua. The set of
+% permissible conversions is described in
+% InterfaceToAlgorithms.declareParameter.
+
+\pgfgdset{
+ conversions/string/.code=\def\pgfgdresult{'\pgfutil@luaescapestring{\detokenize{#1}}'},
+ conversions/raw/.code=\def\pgfgdresult{#1},
+ conversions/nil/.code=\let\pgfgdresult\pgfgd@niltext,
+ conversions/boolean/.code=\def\pgf@test{#1}\ifx\pgf@test\pgf@truetext\def\pgfgdresult{true}\else\ifx\pgf@test\pgfkeysnovalue@text\def\pgfgdresult{true}\else\def\pgfgdresult{false}\fi\fi,
+ conversions/number/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult,
+ conversions/length/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult,
+ conversions/time/.code=\pgfparsetime{#1}\let\pgfgdresult\pgftimeresult,
+ conversions/direction/.code=\pgf@lib@gd@grow@dir{#1}\let\pgfgdresult\pgfmathresult,
+ conversions/canvas coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{pgf.gd.model.Coordinate.new(#1,#2)}},
+ % deprecated, will be removed:
+ conversions/coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{{#1,#2}}}
+}%
+\def\pgf@truetext{true}%
+\def\pgfgd@niltext{nil}%
+
+\def\pgf@lib@gd@grow@dir#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@gd@lib@active@bar%
+ \def\pgfmathresult{-90}
+ \else%
+ \ifcsname pgf@orient@direction@#1\endcsname%
+ \expandafter\let\expandafter\pgfmathresult\csname pgf@orient@direction@#1\endcsname%
+ \else
+ \pgfmathparse{#1}%
+ \fi
+ \fi
+}%
+
+\def\pgf@orient@direction@down{-90}%
+\def\pgf@orient@direction@up{90}%
+\def\pgf@orient@direction@left{180}%
+\def\pgf@orient@direction@right{0}%
+
+\def\pgf@orient@direction@south{-90}%
+\def\pgf@orient@direction@north{90}%
+\def\pgf@orient@direction@west{180}%
+\def\pgf@orient@direction@east{0}%
+
+\expandafter\def\csname pgf@orient@direction@north east\endcsname{45}%
+\expandafter\def\csname pgf@orient@direction@north west\endcsname{135}%
+\expandafter\def\csname pgf@orient@direction@south east\endcsname{-45}%
+\expandafter\def\csname pgf@orient@direction@south west\endcsname{-135}%
+
+\expandafter\def\csname pgf@orient@direction@-\endcsname{0}%
+\expandafter\def\csname pgf@orient@direction@|\endcsname{-90}%
+
+{%
+ \catcode`\|=13
+ \gdef\pgf@gd@lib@active@bar{|}%
+}%
+
+
+
+
+
+% Callback for starting the rendering of a collection kind
+%
+% #1 = Kind
+% #2 = Layer
+%
+% Description:
+%
+% Executes /graph drawing/#1/begin rendering/.try
+%
+
+\def\pgfgdcallbackrendercollectionkindstart#1#2{%
+ \ifnum#2<0\relax
+ \setbox\pgf@gd@prekind@box=\hbox\bgroup%
+ \unhbox\pgf@gd@prekind@box%
+ \else%
+ \setbox\pgf@gd@postkind@box=\hbox\bgroup%
+ \unhbox\pgf@gd@postkind@box%
+ \fi%
+ \pgfgdset{/graph drawing/#1/begin rendering/.try}%
+}%
+
+% Callback for ending the rendering of a collection kind
+%
+% #1 = Kind
+% #2 = Layer
+%
+% Description:
+%
+% Executes /graph drawing/#1/end rendering/.try
+%
+
+\def\pgfgdcallbackrendercollectionkindstop#1#2{%
+ \pgfgdset{/graph drawing/#1/end rendering/.try}%
+ \egroup % close box
+}%
+
+
+
+% Callback for rendering a collection
+%
+% #1 = Kind
+% #2 = Options
+%
+% Description:
+%
+% Executes /graph drawing/#1/render/.try={#2}
+%
+
+\def\pgfgdcallbackrendercollection#1#2{
+ \pgfgdset{/graph drawing/#1/render/.try={#2}}
+}%
+
+
+
+
+
+% Graph events
+%
+% Although a graph consists of nodes and edges, during the
+% construction of the graph a lot of information concerning the
+% structure of the graph is often available. For instance, as we
+% specify a graph using the child-syntax, we do not only which edges
+% are present, but we can implicitly specify an ordering on the
+% nodes. Even more, there is even information available concerning
+% nodes that are not present at all: A child[missing] is not present
+% as a node or an edge, but a tree drawing algorithm will want to know
+% about this child nevertheless.
+%
+% In order to communicate such information to the graph drawing
+% engine, "events" are used. As a graph is created, in addition to
+% nodes and edges, "events" may happen. The events come in a
+% sequential order and they are stored together with the graph. For
+% each node and each edge, its index in the event sequence is
+% stored, that is, it is stored how many events happened before the
+% node or edge was created.
+%
+% Internally, an event consists of a name and, possibly, some
+% parameters. When the parameter is created on the tikz level, it will
+% be a string that is passed down to Lua. Internally created events
+% will also have parameters that are objects.
+%
+% Two events are a bit special since they get special internal
+% support: The begin and end events. The first signals that some kind
+% of group has started; which is closed by the corresponding end
+% event. The "kind" of group is indicated by the parameter of the
+% begin event.
+%
+%
+%
+% Standard events are:
+%
+% For each node entered into a graph, a "node" event is automatically
+% created internally with the parameter being the node. However, you
+% can also create this event yourself. In this case, the parameter
+% will be a string and will mean that the node is "virtual" or
+% "missing", but space should be reserved for it, if possible (this is
+% use, for instance, by certain tree layouts).
+%
+% For each edge entered into a graph, an "edge" event is automatically
+% created, with the edge as the parameter. Again, an event with a
+% string parameter corresponds to a "non-existing" node.
+%
+%
+% Standard event groups are:
+%
+%
+% The "descendants" event group include a set of nodes that, at least
+% inside the specification, are descendants of the last node
+%
+% begin descendants
+% ...
+% end
+%
+%
+% The "array" event group collects together some nodes in an array of
+% nodes. This can be used, for instance, to specify matrices.
+%
+% begin array
+% ...
+% end
+
+
+
+% Create a new event
+%
+% #1 = event name (should be a valid lua identifier name)
+% #2 = parameter (some text)
+%
+% Description:
+%
+% Adds a new event to the event sequence of the graph
+
+\def\pgfgdevent#1#2{%
+ \directlua{pgf.gd.interface.InterfaceToDisplay.createEvent('\pgfutil@luaescapestring{#1}', '\pgfutil@luaescapestring{#2}')}%
+}%
+
+
+% Start an event group
+%
+% #1 = kind of event group
+%
+% Description:
+%
+% Creates a begin event with #1 as the parameter of the begin
+% event.
+
+\def\pgfgdbegineventgroup#1{%
+ \pgfgdevent{begin}{#1}%
+}%
+
+% End an event group
+%
+% Description:
+%
+% Creates an end event.
+
+\def\pgfgdendeventgroup{%
+ \pgfgdevent{end}{}%
+}%
+
+
+% Creates an event group for the current TeX group
+%
+% #1 = event group name
+%
+% Description:
+%
+% Issues a begin event for #1 and, using \aftergroup, adds an end
+% event at the end of the current tex group.
+
+\def\pgfgdeventgroup#1{%
+ \pgfgdbegineventgroup{#1}%
+ \aftergroup\pgfgdendeventgroup%
+}%
+
+
+
+
+
+%
+% Nodes
+%
+
+
+
+%
+% Callback method for \pgfpositionnodelater
+%
+% This function is called by \pgfnode whenever a node has been newly
+% created inside a graph drawing scope. It will create a new vertex on
+% the Lua layer.
+%
+\def\pgf@gd@positionnode@callback{%
+ {%
+ % evaluate coordinates
+ \pgfmathsetmacro{\pgf@gd@node@minx}{\pgfpositionnodelaterminx}%
+ \pgfmathsetmacro{\pgf@gd@node@miny}{\pgfpositionnodelaterminy}%
+ \pgfmathsetmacro{\pgf@gd@node@maxx}{\pgfpositionnodelatermaxx}%
+ \pgfmathsetmacro{\pgf@gd@node@maxy}{\pgfpositionnodelatermaxy}%
+ % Assemble the Path object:
+ \directlua{pgf.temp = require 'pgf.gd.model.Path'.new ()}%
+ \let\pgfsyssoftpath@movetotoken\pgf@gd@movetotoken%
+ \let\pgfsyssoftpath@linetotoken\pgf@gd@linetotoken%
+ \let\pgfsyssoftpath@rectcornertoken\pgf@gd@rectcornertoken%
+ \let\pgfsyssoftpath@curvetosupportatoken\pgf@gd@curvetosupportatoken%
+ \let\pgfsyssoftpath@closepathtoken\pgf@gd@closepathtoken%
+ \pgfpositionnodelaterpath%
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ %
+ {%
+ \pgf@process{\pgfpointanchor{\pgfpositionnodelatername}{center}}
+ \pgfsettransform{\csname pgf@sh@nt@\pgfpositionnodelatername\endcsname}%
+ \pgf@pos@transform{\pgf@x}{\pgf@y}%
+ \global\pgf@x=\pgf@x%
+ \global\pgf@y=\pgf@y%
+ }%
+ % call lua system library to create a lua node object
+ \directlua{
+ pgf.gd.interface.InterfaceToDisplay.createVertex(
+ string.sub('\pgfutil@luaescapestring{\pgfpositionnodelatername}',30), % strip "not yet positionedPGFINTERNAL"
+ '\pgfutil@luaescapestring{\csname pgf@sh@ns@\pgfpositionnodelatername\endcsname}',
+ pgf.temp:pad((\pgf@sys@tonumber\pgf@xa+\pgf@sys@tonumber\pgf@ya)/2), % Padded path
+ \the\pgf@gd@parameter@stack@height, % Stack height
+ {% Binding info
+ x_min = \pgf@gd@node@minx,
+ y_min = \pgf@gd@node@miny,
+ x_max = \pgf@gd@node@maxx,
+ y_max = \pgf@gd@node@maxy,
+ tex_box_number = \pgfpositionnodelaterbox
+ },
+ {% Anchors
+ center = require 'pgf.gd.model.Coordinate'.new(\pgf@sys@tonumber\pgf@x,\pgf@sys@tonumber\pgf@y)
+ }
+ )
+ pgf.temp = nil
+ }
+ }%
+}%
+
+
+\def\pgf@gd@movetotoken#1#2{\directlua{pgf.temp:appendMoveto(\Pgf@geT#1,\Pgf@geT#2)}}%
+\def\pgf@gd@linetotoken#1#2{\directlua{pgf.temp:appendLineto(\Pgf@geT#1,\Pgf@geT#2)}}%
+\def\pgf@gd@rectcornertoken#1#2#3#4#5{%
+ \directlua{%
+ local x,y,dx,dy=\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5
+ pgf.temp:appendMoveto(x,y)
+ pgf.temp:appendLineto(x,y+dy)
+ pgf.temp:appendLineto(x+dx,y+dy)
+ pgf.temp:appendLineto(x+dx,y)
+ pgf.temp:appendClosepath()%
+ }%
+}%
+\def\pgf@gd@curvetosupportatoken#1#2#3#4#5#6#7#8{\directlua{pgf.temp:appendCurveto(\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5,\Pgf@geT#7,\Pgf@geT#8)}}%
+\def\pgf@gd@closepathtoken#1#2{\directlua{pgf.temp:appendClosepath()}}%
+
+
+% Set options for an already existing node
+%
+% #1 = node name
+%
+% These node parameters of #1 will be updated with the current values
+% of the node parameters. The node #1 must previously have been passed
+% to the gd engine. If some of the options have already been set for
+% the node, these settings will be overruled.
+
+\def\pgfgdsetlatenodeoption#1{%
+ \directlua{
+ pgf.gd.interface.InterfaceToDisplay.addToVertexOptions('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height)
+ }
+}%
+
+
+
+%
+% A callback for rendering (finally positioning) a node
+%
+% #1 = name of the node
+% #2 = x min of the bounding box
+% #3 = x max of the bounding box
+% #4 = y min of the bounding box
+% #5 = y max of the bounding box
+% #6 = desired x pos of the node
+% #7 = desired y pos of the node
+% #8 = box register number of the TeX node
+% #9 = animation code
+%
+% This callback will be called by the engine for every original node
+% when it finally needs to placed at a final position.
+
+\def\pgfgdcallbackrendernode#1#2#3#4#5#6#7#8#9{%
+ {%
+ \def\pgfpositionnodelatername{#1}
+ \def\pgfpositionnodelaterminx{#2}
+ \def\pgfpositionnodelatermaxx{#3}
+ \def\pgfpositionnodelaterminy{#4}
+ \def\pgfpositionnodelatermaxy{#5}
+ \directlua{pgf.gd.interface.InterfaceCore.binding:retrieveBox(#8,\pgfpositionnodelaterbox)}
+ \def\pgf@temp{#9}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \pgfpositionnodenow{\pgfqpoint{#6}{#7}}%
+ \else%
+ \pgfset{every graphdrawing animation/.try}%
+ \pgfset{every graphdrawing node animation/.try}%
+ #9%
+ \pgfuseid{pgf@gd}%
+ \pgfidscope%
+ \pgfpositionnodenow{\pgfqpoint{#6}{#7}}%
+ \endpgfidscope%
+ \fi%
+ }%
+}%
+
+\ifx\pgfanimateattribute\pgfutil@undefined
+ \def\pgfanimateattribute#1#2{\tikzerror{You need to say \string\usetikzlibrary{animations} for animated graphs}}%
+\fi
+
+
+% Adds an edge to the graph
+%
+% #1 = first node
+% #2 = second node
+% #3 = edge direction
+% #4 = edge options (will be executed in a protected environment)
+% #5 = aux stuff (curtesy for TikZ -- edge nodes)
+%
+% Description:
+%
+% Creating an edge means that you tell the graph drawing algorithm
+% that #1 and #2 are connected. The "kind" of connection is indicated
+% by #3, which may be one of the following:
+%
+% -> = a directed edge (also known as an arc) from #1 to #2
+% -- = an undirected edge between #1 and #2
+% <- = a directed edge from #2 to #1, but with the "additional hint"
+% that this is a "backward" edge. A graph drawing algorithm may
+% or may not take this hint into account
+% <-> = a bi-directed edge between #1 and #2.
+%
+%
+% The parameters #4 and #5 are a bit more tricky. When an edge between
+% two vertices of a graph is created via \pgfgdedge, nothing is
+% actually done immediately. After all, without knowing the final
+% positions of the nodes #1 and #2, there is no way of
+% creating the actual drawing commands for the edge. Thus, the actual
+% drawing of the edge is done only when the graph drawing algorithm is
+% done (namely in the macro \pgfgdcallbackedge, see later).
+%
+% Because of this "delayed" drawing of edges, options that influence
+% the edge must be retained until the moment when the edge is actually
+% drawn. Parameters #4 and #5 store such options.
+%
+% Let us start with #4. This parameter should be set to a list of
+% key-value pairs like
+%
+% /tikz/.cd, color=red, very thick, this edge must be vertical
+%
+% Some of these options may be of interest to the graph drawing
+% algorithm (like the last option) while others will
+% only be important during the drawing of edge (like the first
+% option). The options that are important for the graph drawing
+% algorithm must be passed to the algorithm via setting keys that have
+% been declared using the handler .edge parameter (see
+% above).
+%
+% The tricky part is that options that are of interest to the graph
+% drawing algorithm must be executed *before* the algorithm starts,
+% but the options as a whole are usually only executed during the
+% drawing of the edges, which is *after* the algorithm has finished.
+%
+% To overcome this problem, the following happens:
+%
+% The options in #4 are executed "tentatively" inside
+% \pgfgdedge. However, this execution is done in a "heavily guarded
+% sandbox" where all effects of the options (like changing the
+% color or the line width) do not propagate beyond the sandbox. Only
+% the changes of the graph drawing edge parameters leave the
+% sandbox. These parameters are then passed down to the graph drawing
+% engine.
+%
+% Later, when the edge is drawn using \pgfgdcallbackedge, the options #4
+% are available once more and then they are executed normally.
+%
+% Note that when the options in #4 are executed, no path is
+% preset. Thus, you typically need to start it with, say, /tikz/.cd.
+%
+%
+% The text in #5 is some "auxiliary" text that is simply stored away
+% and later directly to \pgfgdcallbackedge. This is a curtesy to TikZ,
+% which can use it to store its node labels.
+%
+% Example:
+%
+% \pgfgdedge{A}{B}{->}{red}{}
+%
+\def\pgfgdedge#1#2#3#4#5{%
+ % Ok, setup sandbox
+ \begingroup%
+ \setbox0=\hbox{{%
+ \pgfinterruptpath%
+ \pgfgdprepareedge%
+ \pgfkeys{#4}%
+ % create edge in Lua
+ \toks0={#4}%
+ \toks1={#5}%
+ \directlua{
+ pgf.gd.interface.InterfaceToDisplay.createEdge(
+ '\pgfutil@luaescapestring{#1}','\pgfutil@luaescapestring{#2}','\pgfutil@luaescapestring{#3}',
+ \the\pgf@gd@parameter@stack@height,
+ { pgf_options = '\pgfutil@luaescapestring{\the\toks0}',
+ pgf_edge_nodes = '\pgfutil@luaescapestring{\the\toks1}',
+ })
+ }%
+ \endpgfinterruptpath%
+ }}%
+ \endgroup%
+}%
+
+\let\pgfgdprepareedge=\pgfutil@empty
+\def\pgfgdaddprepareedgehook#1{\expandafter\def\expandafter\pgfgdprepareedge\expandafter{\pgfgdprepareedge#1}}%
+
+
+\newif\ifpgf@gd@nodes@behind@edges
+
+
+
+% Define a callback for rendering edges
+%
+% #1 = macro name
+%
+% Descriptions:
+%
+% This is a callback from the graph drawing engine. At the end of the
+% creation of a graph, when the nodes have been positioned, this macro
+% is called once for each edge. The macro should take the following
+% parameters:
+%
+% #1 = from node, optionally followed by "." and the tail anchor
+% #2 = to node, optionally followed by "." and the head anchor
+% #3 = direction (<-, --, ->, or <->)
+% #4 = original options
+% #5 = aux text (typically edge nodes)
+% #6 = algorithm-generated options
+% #7 = bend information
+% #8 = animations
+%
+% The first five parameters are the original values that were passed
+% down to the \pgfgdedge command.
+%
+% #6 contains options that have been "computed by the algorithm". For
+% instance, an algorithm might have determined, say, flow capacities
+% for edges and it might now wish to communicate this information back
+% to the upper layers. These options should be executed with the path
+% /graph drawing.
+%
+% #7 contains algorithmically-computed information concerning how the
+% edge should bend. This will be a text like
+% "--(10pt,20pt)--(30pt,40pt)" in tikz-syntax, using the path
+% operations "--", "..controls" and "--cycle".
+%
+% By default, a simple line is drawn between the nodes. Usually, you
+% will wish to install a more "fancy" callback, here.
+
+\def\pgfgdsetedgecallback#1{\let\pgfgdcallbackedge=#1}%
+
+\def\pgfgddefaultedgecallback#1#2#3#4#5#6#7#8{%
+ {%
+ \def\pgf@temp{#8}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgfset{every graphdrawing animation/.try}%
+ \pgfset{every graphdrawing edge animation/.try}%
+ #8%
+ \pgfuseid{pgf@gd}%
+ \pgfidscope%
+ \fi%
+ \pgfscope
+ \pgfpathmoveto{
+ \pgfutil@in@.{#1}%
+ \ifpgfutil@in@
+ \pgf@gd@unravel#1\relax%
+ \else
+ \pgfpointshapeborder{#1}{\pgfpointanchor{#2}{center}}
+ \fi
+ }
+ \pgfpathlineto{
+ \pgfutil@in@.{#2}%
+ \ifpgfutil@in@
+ \pgf@gd@unravel#2\relax%
+ \else
+ \pgfpointshapeborder{#2}{\pgfpointanchor{#1}{center}}
+ \fi
+ }
+ \pgfusepath{stroke}
+ \endpgfscope
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \endpgfidscope%
+ \fi%
+ }
+}%
+
+\pgfgdsetedgecallback{\pgfgddefaultedgecallback}%
+
+\def\pgf@gd@unravel#1.#2\relax{%
+ \pgfpointanchor{#1}{#2}%
+}%
+
+
+
+
+% Callbacks: Called before the shipout of nodes and edges starts
+%
+% First, the general begin shipout is called. Then, the node shipout
+% starts, the nodes are created, and then the end of the node shipout
+% is signaled. Next, the edge shipout starts and ends. Finally, the
+% end shipout is called.
+
+\def\pgfgdcallbackbeginshipout{%
+ \pgfscope%
+ \catcode`\@=11\relax%
+ \setbox\pgf@gd@prekind@box=\box\pgfutil@voidb@x%
+ \setbox\pgf@gd@postkind@box=\box\pgfutil@voidb@x%
+}%
+\def\pgfgdcallbackendshipout{%
+ \box\pgf@gd@prekind@box%
+ \ifpgf@gd@nodes@behind@edges%
+ \box\pgf@gd@node@box%
+ \box\pgf@gd@edge@box%
+ \else%
+ \box\pgf@gd@edge@box%
+ \box\pgf@gd@node@box%
+ \fi%
+ \box\pgf@gd@postkind@box%
+ \endpgfscope
+}%
+
+\newbox\pgf@gd@node@box
+\newbox\pgf@gd@edge@box
+\newbox\pgf@gd@prekind@box
+\newbox\pgf@gd@postkind@box
+
+\def\pgfgdcallbackbeginnodeshipout{%
+ \setbox\pgf@gd@node@box=\hbox\bgroup%
+}%
+\def\pgfgdcallbackendnodeshipout{%
+ \egroup%
+}%
+
+\def\pgfgdcallbackbeginedgeshipout{%
+ \setbox\pgf@gd@edge@box=\hbox\bgroup%
+}%
+
+\def\pgfgdcallbackendedgeshipout{%
+ \egroup
+}%
+
+
+
+
+% Generate a node
+%
+% This callback is called from the engine whenever an algorithm
+% generates a new node internally.
+%
+% #1 = name of the node
+% #2 = shape of the node
+% #3 = options generated by the algorithm in key-value syntax. The set
+% of generated options is algorithm-dependent.
+% #4 = text
+%
+% This is an internal function and will be called by the binding layer
+
+\def\pgfgdcallbackcreatevertex#1#2#3#4{%
+ {
+ \pgfkeys{#3}
+ \pgfnode{#2}{\pgfkeysvalueof{/graph drawing/generated
+ node/anchor}}{#4}{#1}{\pgfkeysvalueof{/graph drawing/generated
+ node/use path}}
+ }
+}%
+
+\pgfkeys{
+ /graph drawing/generated node/anchor/.initial=center,
+ /graph drawing/generated node/use path/.initial=\pgfusepath{}
+}%
+
+
+
+%
+% Sublayouts
+%
+% Description: For a general introduction to (sub)layouts, see
+% Section~\ref{section-gd-sublayouts} in the manual.
+%
+
+\def\pgfgdbeginlayout{
+ \begingroup
+ \pgfgdlayoutscopeactivetrue
+ \advance\pgf@gd@parameter@stack@height by1\relax%
+ \directlua{pgf.gd.interface.InterfaceToDisplay.pushLayout(\the\pgf@gd@parameter@stack@height)}
+}%
+
+\def\pgfgdendlayout{
+ \endgroup%
+}%
+
+
+
+
+% Creates a subgraph node
+%
+% #1 = name
+% #2 = node options
+% #3 = node text
+%
+% Description:
+%
+% A subgraph node is a node that "surrounds" the nodes of a
+% subgraph. The special property of a subgraph node opposed to a
+% normal node is that it is created only after the subgraph has been
+% laid out. However, the difference to a collection like "hyper" is
+% that the node is available immediately as a normal node in the sense
+% that you can connect edges to it.
+%
+% What happens internally is that subgraph nodes get "registered"
+% immediately both on the pgf level and on the lua level, but the
+% actual node is only created inside the layout pipeline using a
+% callback. The actual node creation happens when the innermost layout
+% in which the subgraph node is declared has finished.
+%
+% When you create a subgraph node using this macro, you also start a
+% collection (of an internal kind) that stores the subgraph. All
+% following nodes in the current TeX scope will become part of this
+% collection.
+%
+% See |InterfaceToDisplay.pushSubgraphVertex| for details.
+
+\def\pgfgdsubgraphnode#1#2#3{%
+ \advance\pgf@gd@parameter@stack@height by1\relax%
+ {%
+ % create edge in Lua
+ \toks0={#2}%
+ \toks1={#3}%
+ \directlua{pgf.gd.interface.InterfaceToDisplay.pushSubgraphVertex%
+ ('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height,
+ {
+ shape = 'rectangle', % typically overwritten by the pgf_options:
+ pgf_options = '\pgfutil@luaescapestring{\the\toks0}',
+ text = '\pgfutil@luaescapestring{\the\toks1}',
+ })
+ }%
+ }
+}%
+
+\def\pgfgdsubgraphnodecontents#1{% helper function
+ \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{%
+ \vrule width0pt height\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\hfil}%
+}%
+
+\pgfgdset{
+ subgraph point cloud/.initial=,
+ subgraph bounding box width/.initial=,
+ subgraph bounding box height/.initial=,
+}%
+
+
+%
+% Requests
+%
+% Description:
+%
+% This key is used to ``request'' a graph drawing scope and a
+% layout. The objective of this key is to make it easier for users and
+% algorithm designers to control the slightly involved
+% back-and-forth-calling between the different layers.
+%
+% This key does the following: When called inside a pgfpicture
+% (otherwise, the call is "illegal"), it will call a call-back with
+% two parameters. This callback will get passed some code that should
+% be executed at the beginning of ``the next scope'' and some code
+% that should be executed at the end of that scope.
+%
+% The code passed to the callbacks will have a different effect,
+% depending on whether we are currently inside a layout scope or not
+% (if no graph drawing scope is open, we are
+% not inside a layout). If we are not inside a layout scope (or if the
+% layout scope has been interrupted), the code will issue a
+% \pgfgdbeginscope command in the opening code and a corresponding
+% scope ending command in the closing code. Next, the two code pieces
+% always contain \pgfgdbeginlayout and \pgfgdendlayout.
+%
+% Note that the "@request scope and layout" key will not immediately
+% trigger a layout scope to be created; rather, the TikZ callback will
+% call it only at the beginning of the scope, which will be after
+% other options in the current list of options have been parsed. So,
+% when you write \graph [binary tree layout, significant sep=2em] ...,
+% the "significant sep" option has an effect despite being given
+% *after* the "@request scope and layout" key since the actual opening
+% of the scope happens only before the "..." part is parsed.
+
+\pgfgdset{@request scope and layout/.code=\pgfgd@requestcallback{\pgfgdbeginrequest}{\pgfgdendrequest}}%
+
+\def\pgfgd@requestcallback#1#2{%
+ #1\def\pgf@gd@after@request{#2\egroup}\bgroup\aftergroup\pgf@gd@after@request%
+}% Default for basic layer
+
+\def\pgfgdbeginrequest{%
+ \ifpgfgdlayoutscopeactive%
+ \else%
+ \expandafter\pgfgdbeginscope%
+ \fi%
+ \pgfgdbeginlayout%
+}%
+\def\pgfgdendrequest{%
+ \pgfgdendlayout%
+ \ifpgfgdlayoutscopeactive%
+ \else%
+ \expandafter\pgfgdendscope%
+ \fi%
+}%
+\newif\ifpgfgdlayoutscopeactive
+
+
+% Set the request callback
+%
+% #1 = A macro
+%
+% Description:
+%
+% Sets the request callback as described in the "@request scope and
+% layout" key.
+
+\def\pgfgdsetrequestcallback#1{\let\pgfgd@requestcallback#1}%
+
+
+
+
+%
+% An if that is true exactly if we are inside a graph drawing scope
+%
+
+\newif\ifpgfgdgraphdrawingscopeactive
+
+
+% Begins a new graph drawing scope
+%
+% Description:
+%
+% Inside a graph drawing scope, all pgf nodes that are newly created
+% are automatically passed to the graph drawing engine. In contrast,
+% edges have to be indicated explicitly using the macro \pgfgdedge
+% (this is because it is somewhat unclear what, exactly, should count
+% as an edge). Naturally, users typically will not call \pgfgdedge
+% explicitly, but have styles and keys invoke it internally.
+%
+% Usage:
+%
+% \pgfgdset{algorithm=somealgorithm}
+% \pgfgdbeginscope
+% \pgfnode{rectangle}{center}{A}{A}{}
+% \pgfnode{rectangle}{center}{B}{B}{}
+% \pgfnode{rectangle}{center}{C}{C}{}
+% \pgfgdedge{A}{B}{->}{}{}
+% \pgfgdedge{B}{C}{->}{}{}
+% \pgfgdedge{C}{A}{->}{}{}
+% \pgfgdendscope
+%
+% Naturally, users will typically use TikZ's somewhat simpler syntax: '
+%
+% \tikz \graph [some algorithm] { A -> B -> C -> A };
+
+\def\pgfgdbeginscope{%
+ \begingroup % Protecting scope
+ % get options
+ \directlua{
+ pgf.gd.interface.InterfaceToDisplay.beginGraphDrawingScope(\the\pgf@gd@parameter@stack@height)
+ }%
+ \begingroup % Inner scope, the actual nodes will be inserted after
+ % this scope has been closed
+ % Indicate that we are now inside a graph drawing scope
+ \pgfgdgraphdrawingscopeactivetrue
+ % Switch on late positioning
+ \pgfpositionnodelater{\pgf@gd@positionnode@callback}
+ % Switch on late edges
+ \pgfgd@latecallback%
+ % Kill transformations (will be added by the position now
+ % macros)
+ \pgftransformreset
+}%
+
+
+
+% The following is used to ensure that if we need to resume the graph
+% drawing (through co-routines), we pass control back to TeX
+% first. Otherwise, new text input levels are created and there may be
+% only 15 of these...
+\newif\ifpgfgdresumecoroutine
+
+
+% Ends a graph drawing scope
+%
+% Description:
+%
+% This macro invokes the selected graph drawing algorithm and
+% ships out all nodes within this scope
+%
+% See \pgfgdbeginscope
+
+\def\pgfgdendscope{%
+ \pgfgdresumecoroutinefalse%
+ \directlua{
+ pgf.gd.interface.InterfaceToDisplay.runGraphDrawingAlgorithm()
+ }%
+ \pgfutil@loop%
+ \ifpgfgdresumecoroutine%
+ \pgfgdresumecoroutinefalse%
+ \directlua{
+ pgf.gd.interface.InterfaceToDisplay.resumeGraphDrawingCoroutine()
+ }%
+ \pgfutil@repeat%
+ \endgroup%
+ % Late positioning has ended
+ \directlua{pgf.gd.interface.InterfaceToDisplay.renderGraph()}%
+ \directlua{pgf.gd.interface.InterfaceToDisplay.endGraphDrawingScope()}%
+ \endgroup%
+}%
+
+
+
+
+
+
+% Hook into graph specification
+%
+% #1 = code
+%
+% Description:
+%
+% Allows you to specify code that should be active while the graph
+% drawing engine collects the information concerning the graph, but
+% which should no longer be active when the graph is rendered.
+
+\def\pgfgdaddspecificationhook#1{
+ \expandafter\def\expandafter\pgfgd@latecallback\expandafter{\pgfgd@latecallback#1}
+}%
+\let\pgfgd@latecallback\pgfutil@empty
+
+
+
+
+
+
+
+
+% Loading further libraries
+
+% Include a graph drawing library file.
+%
+% #1 = List of names of library file.
+%
+% Description:
+%
+% This command includes a list of graph drawing library files. For
+% each file X in the list, the file pgf.gd.X.lua is included using
+% |require|.
+%
+% For the convenience of Context users, both round and square brackets
+% are possible for the argument.
+%
+%
+% Example:
+%
+% \usegdlibrary{trees}
+% \usegdlibrary[force,circular]
+
+\def\usegdlibrary{\pgfutil@ifnextchar[{\use@gdlibrary}{\use@@gdlibrary}}%}%
+\def\use@gdlibrary[#1]{\use@@gdlibrary{#1}}%
+\def\use@@gdlibrary#1{%
+ \edef\pgf@list{#1}%
+ \pgfutil@for\pgf@temp:=\pgf@list\do{%
+ \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}%
+ \ifx\pgf@temp\pgfutil@empty
+ \else
+ \directlua{if not pgf_lookup_and_require('\pgf@temp') then
+ tex.print('\pgfutil@luaescapestring{\noexpand\pgferror{Graph drawing library '\pgf@temp' not found}}')
+ end}
+ \fi
+ }
+}%
+
+% LaTeX uses kpathsea for file lookup while ConTeXt uses its
+% resolvers. Luckily, kpathsea is still accessible in ConTeXt in a
+% subtable kpse.original which we use if kpse.find_file is nil.
+{%
+\catcode`\%=11
+\directlua{
+ function pgf_lookup_and_require(name)
+ local sep = package.config:sub(1,1)
+ local function lookup(name)
+ local sub = name:gsub('%.',sep)
+ local find_file = context and
+ resolvers.findfile or
+ kpse.find_file
+ if find_file(sub, 'lua') then
+ require(name)
+ elseif find_file(sub, 'clua') then
+ collectgarbage('stop')
+ require(name)
+ collectgarbage('restart')
+ else
+ return false
+ end
+ return true
+ end
+ return
+ lookup('pgf.gd.' .. name .. '.library') or
+ lookup('pgf.gd.' .. name) or
+ lookup(name .. '.library') or
+ lookup(name)
+ end
+}
+}%
+
+
+%
+% Ok, fire up the system by creating the binding!
+%
+\directlua{
+ require 'pgf.gd.interface.InterfaceToDisplay'
+ pgf.gd.interface.InterfaceToDisplay.bind(require 'pgf.gd.bindings.BindingToPGF')
+}%
+
+
+
+%
+% Special setup for keys that are declared by the above libraries, but
+% that have a special meaning on the display layer.
+%
+
+\pgfkeys{/graph drawing/nodes behind edges/.append code=\csname pgf@gd@nodes@behind@edges#1\endcsname}%
+\pgfkeys{/graph drawing/nodes behind edges/.default=true}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex
new file mode 100644
index 0000000000..3a1308320c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex
@@ -0,0 +1,17 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarygraphdrawing.examples.code.tex}
+
+\usepgflibrary{graphdrawing}%
+
+\usegdlibrary{examples}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex
new file mode 100644
index 0000000000..a06d99c5d5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex
@@ -0,0 +1,136 @@
+% Copyright 2019 by Jannis Pohlmann
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarygraphdrawing.force.code.tex}
+
+
+
+\usepgflibrary{graphdrawing}%
+
+\usegdlibrary{force}%
+
+\endinput
+
+
+
+%
+% Definition of spring algorithms as well as options to configure them.
+%
+
+\pgfgdset{
+ force based/.cd,
+ %
+ iterations/.graph parameter=number,
+ iterations/.parameter initial=500,
+ %
+ cooling factor/.graph parameter=number,
+ cooling factor/.parameter initial=0.95,
+ %
+ initial step dimension/.graph parameter=number,
+ initial step dimension/.parameter initial=0,
+ %
+ convergence tolerance/.graph parameter=number,
+ convergence tolerance/.parameter initial=0.01,
+ %
+ spring constant/.graph parameter=number,
+ spring constant/.parameter initial=0.01,
+ %
+ approximate electric forces/.graph parameter=boolean,
+ approximate electric forces/.parameter initial=false,
+ approximate electric forces/.default=true,
+ %
+ electric force order/.graph parameter=number,
+ electric force order/.parameter initial=1,
+ %
+ % Parameters related to the multilevel approach where the input graph
+ % is iteratively coarsened into graphs with fewer nodes, until either
+ % the number of nodes is small enough or the number of nodes in the
+ % could not be reduced by at least a user-defined ratio.
+ %
+ coarsen/.graph parameter=boolean,
+ coarsen/.parameter initial=true,
+ coarsen/.default=true,
+ %
+ coarsening/.code=\pgfkeys{
+ /graph drawing/force based/coarsening/.cd,
+ #1
+ },
+ %
+ coarsening/downsize ratio/.graph parameter=number,
+ coarsening/downsize ratio/.parameter initial=0.25,
+ %
+ coarsening/minimum graph size/.graph parameter=number,
+ coarsening/minimum graph size/.parameter initial=2,
+ %
+ coarsening/collapse independent edges/.graph parameter=boolean,
+ coarsening/collapse independent edges/.parameter initial=true,
+ coarsening/collapse independent edges/.default=true,
+ %
+ coarsening/connect independent nodes/.graph parameter=boolean,
+ coarsening/connect independent nodes/.parameter initial=false,
+ coarsening/connect independent nodes/.default=true,
+ %
+ % Node parameters for spring algorithms.
+ %
+ %
+ % Edge parameters for spring algorithms.
+ %
+}%
+
+\pgfgddeclareforwardedkeys{/graph drawing}{
+ %
+ electric charge/.node parameter=number,
+ electric charge/.parameter initial=1,
+}
+
+
+%
+% Spring algorithm based on the paper
+%
+% "Efficient, High-Quality Force-Directed Graph Drawing"
+% Yifan Hu, 2006
+%
+\pgfgddeclarealgorithmkey
+ {spring layout}
+ {force based}
+ {
+ algorithm=pgf.gd.force.SpringHu2006
+ }
+
+
+%
+% Spring-electrical algorithm based on the paper
+%
+% "Efficient, High-Quality Force-Directed Graph Drawing"
+% Yifan Hu, 2006
+%
+\pgfgddeclarealgorithmkey
+ {spring electrical layout}
+ {force based}
+ {
+ algorithm=pgf.gd.force.SpringElectricalHu2006,
+ force based/spring constant=0.2,
+ }
+
+
+
+%
+% Spring-electrical algorithm based on the paper
+%
+% "A Multilevel Algorithm for Force-Directed Graph Drawing"
+% C. Walshaw, 2000
+%
+\pgfgddeclarealgorithmkey
+ {spring electrical layout'}
+ {force based}
+ {
+ algorithm=pgf.gd.force.SpringElectricalWalshaw2000,
+ force based/spring constant=0.01,
+ force based/convergence tolerance=0.001,
+ }
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex
new file mode 100644
index 0000000000..322296b11b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex
@@ -0,0 +1,17 @@
+% Copyright 2019 by Jannis Pohlmann
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarygraphdrawing.layered.code.tex}
+
+\usepgflibrary{graphdrawing}%
+
+\usegdlibrary{layered}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex
new file mode 100644
index 0000000000..2c05576a86
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex
@@ -0,0 +1,19 @@
+% Copyright 2019 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarygraphdrawing.trees.code.tex}
+
+
+\usepgflibrary{graphdrawing}%
+\usepgflibrary{graphdrawing.layered}%
+
+\usegdlibrary{trees}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex b/graphics/pgf/base/tex/generic/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex
new file mode 100644
index 0000000000..aac7311e34
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex
@@ -0,0 +1,262 @@
+% Copyright 2018 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{tikzlibrarygraphdrawing.code.tex}
+
+\usepgflibrary{graphdrawing}%
+
+\def\tikz@lib@ensure@gd@loaded{}%
+
+
+% Patch the level and sibling distances so that gd and plain tikz are
+% in sync
+\tikzset{level distance=1cm, sibling distance=1cm}%
+
+% Patch node distance because of its special syntax.
+
+\pgfkeysgetvalue{/graph drawing/node distance/.@cmd}\tikz@lib@gd@node@dist@path
+\pgfkeyslet{/graph drawing/node distance/orig/.@cmd}\tikz@lib@gd@node@dist@path
+
+\pgfkeysdef{/graph drawing/node distance}{
+ \pgfutil@in@{ and }{#1}%
+ \ifpgfutil@in@%
+ \tikz@gd@convert@and#1\pgf@stop%
+ \else%
+ \tikz@gd@convert@and#1 and #1\pgf@stop%
+ \fi%
+}%
+\def\tikz@gd@convert@and#1 and #2\pgf@stop{\pgfkeys{/graph drawing/node distance/orig={#1}}}%
+
+
+
+
+%
+% Setup graph drawing for tikz
+%
+
+\def\tikz@gd@request@callback#1#2{%
+ \tikzset{
+ execute at begin scope={
+ \tikzset{
+ --/.style={arrows=-},
+ -!-/.style={draw=none,fill=none},
+ }
+ \pgfgdsetedgecallback{\pgfgdtikzedgecallback}%
+ %
+ % Setup for plain syntax
+ %
+ \pgfgdaddspecificationhook{\tikz@lib@gd@spec@hook}%
+ #1
+ \let\tikzgdeventcallback\pgfgdevent%
+ \let\tikzgdeventgroupcallback\pgfgdeventgroup%
+ \let\tikzgdlatenodeoptionacallback\pgfgdsetlatenodeoption%
+ },
+ execute at end scope={%
+ #2%
+ }
+ }%
+}%
+
+\pgfgdsetrequestcallback\tikz@gd@request@callback
+
+
+
+\pgfgdappendtoforwardinglist{/tikz/,/tikz/graphs/}%
+
+\def\tikz@lib@gd@spec@hook{%
+ \tikzset{
+ edge macro=\tikz@gd@plain@edge@macro,
+ /tikz/at/.style={/graph drawing/desired at={##1}},
+ %
+ % Setup for the tree syntax (do this late so that grow options
+ % are still valid after a layout has been chosen)
+ %
+ /tikz/growth function=\relax,
+ /tikz/edge from parent macro=\tikz@gd@edge@from@parent@macro,
+ %
+ % Setup for the graphs syntax
+ %
+ /tikz/graphs/new ->/.code n args={4}{\tikz@lib@gd@edge{##1}{##2}{->}{/tikz,##3}{##4}},
+ /tikz/graphs/new <-/.code n args={4}{\tikz@lib@gd@edge{##1}{##2}{<-}{/tikz,##3}{##4}},
+ /tikz/graphs/new --/.code n args={4}{\tikz@lib@gd@edge{##1}{##2}{--}{/tikz,##3}{##4}},
+ /tikz/graphs/new <->/.code n args={4}{\tikz@lib@gd@edge{##1}{##2}{<->}{/tikz,##3}{##4}},
+ /tikz/graphs/new -!-/.code n args={4}{\tikz@lib@gd@edge{##1}{##2}{-!-}{/tikz,##3}{##4}},
+ /tikz/graphs/placement/compute position/.code=,%
+ }
+}%
+
+% wrapper for \pgfgdedge
+\def\tikz@lib@gd@edge#1#2{%
+ \pgfgdedge{\tikz@pp@name{#1}}{\tikz@pp@name{#2}}%
+}
+
+\pgfgdaddprepareedgehook{
+ \tikz@enable@edge@quotes%
+ \let\tikz@transform=\pgfutil@empty%
+ \let\tikz@options=\pgfutil@empty%
+ \let\tikz@tonodes=\pgfutil@empty%
+}%
+
+
+\tikzset{
+ parent anchor/.forward to=/graph drawing/tail anchor,
+ child anchor/.forward to=/graph drawing/head anchor
+}%
+
+\def\pgfgdtikzedgecallback#1#2#3#4#5#6#7#8{%
+ \def\pgf@temp{#8}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgfscope%
+ \pgfset{every graphdrawing animation/.try}%
+ \pgfset{every graphdrawing edge animation/.try}%
+ #8%
+ \pgfuseid{pgf@gd}%
+ \pgfidscope%
+ \fi%
+ \begingroup
+ \draw (#1)
+ edge [to path={#7 \tikztonodes},#3,#4,/graph drawing/.cd,#6,/tikz/.cd]
+ #5
+ (#2);
+ \endgroup
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \endpgfidscope%
+ \endpgfscope%
+ \fi%
+}%
+
+\def\tikz@gd@edge@from@parent@macro#1#2{
+ [/utils/exec=\tikz@lib@gd@edge{\tikzparentnode}{\tikzchildnode}{--}{/tikz,#1}{#2}]
+}%
+
+\def\tikz@gd@plain@edge@macro#1#2{
+ \tikz@lib@gd@edge{\tikztostart}{\tikztotarget}{--}{/tikz,#1}{#2}
+}%
+
+
+
+%
+% Conversions: Convert coordinates into pairs of values surrounded by
+% braces.
+%
+
+\pgfgdset{
+ conversions/canvas coordinate/.code={%
+ \tikz@scan@one@point\pgf@process#1%
+ \pgfmathsetmacro{\tikz@gd@temp@x}{\pgf@x}
+ \pgfmathsetmacro{\tikz@gd@temp@y}{\pgf@y}
+ \edef\pgfgdresult{pgf.gd.model.Coordinate.new(\tikz@gd@temp@x,\tikz@gd@temp@y)}
+ },
+ conversions/coordinate/.code={%
+ \tikz@scan@one@point\pgf@process#1%
+ \pgfmathsetmacro{\tikz@gd@temp@x}{\pgf@x}
+ \pgfmathsetmacro{\tikz@gd@temp@y}{\pgf@y}
+ \edef\pgfgdresult{pgf.gd.model.Coordinate.new(\tikz@gd@temp@x,\tikz@gd@temp@y)}
+ }
+}%
+
+
+
+%
+% Overwrite node callback
+%
+
+\def\pgfgdcallbackcreatevertex#1#2#3#4{%
+ \node[every generated node/.try,name={#1},shape={#2},/graph drawing/.cd,#3]{#4};%
+}%
+
+
+%
+% Subgraph handling
+%
+
+% "General" text placement for subgraph nodes that works with all node
+% kinds.
+
+\tikzset{
+ subgraph text top/.code=\tikz@lg@simple@contents@top{#1},%
+ subgraph text top/.default=text ragged,
+ subgraph text bottom/.code=\tikz@lg@simple@contents@bottom{#1},%
+ subgraph text bottom/.default=text ragged,
+ subgraph text sep/.initial=.1em,
+ subgraph text none/.code={
+ \def\pgfgdsubgraphnodecontents##1{%
+ \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax%
+ \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{%
+ \vrule width0pt height.5\pgf@y depth.5\pgf@y\hfil}%
+ }%
+ },
+}%
+
+\def\tikz@lg@simple@contents@top#1{%
+ \def\pgfgdsubgraphnodecontents##1{%
+ \vbox{%
+ \def\pgf@temp{##1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \ifx\pgf@temp\pgfutil@sptoken%
+ \else%
+ \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{%
+ \hsize=\pgfkeysvalueof{/graph drawing/subgraph bounding box width}\relax%
+ \vbox{\noindent\strut\tikzset{#1}\tikz@text@action\pgf@temp}%
+ }%
+ \fi%
+ \fi%
+ \pgfmathparse{\pgfkeysvalueof{/tikz/subgraph text sep}}%
+ \kern\pgfmathresult pt\relax%
+ \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax%
+ \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{%
+ \vrule width0pt height.5\pgf@y depth.5\pgf@y\hfil}%
+ }%
+ }%
+}%
+
+\def\tikz@lg@simple@contents@bottom#1{%
+ \def\pgfgdsubgraphnodecontents##1{%
+ {%
+ \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax%
+ \setbox0=\vbox{%
+ \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{\vrule width0pt height\pgf@y\hfil}%
+ \pgfmathparse{\pgfkeysvalueof{/tikz/subgraph text sep}}%
+ \kern\pgfmathresult pt\relax%
+ \def\pgf@temp{##1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \ifx\pgf@temp\pgfutil@sptoken%
+ \else%
+ \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{%
+ \hsize=\pgfkeysvalueof{/graph drawing/subgraph bounding box width}\relax%
+ \vbox{\noindent\strut\tikzset{#1}\tikz@text@action\pgf@temp}%
+ }%
+ \fi%
+ \fi%
+ }%
+ \pgf@ya=\ht0\relax%
+ \advance\pgf@ya by-.5\pgf@y\relax%
+ \ht0=.5\pgf@y\relax%
+ \dp0=\pgf@ya\relax%
+ \box0\relax%
+ }%
+ }%
+}%
+
+\tikzset{subgraph text top}%
+
+\tikzset{
+ subgraph nodes/.style={/tikz/every subgraph node/.style={#1}},
+ graphs/subgraph nodes/.style={/tikz/every subgraph node/.style={#1}},
+ graphs/@graph drawing setup/.style={/graph drawing/anchor at={(\tikz@lastx,\tikz@lasty)}}
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.barcharts.code.tex b/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.barcharts.code.tex
new file mode 100644
index 0000000000..3ac0d476f9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.barcharts.code.tex
@@ -0,0 +1,135 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarydatavisualization.barcharts.code.tex}
+
+\usepgfmodule{datavisualization}%
+
+
+%
+% This file defines additional data visualization classes.
+%
+
+
+\pgfooclass{candle stick visualizer}
+{%
+ \attribute attribute;%
+ \attribute offset;%
+ \attribute use path rise=\pgfsetfillcolor{white}\pgfusepath{fill,stroke};%
+ \attribute use path fall=\pgfsetfillcolor{black}\pgfusepath{fill,stroke};%
+ \attribute use path wick=\pgfusepath{stroke};%
+
+ \method candle stick visualizer(#1) {
+ \pgfooeset{attribute}{#1}
+ \pgfoothis.set stick width(4pt)
+ }%
+
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,visualize,visualize datapoint signal)
+ }%
+
+ \method set stick width(#1) {
+ \pgfmathparse{#1}
+ \pgfmathdivide{\pgfmathresult}{2}
+ \let\pgf@dv@lib@w=\pgfmathresult
+ % Compute the normalized vector:
+ \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute}}{1}
+ \pgfcanvaspositionofdatapoint%
+ \pgfsettocanvasposition\pgf@dv@lib@lower%
+ \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute}}{10}
+ \pgfcanvaspositionofdatapoint%
+ \pgfsettocanvasposition\pgf@dv@lib@upper%
+ \pgf@process{\pgfpointnormalised{\pgfpointdiff{\pgf@dv@lib@upper}{\pgf@dv@lib@lower}}}%
+ % Rotate by 90 degrees
+ \pgf@xa=\pgf@x%
+ \pgf@x=-\pgf@dv@lib@w\pgf@y%
+ \pgf@y=\pgf@dv@lib@w\pgf@xa%
+ \edef\pgf@dv@lib@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfoolet{offset}\pgf@dv@lib@temp
+ }%
+
+ \method set use path rise(#1) {
+ \pgfooset{use path rise}{#1}
+ }%
+
+ \method set use path fall(#1) {
+ \pgfooset{use path fall}{#1}
+ }%
+
+ \method visualize() {
+ {
+ \pgfooget{attribute}\pgf@lib@attribute%
+ \pgfkeysgetvalue{/data point/\pgf@lib@attribute/low}\pgf@lib@low
+ \pgfkeysgetvalue{/data point/\pgf@lib@attribute/high}\pgf@lib@high
+ \pgfkeysgetvalue{/data point/\pgf@lib@attribute/entry}\pgf@lib@entry
+ \pgfkeysgetvalue{/data point/\pgf@lib@attribute/exit}\pgf@lib@exit
+ \ifx\pgf@lib@low\pgfutil@empty\pgf@dv@lib@cs@skiptrue\fi
+ \ifx\pgf@lib@low\relax\pgf@dv@lib@cs@skiptrue\fi
+ \ifx\pgf@lib@high\pgfutil@empty\pgf@dv@lib@cs@skiptrue\fi
+ \ifx\pgf@lib@high\relax\pgf@dv@lib@cs@skiptrue\fi
+ \ifx\pgf@lib@entry\pgfutil@empty\pgf@dv@lib@cs@skiptrue\fi
+ \ifx\pgf@lib@entry\relax\pgf@dv@lib@cs@skiptrue\fi
+ \ifx\pgf@lib@exit\pgfutil@empty\pgf@dv@lib@cs@skiptrue\fi
+ \ifx\pgf@lib@exit\relax\pgf@dv@lib@cs@skiptrue\fi
+ \ifpgf@dv@lib@cs@skip%
+ \else%
+ \begin{pgfscope}
+ % Ok, compute low point
+ \pgfkeyssetvalue{/data point/\pgf@lib@attribute}\pgf@lib@low
+ \pgfcanvaspositionofdatapoint%
+ \pgfsettocanvasposition\pgf@dv@lib@lowpoint%
+ % Ok, compute hight point
+ \pgfkeyssetvalue{/data point/\pgf@lib@attribute}\pgf@lib@high
+ \pgfcanvaspositionofdatapoint%
+ \pgfsettocanvasposition\pgf@dv@lib@highpoint%
+ % Compute entry and exit
+ \pgfkeyssetvalue{/data point/\pgf@lib@attribute}\pgf@lib@entry
+ \pgfcanvaspositionofdatapoint%
+ \pgfsettocanvasposition\pgf@dv@lib@entrypoint%
+ \pgfkeyssetvalue{/data point/\pgf@lib@attribute}\pgf@lib@exit
+ \pgfcanvaspositionofdatapoint%
+ \pgfsettocanvasposition\pgf@dv@lib@exitpoint%
+ \ifdim\pgf@lib@entry pt<\pgf@lib@exit pt\relax%
+ \pgf@dv@lib@risetrue%
+ \fi%
+ \ifpgf@dv@lib@rise
+ \let\pgf@dv@lib@a=\pgf@dv@lib@entrypoint
+ \let\pgf@dv@lib@b=\pgf@dv@lib@exitpoint
+ \else
+ \let\pgf@dv@lib@a=\pgf@dv@lib@exitpoint
+ \let\pgf@dv@lib@b=\pgf@dv@lib@entrypoint
+ \fi
+ % Start drawing...
+ \pgfpathmoveto{\pgf@dv@lib@lowpoint}
+ \pgfpathlineto{\pgf@dv@lib@a}
+ \pgfpathmoveto{\pgf@dv@lib@highpoint}
+ \pgfpathlineto{\pgf@dv@lib@b}
+ \pgfoovalueof{use path wick}
+ \pgfpathmoveto{\pgfpointadd{\pgf@dv@lib@a}{\pgfoovalueof{offset}}}
+ \pgfpathlineto{\pgfpointadd{\pgf@dv@lib@b}{\pgfoovalueof{offset}}}
+ \pgfpathlineto{\pgfpointadd{\pgf@dv@lib@b}{\pgfpointscale{-1}{\pgfoovalueof{offset}}}}
+ \pgfpathlineto{\pgfpointadd{\pgf@dv@lib@a}{\pgfpointscale{-1}{\pgfoovalueof{offset}}}}
+ \pgfpathclose
+ \ifpgf@dv@lib@rise
+ \pgfoovalueof{use path rise}
+ \else
+ \pgfoovalueof{use path fall}
+ \fi
+ \end{pgfscope}%
+ \fi
+ }
+ }%
+
+ \newif\ifpgf@dv@lib@cs@skip
+ \newif\ifpgf@dv@lib@rise
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex b/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex
new file mode 100644
index 0000000000..d1e87cb1f7
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex
@@ -0,0 +1,209 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarydatavisualization.formats.functions.code.tex}
+
+\usepgfmodule{datavisualization}%
+
+
+
+
+% Function evaluator
+%
+% (This uses TeX evaluation and is slow. *You have been warned*.)
+%
+% Description:
+%
+% The data contains the description of variables and functions.
+%
+% The format for the variables is
+%
+% var <name> : interval "["<start>:<end>"]" [ step <steps> | samples <samples>];
+%
+% (The first two [ and ] are "real", the second pair means "optional",
+% see the examples.)
+%
+%
+% The format for the functions is
+%
+% func <name> = <body>;
+%
+% Additionally, the variables and functions stored in the keys
+% /pgf/data/vars and /pgf/data/funcs will also be used, the format for
+% them is the same as above.
+%
+% The <name> is always the name of a (data point) attribute. Inside
+% the <body> it can be accessed using the \value macro, which is
+% defined locally, here.
+%
+% Newlines are not important, everything is gathered into a single
+% line, the semicolons are used to detect the beginnings and ends of
+% declarations.
+%
+% With everything setup in this way, for each variable, the variable
+% ranges through the values between start and end, either with the
+% given step or the given number of samples. If neither is given, the
+% current value of /pgf/data visualization/samples is used. If there
+% are multiple variables, they all range over their respective
+% intervals independently. Thus, "var x = [0,1]; var y = [0:1];",
+% assuming samples=25, gives you 625 data points.
+%
+% As the variables range over their respective values, the functions
+% are evaluated using the function stored in /pgf/data/evaluator. By
+% default this is set to \pgfmathparse, but
+% you can use a different parser, if you like.
+%
+% Example:
+%
+% data [format=function] {
+%
+% % This is a parametric plot with the parameter called t.
+% var t : interval [0:360] samples 60;
+%
+% % Let's draw a circle:
+% func x = sin(\value t);
+% func y = cos(\value t);
+% }
+%
+% data [format=function] {
+%
+% % This a surface plot data...
+% var x : interval [0:1];
+% var y : interval [0:1];
+%
+% % Let's draw a circle:
+% func height = \value x*\value x + \value y*\value y;
+% }
+
+\pgfdeclaredataformat{function}
+{ % no catcode code
+}
+{ % Startup
+ % Init collectors
+ \let\value=\relax% avoid expansion
+ \pgfkeysgetvalue{/pgf/data/vars}\pgf@lib@dv@collector
+}
+{% Line arguments
+ #1%
+}
+{ % Line action
+ \edef\pgf@lib@dv@collector{\pgf@lib@dv@collector\space #1}%
+}
+{% Ignore empty lines
+}
+{%
+ \edef\pgf@lib@dv@collector{\pgf@lib@dv@collector\space \pgfkeysvalueof{/pgf/data/funcs}}%
+ \let\pgf@lib@dv@parsed\pgfutil@empty%
+ % launch parser on the result
+ \expandafter\pgf@lib@dv@func@parse \pgf@lib@dv@collector\pgf@stop%
+ \let\value\pgf@lib@dv@getval
+ \pgf@lib@dv@parsed\pgfdatapoint\pgfutil@gobble\pgf@stop%
+}%
+
+\pgfkeys{
+ /pgf/data/vars/.initial=,
+ /pgf/data/funcs/.initial=,
+ /pgf/data/evaluator/.initial=\pgfmathparse,
+ /pgf/data/samples/.initial=25}%
+
+\def\pgf@lib@dv@getval#1{\pgfkeysvalueof{/data point/#1}}%
+
+\def\pgf@lib@dv@func@parse{%
+ \pgfutil@ifnextchar\pgf@stop{% done
+ \pgfutil@gobble%
+ }
+ {%
+ \pgfutil@ifnextchar v{% variable
+ \pgf@lib@dv@var%
+ }{%
+ \pgf@lib@dv@func%
+ }%
+ }%
+}%
+
+\def\pgf@lib@dv@func func #1 =#2;{%
+ \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@eval@func{#1}{#2}}
+ \pgf@lib@dv@func@parse%
+}%
+\def\pgf@lib@dv@var var #1 :{\pgfutil@ifnextchar\bgroup{\pgf@lib@dv@var@group{#1}}{\pgf@lib@dv@var@int{#1}}}%
+\def\pgf@lib@dv@var@group#1#2;{%
+ \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@group@var{#1}{#2}}%
+ \pgf@lib@dv@func@parse%
+}%
+\def\pgf@lib@dv@var@int#1#2[#3:#4]{%
+ \pgfutil@ifnextchar s{%
+ \pgf@lib@dv@samplesorsteps{#1}{#3}{#4}%
+ }{%
+ \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{%
+ \pgf@lib@dv@parsed\pgf@lib@dv@samples@var{#1}{#3}{#4}{\pgfkeysvalueof{/pgf/data/samples}}}%
+ \expandafter\pgf@lib@dv@func@parse\pgfutil@gobble%
+ }
+}%
+\def\pgf@lib@dv@samplesorsteps#1#2#3s{%
+ \pgfutil@ifnextchar t{% step
+ \pgf@lib@dv@step{#1}{#2}{#3}%
+ }{% sample
+ \pgf@lib@dv@samples{#1}{#2}{#3}%
+ }%
+}%
+\def\pgf@lib@dv@step#1#2#3tep#4;{%
+ \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@step@var{#1}{#2}{#3}{#4}}%
+ \pgf@lib@dv@func@parse%
+}%
+\def\pgf@lib@dv@samples#1#2#3amples#4;{%
+ \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@samples@var{#1}{#2}{#3}{#4}}%
+ \pgf@lib@dv@func@parse%
+}%
+
+%
+% Executer...
+%
+\def\pgf@lib@dv@samples@var#1#2#3#4{%
+ \pgfmathparse{#3}%
+ \let\pgf@lib@dv@temp=\pgfmathresult%
+ \pgfmathparse{#2}%
+ \pgfmathparse{\pgf@lib@dv@temp-\pgfmathresult}%
+ \pgfmathparse{\pgfmathresult/(#4-1)}%
+ \let\pgf@lib@dv@temp=\pgfmathresult%
+ \pgf@lib@dv@step@var{#1}{#2}{#3}{\pgf@lib@dv@temp}%
+}%
+
+\def\pgf@lib@dv@step@var#1#2#3#4#5\pgf@stop{%
+ {%
+ \def\pgf@loop@body{#5}%
+ \pgfmathparse{#2}%
+ \pgfkeyslet{/data point/#1}{\pgfmathresult}%
+ \pgfmathparse{#3}%
+ \let\pgf@loop@end\pgfmathresult%
+ \pgfmathparse{#4}%
+ \let\pgf@loop@step\pgfmathresult%
+ \pgfmathloop%
+ \pgfmathlessthan{\pgf@loop@end}{\pgfkeysvalueof{/data point/#1}}
+ \ifdim\pgfmathresult pt<1pt\relax%
+ \pgf@loop@body\pgf@stop%
+ \pgfmathparse{\pgfkeysvalueof{/data point/#1}+\pgf@loop@step}%
+ \pgfkeyslet{/data point/#1}{\pgfmathresult}%
+ \repeatpgfmathloop%%
+ }%
+}%
+
+\def\pgf@lib@dv@group@var#1#2#3\pgf@stop{%
+ \foreach \pgf@lib@dv@iterator in {#2} {%
+ \pgfkeyslet{/data point/#1}{\pgf@lib@dv@iterator}%
+ #3\pgf@stop%
+ }%
+}%
+
+\def\pgf@lib@dv@eval@func#1#2{%
+ \pgfkeysvalueof{/pgf/data/evaluator}{#2}%
+ \pgfkeyslet{/data point/#1}{\pgfmathresult}%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex b/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex
new file mode 100644
index 0000000000..a7d493491f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex
@@ -0,0 +1,198 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarydatavisualization.polar.code.tex}
+
+\usepgfmodule{datavisualization}%
+
+% This file defines code for doing plots involving polar
+% coordinates. This includes not only standard polar plots, but also
+% pie charts.
+
+
+
+\pgfooclass{polar transformer}
+{%
+ % Class polar mapper
+ %
+ % A polar mapper is used to transform attributes given as (2d) polar
+ % coordinates to canvas coordinates. Note that no special ranges
+ % can be specified and that the angle must be given in degrees. You
+ % can, however, use a standard mapper to change these things.
+
+ \attribute angle;%
+ % The attribute from which the angle is read.
+
+ \attribute radius;%
+ % The attribute from which the radius is read.
+
+ \attribute unit vector 0 degrees;%
+ % The unit vector 0 degrees
+
+ \attribute unit vector 90 degrees;%
+ % The unit vector 90 degrees
+
+
+
+ % Constructor
+ %
+ % #1 = angle attribute. Example: rotation.
+ % #2 = radius attribute. Example: height.
+ % #3 = unit vector 0 degrees
+ % #4 = unit vector 90 degrees
+ %
+ \method polar transformer(#1,#2,#3,#4) {
+ \pgfooset{angle}{#1}
+ \pgfooset{radius}{#2}
+ \pgfooset{unit vector 0 degrees}{#3}
+ \pgfooset{unit vector 90 degrees}{#4}
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,transform,transform datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,path,path signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,direction,direction signal)
+ }%
+
+ % Getters
+ \method get angle attribute(#1) {
+ \pgfooget{angle}{#1}
+ }%
+
+ \method get radius attribute(#1) {
+ \pgfooget{radius}{#1}
+ }%
+
+
+ % Slot
+ %
+ % This slot should be connected to the transform datapoint
+ % signal. When this signal is emitted, the coordinate system will be
+ % shifted according to the current value of the attribute.
+ \method transform() {
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}/const}\pgf@dv@angle%
+ \ifx\pgf@dv@angle\relax
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@angle%
+ \fi
+ \ifx\pgf@dv@angle\relax\else%
+ \ifx\pgf@dv@angle\pgfutil@empty\else%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}/const}\pgf@dv@radius%
+ \ifx\pgf@dv@radius\relax
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@radius%
+ \fi
+ \ifx\pgf@dv@radius\pgfutil@empty\else%
+ \ifx\pgf@dv@radius\relax\else%
+ \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@angle}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@angle}{\pgf@dv@val}%
+ \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@radius}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@radius}{\pgf@dv@val}%
+ \pgfmathsincos{\pgf@dv@angle}%
+ \pgfmathmultiply{\pgfmathresultx}{\pgf@dv@radius}%
+ \let\pgf@dv@polar@temp=\pgfmathresult
+ \pgftransformshift{\pgfpointscale{\pgf@dv@polar@temp}{\pgfoovalueof{unit vector 0 degrees}}}%
+ \pgfmathmultiply{\pgfmathresulty}{\pgf@dv@radius}%
+ \let\pgf@dv@polar@temp=\pgfmathresult
+ \pgftransformshift{\pgfpointscale{\pgf@dv@polar@temp}{\pgfoovalueof{unit vector 90 degrees}}}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ }%
+
+
+
+ % Reaction to the path signal
+ %
+ % Here is what we do: When a pgfdvpathmoveto is done, the radius and
+ % the angle are recorded. When a pgfdvpathlineto is done, the saved
+ % radius and angle are compared with the new angle and radius. If,
+ % and only if, the radius is the same, but the angle is different,
+ % the lineto is caught and replaced by an arc from the previous
+ % position to the new position.
+
+ \attribute prev angle;%
+ \attribute prev radius;%
+
+ \method path(#1) {%
+ \ifpgfdvhandled%
+ \else%
+ \ifx#1\pgfdvpathlinetotoken
+ % Ok, let us have a look...
+ \pgfooget{prev radius}\pgf@dv@prev@rad
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@current@rad
+ \ifx\pgf@dv@current@rad\relax
+ \else
+ \ifx\pgf@dv@current@rad\pgf@dv@prev@rad%
+ \pgfooget{prev angle}\pgf@dv@prev@angle
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@current@angle
+ \ifx\pgf@dv@current@angle\relax
+ \else
+ \ifx\pgf@dv@current@angle\pgf@dv@prev@angle%
+ % do nothing
+ \else%
+ % Do arc:
+ \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@angle}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@prev@angle}{\pgf@dv@val}%
+ \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@rad}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@prev@rad}{\pgf@dv@val}%
+ \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@angle}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@current@angle}{\pgf@dv@val}%
+ \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@rad}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@current@rad}{\pgf@dv@val}%
+ \pgfpatharcaxes{\pgf@dv@prev@angle}{\pgf@dv@current@angle}
+ {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 0 degrees}}}
+ {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 90 degrees}}}%
+ \pgfdvhandledtrue%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ % No matter what, record the current position
+ \pgfooeset{prev angle}{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}}
+ \pgfooeset{prev radius}{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}}
+ }%
+
+ % Method
+ %
+ % React to direction signals. See pgfpointdvdirection for an
+ % explanation
+ %
+ \method direction(#1) {%
+ \ifx#1\pgfdvdirectionfromtoken
+ % Record from angle and radius
+ \xdef\pgf@dv@polar@from@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}}
+ \xdef\pgf@dv@polar@from@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}}
+ \else\ifx#1\pgfdvdirectiontotoken%
+ % Record to angle and radius
+ \xdef\pgf@dv@polar@to@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}}
+ \xdef\pgf@dv@polar@to@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}}
+ \else%
+ \ifx\pgf@dv@polar@from@radius\pgf@dv@polar@to@radius%
+ \pgfdvmathenter{\pgf@dv@a}{\pgf@dv@polar@from@angle}%
+ \pgfdvmathenter{\pgf@dv@b}{\pgf@dv@polar@to@angle}%
+ \pgfdvmathifless{\pgf@dv@a}{\pgf@dv@b}{\def\pgf@dv@temp@sign{+}}{\def\pgf@dv@temp@sign{-}}%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@temp%
+ \ifx\pgf@temp\relax%
+ \else%
+ \pgfdvmathenter{\pgf@dv@val}{\pgf@temp}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@polar@angle}{\pgf@dv@val}%
+ \pgf@process{\pgfpointpolar{\pgf@dv@polar@angle\pgf@dv@temp@sign90}{1pt}}%
+ \pgfdvhandledtrue%
+ \fi%
+ \fi%
+ \fi\fi%
+ }%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.footprints.code.tex b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.footprints.code.tex
new file mode 100644
index 0000000000..4fc6565c1b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.footprints.code.tex
@@ -0,0 +1,230 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+
+% Parameters
+\pgfset{
+ % Length of a footprint:
+ /pgf/decoration/foot length/.initial=10pt,
+ % Distance between two footprints on the same side of the path
+ /pgf/decoration/stride length/.initial=30pt,
+ % Double distance between footprint and input path
+ /pgf/decoration/foot sep/.initial=4pt,
+ % Rotate feet by this much
+ /pgf/decoration/foot angle/.initial=10,
+ % What animal?
+ /pgf/decoration/foot of/.initial=human,
+}%
+
+
+
+\pgfdeclaredecoration{footprints}{left}
+{%
+ \state{left}[width=\pgfkeysvalueof{/pgf/decoration/stride length}/2,next state=right]
+ {
+ \pgftransformyshift{\pgfkeysvalueof{/pgf/decoration/foot sep}/2}
+ \pgfmathparse{\pgfkeysvalueof{/pgf/decoration/foot length}}
+ \pgftransformscale{\pgfmathresult}
+ \pgftransformrotate{\pgfkeysvalueof{/pgf/decoration/foot angle}}
+ \csname pgf@lib@foot@of@\pgfkeysvalueof{/pgf/decoration/foot of}\endcsname
+ }%
+ \state{right}[width=\pgfkeysvalueof{/pgf/decoration/stride length}/2,next state=left]
+ {
+ \pgftransformyscale{-1}
+ \pgftransformyshift{\pgfkeysvalueof{/pgf/decoration/foot sep}/2}
+ \pgfmathparse{\pgfkeysvalueof{/pgf/decoration/foot length}}
+ \pgftransformscale{\pgfmathresult}
+ \pgftransformrotate{\pgfkeysvalueof{/pgf/decoration/foot angle}}
+ \csname pgf@lib@foot@of@\pgfkeysvalueof{/pgf/decoration/foot of}\endcsname
+ }%
+}%
+
+
+
+% Actual footprints.
+%
+% A footprint must be name \pgf@lib@foot@of@XXX, be a left foot and
+% should fill a rectangle of (0,0) rectangle (1pt,1pt) (more or less)
+% and point right.
+%
+
+
+\def\pgf@lib@foot@of@gnome{
+ % Coordinates from a Gnome logo on wikimedia commons. LGPL
+ % license... Unknown author.
+ %
+ % Flip and rotate
+ \pgftransformcm{0}{-1}{-1}{0}{\pgfqpoint{1pt}{0.8pt}}
+ \pgftransformscale{0.83333}
+ \pgfpathmoveto{\pgfqpoint{.86068pt}{0pt}}
+ \pgfpathcurveto{\pgfqpoint{.61466pt}{0pt}}{\pgfqpoint{.56851pt}{.35041pt}}{\pgfqpoint{.70691pt}{.35041pt}}
+ \pgfpathcurveto{\pgfqpoint{.84529pt}{.35041pt}}{\pgfqpoint{1.10671pt}{0pt}}{\pgfqpoint{.86068pt}{0pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{.45217pt}{.30699pt}}
+ \pgfpathcurveto{\pgfqpoint{.52586pt}{.31149pt}}{\pgfqpoint{.60671pt}{.02577pt}}{\pgfqpoint{.46821pt}{.04374pt}}
+ \pgfpathcurveto{\pgfqpoint{.32976pt}{.06171pt}}{\pgfqpoint{.37845pt}{.30249pt}}{\pgfqpoint{.45217pt}{.30699pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{.11445pt}{.48453pt}}
+ \pgfpathcurveto{\pgfqpoint{.16686pt}{.46146pt}}{\pgfqpoint{.1212pt}{.23581pt}}{\pgfqpoint{.03208pt}{.29735pt}}
+ \pgfpathcurveto{\pgfqpoint{-.057pt}{.3589pt}}{\pgfqpoint{.06204pt}{.50759pt}}{\pgfqpoint{.11445pt}{.48453pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{.26212pt}{.36642pt}}
+ \pgfpathcurveto{\pgfqpoint{.32451pt}{.3537pt}}{\pgfqpoint{.32793pt}{.09778pt}}{\pgfqpoint{.21667pt}{.14369pt}}
+ \pgfpathcurveto{\pgfqpoint{.10539pt}{.18961pt}}{\pgfqpoint{.19978pt}{.37916pt}}{\pgfqpoint{.26212pt}{.36642pt}}
+ \pgfpathlineto{\pgfqpoint{.26212pt}{.36642pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{.58791pt}{.93913pt}}
+ \pgfpathcurveto{\pgfqpoint{.59898pt}{1.02367pt}}{\pgfqpoint{.52589pt}{1.06542pt}}{\pgfqpoint{.45431pt}{1.01092pt}}
+ \pgfpathcurveto{\pgfqpoint{.22644pt}{.83743pt}}{\pgfqpoint{.8316pt}{.75088pt}}{\pgfqpoint{.79171pt}{.51386pt}}
+ \pgfpathcurveto{\pgfqpoint{.7586pt}{.31712pt}}{\pgfqpoint{.15495pt}{.37769pt}}{\pgfqpoint{.08621pt}{.68553pt}}
+ \pgfpathcurveto{\pgfqpoint{.03968pt}{.89374pt}}{\pgfqpoint{.27774pt}{1.1826pt}}{\pgfqpoint{.52614pt}{1.1826pt}}
+ \pgfpathcurveto{\pgfqpoint{.64834pt}{1.1826pt}}{\pgfqpoint{.78929pt}{1.07226pt}}{\pgfqpoint{.81566pt}{.93248pt}}
+ \pgfpathcurveto{\pgfqpoint{.8358pt}{.82589pt}}{\pgfqpoint{.57867pt}{.8686pt}}{\pgfqpoint{.58791pt}{.93913pt}}
+ \pgfpathlineto{\pgfqpoint{.58791pt}{.93913pt}}
+ \pgfpathclose
+}%
+
+
+
+\def\pgf@lib@foot@of@bird{
+ % Coordinates derived from vector image created by Mark Wibrow.
+ %
+ \pgftransformcm{0}{.11}{.11}{0}{\pgfqpoint{.37pt}{.52pt}}
+ \pgfpathmoveto{\pgfqpoint{-.886pt}{1.652pt}}
+ \pgfpathcurveto{\pgfqpoint{-.4632pt}{2.669pt}}{\pgfqpoint{-.5092pt}{4.3712pt}}{\pgfqpoint{-.4512pt}{5.6734pt}}
+ \pgfpathcurveto{\pgfqpoint{-.4374pt}{5.9842pt}}{\pgfqpoint{-.3182pt}{6.0686pt}}{\pgfqpoint{-.2484pt}{5.644pt}}
+ \pgfpathcurveto{\pgfqpoint{-.0534pt}{4.459pt}}{\pgfqpoint{.087pt}{3.0132pt}}{\pgfqpoint{.5206pt}{1.8464pt}}
+ \pgfpathcurveto{\pgfqpoint{.714pt}{1.326pt}}{\pgfqpoint{.692pt}{1.416pt}}{\pgfqpoint{1.0864pt}{1.759pt}}
+ \pgfpathcurveto{\pgfqpoint{1.7662pt}{2.3504pt}}{\pgfqpoint{2.665pt}{3.1756pt}}{\pgfqpoint{3.2028pt}{4.02pt}}
+ \pgfpathcurveto{\pgfqpoint{3.4708pt}{4.4408pt}}{\pgfqpoint{3.4258pt}{4.0814pt}}{\pgfqpoint{3.3366pt}{3.8708pt}}
+ \pgfpathcurveto{\pgfqpoint{2.9068pt}{2.8562pt}}{\pgfqpoint{.8502pt}{.645pt}}{\pgfqpoint{.4808pt}{-.0864pt}}
+ \pgfpathcurveto{\pgfqpoint{.0808pt}{-.8788pt}}{\pgfqpoint{.1664pt}{-2.1246pt}}{\pgfqpoint{.0024pt}{-2.7868pt}}
+ \pgfpathcurveto{\pgfqpoint{-.172pt}{-3.4908pt}}{\pgfqpoint{-.2726pt}{-3.704pt}}{\pgfqpoint{-.3812pt}{-2.9558pt}}
+ \pgfpathcurveto{\pgfqpoint{-.5316pt}{-1.9202pt}}{\pgfqpoint{-.88pt}{-.256pt}}{\pgfqpoint{-1.332pt}{.128pt}}
+ \pgfpathcurveto{\pgfqpoint{-1.716pt}{.4542pt}}{\pgfqpoint{-3.7928pt}{2.3136pt}}{\pgfqpoint{-4.5044pt}{3.3524pt}}
+ \pgfpathcurveto{\pgfqpoint{-4.7618pt}{3.728pt}}{\pgfqpoint{-4.709pt}{3.7864pt}}{\pgfqpoint{-4.4212pt}{3.5818pt}}
+ \pgfpathcurveto{\pgfqpoint{-3.4844pt}{2.9162pt}}{\pgfqpoint{-2.6164pt}{1.654pt}}{\pgfqpoint{-1.454pt}{1.3886pt}}
+ \pgfpathcurveto{\pgfqpoint{-1.0876pt}{1.305pt}}{\pgfqpoint{-1.0296pt}{1.3066pt}}{\pgfqpoint{-.886pt}{1.652pt}}
+ \pgfpathclose
+}%
+
+
+\expandafter\def\csname pgf@lib@foot@of@felis silvestris\endcsname{
+ % Coordinates derived from vector image created by Mark Wibrow, based
+ % on the forefoot of `felis silvestris' shown in
+ % Pearson, B. and Burton, J. A. (1980), `Wild Animals', Collins, 155.
+ %
+ \pgftransformcm{0}{.1}{.1}{0}{\pgfqpoint{.48pt}{.5pt}}
+ \pgfpathmoveto{\pgfqpoint{2.7312pt}{-1.992pt}}
+ \pgfpathcurveto{\pgfqpoint{1.8716pt}{-1.4226pt}}{\pgfqpoint{2.1404pt}{.0436pt}}{\pgfqpoint{.9202pt}{.0436pt}}
+ \pgfpathcurveto{\pgfqpoint{-.1146pt}{.0436pt}}{\pgfqpoint{-.7386pt}{.0178pt}}{\pgfqpoint{-1.319pt}{-1.0288pt}}
+ \pgfpathcurveto{\pgfqpoint{-1.7922pt}{-1.8822pt}}{\pgfqpoint{-2.072pt}{-1.5488pt}}{\pgfqpoint{-2.9638pt}{-1.968pt}}
+ \pgfpathcurveto{\pgfqpoint{-3.9244pt}{-2.4198pt}}{\pgfqpoint{-4.4394pt}{-3.348pt}}{\pgfqpoint{-4.1136pt}{-4.041pt}}
+ \pgfpathcurveto{\pgfqpoint{-3.3862pt}{-5.5882pt}}{\pgfqpoint{-1.6156pt}{-3.83pt}}{\pgfqpoint{-1.1684pt}{-4.312pt}}
+ \pgfpathcurveto{\pgfqpoint{-.5806pt}{-4.9454pt}}{\pgfqpoint{.5032pt}{-4.8822pt}}{\pgfqpoint{1.1748pt}{-4.2878pt}}
+ \pgfpathcurveto{\pgfqpoint{1.5822pt}{-3.9272pt}}{\pgfqpoint{2.6524pt}{-5.0652pt}}{\pgfqpoint{3.3506pt}{-4.1066pt}}
+ \pgfpathcurveto{\pgfqpoint{3.839pt}{-3.4356pt}}{\pgfqpoint{3.1192pt}{-2.249pt}}{\pgfqpoint{2.7312pt}{-1.992pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{5.0576pt}{.4996pt}}
+ \pgfpathcurveto{\pgfqpoint{4.6056pt}{.6536pt}}{\pgfqpoint{4.0596pt}{.2516pt}}{\pgfqpoint{3.8382pt}{-.398pt}}
+ \pgfpathcurveto{\pgfqpoint{3.6168pt}{-1.0478pt}}{\pgfqpoint{3.8038pt}{-1.6996pt}}{\pgfqpoint{4.2558pt}{-1.8536pt}}
+ \pgfpathcurveto{\pgfqpoint{4.7078pt}{-2.0076pt}}{\pgfqpoint{5.2538pt}{-1.6056pt}}{\pgfqpoint{5.4752pt}{-.9558pt}}
+ \pgfpathcurveto{\pgfqpoint{5.6966pt}{-.3062pt}}{\pgfqpoint{5.5096pt}{.3456pt}}{\pgfqpoint{5.0576pt}{.4996pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{3.1212pt}{3.5542pt}}
+ \pgfpathcurveto{\pgfqpoint{2.5874pt}{3.6726pt}}{\pgfqpoint{1.975pt}{3.1756pt}}{\pgfqpoint{1.7538pt}{2.4442pt}}
+ \pgfpathcurveto{\pgfqpoint{1.5324pt}{1.7128pt}}{\pgfqpoint{1.7858pt}{1.0238pt}}{\pgfqpoint{2.3196pt}{.9052pt}}
+ \pgfpathcurveto{\pgfqpoint{2.8534pt}{.7868pt}}{\pgfqpoint{3.4658pt}{1.2838pt}}{\pgfqpoint{3.6872pt}{2.0152pt}}
+ \pgfpathcurveto{\pgfqpoint{3.9084pt}{2.7466pt}}{\pgfqpoint{3.655pt}{3.4358pt}}{\pgfqpoint{3.1212pt}{3.5542pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{-.6182pt}{5.0456pt}}
+ \pgfpathcurveto{\pgfqpoint{-1.2132pt}{5.0456pt}}{\pgfqpoint{-1.6956pt}{4.3104pt}}{\pgfqpoint{-1.6956pt}{3.4038pt}}
+ \pgfpathcurveto{\pgfqpoint{-1.6956pt}{2.4972pt}}{\pgfqpoint{-1.2132pt}{1.7618pt}}{\pgfqpoint{-.6182pt}{1.7618pt}}
+ \pgfpathcurveto{\pgfqpoint{-.0232pt}{1.7618pt}}{\pgfqpoint{.4592pt}{2.4972pt}}{\pgfqpoint{.4592pt}{3.4038pt}}
+ \pgfpathcurveto{\pgfqpoint{.4592pt}{4.3104pt}}{\pgfqpoint{-.0232pt}{5.0456pt}}{\pgfqpoint{-.6182pt}{5.0456pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{-4.1176pt}{1.8248pt}}
+ \pgfpathcurveto{\pgfqpoint{-4.6334pt}{1.7534pt}}{\pgfqpoint{-4.9806pt}{1.0312pt}}{\pgfqpoint{-4.8928pt}{.212pt}}
+ \pgfpathcurveto{\pgfqpoint{-4.8052pt}{-.6072pt}}{\pgfqpoint{-4.3158pt}{-1.2136pt}}{\pgfqpoint{-3.8pt}{-1.1422pt}}
+ \pgfpathcurveto{\pgfqpoint{-3.2842pt}{-1.0708pt}}{\pgfqpoint{-2.9372pt}{-.3486pt}}{\pgfqpoint{-3.0248pt}{.4706pt}}
+ \pgfpathcurveto{\pgfqpoint{-3.1126pt}{1.2898pt}}{\pgfqpoint{-3.6018pt}{1.8962pt}}{\pgfqpoint{-4.1176pt}{1.8248pt}}
+ \pgfpathclose
+}%
+
+
+
+\def\pgf@lib@foot@of@human{%
+ % Coordinates derived from vector image created by Mark Wibrow.
+ \pgftransformcm{0}{.5}{.5}{0}{\pgfqpoint{.48pt}{.2pt}}
+ %
+ % Draw main part of foot.
+ %
+ \pgfpathmoveto{\pgfqpoint{.20175pt}{-.72633pt}}
+ \pgfpathcurveto{\pgfqpoint{.16314pt}{-.88194pt}}{\pgfqpoint{.07386pt}{-1.0167pt}}{\pgfqpoint{-.08385pt}{-1.0167pt}}
+ \pgfpathcurveto{\pgfqpoint{-.24153pt}{-1.0167pt}}{\pgfqpoint{-.36942pt}{-.84897pt}}{\pgfqpoint{-.36942pt}{-.72633pt}}
+ \pgfpathcurveto{\pgfqpoint{-.36942pt}{-.60372pt}}{\pgfqpoint{-.32505pt}{-.54825pt}}{\pgfqpoint{-.27633pt}{-.51192pt}}
+ \pgfpathcurveto{\pgfqpoint{-.23937pt}{-.48435pt}}{\pgfqpoint{-.17031pt}{-.46539pt}}{\pgfqpoint{-.10611pt}{-.40323pt}}
+ \pgfpathcurveto{\pgfqpoint{-.04191pt}{-.3411pt}}{\pgfqpoint{.00495pt}{-.27783pt}}{\pgfqpoint{.00495pt}{-.14787pt}}
+ \pgfpathcurveto{\pgfqpoint{.00495pt}{-.01794pt}}{\pgfqpoint{-.08526pt}{.12648pt}}{\pgfqpoint{-.22194pt}{.22467pt}}
+ \pgfpathcurveto{\pgfqpoint{-.35862pt}{.32286pt}}{\pgfqpoint{-.40863pt}{.50226pt}}{\pgfqpoint{-.32703pt}{.5979pt}}
+ \pgfpathcurveto{\pgfqpoint{-.24543pt}{.69354pt}}{\pgfqpoint{-.00564pt}{.66543pt}}{\pgfqpoint{.17172pt}{.53484pt}}
+ \pgfpathcurveto{\pgfqpoint{.34908pt}{.40422pt}}{\pgfqpoint{.39363pt}{.27192pt}}{\pgfqpoint{.37416pt}{.10971pt}}
+ \pgfpathcurveto{\pgfqpoint{.35472pt}{-.0525pt}}{\pgfqpoint{.26736pt}{-.46203pt}}{\pgfqpoint{.20175pt}{-.72633pt}}
+ \pgfpathclose
+ %
+ % Draw toe.s
+ %
+ \pgfpathmoveto{\pgfqpoint{-.27138pt}{1.01451pt}}
+ \pgfpathcurveto{\pgfqpoint{-.21198pt}{1.01451pt}}{\pgfqpoint{-.1638pt}{.94509pt}}{\pgfqpoint{-.1638pt}{.8595pt}}
+ \pgfpathcurveto{\pgfqpoint{-.1638pt}{.77388pt}}{\pgfqpoint{-.21198pt}{.70446pt}}{\pgfqpoint{-.27138pt}{.70446pt}}
+ \pgfpathcurveto{\pgfqpoint{-.33078pt}{.70446pt}}{\pgfqpoint{-.37896pt}{.77388pt}}{\pgfqpoint{-.37896pt}{.8595pt}}
+ \pgfpathcurveto{\pgfqpoint{-.37896pt}{.94509pt}}{\pgfqpoint{-.33078pt}{1.01451pt}}{\pgfqpoint{-.27138pt}{1.01451pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{-.05769pt}{.90573pt}}
+ \pgfpathcurveto{\pgfqpoint{-.01659pt}{.90573pt}}{\pgfqpoint{.01674pt}{.86445pt}}{\pgfqpoint{.01674pt}{.81354pt}}
+ \pgfpathcurveto{\pgfqpoint{.01674pt}{.7626pt}}{\pgfqpoint{-.01659pt}{.72132pt}}{\pgfqpoint{-.05769pt}{.72132pt}}
+ \pgfpathcurveto{\pgfqpoint{-.09879pt}{.72132pt}}{\pgfqpoint{-.13209pt}{.7626pt}}{\pgfqpoint{-.13209pt}{.81354pt}}
+ \pgfpathcurveto{\pgfqpoint{-.13209pt}{.86445pt}}{\pgfqpoint{-.09879pt}{.90573pt}}{\pgfqpoint{-.05769pt}{.90573pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{.10497pt}{.81636pt}}
+ \pgfpathcurveto{\pgfqpoint{.14214pt}{.81096pt}}{\pgfqpoint{.16722pt}{.77193pt}}{\pgfqpoint{.16104pt}{.72918pt}}
+ \pgfpathcurveto{\pgfqpoint{.15483pt}{.68646pt}}{\pgfqpoint{.11964pt}{.65619pt}}{\pgfqpoint{.08247pt}{.66159pt}}
+ \pgfpathcurveto{\pgfqpoint{.0453pt}{.66699pt}}{\pgfqpoint{.02019pt}{.70602pt}}{\pgfqpoint{.0264pt}{.74874pt}}
+ \pgfpathcurveto{\pgfqpoint{.03261pt}{.79149pt}}{\pgfqpoint{.0678pt}{.82176pt}}{\pgfqpoint{.10497pt}{.81636pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{.24054pt}{.70842pt}}
+ \pgfpathcurveto{\pgfqpoint{.27513pt}{.70842pt}}{\pgfqpoint{.30318pt}{.67686pt}}{\pgfqpoint{.30318pt}{.63795pt}}
+ \pgfpathcurveto{\pgfqpoint{.30318pt}{.59904pt}}{\pgfqpoint{.27513pt}{.56751pt}}{\pgfqpoint{.24054pt}{.56751pt}}
+ \pgfpathcurveto{\pgfqpoint{.20598pt}{.56751pt}}{\pgfqpoint{.17793pt}{.59904pt}}{\pgfqpoint{.17793pt}{.63795pt}}
+ \pgfpathcurveto{\pgfqpoint{.17793pt}{.67686pt}}{\pgfqpoint{.20598pt}{.70842pt}}{\pgfqpoint{.24054pt}{.70842pt}}
+ \pgfpathclose
+ %
+ \pgfpathmoveto{\pgfqpoint{.35973pt}{.57501pt}}
+ \pgfpathcurveto{\pgfqpoint{.3918pt}{.57501pt}}{\pgfqpoint{.41781pt}{.54852pt}}{\pgfqpoint{.41781pt}{.51585pt}}
+ \pgfpathcurveto{\pgfqpoint{.41781pt}{.48318pt}}{\pgfqpoint{.3918pt}{.45669pt}}{\pgfqpoint{.35973pt}{.45669pt}}
+ \pgfpathcurveto{\pgfqpoint{.32769pt}{.45669pt}}{\pgfqpoint{.30168pt}{.48318pt}}{\pgfqpoint{.30168pt}{.51585pt}}
+ \pgfpathcurveto{\pgfqpoint{.30168pt}{.54852pt}}{\pgfqpoint{.32769pt}{.57501pt}}{\pgfqpoint{.35973pt}{.57501pt}}
+ \pgfpathclose
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.fractals.code.tex b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.fractals.code.tex
new file mode 100644
index 0000000000..8355460b54
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.fractals.code.tex
@@ -0,0 +1,65 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+
+
+\pgfdeclaredecoration{Koch curve type 1}{init}
+{%
+ \state{init}[width=\pgfdecoratedinputsegmentremainingdistance]
+ {
+ \pgfpathlineto{\pgfpoint{.33333\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{.33333\pgfdecoratedinputsegmentremainingdistance}{.33333\pgfdecoratedinputsegmentremainingdistance}}
+ \pgfpathlineto{\pgfpoint{.66666\pgfdecoratedinputsegmentremainingdistance}{.33333\pgfdecoratedinputsegmentremainingdistance}}
+ \pgfpathlineto{\pgfpoint{.66666\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ }%
+}%
+
+\pgfdeclaredecoration{Koch curve type 2}{init}
+{%
+ \state{init}[width=\pgfdecoratedinputsegmentremainingdistance]
+ {
+ \pgfpathlineto{\pgfpoint{.25\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{.25\pgfdecoratedinputsegmentremainingdistance}{.25\pgfdecoratedinputsegmentremainingdistance}}
+ \pgfpathlineto{\pgfpoint{.5\pgfdecoratedinputsegmentremainingdistance}{.25\pgfdecoratedinputsegmentremainingdistance}}
+ \pgfpathlineto{\pgfpoint{.5\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{.5\pgfdecoratedinputsegmentremainingdistance}{-.25\pgfdecoratedinputsegmentremainingdistance}}
+ \pgfpathlineto{\pgfpoint{.75\pgfdecoratedinputsegmentremainingdistance}{-.25\pgfdecoratedinputsegmentremainingdistance}}
+ \pgfpathlineto{\pgfpoint{.75\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ }%
+}%
+
+\pgfdeclaredecoration{Koch snowflake}{init}
+{%
+ \state{init}[width=\pgfdecoratedinputsegmentremainingdistance]
+ {
+ \pgfpathlineto{\pgfpoint{.3333\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{.5\pgfdecoratedinputsegmentremainingdistance}{0.2886751347\pgfdecoratedinputsegmentremainingdistance}}
+ \pgfpathlineto{\pgfpoint{.6666\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ }%
+}%
+
+
+\pgfdeclaredecoration{Cantor set}{init}
+{%
+ \state{init}[width=\pgfdecoratedinputsegmentremainingdistance]
+ {
+ \pgfpathlineto{\pgfpoint{.3333\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathmoveto{\pgfpoint{.6666\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ }%
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.markings.code.tex b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.markings.code.tex
new file mode 100644
index 0000000000..23b7ff672e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.markings.code.tex
@@ -0,0 +1,179 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+
+% A marking decoration is used to add markings (which are just pgf
+% scopes, essentially) at certain positions of a path.
+
+\pgfkeys{
+ /pgf/decoration/reset marks/.code=\let\pgf@lib@dec@mark@marks\pgfutil@empty,
+ /pgf/decoration/mark/.code=\pgf@lib@dec@parsemark#1\pgf@lib@dec@stop,
+}%
+
+\let\pgf@lib@dec@mark@marks=\pgfutil@empty
+
+\def\pgf@lib@dec@parsemark{\pgfutil@ifnextchar b{\pgf@lib@dec@parsebetween}{\pgf@lib@dec@parseat}}%
+\def\pgf@lib@dec@parseat at position#1with#2\pgf@lib@dec@stop{%
+ \expandafter\def\expandafter\pgf@lib@dec@mark@marks\expandafter{\pgf@lib@dec@mark@marks%
+ \pgf@lib@dec@domark{#1}{#2}%
+ }%
+}%
+\def\pgf@lib@dec@parsebetween between positions#1and#2step#3with#4\pgf@lib@dec@stop{%
+ \expandafter\def\expandafter\pgf@lib@dec@mark@marks\expandafter{\pgf@lib@dec@mark@marks%
+ \pgf@lib@dec@dobetweenmark{#1}{#2}{#3}{#4}%
+ }%
+}%
+
+\def\pgf@lib@dec@arrowhead#1#2{%
+ \pgftransformxscale{#1}
+ \pgfarrowdraw{#2}%
+}%
+
+\def\pgf@lib@dec@doarrowhead#1{%
+ \pgf@lib@dec@arrowhead{1}{#1}%
+}%
+\def\pgf@lib@dec@doarrowheadrev#1{%
+ \pgf@lib@dec@arrowhead{-1}{#1}%
+}%
+
+
+\pgfdeclaredecoration{markings}{init}
+{%
+ \state{init}
+ [
+ width=0pt,
+ persistent precomputation={%
+ \pgfkeys{/pgf/decoration/mark info/sequence number/.initial=0}%
+ \pgfkeys{/pgf/decoration/mark info/distance from start/.initial=}%
+ },
+ next state=pre
+ ]
+ {}%
+
+ \state{pre}
+ [
+ width=0pt,
+ persistent precomputation={%
+ \def\pgf@lib@dec@computed@width{0pt}%
+ \pgf@lib@dec@mark@marks\pgf@lib@dec@mark@last%
+ \let\arrow=\pgf@lib@dec@doarrowhead%
+ \let\arrowreversed=\pgf@lib@dec@doarrowheadrev%
+ },
+ next state=skipper
+ ]
+ {}%
+
+ \state{skipper}[width=\pgf@lib@dec@computed@width-\pgfdecoratedcompleteddistance-1sp,
+ next state=\pgf@lib@dec@next@state]{}%
+
+ \state{main}
+ [
+ width=1sp,
+ next state=pre,
+ persistent precomputation={%
+ \pgfutil@tempcnta=\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}\relax%
+ \advance\pgfutil@tempcnta by1\relax%
+ \pgfkeys{/pgf/decoration/mark info/sequence number/.expanded=\the\pgfutil@tempcnta}%
+ \pgfkeys{/pgf/decoration/mark info/distance from start/.expanded=\pgf@lib@dec@computed@width}%
+ }%
+ ]
+ {%
+ \pgfinterruptpath%
+ \pgfscope%
+ \let\pgf@lib@dec@mark@marks=\pgfutil@empty%
+ \pgfslopedattimefalse
+ \pgf@lib@dec@computed@action%
+ \endpgfscope%
+ \endpgfinterruptpath%
+ \ifx\pgf@lib@mark@node\pgfutil@empty%
+ \else%
+ \pgf@lib@mark@connect@node%
+ \fi%
+ }%
+
+ \state{final}[width=\pgfdecoratedremainingdistance]{
+ \ifx\pgf@lib@mark@node\pgfutil@empty%
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}
+ \else%
+ \pgfpathlineto{\pgfpointdecoratedpathlast}
+ \fi%
+ }%
+}%
+
+\def\pgf@lib@dec@domark#1#2#3\pgf@lib@dec@mark@last{%
+ \def\pgf@lib@dec@mark@marks{#3}%
+ \pgf@lib@dec@parsenum{#1}%
+ \def\pgf@lib@dec@computed@action{#2}%
+ \def\pgf@lib@dec@next@state{main}%
+}%
+
+
+\def\pgf@lib@dec@dobetweenmark#1#2#3#4#5\pgf@lib@dec@mark@last{%
+ \pgf@lib@dec@parsenum{#1}%
+ \let\pgf@lib@dec@mark@start=\pgf@lib@dec@computed@width%
+ \pgf@lib@dec@parsenum{#2}%
+ \let\pgf@lib@dec@mark@end=\pgf@lib@dec@computed@width%
+ \ifdim\pgf@lib@dec@mark@end<\pgf@lib@dec@mark@start\relax%
+ % Skip!
+ #5\pgf@lib@dec@mark@last%
+ \else%
+ %
+ \pgf@lib@dec@parsenum{#3}%
+ \pgfmathparse{\pgf@lib@dec@mark@start+\pgf@lib@dec@computed@width}%
+ % Update entry in mark list
+ \edef\pgf@temp{\noexpand\pgf@lib@dec@dobetweenmark{\pgfmathresult pt}{\pgf@lib@dec@mark@end}{\pgf@lib@dec@computed@width}}%
+ \expandafter\def\expandafter\pgf@lib@dec@mark@marks\expandafter{\pgf@temp{#4}#5}%
+ \let\pgf@lib@dec@computed@width\pgf@lib@dec@mark@start%
+ \def\pgf@lib@dec@computed@action{#4}%
+ \def\pgf@lib@dec@next@state{main}%
+ \fi%
+}%
+
+
+\def\pgf@lib@dec@parsenum#1{%
+ \pgfmathparse{#1}%
+ \ifpgfmathunitsdeclared%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathparse{\pgfdecoratedpathlength\pgfmathresult pt}%
+ \else%
+ \pgfmathparse{\pgfmathresult pt}%
+ \fi%
+ \else%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathparse{\pgfdecoratedpathlength\pgfmathresult*\pgfdecoratedpathlength}%
+ \else%
+ \pgfmathparse{\pgfmathresult*\pgfdecoratedpathlength}%
+ \fi%
+ \fi%
+ \edef\pgf@lib@dec@computed@width{\pgfmathresult pt}%
+}%
+
+\def\pgf@lib@dec@mark@last{%
+ \def\pgf@lib@dec@next@state{final}%
+}%
+
+
+%
+% If you set the mark connection node inside a mark picture, the
+% output path will contain a line to this node
+%
+
+\pgfkeys{/pgf/decoration/mark connection node/.store in=\pgf@lib@mark@node,
+ /pgf/decoration/mark connection node=}%
+\def\pgf@lib@mark@connect@node{%
+ % Line to "left" end of the node
+ \pgfpathlineto{\pgfpointshapeborder{\pgf@lib@mark@node}{\pgfqpoint{-1pt}{0pt}}}
+ % Move to "right" end of the node
+ \pgfpathmoveto{\pgfpointshapeborder{\pgf@lib@mark@node}{\pgfqpoint{1pt}{0pt}}}
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathmorphing.code.tex b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathmorphing.code.tex
new file mode 100644
index 0000000000..bdc2752cb8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathmorphing.code.tex
@@ -0,0 +1,294 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+
+%
+% These decorations "morph" paths. That means that the
+% original characteristic of the path is kept and the number of
+% subpaths remains the same -- only, the lines are slightly offset or
+% changed by the decoration. For instance a line might be turned into
+% a squiggly line or a snaking line or a bumping line.
+%
+
+
+%
+%
+% Kind 1: Path morphing straight line decorations
+%
+%
+
+
+% zigzag decoration.
+%
+\pgfdeclaredecoration{zigzag}{up from center}{%
+ \state{up from center}[width=+.5\pgfdecorationsegmentlength, next state=big down]
+ {
+ \pgfpathlineto{\pgfqpoint{.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ }%
+ \state{big down}[switch if less than=+.5\pgfdecorationsegmentlength to center finish,
+ width=+.5\pgfdecorationsegmentlength,
+ next state=big up]
+ {
+ \pgfpathlineto{\pgfqpoint{.25\pgfdecorationsegmentlength}{-\pgfdecorationsegmentamplitude}}
+ }%
+ \state{big up}[switch if less than=+.5\pgfdecorationsegmentlength to center finish,
+ width=+.5\pgfdecorationsegmentlength,
+ next state=big down]
+ {
+ \pgfpathlineto{\pgfqpoint{.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ }%
+ \state{center finish}[width=0pt, next state=final]{
+ \pgfpathlineto{\pgfpointorigin}
+ }%
+ \state{final}
+ {
+ \pgfpathlineto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+
+% saw decoration
+%
+% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength
+
+\pgfdeclaredecoration{saw}{initial}
+{%
+ \state{initial}[auto end on length=+\pgfdecorationsegmentlength,
+ auto corner on length=+\pgfdecorationsegmentlength,
+ width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathlineto{\pgfqpoint{\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ \pgfpathlineto{\pgfqpoint{\pgfdecorationsegmentlength}{0pt}}
+ }%
+ \state{final}
+ {}%
+}%
+
+
+
+
+% random steps decoration
+%
+% A decoration that consists of random steps heading towards the target
+%
+% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength
+
+\pgfdeclaredecoration{random steps}{start}
+{%
+ \state{start}[width=+0pt,next state=step,persistent precomputation=\pgfdecoratepathhascornerstrue]{}%
+ \state{step}[auto end on length=1.5\pgfdecorationsegmentlength,
+ auto corner on length=1.5\pgfdecorationsegmentlength,
+ width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathlineto{
+ \pgfpointadd
+ {\pgfpoint{\pgfdecorationsegmentlength}{0pt}}
+ {\pgfpoint{rand*\pgfdecorationsegmentamplitude}{rand*\pgfdecorationsegmentamplitude}}
+ }
+ }%
+ \state{final}
+ {}%
+}%
+
+
+
+% Meta-decoration line zigzag
+
+\pgfdeclaremetadecoration{straight zigzag}{line to}{%
+ \state{line to}[width=\pgfmetadecorationsegmentlength, next state=zigzag]
+ {
+ \decoration{curveto}
+ }%
+ \state{zigzag}[width=\pgfmetadecorationsegmentlength, next state=line to]
+ {
+ \decoration{zigzag}
+ }%
+ \state{final}
+ {
+ \decoration{curveto}
+ }%
+}%
+
+
+
+
+
+%
+%
+% Kind 2: Path morphing curved decorations
+%
+%
+
+
+
+% bent decoration
+%
+% A decoration that looks like someone bent the line a bit.
+%
+% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentaspect
+
+\pgfdeclaredecoration{bent}{bent}
+{%
+ \state{bent}[width=+\pgfdecoratedinputsegmentremainingdistance]
+ {
+ \pgfpathcurveto
+ {\pgfqpoint{\pgfdecorationsegmentaspect\pgfdecoratedinputsegmentremainingdistance}{\pgfdecorationsegmentamplitude}}
+ {\pgfpointadd{\pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ {\pgfqpoint{-\pgfdecorationsegmentaspect\pgfdecoratedinputsegmentremainingdistance}{\pgfdecorationsegmentamplitude}}}
+ {\pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ }%
+ \state{final}
+ {}%
+}%
+
+
+
+% decoration snake
+%
+% This decoration produces a hopefully optically pleasing squiggly snake.
+%
+% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength
+
+\pgfdeclaredecoration{snake}{initial}
+{%
+ \state{initial}[switch if less than=+.625\pgfdecorationsegmentlength to final,
+ width=+.3125\pgfdecorationsegmentlength,
+ next state=down]
+ {
+ \pgfpathcurveto
+ {\pgfqpoint{.125\pgfdecorationsegmentlength}{0pt}}
+ {\pgfqpoint{.1875\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.3125\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ }%
+ \state{down}[switch if less than=+.8125\pgfdecorationsegmentlength to end down,
+ width=+.5\pgfdecorationsegmentlength,
+ next state=up]
+ {
+ \pgfpathcosine{\pgfqpoint{.25\pgfdecorationsegmentlength}{-1\pgfdecorationsegmentamplitude}}
+ \pgfpathsine{\pgfqpoint{.25\pgfdecorationsegmentlength}{-1\pgfdecorationsegmentamplitude}}
+ }%
+ \state{up}[switch if less than=+.8125\pgfdecorationsegmentlength to end up,
+ width=+.5\pgfdecorationsegmentlength,
+ next state=down]
+ {
+ \pgfpathcosine{\pgfqpoint{.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ \pgfpathsine{\pgfqpoint{.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ }%
+ \state{end down}[width=+.3125\pgfdecorationsegmentlength,
+ next state=final]
+ {
+ \pgfpathcurveto
+ {\pgfqpoint{.125\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.1875\pgfdecorationsegmentlength}{0pt}}
+ {\pgfqpoint{.3125\pgfdecorationsegmentlength}{0pt}}
+ }%
+ \state{end up}[width=+.3125\pgfdecorationsegmentlength,
+ next state=final]
+ {
+ \pgfpathcurveto
+ {\pgfqpoint{.125\pgfdecorationsegmentlength}{-\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.1875\pgfdecorationsegmentlength}{0pt}}
+ {\pgfqpoint{.3125\pgfdecorationsegmentlength}{0pt}}
+ }%
+ \state{final}
+ {
+ \pgfpathlineto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+% coil decoration
+%
+% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,
+
+\pgfdeclaredecoration{coil}{coil}
+{%
+ \state{coil}[switch if less than=%
+ 1.5\pgfdecorationsegmentlength+%
+ \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
+ \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
+ width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathcurveto
+ {\pgfpoint@oncoil{0 }{ 0.555}{1}}
+ {\pgfpoint@oncoil{0.445}{ 1 }{2}}
+ {\pgfpoint@oncoil{1 }{ 1 }{3}}
+ \pgfpathcurveto
+ {\pgfpoint@oncoil{1.555}{ 1 }{4}}
+ {\pgfpoint@oncoil{2 }{ 0.555}{5}}
+ {\pgfpoint@oncoil{2 }{ 0 }{6}}
+ \pgfpathcurveto
+ {\pgfpoint@oncoil{2 }{-0.555}{7}}
+ {\pgfpoint@oncoil{1.555}{-1 }{8}}
+ {\pgfpoint@oncoil{1 }{-1 }{9}}
+ \pgfpathcurveto
+ {\pgfpoint@oncoil{0.445}{-1 }{10}}
+ {\pgfpoint@oncoil{0 }{-0.555}{11}}
+ {\pgfpoint@oncoil{0 }{ 0 }{12}}
+ }%
+ \state{last}[width=.5\pgfdecorationsegmentlength+%
+ \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
+ \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude,next state=final]
+ {
+ \pgfpathcurveto
+ {\pgfpoint@oncoil{0 }{ 0.555}{1}}
+ {\pgfpoint@oncoil{0.445}{ 1 }{2}}
+ {\pgfpoint@oncoil{1 }{ 1 }{3}}
+ \pgfpathcurveto
+ {\pgfpoint@oncoil{1.555}{ 1 }{4}}
+ {\pgfpoint@oncoil{2 }{ 0.555}{5}}
+ {\pgfpoint@oncoil{2 }{ 0 }{6}}
+ }%
+ \state{final}
+ {
+ \pgfpathlineto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+\def\pgfpoint@oncoil#1#2#3{%
+ \pgf@x=#1\pgfdecorationsegmentamplitude%
+ \pgf@x=\pgfdecorationsegmentaspect\pgf@x%
+ \pgf@y=#2\pgfdecorationsegmentamplitude%
+ \pgf@xa=0.083333333333\pgfdecorationsegmentlength%
+ \advance\pgf@x by#3\pgf@xa%
+}%
+
+
+% bumps decoration
+%
+% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength
+
+\pgfdeclaredecoration{bumps}{initial}
+{%
+ \state{initial}[auto end on length=+.51\pgfdecorationsegmentlength,
+ auto corner on length=+.51\pgfdecorationsegmentlength,
+ width=+.5\pgfdecorationsegmentlength]
+ {
+ \pgfpathcurveto
+ {\pgfqpoint{0pt}{.555\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{0.11125\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{.38875\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.5\pgfdecorationsegmentlength}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.5\pgfdecorationsegmentlength}{0\pgfdecorationsegmentamplitude}}
+ }%
+ \state{final}
+ {
+ \pgfpathlineto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathreplacing.code.tex b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathreplacing.code.tex
new file mode 100644
index 0000000000..f028ec6c37
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.pathreplacing.code.tex
@@ -0,0 +1,240 @@
+% Copyright 2018 by Mark Wibrow and Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+
+%
+% Path replacing decorations
+%
+% These decorations change the path by replacing it by another path.
+% For instance, a line in the path might be replaced by small
+% ticks or unconnected curves or crosses. Applying a chopping
+% decoration to a path means that the path can no longer be used for
+% filling in the original manner.
+%
+
+
+
+%
+%
+% Kind 1: Path chopping with open subpaths
+%
+%
+
+
+% ticks decoration
+%
+% Parameters: \pgfdecorationsegmentlength, \pgfdecorationsegmentamplitude
+
+\pgfdeclaredecoration{ticks}{ticks}
+{%
+ \state{ticks}[width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfdecorationsegmentamplitude}}
+ }%
+ \state{final}
+ {
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfdecorationsegmentamplitude}}
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+% expanding waves decoration
+%
+% Parameters: \pgfdecorationsegmentangle, \pgfdecorationsegmentlength
+
+\pgfdeclaredecoration{expanding waves}{initial}
+{%
+ \state{initial}[width=+\pgfdecorationsegmentlength,next state=wave]
+ {}%
+
+ \state{wave}[switch if less than=+\pgfdecorationsegmentlength to last,
+ width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathmoveto{
+ \pgfpointadd
+ {\pgfqpoint{-\pgfdecoratedcompleteddistance}{0pt}}%
+ {\pgfpointpolar{\pgfdecorationsegmentangle}{+\pgfdecoratedcompleteddistance}}}%
+ \pgfpatharc{\pgfdecorationsegmentangle}{-\pgfdecorationsegmentangle}{+\pgfdecoratedcompleteddistance}%
+ }%
+ \state{last}[width=+0pt,next state=final]
+ {
+ \pgfpathmoveto{
+ \pgfpointadd
+ {\pgfqpoint{-\pgfdecoratedcompleteddistance}{0pt}}%
+ {\pgfpointpolar{\pgfdecorationsegmentangle}{+\pgfdecoratedcompleteddistance}}}%
+ \pgfpatharc{\pgfdecorationsegmentangle}{-\pgfdecorationsegmentangle}{+\pgfdecoratedcompleteddistance}%
+ }%
+ \state{final}
+ {
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+% waves decoration
+
+\pgfdeclaredecoration{waves}{wave}
+{%
+ \state{wave}[width=\pgfdecorationsegmentlength]
+ {
+ \pgftransformxshift{+\pgfdecorationsegmentlength}
+ \pgfpathmoveto{
+ \pgfpointadd
+ {\pgfqpoint{-\pgfkeysvalueof{/pgf/decoration/start radius}}{0pt}}%
+ {\pgfpointpolar{\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/start radius}}}}%
+ \pgfpatharc{\pgfdecorationsegmentangle}{-\pgfdecorationsegmentangle}{\pgfkeysvalueof{/pgf/decoration/start radius}}%
+ }%
+ \state{final}
+ {
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+% border decoration
+%
+% Parameters: \pgfdecorationsegmentlength, \pgfdecorationsegmentamplitude, \pgfdecorationsegmentangle
+
+\pgfdeclaredecoration{border}{tick}
+{%
+ \state{tick}[switch if less than=+\pgfdecorationsegmentlength to last,
+ width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgfpathlineto{\pgfpointpolar{\pgfdecorationsegmentangle}{+\pgfdecorationsegmentamplitude}}
+ }%
+ \state{last}[width=+\pgfdecorationsegmentamplitude,next state=final]
+ {
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgfpathlineto{\pgfpointpolar{\pgfdecorationsegmentangle}{+\pgfdecorationsegmentamplitude}}
+ }%
+ \state{final}
+ {
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+
+
+
+% brace decorations
+%
+% Parameters: \pgfdecorationsegmentamplitude
+
+\pgfdeclaredecoration{brace}{brace}
+{%
+ \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]
+ {
+ \pgf@yc=\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance
+ \ifdim2\pgfdecorationsegmentamplitude>\pgf@yc
+ \pgf@yc=0.5\pgf@yc
+ \else
+ \pgf@yc=\pgfdecorationsegmentamplitude
+ \fi
+ \pgf@xc=\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance
+ \advance\pgf@xc-\pgfdecoratedremainingdistance
+ \ifdim-2\pgfdecorationsegmentamplitude<\pgf@xc
+ \pgf@xc=-0.5\pgf@xc
+ \else
+ \pgf@xc=\pgfdecorationsegmentamplitude
+ \fi
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgfpathcurveto
+ {\pgfqpoint{.15\pgf@yc}{.3\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.5\pgf@yc}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{\pgf@yc}{.5\pgfdecorationsegmentamplitude}}
+ {
+ \pgftransformxshift{+\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance}
+ \pgfpathlineto{\pgfqpoint{-\pgf@yc}{.5\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.5\pgf@yc}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{-.15\pgf@yc}{.7\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{0\pgf@yc}{1\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{.15\pgf@xc}{.7\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.5\pgf@xc}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{\pgf@xc}{.5\pgfdecorationsegmentamplitude}}
+ }
+ {
+ \pgftransformxshift{+\pgfdecoratedremainingdistance}
+ \pgfpathlineto{\pgfqpoint{-\pgf@xc}{.5\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.5\pgf@xc}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{-.15\pgf@xc}{.3\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{0pt}{0pt}}
+ }
+ }%
+ \state{final}
+ {}%
+}%
+
+
+
+
+% show path construction decoration
+%
+\pgfdeclaredecoration{show path construction}{check for moveto}{%
+ \state{check for moveto}[width=0pt, next state=segment,
+ persistent precomputation={%
+ \begingroup%
+ \pgf@lib@decoraions@installinputsegmentpoints%
+ \ifx\pgfdecorationpreviousinputsegment\pgfdecorationinputsegmentmoveto%
+ \pgfdecoratedinputsegmentmovetocode%
+ \fi%
+ \endgroup%
+ }]{}%
+ \state{segment}[width=\pgfdecoratedinputsegmentremainingdistance, next state=check for moveto,
+ persistent precomputation={%
+ \begingroup%
+ \pgf@lib@decoraions@installinputsegmentpoints%
+ \csname pgfdecoratedinputsegment\pgfdecorationcurrentinputsegment code\endcsname%
+ \endgroup%
+ }]{}%
+ \state{final}{%
+ \egroup%
+ \begingroup%
+ \pgf@lib@decoraions@installinputsegmentpoints%
+ \csname pgfdecoratedinputsegment\pgfdecorationcurrentinputsegment code\endcsname%
+ \endgroup%
+ \bgroup%
+ }%
+}%
+
+\pgfkeys{
+ /pgf/decoration/.cd,
+ moveto code/.code=\def\pgfdecoratedinputsegmentmovetocode{#1},
+ lineto code/.code=\def\pgfdecoratedinputsegmentlinetocode{#1},
+ curveto code/.code=\def\pgfdecoratedinputsegmentcurvetocode{#1},
+ closepath code/.code=\def\pgfdecoratedinputsegmentclosepathcode{#1}
+}%
+
+\let\pgfdecoratedinputsegmentmovetocode\pgfutil@empty%
+\let\pgfdecoratedinputsegmentlinetocode\pgfutil@empty%
+\let\pgfdecoratedinputsegmentcurvetocode\pgfutil@empty%
+\let\pgfdecoratedinputsegmentclosepathcode\pgfutil@empty%
+
+\def\pgf@lib@decoraions@installinputsegmentpoints{%
+ \let\pgfpointdecoratedinputsegmentfirst\pgf@decorate@inputsegment@first%
+ \let\pgfpointdecoratedinputsegmentlast\pgf@decorate@inputsegment@last%
+ \let\pgfpointdecoratedinputsegmentsupporta\pgf@decorate@inputsegment@supporta%
+ \let\pgfpointdecoratedinputsegmentsupportb\pgf@decorate@inputsegment@supportb%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.shapes.code.tex b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.shapes.code.tex
new file mode 100644
index 0000000000..77c366ca0c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.shapes.code.tex
@@ -0,0 +1,468 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+
+% Options for shape decorations
+
+\pgfkeys{
+ /pgf/decoration/.cd,
+ shape/.initial=circle,
+ anchor/.initial=center,
+ shape start width/.initial=2.5pt,
+ shape start height/.initial=2.5pt,
+ shape end width/.initial=2.5pt,
+ shape end height/.initial=2.5pt,
+ shape sep/.store in=\pgf@lib@shapedecoration@sep,
+ shape sloped/.is if=pgfshapedecorationsloped,
+ shape scaled/.is if=pgfshapedecorationscaled,
+ shape evenly spread/.store in=\pgf@lib@shapedecoration@spread,
+ shape start size/.style={%
+ shape start width={#1},
+ shape start height={#1}%
+ },%
+ shape end size/.style={%
+ shape end width={#1},
+ shape end height={#1}%
+ },%
+ shape size/.style={%
+ shape start size={#1},
+ shape end size={#1}%
+ },%
+ shape width/.style={%
+ shape start width={#1},
+ shape end width={#1}
+ },
+ shape height/.style={%
+ shape start height={#1},
+ shape end height={#1}
+ }
+}%
+
+\def\pgf@lib@shapedecoration@sep{.25cm, between centers}%
+\newif\ifpgfshapedecorationsloped
+\pgfshapedecorationslopedtrue
+\newif\ifpgfshapedecorationscaled
+\let\pgf@lib@shapedecoration@spread\pgfutil@empty%
+
+
+
+% triangle decoration
+
+\pgfdeclaredecoration{triangles}{init}
+{%
+ \state{init}[width=+0pt,next state=triangle,persistent precomputation={
+ \pgfmathparse{\pgfkeysvalueof{/pgf/decoration/shape start width}}
+ \edef\pgf@lib@dec@ssw{\pgfmathresult pt}
+ \pgfmathparse{\pgfkeysvalueof{/pgf/decoration/shape start height}/2}
+ \edef\pgf@lib@dec@ssh{\pgfmathresult pt}
+ }]{}%
+ \state{triangle}[switch if less than=+\pgfdecorationsegmentlength to last,
+ width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgf@lib@dec@ssh}}
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@dec@ssw}{0pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@lib@dec@ssh}}
+ \pgfpathclose
+ }%
+ \state{last}[switch if less than=\pgf@lib@dec@ssw to skip,
+ width=\pgfdecoratedremainingdistance,next state=final]
+ {
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgf@lib@dec@ssh}}
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@dec@ssw}{0pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@lib@dec@ssh}}
+ \pgfpathclose
+ }%
+ \state{skip}[width=\pgfdecoratedremainingdistance]
+ {}%
+ \state{final}
+ {
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+
+% crosses decoration
+
+\pgfdeclaredecoration{crosses}{init}
+{%
+ \state{init}[width=+0pt,next state=crosses,persistent precomputation={
+ \pgfmathparse{\pgfkeysvalueof{/pgf/decoration/shape start width}/2}
+ \edef\pgf@lib@dec@ssw{\pgfmathresult pt}
+ \pgfmathparse{\pgfkeysvalueof{/pgf/decoration/shape start height}/2}
+ \edef\pgf@lib@dec@ssh{\pgfmathresult pt}
+ }]{}%
+ \state{crosses}[switch if less than=+\pgfdecorationsegmentlength to last,
+ width=+\pgfdecorationsegmentlength]
+ {
+ \pgfpathmoveto{\pgfqpoint{-\pgf@lib@dec@ssw}{\pgf@lib@dec@ssh}}
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@dec@ssw}{-\pgf@lib@dec@ssh}}
+ \pgfpathmoveto{\pgfqpoint{-\pgf@lib@dec@ssw}{-\pgf@lib@dec@ssh}}
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@dec@ssw}{\pgf@lib@dec@ssh}}
+ }%
+ \state{last}[width=+\pgfdecoratedremainingdistance]
+ {
+ \pgfpathmoveto{\pgfqpoint{-\pgf@lib@dec@ssw}{\pgf@lib@dec@ssh}}
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@dec@ssw}{-\pgf@lib@dec@ssh}}
+ \pgfpathmoveto{\pgfqpoint{-\pgf@lib@dec@ssw}{-\pgf@lib@dec@ssh}}
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@dec@ssw}{\pgf@lib@dec@ssh}}
+ }%
+ \state{final}{
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}
+ }%
+}%
+
+
+
+
+
+
+% The shape background decoration
+%
+% The shape background decoration adds repeated instances of
+% the background path of a specified shape along the path. The shape
+% must have been declared by \pgfdeclareshape. If a shape has
+% specialized keys (e.g. the number of points on a star, or the apex
+% angle the isosceles triangle), these can be specified in the usual manner.
+%
+% The separation between shapes in the path can be specified and can
+% be between the center of the shape or the border of the shape.
+%
+% The height and width of the shape can be independently or
+% simultaneously scaled (linearly) along the path. It is also
+% possible to prevent the shapes being sloped parallel to the
+% path.
+
+% internal if
+\newif\ifpgf@lib@shapedecoration@betweenborders
+
+\edef\pgf@lib@shapedecoration@initialise{0pt}%
+
+\pgfdeclaredecoration{shape backgrounds}{initialise}
+{%
+ \state{initialise}
+ [
+ width=+\pgf@lib@shapedecoration@initialise,
+ next state=shape,
+ persistent precomputation=
+ {
+ %
+ % \egroup ends the group started by the automaton before executing
+ % a decoration state. This prevents the need for (most) \global variables.
+ %
+ %
+ % Check the shape exists.
+ %
+ \pgfutil@ifundefined{pgf@sh@bg@\pgfkeysvalueof{/pgf/decoration/shape}}{%
+ \pgferror{I do not know the shape `\pgfkeysvalueof{/pgf/decoration/shape}',
+ so I cannot use it in a decoration. Check if its library been loaded or if you
+ simply mistyped the name}}{}%
+ %
+ % Calculate a `default' path size.
+ %
+ \pgfinterruptpath%
+ \pgfinterruptboundingbox%
+ \pgftransformreset%
+ \pgf@relevantforpicturesizetrue%
+ %
+ % This size of this shape is unimportant, but it should
+ % be just large/small enough to avoid huge errors when
+ % calculating the scaling factors later on.
+ %
+ \pgfkeys{/pgf/inner sep=50pt, /pgf/minimum size=1pt}% Arbitrary lengths.
+ \setbox\pgfnodeparttextbox\hbox{}% Assume shape does nothing special if box is empty.
+ \let\pgf@sh@savedmacros\pgfutil@empty%
+ \let\pgf@sh@savedpoints\pgfutil@empty%
+ \csname pgf@sh@s@\pgfkeysvalueof{/pgf/decoration/shape}\endcsname%
+ \pgf@sh@savedpoints%
+ \pgf@sh@savedmacros%
+ %
+ % Save the macros and points.
+ %
+ \expandafter\gdef\expandafter\pgf@lib@shapedecoration@points\expandafter{\pgf@sh@savedpoints}%
+ \expandafter\gdef\expandafter\pgf@lib@shapedecoration@macros\expandafter{\pgf@sh@savedmacros}%
+ \csname pgf@sh@bg@\pgfkeysvalueof{/pgf/decoration/shape}\endcsname%
+ %
+ % Save the dimensions of the shape path.
+ %
+ \pgf@x\pgf@picmaxx%
+ \pgf@y\pgf@picmaxy%
+ \advance\pgf@x-\pgf@picminx%
+ \advance\pgf@y-\pgf@picminy%
+ \xdef\pgf@lib@shapedecoration@shapepathsize{%
+ \noexpand\pgf@x\the\pgf@x%
+ \noexpand\pgf@y\the\pgf@y%
+ }%
+ \endpgfinterruptboundingbox%
+ \endpgfinterruptpath%
+ %
+ \edef\pgf@lib@shapedecoration@beforeshape{0pt}%
+ \edef\pgf@lib@shapedecoration@aftershape{0pt}%
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/decoration/shape start width}}%
+ \edef\pgf@lib@shapedecoration@startwidth{\the\pgf@x}%
+ \edef\pgf@lib@shapedecoration@width{\the\pgf@x}%
+ \pgf@x-\pgf@x%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/decoration/shape end width}}%
+ \edef\pgf@lib@shapedecoration@widthchange{\the\pgf@x}%
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/decoration/shape start height}}%
+ \edef\pgf@lib@shapedecoration@initialheight{\the\pgf@y}%
+ \edef\pgf@lib@shapedecoration@height{\the\pgf@y}%
+ \pgf@y-\pgf@y%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/decoration/shape end height}}%
+ \edef\pgf@lib@shapedecoration@heightchange{\the\pgf@y}%
+ %
+ % Calculate the sep.
+ %
+ \ifx\pgf@lib@shapedecoration@spread\pgfutil@empty%
+ %
+ % Not spreading, so easy:
+ %
+ \def\pgf@lib@shapedecoration@borderstext{between borders}%
+ \afterassignment\pgf@lib@shapedecoration@setkeyword%
+ \expandafter\pgf@x\pgf@lib@shapedecoration@sep,\pgf@stop%
+ \edef\pgf@lib@shapedecoration@sep{\the\pgf@x}%
+ \else%
+ %
+ % Spreading (a bit of a nuiscence actually).
+ %
+ \def\pgf@lib@shapedecoration@borderstext{by borders}%
+ \afterassignment\pgf@lib@shapedecoration@setkeyword%
+ \expandafter\c@pgf@counta\pgf@lib@shapedecoration@spread,\pgf@stop%
+ \ifpgf@lib@shapedecoration@betweenborders%
+ %
+ % Ok. The required sep between borders is:
+ %
+ % (r -(n-1)((a+b)/2))/(n-1)
+ %
+ % r = decoration length (here, the remaining distance)
+ % a = initial width
+ % b = end width
+ % n = the number of shapes
+ %
+ \ifnum\c@pgf@counta>1\relax%
+ \advance\c@pgf@counta-1\relax%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/decoration/shape start width}}%
+ \ifpgfshapedecorationscaled%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/decoration/shape end width}}%
+ \else%
+ \advance\pgf@x\pgf@x%
+ \fi%
+ \pgf@x.5\pgf@x% (a+b)/2
+ \multiply\pgf@x-\c@pgf@counta% -(n-1)((a+b)/2)
+ \advance\pgf@x\pgfdecoratedremainingdistance%
+ \divide\pgf@x\c@pgf@counta%
+ \pgf@x.9999\pgf@x% Hackery to control some native TeX inaccuracies.
+ %
+ % Unfortunately if the shape is scaled, and evenly spread by borders,
+ % it is necessary to do something a bit different to control for
+ % (most) inaccuracies.
+ %
+ \ifpgfshapedecorationscaled%
+ \pgf@xa\pgf@lib@shapedecoration@widthchange\relax%
+ \divide\pgf@xa\c@pgf@counta%
+ \edef\pgf@lib@shapedecoration@specialwidth{\the\pgf@xa}%
+ \fi%
+ \else%
+ \pgf@lib@shapedecoration@betweenbordersfalse%
+ \pgf@x\pgfdecoratedremainingdistance%
+ \ifnum\c@pgf@counta=1\relax%
+ \pgf@y.5\pgf@x%
+ \edef\pgf@lib@shapedecoration@initialise{\the\pgf@y}%
+ \else%
+ \advance\pgf@x5pt\relax% An arbitrary value >0pt.
+ \edef\pgf@lib@shapedecoration@initialise{\the\pgf@x}%
+ \fi%
+ \fi%
+ \else%
+ %
+ % Between centers.
+ %
+ \pgf@x\pgfdecoratedremainingdistance%
+ \ifnum\c@pgf@counta>1\relax%
+ \advance\c@pgf@counta-1\relax%
+ \divide\pgf@x\c@pgf@counta\relax%
+ \else%
+ \ifnum\c@pgf@counta=1\relax%
+ \pgf@y.5\pgf@x%
+ \edef\pgf@lib@shapedecoration@initialise{\the\pgf@y}%
+ \else%
+ \advance\pgf@x5pt\relax% An arbitrary value >0pt.
+ \edef\pgf@lib@shapedecoration@initialise{\the\pgf@x}%
+ \fi%
+ \fi%
+ \fi%
+ \edef\pgf@lib@shapedecoration@sep{\the\pgf@x}%
+ \fi%
+ }]
+ {}%
+ \state{before shape}
+ [
+ width=\pgf@lib@shapedecoration@beforeshape-1sp,
+ next state=shape,
+ persistent precomputation=
+ {
+ \ifpgfshapedecorationscaled%
+ \ifpgf@lib@shapedecoration@betweenborders%
+ \ifx\pgf@lib@shapedecoration@spread\pgfutil@empty%
+ %
+ % Not so straightforward. The required ratio is given by
+ %
+ % R = (c+W/2)/(c+r-.5*w)
+ %
+ % c = completed distance
+ % r = remaining distance
+ % W = initial width
+ % w = the change in width (i.e., end - start)
+ %
+ \pgf@x\pgfdecoratedcompleteddistance%
+ \advance\pgf@x\pgfdecoratedremainingdistance%
+ \pgf@xa\pgf@lib@shapedecoration@startwidth\relax%
+ \pgf@xa.5\pgf@xa%
+ \advance\pgf@xa\pgfdecoratedcompleteddistance% c+W/2
+ %
+ \pgf@xb\pgf@lib@shapedecoration@widthchange\relax%
+ \pgf@xb-.5\pgf@xb%
+ \advance\pgf@xb\pgf@x% c+r-.5*w
+ %
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@xb}}%
+ \fi%
+ \else%
+ %
+ % Easy peasy. The required ratio is
+ %
+ % R = c / (c+r)
+ %
+ \pgf@y\pgfdecoratedcompleteddistance%
+ \advance\pgf@y\pgfdecoratedremainingdistance%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgfdecoratedcompleteddistance}}{\pgfmath@tonumber{\pgf@y}}%
+ \fi%
+ %
+ % Get the new width.
+ %
+ \ifx\pgf@lib@shapedecoration@spread\pgfutil@empty%
+ \pgf@x\pgf@lib@shapedecoration@widthchange\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \advance\pgf@x\pgf@lib@shapedecoration@startwidth\relax%
+ \else%
+ \ifpgf@lib@shapedecoration@betweenborders%
+ %
+ % Special case when decoration is scaled, and evenly spread by borders.
+ %
+ \pgf@x\pgf@lib@shapedecoration@width\relax%
+ \advance\pgf@x\pgf@lib@shapedecoration@specialwidth\relax%
+ \pgf@xa\pgf@x%
+ \advance\pgf@xa-\pgf@lib@shapedecoration@startwidth\relax%
+ \pgf@xb\pgf@lib@shapedecoration@widthchange\relax%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@xb}}%
+ \else%
+ \pgf@x\pgf@lib@shapedecoration@widthchange\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \advance\pgf@x\pgf@lib@shapedecoration@startwidth\relax%
+ \fi%
+ \fi%
+ \edef\pgf@lib@shapedecoration@width{\the\pgf@x}%
+ %
+ % New height = R*h + H
+ %
+ \pgf@y\pgf@lib@shapedecoration@heightchange\relax%
+ \pgf@y\pgfmathresult\pgf@y%
+ \advance\pgf@y\pgf@lib@shapedecoration@initialheight\relax%
+ \edef\pgf@lib@shapedecoration@height{\the\pgf@y}%
+ \fi%
+ %
+ \ifpgf@lib@shapedecoration@betweenborders%
+ \pgf@x\pgf@lib@shapedecoration@width\relax%
+ \pgf@x.5\pgf@x%
+ \edef\pgf@lib@shapedecoration@beforeshape{\the\pgf@x}%
+ \else%
+ \def\pgf@lib@shapedecoration@beforeshape{0pt}%
+ \fi%
+ }]
+ {}%
+ \state{shape}[width=+0sp,next state=after shape]
+ {
+ \ifpgfshapedecorationsloped%
+ \else%
+ \pgftransformrotate{-\pgfdecoratedangle}%
+ \fi%
+ %
+ % Scale the path when it is actually drawn.
+ %
+ \pgf@lib@shapedecoration@shapepathsize%
+ \pgfutil@tempdima\pgf@x%
+ \pgfutil@tempdimb\pgf@y%
+ \pgf@xa\pgf@lib@shapedecoration@width\relax%
+ \pgf@xb\pgfutil@tempdima%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@xb}}%
+ \expandafter\pgftransformxscale\expandafter{\pgfmathresult}%
+ %
+ \pgf@ya\pgf@lib@shapedecoration@height\relax%
+ \pgf@yb\pgfutil@tempdimb%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@ya}}{\pgfmath@tonumber{\pgf@yb}}%
+ \expandafter\pgftransformyscale\expandafter{\pgfmathresult}%
+ %
+ % Move to the center anchor.
+ %
+ \pgf@lib@shapedecoration@points%
+ \pgf@lib@shapedecoration@macros%
+ \pgftransformshift{%
+ \pgf@sh@reanchor{\pgfkeysvalueof{/pgf/decoration/shape}}{\pgfkeysvalueof{/pgf/decoration/anchor}}%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }%
+ %
+ % And draw the shape path.
+ %
+ \csname pgf@sh@bg@\pgfkeysvalueof{/pgf/decoration/shape}\endcsname%
+ }%
+ \state{after shape}
+ [
+ width=\pgf@lib@shapedecoration@aftershape-1sp,
+ next state=sep,
+ persistent precomputation=
+ {
+ \ifpgf@lib@shapedecoration@betweenborders%
+ \pgf@x\pgf@lib@shapedecoration@width\relax%
+ \pgf@x.5\pgf@x%
+ \edef\pgf@lib@shapedecoration@aftershape{\the\pgf@x}%
+ \else%
+ \edef\pgf@lib@shapedecoration@aftershape{0pt}%
+ \fi%
+ }
+ ]
+ {}%
+ \state{sep}[width=\pgf@lib@shapedecoration@sep,next state=before shape,
+ persistent precomputation=\def\pgf@lib@shapedecoration@beforeshape{0pt}]
+ {}%
+ \state{final}
+ {
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}%
+ }%
+}%
+
+\def\pgf@lib@shapedecoration@setkeyword,{%
+ \pgfutil@ifnextchar\pgf@stop{\def\pgf@temp{}\pgf@lib@@@shapedecoration@setkeyword}{\pgf@lib@@shapedecoration@setkeyword}%
+}%
+\def\pgf@lib@@shapedecoration@setkeyword#1,{\def\pgf@temp{#1}\pgf@lib@@@shapedecoration@setkeyword}%
+\def\pgf@lib@@@shapedecoration@setkeyword\pgf@stop{%
+ \ifx\pgf@temp\pgf@lib@shapedecoration@borderstext%
+ \pgf@lib@shapedecoration@betweenborderstrue%
+ \else%
+ \pgf@lib@shapedecoration@betweenbordersfalse%
+ \fi%
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.text.code.tex b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.text.code.tex
new file mode 100644
index 0000000000..301fa24784
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/decorations/pgflibrarydecorations.text.code.tex
@@ -0,0 +1,357 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgfmodule{decorations}%
+
+
+% Options for text decorations
+
+\pgfkeys{
+ /pgf/decoration/.cd,
+ text/.store in=\pgfdecorationtext,%
+ text color/.store in=\pgf@lib@decorationtextcolor,%
+ text format delimiters/.code={\expandafter\pgfsetdecoratetextformatdelimiters#1},
+ text align/.code={\pgfkeys{/pgf/decoration/text align/.cd,#1}},
+ text align/.cd,
+ align/.initial=left,
+ left/.style={/pgf/decoration/text align/align=left},
+ right/.style={/pgf/decoration/text align/align=right},
+ center/.style={/pgf/decoration/text align/align=center},
+ left indent/.initial=0pt,
+ right indent/.initial=0pt,
+ fit to path/.is if=pgf@lib@dec@text@fit,
+ fit to path stretching spaces/.default=true,
+ fit to path stretching spaces/.code={%
+ \csname pgf@lib@dec@text@fit#1\endcsname%
+ \csname pgf@lib@dec@text@stretch@spaces#1\endcsname%
+ }%
+}%
+
+\newif\ifpgf@lib@dec@text@scan@space
+\newif\ifpgf@lib@dec@text@stretch@spaces
+\newif\ifpgf@lib@dec@text@fit
+
+\def\pgf@lib@decorationtextcolor{black}%
+
+\def\pgf@lib@dec@text@left@text{left}%
+\def\pgf@lib@dec@text@right@text{right}%
+\def\pgf@lib@dec@text@right@center{center}%
+
+% Decorates a path with a text. The path is removed during this
+% process
+
+\pgfdeclaredecoration{text along path}{initial}{%
+ \state{initial}[
+ width=+0pt, next state=left indent,
+ persistent precomputation={%
+ \edef\pgf@lib@dec@text@indent@left{\pgfkeysvalueof{/pgf/decoration/text align/left indent}}%
+ \edef\pgf@lib@dec@text@indent@right{\pgfkeysvalueof{/pgf/decoration/text align/right indent}}%
+ \edef\pgf@lib@dec@text@align{\pgfkeysvalueof{/pgf/decoration/text align/align}}%
+ \pgfdecoratedremainingdistance=\pgfdecoratedpathlength%
+ \advance\pgfdecoratedremainingdistance by-\pgf@lib@dec@text@indent@right\relax%
+ \edef\pgfdecoratedpathlength{\the\pgfdecoratedremainingdistance}%
+ \pgf@lib@dec@text@getwidth%
+ \pgf@x=\pgf@lib@dec@text@width\relax%
+ \pgf@y=\pgfdecoratedremainingdistance%
+ \ifpgf@lib@dec@text@fit%
+ \advance\pgf@y by-\pgf@lib@dec@text@indent@left\relax%
+ \advance\pgf@y by-\pgf@x%
+ \ifpgf@lib@dec@text@stretch@spaces%
+ \def\pgf@lib@dec@text@character@shift{0pt}%
+ \divide\pgf@y by\pgf@lib@dec@space@count\relax%
+ \edef\pgf@lib@dec@text@space@shift{\the\pgf@y}%
+ \else%
+ \c@pgf@counta=\pgf@lib@dec@character@count\relax%
+ \advance\c@pgf@counta by-1\relax%
+ \divide\pgf@y by\c@pgf@counta\relax%
+ \edef\pgf@lib@dec@text@character@shift{\the\pgf@y}%
+ \def\pgf@lib@dec@text@space@shift{0pt}%
+ \fi%
+ \ifdim\pgf@y<0pt\relax%
+ \pgf@lib@dec@text@fitfalse%
+ \pgf@lib@dec@text@stretch@spacesfalse%
+ \def\pgf@lib@dec@text@character@shift{0pt}%
+ \def\pgf@lib@dec@text@space@shift{0pt}%
+ \fi%
+ \else%
+ \def\pgf@lib@dec@text@character@shift{0pt}%
+ \def\pgf@lib@dec@text@space@shift{0pt}%
+ \ifx\pgf@lib@dec@text@align\pgf@lib@dec@text@left@text%
+ \else%
+ \ifx\pgf@lib@dec@text@align\pgf@lib@dec@text@right@text%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgf@lib@dec@text@indent@left{\the\pgf@y}%
+ \else%
+ \advance\pgf@y by-\pgf@x%
+ \advance\pgf@y by-\pgf@lib@dec@text@indent@left\relax%
+ \pgf@y=0.5\pgf@y%
+ \advance\pgf@y by\pgf@lib@dec@text@indent@left\relax%
+ \edef\pgf@lib@dec@text@indent@left{\the\pgf@y}%
+ \fi%
+ \fi%
+ \fi%
+ \let\pgfdecorationrestoftext=\pgfdecorationtext%
+ }]{}%
+\state{left indent}[width=+\pgf@lib@dec@text@indent@left, next state=scan]{}%
+%
+\state{scan}[
+ width=+0pt,
+ next state=before typeset,
+ persistent precomputation={
+ \pgf@lib@dec@text@scanchar%
+ \ifvoid\pgf@lib@dec@text@box%
+ \setbox\pgf@lib@dec@text@box\hbox{}%
+ \wd\pgf@lib@dec@text@box16383pt\relax%
+ \fi%
+}]{}%
+%
+\state{before typeset}[width=+.5\wd\pgf@lib@dec@text@box, next state=typeset]{}%
+%
+\state{typeset}[width=+0pt, next state=after typeset]
+{%
+ \pgftransformxshift{+-.5\wd\pgf@lib@dec@text@box}%
+ \setbox\pgf@hbox\hbox{\copy\pgf@lib@dec@text@box}%
+ \pgfqboxsynced\pgf@hbox%
+}%
+\state{after typeset}[width=+.5\wd\pgf@lib@dec@text@box, next state=shift,
+ persistent precomputation={%
+ \ifpgf@lib@dec@text@fit%
+ \ifpgf@lib@dec@text@stretch@spaces%
+ \ifpgf@lib@dec@text@scan@space%
+ \let\pgf@lib@dec@text@shift=\pgf@lib@dec@text@space@shift%
+ \else%
+ \def\pgf@lib@dec@text@shift{0pt}%
+ \fi%
+ \else%
+ \let\pgf@lib@dec@text@shift=\pgf@lib@dec@text@character@shift%
+ \fi%
+ \else%
+ \def\pgf@lib@dec@text@shift{0pt}%
+ \fi%
+ }]{}%
+\state{shift}[width=+\pgf@lib@dec@text@shift, next state=scan]{}%
+\state{final}{}%
+}%
+
+
+% \pgfsetdecoratetextformatdelimiters
+%
+% Set the delimiters for formatting in the text decoration.
+% NB: Catcodes for delimiters should be 11 or 12.
+%
+% Examples:
+%
+% \pgfsetdecoratetextformatdelimiters{|}{}% 2nd argument can be empty.
+%
+% \def\pgfdecoratetext{A big |\color{red}|red|| apple.}
+%
+% \pgfsetdecoratetextformatdelimiters{[}{]}
+%
+% \def\pgfdecoratetext{The [\it]very[+\color{green}]green[] sprouts.}
+%
+\def\pgfsetdecoratetextformatdelimiters#1#2{%
+ \def\pgf@lib@dec@text@formatchar{#1}%
+ \def\pgf@test{#2}%
+ \ifx\pgf@test\pgfutil@empty%
+ \def\pgf@lib@dec@text@collectformat##1#1{%
+ \pgf@lib@dec@text@@collectformat##1\pgf@stop}%
+ \else%
+ \def\pgf@lib@dec@text@collectformat##1#2{%
+ \pgf@lib@dec@text@@collectformat##1\pgf@stop}%
+ \fi%
+}%
+
+\pgfsetdecoratetextformatdelimiters{|}{}%
+
+\newbox\pgf@lib@dec@text@box
+\newif\ifpgf@lib@decorate@textmathmode
+
+\let\pgfdecorationtext=\pgfutil@empty
+\let\pgfdecorationrestoftext=\pgfutil@empty%
+\let\pgf@lib@dec@text@format=\pgfutil@empty
+
+\def\pgf@lib@dec@text@scanchar{%
+ \pgf@lib@dec@text@scan@spacefalse%
+ \ifx\pgfdecorationrestoftext\pgfutil@empty%
+ \let\pgf@lib@dec@text@char\pgfutil@empty%
+ \setbox\pgf@lib@dec@text@box\box\pgfutil@voidb@x%
+ \let\pgf@next\relax%
+ \else\ifx\pgfdecorationrestoftext\pgf@lib@dec@mathshift%
+ \ifpgf@lib@decorate@textmathmode%
+ \pgf@lib@decorate@textmathmodefalse%
+ \fi%
+ \let\pgf@lib@dec@text@char\pgfutil@empty%
+ \setbox\pgf@lib@dec@text@box\box\pgfutil@voidb@x%
+ \let\pgf@next\relax%
+ \else
+ \let\pgf@next\pgf@lib@dec@text@@scanchar%
+ \fi\fi%
+ \pgf@next}%
+
+\def\pgf@lib@dec@text@@scanchar{%
+ \expandafter\pgf@lib@dec@text@@@scanchar\pgfdecorationrestoftext\pgf@stop}%
+
+\def\pgf@lib@dec@text@@@scanchar{%
+ \futurelet\pgf@lib@dec@lettoken%
+ \pgf@lib@dec@text@@@@scanchar}%
+
+\def\pgf@lib@dec@text@@@@scanchar{%
+ \ifx\pgf@lib@dec@lettoken\pgfutil@sptoken%
+ \let\pgf@next\pgf@lib@dec@text@insertspace%
+ \else%
+ \let\pgf@next\pgf@lib@dec@text@@@@@scanchar%
+ \fi%
+ \pgf@next}%
+
+\def\pgf@lib@dec@text@@@@@scanchar{%
+ \pgfutil@ifnextchar\bgroup{\pgf@lib@dec@text@collectgroup}%
+ {\pgf@lib@dec@text@@@@@@scanchar}}%
+
+\def\pgf@lib@dec@text@collectgroup#1{%
+ \def\pgf@lib@dec@text@char{#1}%
+ \pgf@lib@dec@text@collectrestoftext}%
+
+\def\pgf@lib@dec@text@@@@@@scanchar#1{%
+ \ifx#1\pgf@stop%
+ \pgf@lib@dec@text@box\box\pgfutil@voidb@x%
+ \let\pgf@next\pgf@lib@dec@text@endoftext%
+ \else%
+ \def\pgf@lib@dec@text@char{#1}%
+ \ifx#1\space%
+ \let\pgf@next\pgf@lib@dec@text@collectrestoftext%
+ \else%
+ \ifx#1\ %
+ \let\pgf@next\pgf@lib@dec@text@collectrestoftext%
+ \else%
+ \ifx\pgf@lib@dec@text@char\pgf@lib@dec@text@formatchar%
+ \let\pgf@next\pgf@lib@dec@text@collectformat%
+ \else%
+ \expandafter\ifcat\noexpand#1\relax%
+ \let\pgf@next\pgf@lib@dec@text@expandcs%
+ \else%
+ \ifnum\catcode`#1=3\relax%
+ \ifpgf@lib@decorate@textmathmode%
+ \pgf@lib@decorate@textmathmodefalse%
+ \else%
+ \pgf@lib@decorate@textmathmodetrue%
+ \fi%
+ \let\pgf@next\pgf@lib@dec@text@@@scanchar%
+ \else%
+ \let\pgf@next\pgf@lib@dec@text@collectrestoftext%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgf@next%
+}%
+
+\def\pgf@lib@dec@text@@collectformat{%
+ \pgfutil@ifnextchar+{\pgf@lib@dec@text@addtoformat}{\pgf@lib@dec@text@setformat}}%
+
+\def\pgf@lib@dec@text@setformat#1\pgf@stop{%
+ \def\pgf@lib@dec@text@format{#1}%
+ \pgf@lib@dec@text@@@scanchar%
+}%
+
+\def\pgf@lib@dec@text@addtoformat+#1\pgf@stop{%
+ \expandafter\def\expandafter\pgf@lib@dec@text@format\expandafter{\pgf@lib@dec@text@format#1}%
+ \pgf@lib@dec@text@@@scanchar%
+}%
+
+\def\pgf@lib@dec@text@insertspace{%
+ \pgf@lib@dec@text@scan@spacetrue%
+ \pgfutil@ifnextchar\bgroup{\pgf@lib@dec@text@@insertspacegrp}%
+ {\pgf@lib@dec@text@@insertspace}}%
+
+\def\pgf@lib@dec@text@@insertspacegrp#1{%
+ \pgf@lib@dec@text@@@@@@scanchar\space{#1}}%
+
+\def\pgf@lib@dec@text@@insertspace#1{%
+ \pgf@lib@dec@text@@@@@@scanchar\space#1}%
+
+\def\pgf@lib@dec@text@expandcs{%
+ \expandafter\expandafter\expandafter\pgf@lib@dec@text@@@@@scanchar%
+ \pgf@lib@dec@text@char}%
+
+\def\pgf@lib@dec@text@endoftext{%
+ \let\pgfdecorationrestoftext\pgfutil@empty%
+ \let\pgf@lib@dec@text@char\pgfutil@empty%
+}%
+\def\pgf@lib@dec@text@collectrestoftext{%
+ \pgf@lib@dec@text@dobox%
+ \futurelet\pgf@lib@dec@text@lettoken%
+ \pgf@lib@dec@text@@collectrestoftext}%
+
+\def\pgf@lib@dec@text@@collectrestoftext{%
+ \ifx\bgroup\pgf@lib@dec@text@lettoken%
+ \let\pgf@next\pgf@lib@dec@text@@@collectrestoftextgrp%
+ \else%
+ \let\pgf@next\pgf@lib@dec@text@@@collectrestoftext%
+ \fi%
+ \pgf@next}%
+
+\def\pgf@lib@dec@text@@@collectrestoftextgrp#1#2\pgf@stop{\def\pgfdecorationrestoftext{{#1}#2}%
+}%
+
+\def\pgf@lib@dec@text@@@collectrestoftext#1\pgf@stop{\def\pgfdecorationrestoftext{#1}}%
+
+{%
+ \catcode`\$3 %
+ \gdef\pgf@lib@dec@mathshift{$}%
+ \catcode`\$9 $% For editors with annoying syntax highlighting.
+}%
+
+\def\pgf@lib@dec@text@dobox{%
+ \setbox\pgf@lib@dec@text@box\hbox{%
+ \pgfinterruptpicture%
+ \begingroup%
+ \pgfsetcolor{\pgf@lib@decorationtextcolor}%
+ \ifpgf@lib@decorate@textmathmode\pgf@lib@dec@mathshift\fi%
+ \pgf@lib@dec@text@format\relax%
+ \pgf@lib@dec@text@char%
+ \ifpgf@lib@decorate@textmathmode\pgf@lib@dec@mathshift\fi%
+ \endgroup%
+ \endpgfinterruptpicture%
+ }%
+}%
+
+\def\pgf@lib@dec@text@getwidth{%
+ \begingroup%
+ \let\c@pgf@lib@dec@characters=\c@pgf@counta%
+ \let\c@pgf@lib@dec@spaces=\c@pgf@countb%
+ \let\pgfdecorationrestoftext=\pgfdecorationtext%
+ \c@pgf@lib@dec@spaces=0\relax%
+ \c@pgf@lib@dec@characters=0\relax%
+ \pgfmathloop%
+ \pgf@lib@dec@text@scanchar%
+ \ifvoid\pgf@lib@dec@text@box%
+ \else%
+ \setbox\pgf@hbox=\hbox{{%
+ \unhbox\pgf@hbox%
+ \unhbox\pgf@lib@dec@text@box%
+ }}%
+ \advance\c@pgf@lib@dec@characters by1\relax%
+ \ifpgf@lib@dec@text@scan@space%
+ \advance\c@pgf@lib@dec@spaces by1\relax%
+ \fi%
+ \repeatpgfmathloop%
+ \global\pgf@x=\the\wd\pgf@hbox%
+ \xdef\pgf@lib@dec@temp{\the\c@pgf@lib@dec@characters}%
+ \xdef\pgf@lib@dec@@temp{\the\c@pgf@lib@dec@spaces}%
+ \endgroup%
+ \edef\pgf@lib@dec@text@width{\the\pgf@x}%
+ \let\pgf@lib@dec@character@count=\pgf@lib@dec@temp%
+ \let\pgf@lib@dec@space@count=\pgf@lib@dec@@temp%
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/functions.lua b/graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/functions.lua
new file mode 100644
index 0000000000..367d6ae298
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/functions.lua
@@ -0,0 +1,626 @@
+-- Copyright 2011 by Christophe Jorssen
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License.
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more details.
+--
+-- $Id$
+--
+
+local pgfluamathfunctions = pgfluamathfunctions or {}
+
+-- Maps function names to their function.
+--
+-- Note that this allows to register functions which are not in pgfluamathfunctions.
+--
+-- Note that the string keys are not necessarily the same as the function
+-- names. In particular, the math expression "not(1,1)" will execute notPGF(1,1)
+--
+-- Note that each function which is added to pgfluamathfunctions will _automatically_ be inserted into this map, see __newindex.
+-- (I fear it will not be erased directly...)
+pgfluamathfunctions.stringToFunctionMap = {}
+
+local newFunctionAllocatedCallback = function(table,key,value)
+ local keyName = tostring(key):gsub("PGF","")
+ if not value then
+ stringToFunctionMap[keyName] = nil
+ elseif type(value) == 'function' then
+ -- remember it, and strip PGF suffix (i.e. remember 'not' instead of 'notPGF')
+ pgfluamathfunctions.stringToFunctionMap[keyName] = value
+ end
+ rawset(table,key,value)
+end
+
+setmetatable(pgfluamathfunctions, { __newindex = newFunctionAllocatedCallback })
+
+local mathabs, mathacos, mathasin = math.abs, math.acos, math.asin
+local mathatan, mathceil = math.atan, math.ceil
+local mathcos, mathdeg = math.cos, math.deg
+local mathexp, mathfloor, mathfmod = math.exp, math.floor, math.fmod
+local mathlog, mathmax = math.log, math.max
+local mathmin, mathpi = math.min, math.pi
+local mathrad, mathrandom = math.rad, math.random
+local mathrandomseed, mathsin = math.randomseed, math.sin
+local mathsqrt = math.sqrt
+local mathtan = math.tan
+
+local trigFormatToRadians = mathrad
+
+local radiansToTrigFormat = mathdeg
+
+pgfluamathfunctions.TrigFormat = { 'deg', 'rad' }
+pgfluamathfunctions.stringToFunctionMap["TrigFormat"] = nil
+
+-- choice is one of the valid choices in TrigFormat.
+function pgfluamathfunctions.setTrigFormat(choice)
+ if choice == 'deg' then
+ trigFormatToRadians = mathrad
+ radiansToTrigFormat = mathdeg
+ elseif choice == 'rad' then
+ local identity = function(x) return x end
+ trigFormatToRadians = identity
+ radiansToTrigFormat = identity
+ else
+ error("The argument '" .. tostring(choice) .. "' is no valid choice for setTrigFormat.")
+ end
+end
+pgfluamathfunctions.stringToFunctionMap["setTrigFormat"] = nil
+
+pgfluamathfunctions.setRandomSeed = mathrandomseed
+pgfluamathfunctions.stringToFunctionMap["setRandomSeed"] = nil
+
+-------------------------------------------
+
+function pgfluamathfunctions.add(x,y)
+ return x+y
+end
+
+function pgfluamathfunctions.subtract(x,y)
+ return x-y
+end
+
+function pgfluamathfunctions.neg(x)
+ return -x
+end
+
+function pgfluamathfunctions.multiply(x,y)
+ return x*y
+end
+
+function pgfluamathfunctions.veclen(x,y)
+ return mathsqrt(x*x+y*y)
+end
+
+function pgfluamathfunctions.divide(x,y)
+ return x/y
+end
+
+function pgfluamathfunctions.div(x,y)
+ return mathfloor(x/y)
+end
+
+function pgfluamathfunctions.pow(x,y)
+ -- do not use math.pow -- it is deprecated as of LUA 5.3
+ return x^y
+end
+
+function pgfluamathfunctions.factorial(x)
+-- TODO: x must be an integer
+ if x == 0 then
+ return 1
+ else
+ return x * pgfluamathfunctions.factorial(x-1)
+ end
+end
+
+function pgfluamathfunctions.ifthenelse(x,y,z)
+ if x~= 0 then
+ return y
+ else
+ return z
+ end
+end
+
+function pgfluamathfunctions.equal(x,y)
+ if x == y then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.greater(x,y)
+ if x > y then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.less(x,y)
+ if x < y then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.min(x,y)
+ return mathmin(x,y)
+end
+
+function pgfluamathfunctions.max(x,y)
+ return mathmax(x,y)
+end
+
+function pgfluamathfunctions.notequal(x,y)
+ if x ~= y then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.notless(x,y)
+ if x >= y then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.notgreater(x,y)
+ if x <= y then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.andPGF(x,y)
+ if (x ~= 0) and (y ~= 0) then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.orPGF(x,y)
+ if (x ~= 0) or (y ~= 0) then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.notPGF(x)
+ if x == 0 then
+ return 1
+ else
+ return 0
+ end
+end
+
+function pgfluamathfunctions.pi()
+ return mathpi
+end
+
+function pgfluamathfunctions.e()
+ return mathexp(1)
+end
+
+function pgfluamathfunctions.abs(x)
+ return mathabs(x)
+end
+
+function pgfluamathfunctions.floor(x)
+ return mathfloor(x)
+end
+
+function pgfluamathfunctions.ceil(x)
+ return mathceil(x)
+end
+
+function pgfluamathfunctions.exp(x)
+ return mathexp(x)
+end
+
+function pgfluamathfunctions.ln(x)
+ return mathlog(x)
+end
+
+local logOf10 = mathlog(10)
+function pgfluamathfunctions.log10(x)
+ return mathlog(x) / logOf10
+end
+
+local logOf2 = mathlog(2)
+function pgfluamathfunctions.log2(x)
+ return mathlog(x) / logOf2
+end
+
+function pgfluamathfunctions.sqrt(x)
+ return mathsqrt(x)
+end
+
+function pgfluamathfunctions.sign(x)
+ if x < 0 then
+ return -1.0
+ elseif x == 0 then
+ return 0.0
+ else
+ return 1.0
+ end
+end
+function pgfluamathfunctions.real(x)
+ -- "ensure that x contains a decimal point" is kind of a no-op here, isn't it!?
+ return x
+end
+
+function pgfluamathfunctions.rnd()
+ return mathrandom()
+end
+
+function pgfluamathfunctions.rand()
+ return -1 + mathrandom() *2
+end
+
+function pgfluamathfunctions.random(x,y)
+ if x == nil and y == nil then
+ return mathrandom()
+ elseif y == nil then
+ return mathrandom(x)
+ else
+ return mathrandom(x,y)
+ end
+end
+
+function pgfluamathfunctions.deg(x)
+ return mathdeg(x)
+end
+
+function pgfluamathfunctions.rad(x)
+ return mathrad(x)
+end
+
+function pgfluamathfunctions.round(x)
+ if x<0 then
+ return -mathfloor(mathabs(x)+0.5)
+ else
+ return mathfloor(x + 0.5)
+ end
+end
+
+function pgfluamathfunctions.gcd(a, b)
+ if b == 0 then
+ return a
+ else
+ return pgfluamathfunctions.gcd(b, a%b)
+ end
+end
+
+function pgfluamathfunctions.isprime(a)
+ local ifisprime = true
+ if a == 1 then
+ ifisprime = false
+ elseif a == 2 then
+ ifisprime = true
+-- if a > 2 then
+ else
+ local i, imax = 2, mathceil(mathsqrt(a)) + 1
+ while ifisprime and (i < imax) do
+ if pgfluamathfunctions.gcd(a,i) ~= 1 then
+ ifisprime = false
+ end
+ i = i + 1
+ end
+ end
+ if ifisprime then
+ return 1
+ else
+ return 0
+ end
+end
+
+
+function pgfluamathfunctions.split_braces_to_explist(s)
+ -- (Thanks to mpg and zappathustra from fctt)
+ -- Make unpack available whatever lua version is used
+ -- (unpack in lua 5.1 table.unpack in lua 5.2)
+ local unpack = table.unpack or unpack
+ local t = {}
+ for i in s:gmatch('%b{}') do
+ table.insert(t, tonumber(i:sub(2, -2)))
+ end
+ return unpack(t)
+end
+
+function pgfluamathfunctions.split_braces_to_table(s)
+ local t = {}
+ for i in s:gmatch('%b{}') do
+ table.insert(t, tonumber(i:sub(2, -2)))
+ end
+ return t
+end
+
+function pgfluamathfunctions.mathtrue()
+ return 1.0
+end
+pgfluamathfunctions.stringToFunctionMap["true"] = pgfluamathfunctions.mathtrue
+
+function pgfluamathfunctions.mathfalse()
+ return 0.0
+end
+pgfluamathfunctions.stringToFunctionMap["false"] = pgfluamathfunctions.mathfalse
+
+function pgfluamathfunctions.frac(a)
+ -- should be positive, apparently
+ return mathabs(a - pgfluamathfunctions.int(a))
+end
+
+function pgfluamathfunctions.int(a)
+ if a < 0 then
+ return -mathfloor(mathabs(a))
+ else
+ return mathfloor(a)
+ end
+end
+
+function pgfluamathfunctions.iseven(a)
+ if (a % 2) == 0 then
+ return 1.0
+ else
+ return 0.0
+ end
+end
+
+function pgfluamathfunctions.isodd(a)
+ if (a % 2) == 0 then
+ return 0.0
+ else
+ return 1.0
+ end
+end
+
+function pgfluamathfunctions.mod(x,y)
+ if x/y < 0 then
+ return -(mathabs(x)%mathabs(y))
+ else
+ return mathabs(x)%mathabs(y)
+ end
+end
+
+function pgfluamathfunctions.Mod(x,y)
+ local tmp = pgfluamathfunctions.mod(x,y)
+ if tmp < 0 then
+ tmp = tmp + y
+ end
+ return tmp
+end
+
+function pgfluamathfunctions.Sin(x)
+ return mathsin(trigFormatToRadians(x))
+end
+pgfluamathfunctions.sin=pgfluamathfunctions.Sin
+
+
+function pgfluamathfunctions.cosh(x)
+ -- math.cosh is deprecated as of LUA 5.3 . reimplement it:
+ return 0.5* (mathexp(x) + mathexp(-x))
+end
+function pgfluamathfunctions.sinh(x)
+ -- math.sinh is deprecated as of LUA 5.3 . reimplement it:
+ return 0.5* (mathexp(x) - mathexp(-x))
+end
+
+local sinh = pgfluamathfunctions.sinh
+local cosh = pgfluamathfunctions.cosh
+function pgfluamathfunctions.tanh(x)
+ -- math.tanh is deprecated as of LUA 5.3 . reimplement it:
+ return sinh(x)/cosh(x)
+end
+
+function pgfluamathfunctions.Cos(x)
+ return mathcos(trigFormatToRadians(x))
+end
+pgfluamathfunctions.cos=pgfluamathfunctions.Cos
+
+function pgfluamathfunctions.Tan(x)
+ return mathtan(trigFormatToRadians(x))
+end
+pgfluamathfunctions.tan=pgfluamathfunctions.Tan
+
+function pgfluamathfunctions.aSin(x)
+ return radiansToTrigFormat(mathasin(x))
+end
+pgfluamathfunctions.asin=pgfluamathfunctions.aSin
+
+function pgfluamathfunctions.aCos(x)
+ return radiansToTrigFormat(mathacos(x))
+end
+pgfluamathfunctions.acos=pgfluamathfunctions.aCos
+
+function pgfluamathfunctions.aTan(x)
+ return radiansToTrigFormat(mathatan(x))
+end
+pgfluamathfunctions.atan=pgfluamathfunctions.aTan
+
+local mathatan2
+if math.atan2 == nil then
+ -- math.atan2 has been deprecated since LUA 5.3
+ mathatan2 = function (y,x) return mathatan(y,x) end
+else
+ mathatan2 = math.atan2
+end
+
+function pgfluamathfunctions.aTan2(y,x)
+ return radiansToTrigFormat(mathatan2(y,x))
+end
+pgfluamathfunctions.atan2=pgfluamathfunctions.aTan2
+pgfluamathfunctions.atantwo=pgfluamathfunctions.aTan2
+
+function pgfluamathfunctions.cot(x)
+ return pgfluamathfunctions.cos(x) / pgfluamathfunctions.sin(x)
+end
+function pgfluamathfunctions.sec(x)
+ return 1 / pgfluamathfunctions.cos(x)
+end
+function pgfluamathfunctions.cosec(x)
+ return 1 / pgfluamathfunctions.sin(x)
+end
+
+function pgfluamathfunctions.pointnormalised (pgfx, pgfy)
+ local pgfx_normalised, pgfy_normalised
+ if pgfx == 0. and pgfy == 0. then
+ -- Original pgf macro gives this result
+ tex.dimen['pgf@x'] = "0pt"
+ tex.dimen['pgf@y'] = "1pt"
+ else
+ pgfx_normalised = pgfx/math.sqrt(pgfx^2 + pgfy^2)
+ pgfx_normalised = pgfx_normalised - pgfx_normalised%0.00001
+ pgfy_normalised = pgfy/math.sqrt(pgfx^2 + pgfy^2)
+ pgfy_normalised = pgfy_normalised - pgfy_normalised%0.00001
+ tex.dimen['pgf@x'] = tostring(pgfx_normalised) .. "pt"
+ tex.dimen['pgf@y'] = tostring(pgfy_normalised) .. "pt"
+ end
+ return nil
+end
+
+local isnan = function(x)
+ return x ~= x
+end
+
+pgfluamathfunctions.isnan = isnan
+
+local infty = 1/0
+pgfluamathfunctions.infty = infty
+
+local nan = math.sqrt(-1)
+pgfluamathfunctions.nan = nan
+
+local stringlen = string.len
+local globaltonumber = tonumber
+local stringsub=string.sub
+local stringformat = string.format
+local stringsub = string.sub
+
+-- like tonumber(x), but it also accepts nan, inf, infty, and the TeX FPU format
+function pgfluamathfunctions.tonumber(x)
+ if type(x) == 'number' then return x end
+ if not x then return x end
+
+ local len = stringlen(x)
+ local result = globaltonumber(x)
+ if not result then
+ if len >2 and stringsub(x,2,2) == 'Y' and stringsub(x,len,len) == ']' then
+ -- Ah - some TeX FPU input of the form 1Y1.0e3] . OK. transform it
+ local flag = stringsub(x,1,1)
+ if flag == '0' then
+ -- ah, 0.0
+ result = 0.0
+ elseif flag == '1' then
+ result = globaltonumber(stringsub(x,3, len-1))
+ elseif flag == '2' then
+ result = globaltonumber("-" .. stringsub(x,3, len-1))
+ elseif flag == '3' then
+ result = nan
+ elseif flag == '4' then
+ result = infty
+ elseif flag == '5' then
+ result = -infty
+ end
+ else
+ local lower = x:lower()
+ if lower == 'nan' then
+ result = nan
+ elseif lower == "-nan" then
+ result = nan
+ elseif lower == 'inf' or lower == 'infty' then
+ result = infty
+ elseif lower == '-inf' or lower == '-infty' then
+ result = -infty
+ end
+ end
+ end
+
+ return result
+end
+
+local stringlen = string.len
+local globaltonumber = tonumber
+local stringformat = string.format
+local stringsub = string.sub
+local stringfind = string.find
+local stringbyte = string.byte
+local NULL_CHAR = string.byte("0",1)
+
+local function discardTrailingZeros(x)
+ local result = x
+ -- printf is too stupid: I would like to have
+ -- 1. a fast method
+ -- 2. a reliable method
+ -- 3. full precision of x
+ -- 4. a fixed point representation
+ -- the 'f' modifier has trailing zeros (stupid!)
+ -- the 'g' modified can switch to scientific notation (no-go!)
+ local periodOff = stringfind(result, '.',1,true)
+ if periodOff ~= nil then
+ -- strip trailing zeros
+ local chars = { stringbyte(result,1,#result) };
+ local lastNonZero = #chars
+ for i = #chars, periodOff, -1 do
+ if chars[i] ~= NULL_CHAR then lastNonZero=i; break; end
+ end
+ if lastNonZero ~= #chars then
+ -- Ah: we had at least one trailing zero.
+ -- discard all but the last.
+ lastNonZero = mathmax(periodOff+1,lastNonZero)
+ end
+ result = stringsub(result, 1, lastNonZero)
+ end
+ return result;
+end
+
+local function discardTrailingZerosFromMantissa(x)
+ local mantissaStart = stringfind(x, "e")
+
+ local mantissa = stringsub(x,1,mantissaStart-1)
+ local exponent = stringsub(x,mantissaStart)
+
+ return discardTrailingZeros(mantissa) .. exponent
+end
+
+
+-- a helper function which has no catcode issues when communicating with TeX:
+function pgfluamathfunctions.tostringfixed(x)
+ if x == nil then
+ return ""
+ end
+
+ return discardTrailingZeros(stringformat("%f", x))
+end
+
+-- converts an input number to a string which is accepted by the TeX FPU
+function pgfluamathfunctions.toTeXstring(x)
+ local result = ""
+ if x ~= nil then
+ if x == infty then result = "4Y0.0e0]"
+ elseif x == -infty then result = "5Y0.0e0]"
+ elseif isnan(x) then result = "3Y0.0e0]"
+ elseif x == 0 then result = "0Y0.0e0]"
+ else
+ result = discardTrailingZerosFromMantissa(stringformat("%.10e", x))
+ if x > 0 then
+ result = "1Y" .. result .. "]"
+ else
+ result = "2Y" .. stringsub(result,2) .. "]"
+ end
+ end
+ end
+ return result
+end
+
+return pgfluamathfunctions
diff --git a/graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/parser.lua b/graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/parser.lua
new file mode 100644
index 0000000000..42b690e6cf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/luamath/pgf/luamath/parser.lua
@@ -0,0 +1,481 @@
+-- Copyright 2011 by Christophe Jorssen and Mark Wibrow
+-- Copyright 2014 by Christian Feuersaenger
+--
+-- This file may be distributed and/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License.
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more details.
+--
+-- $Id$
+--
+-- usage:
+--
+-- pgfluamathparser = require("pgf.luamath.parser")
+--
+-- local result = pgfluamathparser.pgfmathparse("1+ 2*4^2")
+--
+-- This LUA class has a direct backend in \pgfuselibrary{luamath}, see the documentation of that TeX package.
+
+local pgfluamathparser = pgfluamathparser or {}
+
+pgfluamathfunctions = require("pgf.luamath.functions")
+
+-- lpeg is always present in luatex
+local lpeg = require("lpeg")
+
+local S, P, R = lpeg.S, lpeg.P, lpeg.R
+local C, Cc, Ct = lpeg.C, lpeg.Cc, lpeg.Ct
+local Cf, Cg, Cs = lpeg.Cf, lpeg.Cg, lpeg.Cs
+local V = lpeg.V
+local match = lpeg.match
+
+local space_pattern = S(" \n\r\t")^0
+local tex_unit =
+ P('pt') + P('mm') + P('cm') + P('in') +
+ -- while valid units, the font-depending ones need special attention... move them to the TeX side. For now.
+ -- P('ex') + P('em') +
+ P('bp') + P('pc') +
+ P('dd') + P('cc') + P('sp');
+
+local one_digit_pattern = R("09")
+local positive_integer_pattern = one_digit_pattern^1
+-- FIXME : it might be a better idea to remove '-' from all number_patterns! Instead, rely on the prefix operator 'neg' to implement negative numbers.
+-- Is that wise? It is certainly less efficient...
+local integer_pattern = S("+-")^-1 * positive_integer_pattern
+-- Valid positive decimals are |xxx.xxx|, |.xxx| and |xxx.|
+local positive_integer_or_decimal_pattern = positive_integer_pattern * ( P(".") * one_digit_pattern^0)^-1 +
+ (P(".") * one_digit_pattern^1)
+local integer_or_decimal_pattern = S("+-")^-1 * positive_integer_or_decimal_pattern
+local fpu_pattern = R"05" * P"Y" * positive_integer_or_decimal_pattern * P"e" * S("+-")^-1 * R("09")^1 * P"]"
+local unbounded_pattern = P"inf" + P"INF" + P"nan" + P"NaN" + P"Inf"
+local number_pattern = C(unbounded_pattern + fpu_pattern + integer_or_decimal_pattern * (S"eE" * integer_pattern + C(tex_unit))^-1)
+
+local underscore_pattern = P("_")
+
+local letter_pattern = R("az","AZ")
+local alphanum__pattern = letter_pattern + one_digit_pattern + underscore_pattern
+
+local identifier_pattern = letter_pattern^1 * alphanum__pattern^0
+
+local openparen_pattern = P("(") * space_pattern
+local closeparen_pattern = P(")")
+local opencurlybrace_pattern = P("{")
+local closecurlybrace_pattern = P("}")
+local openbrace_pattern = P("[")
+local closebrace_pattern = P("]")
+
+-- hm. what about '\\' or '\%' ?
+-- accept \pgf@x, \count0, \dimen42, \c@pgf@counta, \wd0, \ht0, \dp 0
+local controlsequence_pattern = P"\\" * C( (R("az","AZ") + P"@")^1) * space_pattern* C( R"09"^0 )
+
+-- local string = P('"') * C((1 - P('"'))^0) * P('"')
+
+local comma_pattern = P(",") * space_pattern
+
+
+----------------
+local TermOp = C(S("+-")) * space_pattern
+local EqualityOp = C( P"==" + P"!=" ) * space_pattern
+local RelationalOp = C( P"<=" + P">=" + P"<" + P">" ) * space_pattern
+local FactorOp = C(S("*/")) * space_pattern
+
+-- Grammar
+local Exp, Term, Factor = V"Exp", V"Term", V"Factor"
+local Prefix = V"Prefix"
+local Postfix = V"Postfix"
+
+
+
+local function eval (v1, op, v2)
+ if (op == "+") then return v1 + v2
+ elseif (op == "-") then return v1 - v2
+ elseif (op == "*") then return v1 * v2
+ elseif (op == "/") then return v1 / v2
+ else
+ error("This function must not be invoked for operator "..op)
+ end
+end
+
+local pgfStringToFunctionMap = pgfluamathfunctions.stringToFunctionMap
+local function function_eval(name, ... )
+ local f = pgfStringToFunctionMap[name]
+ if not f then
+ error("Function '" .. name .. "' is undefined (did not find pgfluamathfunctions."..name .." (looked into pgfluamathfunctions.stringToFunctionMap))")
+ end
+ -- FIXME: validate signature
+ return f(...)
+end
+
+
+local func =
+ (C(identifier_pattern) * space_pattern * openparen_pattern * Exp * (comma_pattern * Exp)^0 * closeparen_pattern) / function_eval;
+
+local functionWithoutArg = identifier_pattern / function_eval
+
+-- this is what can occur as exponent after '^'.
+-- I have the impression that the priorities could be implemented in a better way than this... but it seems to work.
+local pow_exponent =
+ -- allows 2^-4, 2^1e4, 2^2
+ -- FIXME : why not 2^1e2 ?
+ Cg(C(integer_or_decimal_pattern)
+ -- 2^pi, 2^multiply(2,2)
+ + Cg(func+functionWithoutArg)
+ -- 2^(2+2)
+ + openparen_pattern * Exp * closeparen_pattern )
+
+local function prefix_eval(op, x)
+ if op == "-" then
+ return pgfluamathfunctions.neg(x)
+ elseif op == "!" then
+ return pgfluamathfunctions.notPGF(x)
+ else
+ error("This function must not be invoked for operator "..op)
+ end
+end
+
+
+local prefix_operator = C( S"-!" )
+local prefix_operator_pattern = (prefix_operator * space_pattern * Cg(Prefix) ) / prefix_eval
+
+-- apparently, we need to distinguish between <expr> ! and <expr> != <expr2>:
+local postfix_operator = C( S"r!" - P"!=" ) + C(P"^") * space_pattern * pow_exponent
+
+pgfluamathfunctions.functionMustBeEvaluatedInTeX = function()
+ error("The function in this context cannot be evaluated by LUA because it depends on TeX macros.")
+end
+
+local ternary_eval = pgfluamathfunctions.ifthenelse
+
+local factorial_eval = pgfluamathfunctions.factorial
+local deg = pgfluamathfunctions.deg
+local pow_eval = pgfluamathfunctions.pow
+
+-- @param prefix the argument before the postfix operator.
+-- @param op either nil or the postfix operator
+-- @param arg either nil or the (mandatory) argument for 'op'
+local function postfix_eval(prefix, op, arg)
+ local result
+ if op == nil then
+ result = prefix
+ elseif op == "r" then
+ if arg then error("parser setup error: expected nil argument") end
+ result = deg(prefix)
+ elseif op == "!" then
+ if arg then error("parser setup error: expected nil argument") end
+ result = factorial_eval(prefix)
+ elseif op == "^" then
+ if not arg then error("parser setup error: ^ with its argument") end
+ result = pow_eval(prefix, arg)
+ else
+ error("Parser setup error: " .. tostring(op) .. " unexpected in this context")
+ end
+ return result
+end
+
+local function equality_eval(v1, op, v2)
+ local fct
+ if (op == "==") then fct = pgfluamathfunctions.equal
+ elseif (op == "!=") then fct = pgfluamathfunctions.notequal
+ else
+ error("This function must not be invoked for operator "..op)
+ end
+ return fct(v1,v2)
+end
+local function relational_eval(v1, op, v2)
+ local fct
+ if (op == "<") then fct = pgfluamathfunctions.less
+ elseif (op == ">") then fct = pgfluamathfunctions.greater
+ elseif (op == ">=") then fct = pgfluamathfunctions.notless
+ elseif (op == "<=") then fct = pgfluamathfunctions.notgreater
+ else
+ error("This function must not be invoked for operator "..op)
+ end
+ return fct(v1,v2)
+end
+
+-- @return either the box property or nil
+-- @param cs "wd", "ht", or "dp"
+-- @param intSuffix some integer
+local function get_tex_box(cs, intSuffix)
+ -- assume get_tex_box is only called when a dimension is required.
+ local result
+ pgfluamathparser.units_declared = true
+ local box =tex.box[tonumber(intSuffix)]
+ if not box then error("There is no box " .. intSuffix) end
+ if cs == "wd" then
+ result = box.width / 65536
+ elseif cs == "ht" then
+ result = box.height / 65536
+ elseif cs == "dp" then
+ result = box.depth / 65536
+ else
+ result = nil
+ end
+ return result
+end
+
+
+local function controlsequence_eval(cs, intSuffix)
+ local result
+ if intSuffix and #intSuffix >0 then
+ if cs == "count" then
+ result= pgfluamathparser.get_tex_count(intSuffix)
+ elseif cs == "dimen" then
+ result= pgfluamathparser.get_tex_dimen(intSuffix)
+ else
+ result = get_tex_box(cs,intSuffix)
+ if not result then
+ -- this can happen - we cannot expand \chardef'ed boxes here.
+ -- this will be done by the TeX part
+ error('I do not know/support the TeX register "\\' .. cs .. '"')
+ end
+ end
+ else
+ result = pgfluamathparser.get_tex_register(cs)
+ end
+ return result
+end
+
+pgfluamathparser.units_declared = false
+function pgfluamathparser.get_tex_register(register)
+ -- register is a string which could be a count or a dimen.
+ if pcall(tex.getcount, register) then
+ return tex.count[register]
+ elseif pcall(tex.getdimen, register) then
+ pgfluamathparser.units_declared = true
+ return tex.dimen[register] / 65536 -- return in points.
+ else
+ error('I do not know the TeX register "' .. register .. '"')
+ return nil
+ end
+end
+
+function pgfluamathparser.get_tex_count(count)
+ -- count is expected to be a number
+ return tex.count[tonumber(count)]
+end
+
+function pgfluamathparser.get_tex_dimen(dimen)
+ -- dimen is expected to be a number
+ pgfluamathparser.units_declared = true
+ return tex.dimen[tonumber(dimen)] / 65536
+end
+
+function pgfluamathparser.get_tex_sp(dimension)
+ -- dimension should be a string
+ pgfluamathparser.units_declared = true
+ return tex.sp(dimension) / 65536
+end
+
+
+local initialRule = V"initial"
+
+local Summand = V"Summand"
+local Relational = V"Relational"
+local Equality = V"Equality"
+local LogicalOr = V"LogicalOr"
+local LogicalAnd = V"LogicalAnd"
+
+local pgftonumber = pgfluamathfunctions.tonumber
+local tonumber_withunit = pgfluamathparser.get_tex_sp
+local function number_optional_units_eval(x, unit)
+ if not unit then
+ return pgftonumber(x)
+ else
+ return tonumber_withunit(x)
+ end
+end
+
+-- @param scale the number.
+-- @param controlsequence either nil in which case just the number must be returned or a control sequence
+-- @see controlsequence_eval
+local function scaled_controlsequence_eval(scale, controlsequence, intSuffix)
+ if controlsequence==nil then
+ return scale
+ else
+ return scale * controlsequence_eval(controlsequence, intSuffix)
+ end
+end
+
+-- Grammar
+--
+-- for me:
+-- - use '/' to evaluate all expressions which contain a _constant_ number of captures.
+-- - use Cf to evaluate expressions which contain a _dynamic_ number of captures
+--
+-- see unittest_luamathparser.tex for tons of examples
+local G = P{ "initialRule",
+ initialRule = space_pattern* Exp * -1;
+ -- ternary operator (or chained ternary operators):
+ -- FIXME : is this chaining a good idea!?
+ Exp = Cf( LogicalOr * Cg(P"?" * space_pattern * LogicalOr * P":" *space_pattern * LogicalOr )^0, ternary_eval) ;
+ LogicalOr = Cf(LogicalAnd * (P"||" * space_pattern * LogicalAnd)^0, pgfluamathfunctions.orPGF);
+ LogicalAnd = Cf(Equality * (P"&&" * space_pattern * Equality)^0, pgfluamathfunctions.andPGF);
+ Equality = Cf(Relational * Cg(EqualityOp * Relational)^0, equality_eval);
+ Relational = Cf(Summand * Cg(RelationalOp * Summand)^0, relational_eval);
+ Summand = Cf(Term * Cg(TermOp * Term)^0, eval) ;
+ Term = Cf(Prefix * Cg(FactorOp * Prefix)^0, eval);
+ Prefix = prefix_operator_pattern + Postfix;
+ -- this calls 'postfix_eval' with nil arguments if it is no postfix operation.. but that does not hurt (right?)
+ Postfix = Factor * (postfix_operator * space_pattern)^-1 / postfix_eval;
+ Factor =
+ (
+ number_pattern / number_optional_units_eval *
+ -- this construction will evaluate number_pattern with 'number_optional_units_eval' FIRST.
+ -- also accept '0.5 \pgf@x' here:
+ space_pattern *controlsequence_pattern^-1 / scaled_controlsequence_eval
+ + func
+ + functionWithoutArg
+ + openparen_pattern * Exp * closeparen_pattern
+ + controlsequence_pattern / controlsequence_eval
+ ) *space_pattern
+ ;
+}
+
+-- does not reset units_declared.
+local function pgfmathparseinternal(str)
+ local result = match(G,str)
+ if result == nil then
+ error("The string '" .. str .. "' is no valid PGF math expression. Please check for syntax errors.")
+ end
+ return result
+end
+
+
+-- This is the math parser function in this module.
+--
+-- @param str a string like "1+1" which is accepted by the PGF math language
+-- @return the result of the expression.
+--
+-- Throws an error if the string is no valid expression.
+function pgfluamathparser.pgfmathparse(str)
+ pgfluamathparser.units_declared = false
+
+ return pgfmathparseinternal(str)
+end
+
+local pgfmathparse = pgfluamathparser.pgfmathparse
+local tostringfixed = pgfluamathfunctions.tostringfixed
+local tostringfpu = pgfluamathfunctions.toTeXstring
+
+local tmpFunctionArgumentPrefix = "tmpVar"
+local stackOfLocalFunctions = {}
+
+-- This is a backend for PGF's 'declare function'.
+-- \tikzset{declare function={mu(\x,\i)=\x^\i;}}
+-- will boil down to
+-- pgfluamathparser.declareExpressionFunction("mu", 2, "#1^#2")
+--
+-- The local function will be pushed on a stack of known local functions and is
+-- available until popLocalExpressionFunction() is called. TeX will call this using
+-- \aftergroup.
+--
+-- @param name the name of the new function
+-- @param numArgs the number of arguments
+-- @param expression an expression containing #1, ... #n where n is numArgs
+--
+-- ATTENTION: local functions behave DIFFERENTLY in LUA!
+-- In LUA, local variables are not expanded whereas TeX expands them.
+-- The difference is
+--
+-- declare function={mu1(\x,\i)=\x^\i;}
+-- \pgfmathparse{mu1(-5,2)} --> -25
+-- \pgfluamathparse{mu1(-5,2)} --> 25
+--
+-- x = -5
+-- \pgfmathparse{mu1(x,2)} --> 25
+-- \pgfluamathparse{mu1(x,2)} --> 25
+--
+-- In an early prototype, I simulated TeX's expansion to fix the first case (successfully).
+-- BUT: that "simulated expansion" broke the second case because LUA will evaluate "x" and hand -5 to the local function.
+-- I decided to keep it as is. Perhaps we should fix PGF's expansion approach in TeX (which is ugly anyway)
+function pgfluamathparser.pushLocalExpressionFunction(name, numArgs, expression)
+ -- now we have "tmpVar1^tmpVar2" instead of "#1^#2"
+ local normalizedExpr = expression:gsub("#", tmpFunctionArgumentPrefix)
+ local restores = {}
+ local tmpVars = {}
+ for i=1,numArgs do
+ local tmpVar = tmpFunctionArgumentPrefix .. tostring(i)
+ tmpVars[i] = tmpVar
+ end
+
+ local newFunction = function(...)
+ local args = table.pack(...)
+
+ -- define "tmpVar1" ... "tmpVarN" to return args[i].
+ -- Of course, we need to restore "tmpVar<i>" after we return!
+ for i=1,numArgs do
+ local tmpVar = tmpVars[i]
+ local value = args[i]
+ restores[i] = pgfStringToFunctionMap[tmpVar]
+ pgfStringToFunctionMap[tmpVar] = function () return value end
+ end
+
+ -- parse our expression.
+
+ -- FIXME : this here is an attempt to mess around with "units_declared".
+ -- It would be better to call pgfmathparse and introduce some
+ -- semaphore to check if pgfmathparse is a nested call-- in this case, it should
+ -- not reset units_declared. But there is no "finally" block and pcall is crap (looses stack trace).
+ local success,result = pcall(pgfmathparseinternal, normalizedExpr)
+
+ -- remove 'tmpVar1', ... from the function table:
+ for i=1,numArgs do
+ local tmpVar = tmpVars[i]
+ pgfStringToFunctionMap[tmpVar] = restores[i]
+ end
+
+ if success==false then error(result) end
+ return result
+ end
+ table.insert(stackOfLocalFunctions, name)
+ pgfStringToFunctionMap[name] = newFunction
+end
+
+function pgfluamathparser.popLocalExpressionFunction()
+ local name = stackOfLocalFunctions[#stackOfLocalFunctions]
+ pgfStringToFunctionMap[name] = nil
+ -- this removes the last element:
+ table.remove(stackOfLocalFunctions)
+end
+
+
+-- A Utility function which simplifies the interaction with the TeX code
+-- @param expression the input expression (string)
+-- @param outputFormatChoice 0 if the result should be a fixed point number, 1 if it should be in FPU format
+-- @param showErrorMessage (boolean) true if any error should be displayed, false if errors should simply result in an invocation of TeX's parser (the default)
+--
+-- it defines \pgfmathresult and \ifpgfmathunitsdeclared
+function pgfluamathparser.texCallParser(expression, outputFormatChoice, showErrorMessage)
+ local success, result
+ if showErrorMessage then
+ result = pgfmathparse(expression)
+ success = true
+ else
+ success, result = pcall(pgfmathparse, expression)
+ end
+
+ if success and result then
+ local result_str
+ if outputFormatChoice == 0 then
+ -- luamath/output format=fixed
+ result_str = tostringfixed(result)
+ else
+ -- luamath/output format=fixed
+ result_str = tostringfpu(result)
+ end
+ tex.sprint("\\def\\pgfmathresult{" .. result_str .. "}")
+ if pgfluamathparser.units_declared then
+ tex.sprint("\\pgfmathunitsdeclaredtrue")
+ else
+ tex.sprint("\\pgfmathunitsdeclaredfalse")
+ end
+ else
+ tex.sprint("\\def\\pgfmathresult{}")
+ tex.sprint("\\pgfmathunitsdeclaredfalse")
+ end
+end
+
+return pgfluamathparser
diff --git a/graphics/pgf/base/tex/generic/libraries/luamath/pgflibraryluamath.code.tex b/graphics/pgf/base/tex/generic/libraries/luamath/pgflibraryluamath.code.tex
new file mode 100644
index 0000000000..cd991dab4c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/luamath/pgflibraryluamath.code.tex
@@ -0,0 +1,558 @@
+% Copyright 2019 by Christophe Jorssen and Mark Wibrow
+% Copyright 2019 by Christian Feuersänger
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% $Id$
+%
+%
+% This is a library for a LUA math parser and LUA math operations.
+% Advantage compared to its TeX pendant: it is FASTER and has HIGHER
+% ACCURACY.
+% Disadvantage: any function declared by means of
+% \pgfmathdeclarefunction is NOT automatically transported to the LUA
+% side (at the time of this writing).
+% LUA functions need to be defined by means of LUA code
+%
+% function pgfluamathfunctions.myoperation(a,b)
+% return a*2*b
+% end
+%
+% this will automatically set up 'myoperation' for use in
+% \pgfluamathparse{myoperation(4,2)}
+%
+% The library has TWO use-cases which are more or less distinct: one
+% is to use LUA for all math function, but not for math expression
+% parsing -- this was still under control of the TeX math parser.
+% This approach works like the 'fpu' library.
+%
+% The second approach is to use LUA to parse all math expressions -
+% but if someone calls \pgfmathadd@{1}{2}, it would use the TeX
+% command. This approach is relatively lightweight because it does not
+% need to substitute all \pgfmath* macros.
+%
+% One can mix both modes.
+
+% *******************************************************************
+% Some luatex stuff. Should be put elsewhere (e.g. in
+% pgfutil-luatex-engine).
+
+\edef\pgfliblua@oldcatcodedoublequote{\the\catcode`\"}%
+\catcode`\"=12
+
+% We assume luatex version > 0.39:
+% - \directlua <general text> will work
+% - \directlua is the only luatex primitive that we can assume
+% accessible without being prefixed by the format via
+% tex.enableprimitives.
+% Ideas taken from the ifluatex package (Heiko Oberdiek)
+\let\pgfutil@ifluatex\iffalse
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+\else
+ \expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname
+ \csname iftrue\endcsname
+\fi
+
+\pgfutil@ifluatex
+ \let\pgfutil@directlua\directlua
+ \pgfutil@directlua{%
+ tex.enableprimitives('pgfutil@',{'luaescapestring'})}%
+\else
+ \def\pgfutil@directlua#1{}%
+ \def\pgfutil@luaescapestring#1{}%
+\fi
+
+\pgfutil@directlua{%
+ pgfluamathfunctions = require("pgf.luamath.functions")
+ pgfluamathparser = require("pgf.luamath.parser")}%
+
+
+% Patch some configuration macros such that the modifications are
+% available in LUA as well:
+\pgfkeys{
+ /pgf/trig format/deg/.add code={}{\directlua{pgfluamathfunctions.setTrigFormat("deg")}\aftergroup\pgfmath@settrigformat},
+ /pgf/trig format/rad/.add code={}{\directlua{pgfluamathfunctions.setTrigFormat("rad")}\aftergroup\pgfmath@settrigformat},
+}%
+% ... and reactivate the key:
+\pgfmathiftrigonometricusesdeg{%
+ \pgfkeys{/pgf/trig format/deg}%
+}{%
+ \pgfkeys{/pgf/trig format/rad}%
+}%
+
+% re-activates the current trig format. This is important after a TeX
+% group has been closed.
+\def\pgfmath@settrigformat{%
+ \pgfmathiftrigonometricusesdeg{%
+ \directlua{pgfluamathfunctions.setTrigFormat("deg")}%
+ }{%
+ \directlua{pgfluamathfunctions.setTrigFormat("rad")}%
+ }%
+}%
+
+\let\pgfmathsetseed@pgfbasic = \pgfmathsetseed
+\def\pgfmathsetseed#1{%
+ \pgfmathsetseed@pgfbasic{#1}%
+ \directlua{pgfluamathfunctions.setRandomSeed(pgfluamathfunctions.tonumber("\pgfmathresult"))}%
+}%
+
+% Patch 'declare function' such that it communicates the function
+% directly to LUA.
+\let\pgfmathnotifynewdeclarefunction@orig=\pgfmathnotifynewdeclarefunction
+\def\pgfmathnotifynewdeclarefunction#1#2#3{%
+ \pgfmathnotifynewdeclarefunction@orig{#1}{#2}{#3}%
+ %
+ % we have to check if '#3' contains control sequences.
+ % this is highly tricky as it may contain '#1'...
+ \begingroup
+ \toks0={#3}%
+ \xdef\pgf@marshal@glob{\the\toks0 }%
+ \endgroup
+ \pgfutil@command@to@string\pgf@marshal@glob\pgf@marshal
+ \expandafter\pgfutilifcontainsmacro\expandafter{\pgf@marshal}{%
+ \def\pgf@temp{1}%
+ }{%
+ \def\pgf@temp{0}%
+ }%
+ \if1\pgf@temp
+ % let lua produce an error when evaluating this function -- we cannot possibly expand the macro to its current state:
+ \directlua{pgfluamathparser.pushLocalExpressionFunction(%
+ "\pgfutil@luaescapestring{#1}",%
+ #2,%
+ "functionMustBeEvaluatedInTeX")}%
+ \else
+ \directlua{pgfluamathparser.pushLocalExpressionFunction(%
+ "\pgfutil@luaescapestring{#1}",%
+ #2,%
+ "\pgfutil@luaescapestring{#3}")}%
+ \fi
+ %
+ % ensure that the local function is removed at the end of the
+ % scope. To this end, we maintain a stack on the LUA side.
+ \aftergroup\pgfluamathparse@pop@local@function
+}%
+
+\def\pgfluamathparse@pop@local@function{%
+ \directlua{pgfluamathparser.popLocalExpressionFunction()}%
+}%
+
+% End of luatex stuff
+% *******************************************************************
+
+% Loading part: based on fpu library
+
+
+% if LUA failed to evaluate the expression, it will be evaluated in
+% TeX as fallback. This boolean defines if the error message shall be
+% shown or suppressed. The default is to suppress it and show any
+% resulting TeX errors.
+%
+% If LUA fails \pgfmathresult will be empty.
+%
+% This is actually only for debugging; it will be set implicitly when
+% activating/deactivating TeX fallback.
+\newif\ifpgfluamathshowerrormessage
+
+% Defines what happens if LUA failed to evaluate the expression: if
+% this is true, the TeX parser will be invoked as fallback.
+%
+% This happens
+% - for \chardef'ed boxes for which LUA lacks evaluation capabilities
+% - if the expression includes some function which is unavailable in
+% LUA (defined only in TeX)
+% - some special cases which simply haven't been added to the LUA
+% parser (yet).
+% At the time of this writing, this includes
+% -- arrays created via '{}' and indexed with '[]'
+% -- strings with "<str>"
+% -- 'scalar' function
+% -- hex/octal/binary input
+\newif\ifpgfluamathenableTeXfallback
+
+\newif\ifpgfluamathcomputationactive
+\newif\ifpgfluamathparseractive
+
+\def\pgfluamath@makecomputationactive{%
+ \ifpgfluamathcomputationactive
+ \else
+ \pgfluamath@checkuninstallcmd%
+ \pgfluamath@install%
+ \pgfluamathcomputationactivetrue
+ \fi}%
+
+\def\pgfluamath@makecomputationinactive{%
+ \ifpgfluamathcomputationactive
+ \pgfluamath@uninstall%
+ \pgfluamathcomputationactivefalse
+ \fi}%
+
+\let\pgfluamath@pgfmathparse\pgfmathparse
+\def\pgfluamath@makeparseractive{%
+ \ifpgfluamathparseractive
+ \else
+ \let\pgfluamath@pgfmathparse\pgfmathparse
+ \let\pgfmathparse\pgfluamathparse
+ \let\pgfmath@iftrue=\pgfmathluamath@iftrue
+ \pgfluamathparseractivetrue
+ \fi}%
+
+\let\pgfmath@iftrue@basic=\pgfmath@iftrue
+
+\def\pgfluamath@makeparserinactive{%
+ \ifpgfluamathparseractive
+ \let\pgfmathparse\pgfluamath@pgfmathparse
+ \let\pgfmath@iftrue=\pgfmath@iftrue@basic
+ \pgfluamathparseractivefalse
+ \fi}%
+
+\pgfqkeys{/pgf}{%
+ % Enable lua-side computation of \pgfmathresult
+ % (will be deactivated after the current TeX group)
+ luamath/.is choice,
+ luamath/only computation/.code={%
+ \pgfutil@ifluatex
+ \pgfluamath@makecomputationactive
+ \pgfluamath@makeparserinactive
+ \else
+ \pgfmath@error{Sorry, you need the luaTeX engine to use the
+ luamath library}{}%
+ \fi},
+ luamath/parser and computation/.code={%
+ \pgfutil@ifluatex
+ \pgfluamath@makecomputationactive
+ \pgfluamath@makeparseractive
+ \else
+ \pgfmath@error{Sorry, you need the luaTeX engine to use the
+ luamath library}{}%
+ \fi},
+ luamath/off/.code={%
+ \pgfluamath@makecomputationinactive
+ \pgfluamath@makeparserinactive},
+ luamath/.default=only computation,
+ %
+ % activates ONLY the parser. This is fast and does not replace the
+ % \pgfmath* functions.
+ % @see |parser and computation| which also allows to write
+ % \pgfmathadd{1}{2} to call LUA
+ luamath/parser/.code={%
+ \pgfutil@ifluatex
+ \pgfluamath@makeparseractive
+ \else
+ \pgfmath@error{Sorry, you need the luaTeX engine to use the
+ luamath library}{}%
+ \fi
+ },
+ luamath/output format/.is choice,
+ luamath/output format/fixed/.code= {\def\pgfluamath@outputformat@choice{0}},
+ % returns results for use in the FPU
+ luamath/output format/float/.code= {\def\pgfluamath@outputformat@choice{1}},
+ luamath/output format/fixed,
+ % this is merely useful for debugging purposes, I guess.
+ luamath/show error message/.is if=pgfluamathshowerrormessage,
+ luamath/enable TeX fallback/.is choice,
+ luamath/enable TeX fallback/true/.code={\pgfluamathenableTeXfallbacktrue\pgfluamathshowerrormessagefalse},
+ luamath/enable TeX fallback/false/.code={\pgfluamathenableTeXfallbackfalse\pgfluamathshowerrormessagetrue},
+ luamath/enable TeX fallback/.default=true,
+ luamath/enable TeX fallback=true,
+}%
+
+\def\pgfluamath@uninstall@appendcmd#1{%
+ \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{%
+ \pgfluamath@uninstall #1}}%
+
+% If the uninstall command is already assembled, it will skip the
+% uninstall assemblation.
+\def\pgfluamath@checkuninstallcmd{%
+ \pgfutil@ifundefined{pgfluamath@uninstall}{%
+ \global\let\pgfluamath@uninstall=\pgfutil@empty
+ }{%
+ % We already HAVE an uninstall command (prepared globally).
+ % So: don't waste time assembling one!
+ \def\pgfluamath@uninstall@appendcmd##1{}%
+ \def\pgfluamath@prepareuninstallcmd##1{}%
+ }%
+}%
+
+% This assembles an uninstall command globally ON FIRST USAGE.
+% See \pgfmathfloat@plots@checkuninstallcmd
+\def\pgfluamath@prepareuninstallcmd#1{%
+ \expandafter\global\expandafter\let
+ \csname pgfluamath@backup@\string#1\endcsname=#1%
+ \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{%
+ \pgfluamath@uninstall
+ \expandafter\let\expandafter#1\csname pgfluamath@backup@\string#1\endcsname}%
+}%
+
+\def\pgfluamath@install@function#1=#2{%
+ \pgfluamath@prepareuninstallcmd{#1}%
+ \let#1=#2%
+}%
+
+\def\pgfluamath@install{%
+ \pgfluamath@install@function\pgfmathadd@=\pgfluamathadd@%
+ \pgfluamath@install@function\pgfmathsubtract@=\pgfluamathsubtract@%
+ \pgfluamath@install@function\pgfmathneg@=\pgfluamathneg@%
+ \pgfluamath@install@function\pgfmathmultiply@=\pgfluamathmultiply@%
+ \pgfluamath@install@function\pgfmath@iftrue=\pgfmathluamath@iftrue%
+ \pgfluamath@install@function\pgfmathdivide@=\pgfluamathdivide@%
+ % \pgfluamath@install@function\pgfmathdiv@=\pgfluamathdiv@%
+ \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@%
+ \pgfluamath@install@function\pgfmathsqrt@=\pgfluamathsqrt@%
+ % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@%
+ \pgfluamath@install@function\pgfmathe@=\pgfluamathe@%
+ \pgfluamath@install@function\pgfmathexp@=\pgfluamathexp@%
+ \pgfluamath@install@function\pgfmathln@=\pgfluamathln@%
+ \pgfluamath@install@function\pgfmathlogten@=\pgfluamathlogten@%
+ % \pgfluamath@install@function\pgfmathlogtwo@=\pgfluamathlogtwo@%
+ \pgfluamath@install@function\pgfmathabs@=\pgfluamathabs@%
+ \pgfluamath@install@function\pgfmathmod@=\pgfluamathmod@%
+ \pgfluamath@install@function\pgfmathMod@=\pgfluamathMod@%
+ \pgfluamath@install@function\pgfmathround@=\pgfluamathround@%
+ \pgfluamath@install@function\pgfmathfloor@=\pgfluamathfloor@%
+ \pgfluamath@install@function\pgfmathceil@=\pgfluamathceil@%
+ % \pgfluamath@install@function\pgfmathint@=\pgfluamathint@%
+ % \pgfluamath@install@function\pgfmathfrac@=\pgfluamathfrac@%
+ % \pgfluamath@install@function\pgfmathreal@=\pgfluamathreal@%
+ \pgfluamath@install@function\pgfmathgcd@=\pgfluamathgcd@%
+ \pgfluamath@install@function\pgfmathisprime@=\pgfluamathisprime@%
+ \pgfluamath@install@function\pgfmathpi@=\pgfluamathpi@%
+ \pgfluamath@install@function\pgfmathrad@=\pgfluamathrad@%
+ \pgfluamath@install@function\pgfmathdeg@=\pgfluamathdeg@%
+ \pgfluamath@install@function\pgfmathsin@=\pgfluamathsin@%
+ \pgfluamath@install@function\pgfmathcos@=\pgfluamathcos@%
+ \pgfluamath@install@function\pgfmathtan@=\pgfluamathtan@%
+ \pgfluamath@install@function\pgfmathsec@=\pgfluamathsec@%
+ \pgfluamath@install@function\pgfmathcosec@=\pgfluamathcosec@%
+ \pgfluamath@install@function\pgfmathcot@=\pgfluamathcot@%
+ \pgfluamath@install@function\pgfmathasin@=\pgfluamathasin@%
+ \pgfluamath@install@function\pgfmathacos@=\pgfluamathacos@%
+ \pgfluamath@install@function\pgfmathatan@=\pgfluamathatan@%
+ \pgfluamath@install@function\pgfmathatantwo@=\pgfluamathatantwo@%
+ \pgfluamath@install@function\pgfmathmax@=\pgfluamathmax@%
+ \pgfluamath@install@function\pgfmathmin@=\pgfluamathmin@%
+ % \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@%
+ % \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@%
+ % \pgfluamath@install@function\pgfmathe@=\pgfluamathe@%
+ % \pgfluamath@install@function\pgfmathe=\pgfluamathe@%
+ % \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@%
+ % \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@%
+ % \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@%
+ % \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@%
+ % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@
+ \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@
+ \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@
+ \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@
+ \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@
+ % \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@
+ % \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@
+ % \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@
+ % \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@
+ % \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@
+ % \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@
+ % \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@
+ % \pgfluamath@install@function\pgfmathand@=\pgfluamathand@
+ % \pgfluamath@install@function\pgfmathor@=\pgfluamathor@
+ % \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@
+ % \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@
+ % \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@
+ % \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@
+ % \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@
+ % \pgfluamath@install@function@unimplemented{ceil}%
+ % \pgfluamath@install@function@unimplemented{frac}%
+ % \pgfluamath@install@function@unimplemented{log2}%
+ % \pgfluamath@install@function@unimplemented{log10}%
+ % \pgfluamath@install@function@unimplemented{equalto}%
+ % \pgfluamath@install@function@unimplemented{random}%
+ % \pgfluamath@install@function@unimplemented{setseed}%
+ % \pgfluamath@install@function@unimplemented{Mod}%
+ % \pgfluamath@install@function@unimplemented{real}%
+ % \pgfluamath@install@function@unimplemented{notequal}%
+ \pgfluamath@install@function\pgfmathreciprocal=\pgfluamathreciprocal%
+ \pgfluamath@install@function\pgfpointnormalised=\pgfluamathpointnormalised
+}%
+
+\def\pgfluamathgetresult#1{%
+ \edef\pgfmathresult{\pgfutil@directlua{tex.print(-1,#1)}}}%
+
+\def\pgfmathluamath@iftrue{%
+ \if 0\pgfluamath@outputformat@choice
+ \let\pgfmathluamath@@iftrue@v=\pgfluamathone
+ \else
+ \let\pgfmathluamath@@iftrue@v=\pgfluamathfloatone
+ \fi
+ \pgfmathluamath@iftrue@
+}%
+\def\pgfluamathone{1.0}%
+\def\pgfluamathfloatone{1Y1.0e+00]}%
+\def\pgfmathluamath@iftrue@#1#2{%
+ \ifx\pgfmathresult\pgfmathluamath@@iftrue@v
+ \def\pgfmath@next{#1}%
+ \else
+ \def\pgfmath@next{#2}%
+ \fi
+ \pgfmath@next
+}%
+
+\def\pgfluamathpi@{%
+ \pgfluamathgetresult{pgfluamathfunctions.pi()}}%
+\def\pgfluamathe@{%
+ \pgfluamathgetresult{pgfluamathfunctions.e()}}%
+\def\pgfluamathadd@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.add(#1,#2)}}%
+\def\pgfluamathsubtract@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.subtract(#1,#2)}}%
+\def\pgfluamathneg@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.neg(#1)}}%
+\def\pgfluamathmultiply@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.multiply(#1,#2)}}%
+\def\pgfluamathdivide@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.divide(#1,#2)}}%
+\def\pgfluamathabs@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.abs(#1)}}%
+\def\pgfluamathround@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.round(#1)}}%
+\def\pgfluamathfloor@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.floor(#1)}}%
+\def\pgfluamathceil@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.ceil(#1)}}%
+\def\pgfluamathgcd@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.gcd(#1,#2)}}%
+\def\pgfluamathisprime@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.isprime(#1)}}%
+\def\pgfluamathmax@#1{%
+ \pgfluamathgetresult{%
+ math.max(pgfluamathfunctions.split_braces_to_explist("#1"))}}%
+\def\pgfluamathmin@#1{%
+ \pgfluamathgetresult{%
+ math.min(pgfluamathfunctions.split_braces_to_explist("#1"))}}%
+\def\pgfluamathsin@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.Sin(#1)}}%
+\def\pgfluamathcos@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.Cos(#1)}}%
+\def\pgfluamathtan@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.Tan(#1)}}%
+\def\pgfluamathmod@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.mod(#1,#2)}}%
+\def\pgfluamathMod@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.Mod(#1,#2)}}%
+\def\pgfluamathrad@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.rad(#1)}}%
+\def\pgfluamathdeg@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.deg(#1)}}%
+\def\pgfluamathatan@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.aTan(#1)}}%
+\def\pgfluamathatantwo@#1#2{%
+ \pgfluamathgetresult{pgfluamathfunctions.aTan2(#1,#2)}}%
+\def\pgfluamathasin@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.aSin(#1)}}%
+\def\pgfluamathacos@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.aCos(#1)}}%
+\def\pgfluamathcot@#1{%
+ \pgfluamathgetresult{1/pgfluamathfunctions.Tan(#1)}}%
+\def\pgfluamathsec@#1{%
+ \pgfluamathgetresult{1/pgfluamathfunctions.Cos(#1)}}%
+\def\pgfluamathcosec@#1{%
+ \pgfluamathgetresult{1/pgfluamathfunctions.Sin(#1)}}%
+\def\pgfluamathexp@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.exp(#1)}}%
+\def\pgfluamathln@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.log(#1)}}%
+\def\pgfluamathlogten@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.log10(#1)}}%
+\def\pgfluamathsqrt@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.sqrt(#1)}}%
+\def\pgfluamathrnd@{%
+ \pgfluamathgetresult{pgfluamathfunctions.rnd()}}%
+\def\pgfluamathrand@{%
+ \pgfluamathgetresult{pgfluamathfunctions.rand(-1,1)}}%
+\def\pgfluamathfactorial@#1{%
+ \pgfluamathgetresult{pgfluamathfunctions.factorial(#1)}}%
+\def\pgfluamathreciprocal#1{%
+ \pgfluamathgetresult{1/#1}}%
+% \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@%
+% \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@%
+% \pgfluamath@install@function\pgfmathe@=\pgfluamathe@%
+% \pgfluamath@install@function\pgfmathe=\pgfluamathe@%
+% \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@%
+% \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@%
+% \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@%
+% \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@%
+% \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@
+% \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@
+% \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@
+% \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@
+% \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@
+% \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@
+% \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@
+% \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@
+% \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@
+% \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@
+% \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@
+% \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@
+% \pgfluamath@install@function\pgfmathand@=\pgfluamathand@
+% \pgfluamath@install@function\pgfmathor@=\pgfluamathor@
+% \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@
+% \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@
+% \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@
+% \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@
+% \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@
+
+\def\pgfluamathpointnormalised#1{%
+ \pgf@process{#1}%
+ \pgfutil@directlua{%
+ pgfluamathfunctions.pointnormalised(%
+ \pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})}%
+ \ignorespaces}%
+
+% Parser
+
+\newif\ifpgfluamathunitsdeclared
+
+% true if and only if LUA failed to evaluate the expression and the
+% expression was evaluated by means of the TeX parser as fallback.
+%
+% This happens
+% - for \chardef'ed boxes for which LUA lacks evaluation capabilities
+% - if the expression includes some function which is unavailable in
+% LUA (defined only in TeX)
+% - some special cases which simply haven't been added to the LUA
+% parser (yet).
+% At the time of this writing, this includes
+% -- arrays created via '{}' and indexed with '[]'
+% -- strings with "<str>"
+% -- 'scalar' function
+% -- hex/octal/binary input
+\newif\ifpgfluamathusedTeXfallback
+
+% Parses the math expression and defines \pgfmathresult and
+% \ifpgfmathunitsdeclared to contain the result.
+%
+% If \ifpgfluamathparseractive then the result is also assigned to
+% \pgfmathresult. Furthermore, if the expression cannot be evaluated (because LUA does not support
+% it), it will be evaluated by mean of TeX as fallback.
+%
+% @see \ifpgfluamathusedTeXfallback
+% @see \ifpgfluamathshowerrormessage
+\def\pgfluamathparse#1{%
+ \pgfluamathusedTeXfallbackfalse
+ \pgfutil@directlua{pgfluamathparser.texCallParser(
+ "\pgfutil@luaescapestring{#1}",
+ \pgfluamath@outputformat@choice,
+ \ifpgfluamathshowerrormessage true\else false\fi)%
+ }%
+ \ifx\pgfmathresult\pgfutil@empty
+ \ifpgfluamathenableTeXfallback
+ \pgfluamathusedTeXfallbacktrue
+ \pgfluamath@pgfmathparse{#1}%
+ \fi
+ \fi
+}%
+
+\catcode`\"=\pgfliblua@oldcatcodedoublequote
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.code.tex
new file mode 100644
index 0000000000..96216c5f24
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.code.tex
@@ -0,0 +1,936 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryarrows.code.tex}
+
+
+% A square bracket shaped arrow
+
+\pgfarrowsdeclare{square bracket}{square bracket}
+{
+ \pgfutil@tempdima=1pt%
+ \advance\pgfutil@tempdima by1.25\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdima}
+ \pgfarrowsrightextend{+.5\pgflinewidth}
+}
+{
+ \pgfutil@tempdima=2pt%
+ \advance\pgfutil@tempdima by1.5\pgflinewidth%
+ \pgfutil@tempdimb=\pgfutil@tempdima%
+ \advance\pgfutil@tempdimb by\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfsetbuttcap
+ \pgfpathmoveto{\pgfqpoint{-.5\pgfutil@tempdimb}{-1\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-1\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-.5\pgfutil@tempdimb}{\pgfutil@tempdima}}
+ \pgfusepathqstroke
+}%
+\pgfdeclarearrow{name=[-], means=square bracket}%
+
+\pgfarrowsdeclarereversed{]}{[}{[}{]}%
+
+
+% A round bracket shaped arrow
+
+\pgfarrowsdeclare{(}{)}
+{
+ \pgfutil@tempdima=2pt%
+ \advance\pgfutil@tempdima by1.5\pgflinewidth%
+ \pgfutil@tempdimb=0.0625\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+ \pgfutil@tempdimb=0.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=2pt%
+ \advance\pgfutil@tempdima by1.5\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfpathmoveto{\pgfqpoint{-.5\pgfutil@tempdima}{-1\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{.25\pgfutil@tempdima}{-.5\pgfutil@tempdima}}
+ {\pgfqpoint{.25\pgfutil@tempdima}{.5\pgfutil@tempdima}}
+ {\pgfqpoint{-.5\pgfutil@tempdima}{\pgfutil@tempdima}}
+ \pgfusepathqstroke
+}%
+
+\pgfarrowsdeclarereversed{)}{(}{(}{)}%
+
+
+
+
+% A pointed bracket shaped arrow
+
+\pgfarrowsdeclare{angle 90}{angle 90}
+{
+ \pgfutil@tempdima=0.3pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfutil@tempdimb=5.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=.5\pgfutil@tempdima\advance\pgfutil@tempdimb by0.707\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.3pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfqpoint{-5.5\pgfutil@tempdima}{-6\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-5.5\pgfutil@tempdima}{6\pgfutil@tempdima}}
+ \pgfusepathqstroke
+}%
+
+\pgfarrowsdeclarereversed{angle 90 reversed}{angle 90 reversed}{angle 90}{angle 90}%
+
+
+\pgfarrowsdeclare{angle 60}{angle 60}
+{
+ \pgfutil@tempdima=0.3pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfutil@tempdimb=7.29\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=.5\pgfutil@tempdima\advance\pgfutil@tempdimb by\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.3pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{150}{9\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{-150}{9\pgfutil@tempdima}}}
+ \pgfusepathqstroke
+}%
+
+\pgfarrowsdeclarereversed{angle 60 reversed}{angle 60 reversed}{angle 60}{angle 60}%
+
+
+
+\pgfarrowsdeclare{angle 45}{angle 45}
+{
+ \pgfutil@tempdima=0.3pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfutil@tempdimb=8.705\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=.5\pgfutil@tempdima\advance\pgfutil@tempdimb by1.28\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.3pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{157}{10\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{-157}{10\pgfutil@tempdima}}}
+ \pgfusepathqstroke
+}%
+
+\pgfarrowsdeclarereversed{angle 45 reversed}{angle 45 reversed}{angle 45}{angle 45}%
+
+
+
+% A dot shaped arrow
+
+\pgfarrowsdeclare{*}{*}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfutil@tempdimb=7.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=1.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfpathcircle{\pgfqpoint{-3\pgfutil@tempdima}{0pt}}{+4.5\pgfutil@tempdima}
+ \pgfusepathqfillstroke
+}%
+
+
+% An open dot shaped arrow
+
+\pgfarrowsdeclare{o}{o}
+{
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfutil@tempdimb=9\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfpathcircle{\pgfqpoint{4.5\pgfutil@tempdima}{0bp}}{4.5\pgfutil@tempdima}
+ \pgfusepathqstroke
+}%
+
+
+
+% A diamond shaped arrow
+
+\pgfarrowsdeclare{diamond}{diamond}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.275\pgflinewidth%
+ \pgfutil@tempdimb=13\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=1\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.275\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{1\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-6\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-6\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+\pgfarrowsdeclare{open diamond}{open diamond}%{{-.5bp}{14.5bp}}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.275\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdimb=14\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.275\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{14\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{7\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{7\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+% A square shaped arrow
+\newdimen\arrowsize
+\pgfarrowsdeclare{square}{square}
+{
+ \arrowsize=0.4pt
+ \advance\arrowsize by.275\pgflinewidth%
+ \pgfarrowsleftextend{-7\arrowsize-.5\pgflinewidth}
+ \advance\arrowsize by.5\pgflinewidth
+ \pgfarrowsrightextend{+\arrowsize}
+}
+{
+ \arrowsize=0.4pt
+ \advance\arrowsize by.275\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{1\arrowsize}{4\arrowsize}}
+ \pgfpathlineto{\pgfqpoint{-7\arrowsize}{4\arrowsize}}
+ \pgfpathlineto{\pgfqpoint{-7\arrowsize}{-4\arrowsize}}
+ \pgfpathlineto{\pgfqpoint{1\arrowsize}{-4\arrowsize}}
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+% A open square shaped arrow
+
+\pgfarrowsdeclare{open square}{open square}%{{-.5bp}{8.5bp}}
+{
+ \arrowsize=0.4pt
+ \advance\arrowsize by.275\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \advance\arrowsize by7\arrowsize
+ \advance\arrowsize by.5\pgflinewidth
+ \pgfarrowsrightextend{+\arrowsize}
+}
+{
+ \arrowsize=0.4pt
+ \advance\arrowsize by.275\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{8\arrowsize}{4\arrowsize}}
+ \pgfpathlineto{\pgfqpoint{0\arrowsize}{4\arrowsize}}
+ \pgfpathlineto{\pgfqpoint{0\arrowsize}{-4\arrowsize}}
+ \pgfpathlineto{\pgfqpoint{8\arrowsize}{-4\arrowsize}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+
+% A triangle shaped arrow
+
+\pgfarrowsdeclare{triangle 90}{triangle 90}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfutil@tempdimb=5.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=.5\pgfutil@tempdima\advance\pgfutil@tempdimb by0.707\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfqpoint{-5.5\pgfutil@tempdima}{-6\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-5.5\pgfutil@tempdima}{6\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+\pgfarrowsdeclarereversed{triangle 90 reversed}{triangle 90 reversed}{triangle 90}{triangle 90}%
+
+
+\pgfarrowsdeclare{triangle 60}{triangle 60}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfutil@tempdimb=7.29\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=.5\pgfutil@tempdima\advance\pgfutil@tempdimb by\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{150}{9\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{-150}{9\pgfutil@tempdima}}}
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+\pgfarrowsdeclarereversed{triangle 60 reversed}{triangle 60 reversed}{triangle 60}{triangle 60}%
+
+
+
+
+\pgfarrowsdeclare{triangle 45}{triangle 45}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfutil@tempdimb=8.705\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=.5\pgfutil@tempdima\advance\pgfutil@tempdimb by1.28\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{157}{10\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{0.5\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{-157}{10\pgfutil@tempdima}}}
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+\pgfarrowsdeclarereversed{triangle 45 reversed}{triangle 45 reversed}{triangle 45}{triangle 45}%
+
+
+
+
+\pgfarrowsdeclare{open triangle 90}{open triangle 90}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdimb=6\pgfutil@tempdima\advance\pgfutil@tempdimb by0.707\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{-6\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{6\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0\pgfutil@tempdima}{6\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+\pgfarrowsdeclare{open triangle 90 reversed}{open triangle 90 reversed}%
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfarrowsleftextend{+-.707\pgflinewidth}
+ \pgfutil@tempdimb=6\pgfutil@tempdima\advance\pgfutil@tempdimb by0.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfqpoint{6\pgfutil@tempdima}{-6\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{6\pgfutil@tempdima}{6\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+
+\pgfarrowsdeclare{open triangle 60}{open triangle 60}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdimb=7.794\pgfutil@tempdima\advance\pgfutil@tempdimb by\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{7.794\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{150}{9\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfqpoint{7.794\pgfutil@tempdima}{0pt}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{7.794\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{-150}{9\pgfutil@tempdima}}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+
+\pgfarrowsdeclare{open triangle 60 reversed}{open triangle 60 reversed}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgflinewidth}
+ \pgfutil@tempdimb=7.794\pgfutil@tempdima\advance\pgfutil@tempdimb by0.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfqpointpolar{30}{9\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfpointorigin}
+ \pgfpathlineto{\pgfqpointpolar{-30}{9\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+
+\pgfarrowsdeclare{open triangle 45}{open triangle 45}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdimb=9.205\pgfutil@tempdima\advance\pgfutil@tempdimb by1.28\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{9.205\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{157}{10\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfqpoint{9.205\pgfutil@tempdima}{0pt}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{9.205\pgfutil@tempdima}{0pt}}{\pgfqpointpolar{-157}{10\pgfutil@tempdima}}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+
+\pgfarrowsdeclare{open triangle 45 reversed}{open triangle 45 reversed}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfarrowsleftextend{+-1.28\pgflinewidth}
+ \pgfutil@tempdimb=9.205\pgfutil@tempdima\advance\pgfutil@tempdimb by0.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.5pt%
+ \advance\pgfutil@tempdima by.25\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetmiterjoin
+ \pgfpathmoveto{\pgfqpointpolar{23}{10\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfpointorigin}
+ \pgfpathlineto{\pgfqpointpolar{-23}{10\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+
+% A less fleshy variant of LaTeX's ordinal arrow type
+
+\pgfarrowsdeclare{latex'}{latex'}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfarrowsleftextend{+-4\pgfutil@tempdima}
+ \pgfarrowsrightextend{+6\pgfutil@tempdima}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfpathmoveto{\pgfqpoint{6\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{3.5\pgfutil@tempdima}{.5\pgfutil@tempdima}}
+ {\pgfqpoint{-1\pgfutil@tempdima}{1.5\pgfutil@tempdima}}
+ {\pgfqpoint{-4\pgfutil@tempdima}{3.75\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-1.5\pgfutil@tempdima}{1\pgfutil@tempdima}}
+ {\pgfqpoint{-1.5\pgfutil@tempdima}{-1\pgfutil@tempdima}}
+ {\pgfqpoint{-4\pgfutil@tempdima}{-3.75\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-1\pgfutil@tempdima}{-1.5\pgfutil@tempdima}}
+ {\pgfqpoint{3.5\pgfutil@tempdima}{-.5\pgfutil@tempdima}}
+ {\pgfqpoint{6\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfill
+}%
+
+\pgfarrowsdeclarereversed{latex' reversed}{latex' reversed}{latex'}{latex'}%
+
+
+% A rounded variant of the stealth arrow
+
+\pgfarrowsdeclare{stealth'}{stealth'}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfutil@tempdimb=6\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth%
+ \pgfarrowsleftextend{+-\pgfutil@tempdimb}
+ \pgfutil@tempdimb=2\pgfutil@tempdima\advance\pgfutil@tempdimb by0.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{2\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.5\pgfutil@tempdima}{.5\pgfutil@tempdima}}
+ {\pgfqpoint{-3\pgfutil@tempdima}{1.5\pgfutil@tempdima}}
+ {\pgfqpoint{-6\pgfutil@tempdima}{3.25\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-3\pgfutil@tempdima}{1\pgfutil@tempdima}}
+ {\pgfqpoint{-3\pgfutil@tempdima}{-1\pgfutil@tempdima}}
+ {\pgfqpoint{-6\pgfutil@tempdima}{-3.25\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-3\pgfutil@tempdima}{-1.5\pgfutil@tempdima}}
+ {\pgfqpoint{-.5\pgfutil@tempdima}{-.5\pgfutil@tempdima}}
+ {\pgfqpoint{2\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+\pgfarrowsdeclarereversed{stealth' reversed}{stealth' reversed}{stealth'}{stealth'}%
+
+
+
+% The two half of the $\to$ arrow
+
+\pgfarrowsdeclare{left to}{left to}
+{
+ \pgfutil@tempdima=-0.84pt%
+ \advance\pgfutil@tempdima by-1.3\pgflinewidth%
+ \pgfutil@tempdimb=0.21pt%
+ \advance\pgfutil@tempdimb by.625\pgflinewidth%
+ \pgfarrowsleftextend{+\pgfutil@tempdima}
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfsetlinewidth{0.8\pgflinewidth}
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{-3\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-2.75\pgfutil@tempdima}{2.5\pgfutil@tempdima}}
+ {\pgfqpoint{0pt}{0.25\pgfutil@tempdima}}
+ {\pgfqpoint{0.75\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfqpoint{0.55\pgfutil@tempdima}{-0.125\pgflinewidth}}
+ {\pgfqpoint{0.5\pgfutil@tempdima}{-0.125\pgflinewidth}}
+ {\pgfqpoint{0.5\pgfutil@tempdima}{-0.125\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-0.125\pgflinewidth}}
+ \pgfusepathqstroke
+}%
+
+
+\pgfarrowsdeclare{right to}{right to}
+{
+ \pgfutil@tempdima=-0.84pt%
+ \advance\pgfutil@tempdima by-1.3\pgflinewidth%
+ \pgfutil@tempdimb=0.21pt%
+ \advance\pgfutil@tempdimb by.625\pgflinewidth%
+ \pgfarrowsleftextend{+\pgfutil@tempdima}
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfsetlinewidth{0.8\pgflinewidth}
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-2.75\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}
+ {\pgfqpoint{0pt}{-0.25\pgfutil@tempdima}}
+ {\pgfqpoint{0.75\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfqpoint{0.55\pgfutil@tempdima}{0.125\pgflinewidth}}
+ {\pgfqpoint{0.5\pgfutil@tempdima}{0.125\pgflinewidth}}
+ {\pgfqpoint{0.5\pgfutil@tempdima}{0.125\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{0pt}{0.125\pgflinewidth}}
+ \pgfusepathqstroke
+}%
+
+
+
+% The halfs of the $\to$ arrow reversed
+
+\pgfarrowsdeclare{left to reversed}{left to reversed}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfarrowsleftextend{+-.1\pgflinewidth}
+ \pgfutil@tempdimb=3.75\pgfutil@tempdima\advance\pgfutil@tempdimb by0.9\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfsetbuttcap
+ \pgfpathmoveto{\pgfqpoint{0.5\pgflinewidth}{0pt}}
+ \pgfpathlineto{\pgfqpoint{-0.1\pgflinewidth}{0pt}}
+ \pgfusepathqstroke
+ \pgfsetroundcap
+ \pgfsetlinewidth{.8\pgflinewidth}
+ {\pgftransformxshift{0.625\pgflinewidth}
+ \pgfpathmoveto{\pgfqpoint{3.75\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.5\pgfutil@tempdima}{2.5\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{0.25\pgfutil@tempdima}}{\pgfqpoint{0pt}{0.125\pgflinewidth}}
+ \pgfpathmoveto{\pgfqpoint{3.75\pgfutil@tempdima}{4\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.5\pgfutil@tempdima}{2.5\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{0.25\pgfutil@tempdima}}{\pgfqpoint{0pt}{-0.125\pgflinewidth}}
+ }
+ \pgfusepathqstroke%
+}%
+
+\pgfarrowsdeclare{right to reversed}{right to reversed}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfarrowsleftextend{+-.1\pgflinewidth}
+ \pgfutil@tempdimb=3.75\pgfutil@tempdima\advance\pgfutil@tempdimb by0.9\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.28pt%
+ \advance\pgfutil@tempdima by.3\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfsetbuttcap
+ \pgfpathmoveto{\pgfqpoint{0.5\pgflinewidth}{0pt}}
+ \pgfpathlineto{\pgfqpoint{-0.1\pgflinewidth}{0pt}}
+ \pgfusepathqstroke
+ \pgfsetroundcap
+ \pgfsetlinewidth{.8\pgflinewidth}
+ {\pgftransformxshift{0.625\pgflinewidth}
+ \pgfpathmoveto{\pgfqpoint{3.75\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.5\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{-0.25\pgfutil@tempdima}}{\pgfqpoint{0pt}{-0.125\pgflinewidth}}
+ \pgfpathmoveto{\pgfqpoint{3.75\pgfutil@tempdima}{-4\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.5\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{-0.25\pgfutil@tempdima}}{\pgfqpoint{0pt}{0.125\pgflinewidth}}
+ }
+ \pgfusepathqstroke%
+}%
+
+
+
+% A left hook
+
+\pgfarrowsdeclare{left hook}{left hook}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdimb=3.75\pgfutil@tempdima\advance\pgfutil@tempdimb by0.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0.75\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{2.415\pgfutil@tempdima}{0\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{1.665\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{3\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.75\pgfutil@tempdima}{4.665\pgfutil@tempdima}}{\pgfqpoint{2.415\pgfutil@tempdima}{6\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{6\pgfutil@tempdima}}
+ \pgfusepathqstroke%
+}%
+
+\pgfarrowsdeclarereversed{left hook reversed}{left hook reversed}{left hook}{left hook}%
+
+
+
+% A right hook
+
+\pgfarrowsdeclare{right hook}{right hook}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdimb=3.75\pgfutil@tempdima\advance\pgfutil@tempdimb by0.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0.75\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{2.415\pgfutil@tempdima}{0\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{-1.665\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{-3\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.75\pgfutil@tempdima}{-4.665\pgfutil@tempdima}}{\pgfqpoint{2.415\pgfutil@tempdima}{-6\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{-6\pgfutil@tempdima}}
+ \pgfusepathqstroke%
+}%
+
+\pgfarrowsdeclarereversed{right hook reversed}{right hook reversed}{right hook}{right hook}%
+
+
+% Hooks in both directions
+
+\pgfarrowsdeclare{hooks}{hooks}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfarrowsleftextend{+-.5\pgflinewidth}
+ \pgfutil@tempdimb=3.75\pgfutil@tempdima\advance\pgfutil@tempdimb by0.5\pgflinewidth%
+ \pgfarrowsrightextend{+\pgfutil@tempdimb}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.2\pgflinewidth%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0.75\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{2.415\pgfutil@tempdima}{0\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{1.665\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{3\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.75\pgfutil@tempdima}{4.665\pgfutil@tempdima}}{\pgfqpoint{2.415\pgfutil@tempdima}{6\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{6\pgfutil@tempdima}}
+ \pgfpathmoveto{\pgfqpoint{0.75\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{2.415\pgfutil@tempdima}{0\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{-1.665\pgfutil@tempdima}}{\pgfqpoint{3.75\pgfutil@tempdima}{-3\pgfutil@tempdima}}
+ \pgfpathcurveto{\pgfqpoint{3.75\pgfutil@tempdima}{-4.665\pgfutil@tempdima}}{\pgfqpoint{2.415\pgfutil@tempdima}{-6\pgfutil@tempdima}}{\pgfqpoint{0.75\pgfutil@tempdima}{-6\pgfutil@tempdima}}
+ \pgfusepathqstroke%
+}%
+
+\pgfarrowsdeclarereversed{hooks reversed}{hooks reversed}{hooks}{hooks}%
+
+
+% An arrow that looks like a serif of the computer modern font
+
+\pgfarrowsdeclare{serif cm}{serif cm}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.45\pgflinewidth%
+ \pgfarrowsleftextend{+-.75\pgfutil@tempdima}
+ \pgfarrowsrightextend{+.04\pgflinewidth}
+}
+{
+ \pgfutil@tempdima=0.4pt%
+ \advance\pgfutil@tempdima by.45\pgflinewidth%
+ \pgftransformxshift{.04\pgflinewidth}
+ \pgfpathmoveto{\pgfqpoint{-.75\pgfutil@tempdima}{.5\pgflinewidth}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.375\pgfutil@tempdima}{.5\pgflinewidth}}
+ {\pgfqpoint{-.375\pgfutil@tempdima}{.7\pgflinewidth}}
+ {\pgfqpoint{-.375\pgfutil@tempdima}{1.95\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1.95\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.04\pgflinewidth}{.5\pgfutil@tempdima}}
+ {\pgfqpoint{-.04\pgflinewidth}{-.5\pgfutil@tempdima}}
+ {\pgfqpoint{0pt}{-1.95\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-.375\pgfutil@tempdima}{-1.95\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.375\pgfutil@tempdima}{-.7\pgflinewidth}}
+ {\pgfqpoint{-.375\pgfutil@tempdima}{-.5\pgflinewidth}}
+ {\pgfqpoint{-.75\pgfutil@tempdima}{-.5\pgflinewidth}}
+ \pgfpathclose
+ \pgfusepathqfill
+}%
+
+
+
+% Round cap
+
+\pgfarrowsdeclare{round cap}{round cap}
+{\pgfarrowsleftextend{+0pt}\pgfarrowsrightextend{+\pgflinewidth}}
+{
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgfpathlineto{\pgfqpoint{0.5\pgflinewidth}{0pt}}
+ \pgfusepathqstroke
+}%
+
+
+% Butt cap
+
+\pgfarrowsdeclare{butt cap}{butt cap}
+{\pgfarrowsleftextend{+-.1\pgflinewidth}\pgfarrowsrightextend{+.5\pgflinewidth}}
+{
+ \pgfsetdash{}{+0pt}
+ \pgfsetbuttcap
+ \pgfpathmoveto{\pgfqpoint{-.1\pgflinewidth}{0pt}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgflinewidth}{0pt}}
+ \pgfusepathqstroke
+}%
+
+
+
+% 90 degrees cap
+
+\pgfarrowsdeclare{triangle 90 cap}{triangle 90 cap}
+{\pgfarrowsleftextend{+-.1\pgflinewidth}\pgfarrowsrightextend{+\pgflinewidth}}
+{
+ \pgfpathmoveto{\pgfqpoint{-.1\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{\pgflinewidth}{0pt}}
+ \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{-.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-0.5\pgflinewidth}}
+ \pgfpathclose
+ \pgfusepathqfill
+}%
+
+
+% reversed 90 degrees cap
+
+\pgfarrowsdeclare{triangle 90 cap reversed}{triangle 90 cap reversed}
+{\pgfarrowsleftextend{+-.1\pgflinewidth}\pgfarrowsrightextend{+\pgflinewidth}}
+{
+ \pgfpathmoveto{\pgfqpoint{1\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{-.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgflinewidth}{0\pgflinewidth}}
+ \pgfpathclose
+ \pgfusepathqfill
+}%
+
+
+
+% fast
+
+\pgfarrowsdeclare{fast cap}{fast cap}
+{\pgfarrowsleftextend{+-.1\pgflinewidth}\pgfarrowsrightextend{+2\pgflinewidth}}
+{
+ \pgfpathmoveto{\pgfqpoint{-.1\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{0\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{-.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-0.5\pgflinewidth}}
+ \pgfpathclose
+ \pgfpathmoveto{\pgfqpoint{1\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1.5\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{2\pgflinewidth}{0\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1.5\pgflinewidth}{-.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{-0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1.5\pgflinewidth}{0\pgflinewidth}}
+ \pgfpathclose
+ \pgfusepathqfill
+}%
+
+
+\pgfarrowsdeclare{fast cap reversed}{fast cap reversed}
+{\pgfarrowsleftextend{+-.1\pgflinewidth}\pgfarrowsrightextend{+2\pgflinewidth}}
+{
+ \pgfpathmoveto{\pgfqpoint{-.1\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{0\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{-.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-0.5\pgflinewidth}}
+ \pgfpathclose
+ \pgfpathmoveto{\pgfqpoint{1.5\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{2\pgflinewidth}{0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1.5\pgflinewidth}{0\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{2\pgflinewidth}{-.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1.5\pgflinewidth}{-0.5\pgflinewidth}}
+ \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{0\pgflinewidth}}
+ \pgfpathclose
+ \pgfusepathqfill
+}%
+
+
+
+
+
+% Mathematical arrows
+
+
+% The arrow tip of an \implies arrow, to be used with an inner line.
+%
+% Example:
+%
+% \pgfsetarrow{-implies}
+% \pgfsetlinewidth{1.8pt}
+% \pgfsetinnerlinewidth{1pt}
+
+\pgfarrowsdeclare{implies}{implies}
+{
+ \pgfmathsetlength{\pgfutil@tempdima}{.25\pgflinewidth+.25*\pgfinnerlinewidth}%
+ \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth}%
+ \pgfarrowsrightextend{2.06\pgfutil@tempdima+.5\pgfutil@tempdimb}
+ \pgfarrowsleftextend{-1.36\pgfutil@tempdima-.5\pgfutil@tempdimb}
+}
+{
+ \pgfmathsetlength{\pgfutil@tempdima}{.25\pgflinewidth+.25*\pgfinnerlinewidth}%
+ \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth}%
+ \pgftransformxshift{.06\pgfutil@tempdima}
+ \pgfsetlinewidth{\pgfutil@tempdimb}
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfpoint{-1.4\pgfutil@tempdima}{2.65\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfpoint{-0.75\pgfutil@tempdima}{1.25\pgfutil@tempdima}}
+ {\pgfpoint{1\pgfutil@tempdima}{0.05\pgfutil@tempdima}}
+ {\pgfpoint{2\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfpoint{1\pgfutil@tempdima}{-0.05\pgfutil@tempdima}}
+ {\pgfpoint{-.75\pgfutil@tempdima}{-1.25\pgfutil@tempdima}}
+ {\pgfpoint{-1.4\pgfutil@tempdima}{-2.65\pgfutil@tempdima}}
+ \pgfusepathqstroke
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.meta.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.meta.code.tex
new file mode 100644
index 0000000000..dbe2fb77d4
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.meta.code.tex
@@ -0,0 +1,1607 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryarrows.meta.code.tex}
+
+
+
+%
+%
+% Meta keys
+%
+%
+
+
+\newdimen\pgfarrowinset
+\newdimen\pgfarrowlength
+\newdimen\pgfarrowwidth
+\newdimen\pgfarrowlinewidth
+\newif\ifpgfarrowroundcap
+\newif\ifpgfarrowroundjoin
+
+\pgfarrowsaddtolengthscalelist\pgfarrowlength
+\pgfarrowsaddtolengthscalelist\pgfarrowinset
+\pgfarrowsaddtowidthscalelist\pgfarrowwidth
+
+
+\pgfkeys{
+ /pgf/arrow keys/.cd,
+ length/.code={%
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowlength\pgf@x}%
+ },
+ inset/.code={%
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowinset\pgf@x}%
+ },
+ inset'/.code={
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowinset}%
+ },
+ line width/.code={%
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowlinewidth\pgf@x}%
+ },
+ line width'/.code={
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowlinewidth}%
+ },
+ width/.code={%
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowwidth\pgf@x}%
+ },
+ width'/.code={%
+ \pgfarrowsthreeparameters{#1}%
+ \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowwidth}%
+ },
+ angle/.code={%
+ \pgfarrowsfourparameters{#1}%
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrows@angle@setup\pgfarrowstheparameters}%
+ },
+ angle'/.code={
+ \pgfarrowsaddtolateoptions{\pgfarrows@angle@setup@prime{#1}}%
+ },
+ %
+ line cap/.is choice,
+ line cap/butt/.code=\pgfarrowsaddtooptions{\pgfarrowroundcapfalse},
+ line cap/round/.code=\pgfarrowsaddtooptions{\pgfarrowroundcaptrue},
+ line join/.is choice,
+ line join/miter/.code=\pgfarrowsaddtooptions{\pgfarrowroundjoinfalse},
+ line join/round/.code=\pgfarrowsaddtooptions{\pgfarrowroundjointrue},
+ round/.style={line cap=round,line join=round},
+ sharp/.style={line cap=butt,line join=miter},
+}%
+%
+%
+% Classification of arrow tips:
+%
+%
+% Barbs
+% -----
+%
+% These arrow tips consisting of stroked lines starting at the tip,
+% typically going backward. They cannot be filled, only stroked
+%
+% A special case are the arrows mimicking the tip at the end of a
+% \rightarrow command.
+%
+%
+% Geometric
+% ---------
+%
+% The arrow tips have a geometric form like a triangle or a
+% "stealth" fighter or a kite. They can be filled and/or stroked.
+%
+%
+% Caps
+% ----
+%
+% These arrow tips have their width fixed to the line width and
+% provide different ways of adding a "cap" to the end of a line. This
+% allows one to use more than just the standard "round cap", "butt
+% cap" and "rect cap" and, additionally, one can one kind of cap at
+% one end and another at the other end.
+%
+%
+% Other
+% -----
+%
+% Special purpose arrow tips.
+%
+
+
+
+%
+%
+% Barbs arrow tips
+%
+%
+
+
+% An Straight Barb yields a simple angle
+
+\pgfdeclarearrow{
+ name = Straight Barb,
+ defaults = {
+ length = +1.5pt 2,
+ width' = +0pt 2,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ % Compute front miter length:
+ \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowlength}{\pgf@sys@tonumber\pgfarrowwidth}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x4\pgf@x%
+ \advance\pgf@x by1pt%
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter
+ \pgf@xc.5\pgf@xc
+ \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter
+ % Set ends
+ \ifpgfarrowroundjoin
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi}
+ \fi
+ \pgfarrowssetvisualbackend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}
+ \pgfarrowssetbackend{-.5\pgfarrowlinewidth}
+ % harpoon miter correction
+ \ifpgfarrowreversed
+ \pgfarrowssetlineend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by.5\pgfarrowlinewidth\fi}
+ \else
+ \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}
+ \fi
+ % The hull:
+ \ifpgfarrowroundjoin
+ \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
+ \else%
+ \ifpgfarrowharpoon
+ \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgf@xc\advance\pgf@x by\pgf@xa}{-.5\pgfarrowlinewidth}%
+ \else
+ \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgf@xc\advance\pgf@x by\pgf@xa}{0pt}%
+ \fi%
+ \fi
+ \pgfarrowsupperhullpoint{.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}%
+ \pgfarrowsupperhullpoint{-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}%
+ \ifpgfarrowharpoon
+ \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}%
+ \fi
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowwidth
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth}}
+ \pgfpathlineto{\pgfqpoint{\pgfarrowlength}{0pt}}
+ \ifpgfarrowharpoon
+ \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by\ifpgfarrowreversed\else-\fi\pgfarrowlinewidth}{0pt}}
+ \else
+ \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth}}
+ \fi
+ \pgfusepathqstroke
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowroundjoin j\fi%
+ \ifpgfarrowroundcap c\fi%
+ },
+}%
+%
+%
+% Hooks are barbs that consist of an arc going forward from the line
+% end and curving back by a given angle specified using the |arc|
+% key.
+
+\pgfkeys{
+ /pgf/arrow keys/.cd,
+ arc/.code={%
+ \pgfmathparse{#1}%
+ \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrowarc\expandafter{\pgfmathresult}}
+ }
+}%
+
+\def\pgfarrowarc{180}%
+
+\pgfdeclarearrow{
+ name = Hooks,
+ defaults = {
+ length = +0.75pt 1.25,
+ width' = +0pt 4 -1,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ \ifpgfarrowharpoon
+ \pgfarrowshullpoint{.5\pgfarrowlength}{-.5\pgfarrowlinewidth}
+ \pgfarrowshullpoint{\pgfarrowlength}{-.5\pgfarrowlinewidth\advance\pgf@y by.125\pgfarrowwidth}
+ \fi
+ \ifdim\pgfarrowarc pt<90.1pt
+ \pgfarrowsupperhullpoint{0pt}{.25\pgfarrowwidth\ifpgfarrowroundcap\else\advance\pgf@y by-.25\pgfarrowlinewidth\fi}
+ \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth\ifpgfarrowroundcap\else\advance\pgf@y by-.25\pgfarrowlinewidth\fi}
+ \else%
+ \pgfarrowsupperhullpoint{\pgfarrowlength}{.375\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{.5\pgfarrowlength}{.5\pgfarrowwidth}
+ \ifdim\pgfarrowarc pt>180pt
+ \pgfarrowsupperhullpoint{-.5\pgfarrowlength}{.5\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{-\pgfarrowlength}{.375\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{-\pgfarrowlength}{.25\pgfarrowwidth}
+ \else
+ \pgfarrowsupperhullpoint{\ifpgfarrowroundcap-.5\pgfarrowlinewidth\else0pt\fi}{.25\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{\ifpgfarrowroundcap-.5\pgfarrowlinewidth\else0pt\fi}{.5\pgfarrowwidth}
+ \fi
+ \fi
+ % Adjust width and length: Take line thickness into account:
+ \advance\pgfarrowlength by-.5\pgfarrowlinewidth
+ \advance\pgfarrowwidth by-\pgfarrowlinewidth
+ \ifpgfarrowreversed
+ \ifpgfarrowroundjoin
+ \pgfarrowssetbackend{-.5\pgfarrowlinewidth}
+ \fi
+ \fi
+ % There are four different intervals for the values of
+ % \pgfarrowsarc that give rise to four different settings of tip
+ % ends and so on:
+ %
+ % Case 1: 0 <= Angle < 90
+ %
+ \ifdim\pgfarrowarc pt<90pt%
+ % Tip end is given by sin(pgfarrowarc)*length
+ \pgfmathsin@{\pgfarrowarc}
+ \pgfarrowssettipend{\pgfmathresult\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}%
+ \else\ifdim\pgfarrowarc pt<180pt%
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}%
+ \ifpgfarrowroundcap\pgfarrowssetbackend{-.5\pgfarrowlinewidth}\fi%
+ \else\ifdim\pgfarrowarc pt<270pt%
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}%
+ \ifdim\pgfarrowarc pt>180pt
+ % Back end is given by sin(pgfarrowarc)*length
+ \pgfmathsin@{\pgfarrowarc}
+ \pgfarrowssetbackend{\pgfmathresult\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}%
+ \else
+ \ifpgfarrowroundcap\pgfarrowssetbackend{-.5\pgfarrowlinewidth}\fi%
+ \fi%
+ \else%
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}%
+ \pgfarrowssetbackend{-\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}%
+ \fi\fi\fi%
+ \ifpgfarrowreversed
+ \pgfarrowssetlineend{.5\pgfarrowlinewidth}
+ \else%
+ \ifpgfarrowharpoon
+ \pgfarrowssetlineend{0pt}
+ \else
+ \pgfarrowssetlineend{.25\pgfarrowlinewidth}
+ \fi
+ \fi
+ % Adjust arc:
+ \pgf@x\pgfarrowarc pt%
+ \advance\pgf@x by-90pt%
+ \edef\pgfarrowarc{\pgf@sys@tonumber\pgf@x}%
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowwidth
+ \pgfarrowssave\pgfarrowarc
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ {%
+ \pgftransformxscale{+\pgfarrowlength}
+ \pgftransformyscale{+.25\pgfarrowwidth}
+ \pgfpathmoveto{\pgfpointpolar{+\pgfarrowarc}{+1pt}\advance\pgf@y by1pt}
+ \pgfpatharc{\pgfarrowarc}{+-90}{+1pt}
+ \ifpgfarrowharpoon
+ \else
+ \pgfpatharc{+90}{+-\pgfarrowarc}{+1pt}
+ \fi
+ }
+ \ifpgfarrowharpoon\ifpgfarrowreversed
+ \pgfpathlineto{\pgfqpoint{\pgflinewidth}{0pt}}
+ \fi\fi
+ \pgfusepathqstroke
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \pgfarrowarc,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowroundjoin j\fi%
+ \ifpgfarrowroundcap c\fi%
+ },
+}%
+
+
+\pgfdeclarearrow{
+ name = Arc Barb,
+ defaults = {
+ length = +1.5pt 2,
+ width' = +0pt 2,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ % Adjust arc:
+ \pgf@x\pgfarrowarc pt%
+ \pgf@x.5\pgf@x%
+ \edef\pgfarrowarc{\pgf@sys@tonumber\pgf@x}%
+ % The tips:
+ \pgfarrowssettipend{\pgfarrowlength}
+ \pgfarrowssetvisualbackend{\pgfarrowlength}
+ \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}
+ % The hull:
+ \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth}
+ \ifpgfarrowharpoon\pgfarrowshullpoint{\pgfarrowlength}{-.5\pgflinewidth}\fi
+ \pgfmathsincos@{\pgfarrowarc}%
+ \pgf@xa.5\pgfarrowwidth%
+ \pgfarrowsupperhullpoint{\pgfmathresultx\pgfarrowlength}{\pgfmathresulty\pgf@xa}
+ \ifdim\pgfarrowarc pt>60pt
+ \pgfarrowsupperhullpoint{.5\pgfarrowlength}{\ifdim\pgfarrowarc pt<90pt\pgfmathresulty\pgf@xa\else.5\pgfarrowwidth\fi}
+ \fi
+ \ifdim\pgfarrowarc pt>90pt
+ \ifdim\pgfarrowarc pt<120pt
+ \pgfarrowsupperhullpoint{\pgfmathresultx\pgfarrowlength}{.5\pgfarrowwidth}
+ \else
+ \pgfarrowsupperhullpoint{-.5\pgfarrowlength}{.5\pgfarrowwidth}
+ \ifdim\pgfarrowarc pt>150pt
+ \pgfarrowsupperhullpoint{-\pgfarrowlength}{.25\pgfarrowwidth}
+ \fi
+ \fi
+ \fi
+ \pgfutil@tempswafalse
+ \ifdim\pgfarrowarc pt<90pt
+ \pgfutil@tempswatrue
+ \fi
+ \ifpgfarrowharpoon
+ \pgfutil@tempswatrue
+ \fi
+ \ifpgfutil@tempswa
+ \pgf@xa.5\pgfarrowwidth\advance\pgf@xa by-\pgfarrowlinewidth%
+ \pgf@ya\pgfarrowlength\advance\pgf@ya by-\pgfarrowlinewidth%
+ \pgfarrowsupperhullpoint{\pgfmathresultx\pgf@ya}{\pgfmathresulty\pgf@xa}
+ \fi
+ % Compute back end
+ \ifpgfarrowroundcap
+ \pgf@y\pgfarrowlength
+ \advance\pgf@y by-.5\pgfarrowlinewidth
+ \pgf@x\pgfmathresultx\pgf@y%
+ \else
+ \ifdim\pgfarrowarc pt<90pt
+ \pgf@y\pgfarrowlength
+ \advance\pgf@y by-\pgfarrowlinewidth
+ \pgf@x\pgfmathresultx\pgf@y%
+ \else
+ \pgf@x\pgfmathresultx\pgfarrowlength%
+ \fi
+ \fi
+ \pgfarrowssetbackend{\pgf@x\ifpgfarrowroundcap\advance\pgf@x by-.5\pgfarrowlinewidth\fi}
+ % Adjust width and length: Take line thickness into account:
+ \advance\pgfarrowlength by-.5\pgfarrowlinewidth
+ \advance\pgfarrowwidth by-\pgfarrowlinewidth
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowwidth
+ \pgfarrowssave\pgfarrowarc
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ {%
+ \pgftransformxscale{+\pgfarrowlength}
+ \pgftransformyscale{+.5\pgfarrowwidth}
+ \pgfpathmoveto{\pgfpointpolar{+\pgfarrowarc}{+1pt}}
+ \ifpgfarrowharpoon
+ \pgfpatharc{+\pgfarrowarc}{0pt}{+1pt}
+ \else
+ \pgfpatharc{+\pgfarrowarc}{+-\pgfarrowarc}{+1pt}
+ \fi
+ }
+ \ifpgfarrowharpoon
+ \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by\ifpgfarrowreversed\else-\fi.5\pgflinewidth}{0pt}}
+ \fi
+ \pgfusepathqstroke
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \pgfarrowarc,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowroundcap c\fi%
+ \ifpgfarrowroundjoin j\fi%
+ },
+}%
+
+
+
+% Tee Barb are barb arrows heads that look like a T
+
+\pgfdeclarearrow{
+ name = Tee Barb,
+ defaults = {
+ length = +1.5pt 2,
+ width = +3pt 4,
+ inset' = +0pt .5,
+ line width = +0pt 1 1,
+ },
+ bending mode=polar,
+ setup code = {
+ % Two useful numbers...
+ \pgfutil@tempswafalse%
+ \pgfutil@tempswbfalse%
+ \pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset\ifdim\pgfutil@tempdima<.5\pgfarrowlinewidth\pgfutil@tempdima.5\pgfarrowlinewidth\pgfutil@tempswatrue\fi%
+ \pgfutil@tempdimb-\pgfarrowinset\ifdim\pgfutil@tempdimb>-.5\pgfarrowlinewidth\pgfutil@tempdimb-.5\pgfarrowlinewidth\pgfutil@tempswbtrue\fi
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfarrowwidth
+ \pgfarrowssavethe\pgfutil@tempdima
+ \pgfarrowssavethe\pgfutil@tempdimb
+ % Infos:
+ \pgfarrowssettipend{\pgfutil@tempdima\ifpgfarrowroundcap\ifpgfutil@tempswa\else\advance\pgf@x by.5\pgfarrowlinewidth\fi\fi}
+ \pgfarrowssetvisualbackend{.5\pgfarrowlinewidth}
+ \pgfarrowssetbackend{\pgfutil@tempdimb\ifpgfarrowroundcap\ifpgfutil@tempswb\else\advance\pgf@x by-.5\pgfarrowlinewidth\fi\fi}
+ \pgfarrowssetlineend{\ifpgfarrowreversed\else-\fi.25\pgfarrowlinewidth}%
+ % The hull:
+ \pgfarrowsupperhullpoint{\pgfutil@tempdima\ifpgfarrowroundcap\ifpgfutil@tempswa\else\advance\pgf@x by.5\pgfarrowlinewidth\fi\fi}{.5\pgfarrowwidth}%
+ \pgfarrowsupperhullpoint{\pgfutil@tempdimb\ifpgfarrowroundcap\ifpgfutil@tempswb\else\advance\pgf@x by-.5\pgfarrowlinewidth\fi\fi}{.5\pgfarrowwidth}%
+ \ifpgfarrowharpoon
+ \pgfarrowshullpoint{.5\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}%
+ \fi
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \pgf@yc\pgflinewidth% save...
+ \ifdim\pgflinewidth=\pgfarrowlinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \pgf@x\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth%
+ \pgf@y\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth%
+ % Case 1: No bar atop the I:
+ \ifdim\pgf@x=\pgf@y%
+ \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth}}
+ \pgfpathlineto{\pgfqpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}}
+ \else
+ % Case 2: Bar, but only in one direction:
+ \ifdim\pgfutil@tempdima=.5\pgfarrowlinewidth%
+ \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}}
+ \pgfpathlineto{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}}
+ \ifpgfarrowharpoon%
+ \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgf@yc}}%
+ \else%
+ \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}}
+ \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}}
+ \fi
+ \else% Case 3: Complete I:
+ \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}}
+ \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}}
+ \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}}
+ \ifpgfarrowharpoon%
+ \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgf@yc}}%
+ \else%
+ \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}}
+ \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}}
+ \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}}
+ \fi
+ \fi
+ \fi
+ \pgfusepathqstroke
+ },
+ parameters = {
+ \the\pgfarrowwidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowinset,%
+ \the\pgfarrowlinewidth,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowroundjoin j\fi%
+ \ifpgfarrowroundcap c\fi%
+ },
+}%
+
+
+% Math barbs that resemble \rightarrow in different fonts:
+
+
+
+% The original default arrow head used in TikZ. It is modeled on an
+% old version of the \rightarrow head of the *old* Computer Modern
+% fonts.
+
+\pgfdeclarearrow{
+ name = Classical TikZ Rightarrow,
+ defaults = {
+ length = +1.05pt 1.925,
+ width' = +0pt 1.9237,
+ line width = 0pt 0.8 1,
+ round
+ },
+ setup code =
+ {
+ \ifpgfarrowharpoon\pgfarrowroundjointrue\fi
+ % inner length:
+ \pgfutil@tempdima\pgfarrowlength
+ \advance\pgfutil@tempdima by-\pgfarrowlinewidth
+ \pgfutil@tempdimb\pgfarrowwidth
+ \advance\pgfutil@tempdimb by-\pgfarrowlinewidth
+ \ifpgfarrowroundjoin%
+ \else%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgfutil@tempdima}{\pgf@sys@tonumber\pgfutil@tempdimb}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x40.96\pgf@x%
+ \advance\pgf@x by1pt% \pgflinewidth^2 + (6.4 \pgftempdim@a / \pgfutil@tempdimb) \pgflinewidth^2
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter
+ \pgf@xc.5\pgf@xc
+ \fi%
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfutil@tempdima
+ \pgfarrowssavethe\pgfutil@tempdimb
+ % The extend:
+ \pgfarrowssettipend{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}%
+ \pgfarrowssetvisualbackend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}%
+ \ifpgfarrowreversed%
+ \ifpgfarrowharpoon%
+ % A reversed arrow needs a slightly different line end:
+ \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by.5\pgflinewidth}%
+ \else%
+ % A reversed arrow needs a slightly different line end:
+ \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.25\pgflinewidth}%
+ \fi%
+ \else%
+ \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.6\pgflinewidth}%
+ \fi%
+ \pgfarrowssetbackend{-.5\pgfarrowlinewidth}%
+ % The hull:
+ % Tip:
+ \pgfarrowshullpoint{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}{.5\pgfarrowlinewidth}%
+ \pgfarrowshullpoint{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}{-.5\pgfarrowlinewidth}%
+ % Upper end:
+ \pgfarrowsupperhullpoint{.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}%
+ \pgfarrowsupperhullpoint{-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}%
+ % Lower end:
+ \ifpgfarrowharpoon
+ \pgfarrowshullpoint{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth}{-.5\pgflinewidth}%
+ \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by-.5\pgflinewidth}%
+ \fi
+ },
+ drawing code =
+ {
+ \pgfsetdash{}{+0pt}
+ \edef\pgf@orig@linewidth{\the\pgflinewidth}
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \ifpgfarrowharpoon\pgfarrowroundjointrue\fi
+ \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \pgfpathmoveto
+ {\pgfqpoint{0pt}{.5\pgfutil@tempdimb}}
+ \ifpgfarrowharpoon
+ \pgf@arrows@old@tikz@harpoon
+ \else
+ \pgfpathcurveto
+ {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}}
+ {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}}
+ {\pgfqpoint{\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfqpoint{.8\pgfutil@tempdima}{-.03125\pgfutil@tempdimb}}
+ {\pgfqpoint{0.066666\pgfutil@tempdima}{-.3125\pgfutil@tempdimb}}
+ {\pgfqpoint{0pt}{-.5\pgfutil@tempdimb}}
+ \pgfsetlinewidth{+\pgfarrowlinewidth}
+ \pgfusepathqstroke
+ \fi
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowroundjoin j\fi%
+ \ifpgfarrowroundcap c\fi%
+ },
+}%
+
+\def\pgf@arrows@old@tikz@harpoon{
+ \ifpgfarrowreversed
+ \pgf@arrows@old@tikz@harpoon@reversed
+ \else
+ \pgfpathcurveto
+ {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}}
+ {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}}
+ {\pgfqpoint{\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfqpoint{0.95\pgfutil@tempdima}{-0.125\pgflinewidth}}
+ {\pgfqpoint{0.933333\pgfutil@tempdima}{-0.125\pgflinewidth}}
+ {\pgfqpoint{0.933333\pgfutil@tempdima}{-0.125\pgflinewidth}}
+ \pgfpathlineto
+ {\pgfqpoint{0.8\pgfutil@tempdima\advance\pgf@x by-.5\pgflinewidth}{-0.125\pgflinewidth}}
+ \pgfusepathqstroke
+ \fi
+}%
+\def\pgf@arrows@old@tikz@harpoon@reversed{
+ \pgfpathcurveto
+ {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}}
+ {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}}
+ {\pgfqpoint{\pgfutil@tempdima}{0.125\pgflinewidth}}
+ \pgfpathmoveto
+ {\pgfqpoint{0pt}{.5\pgfutil@tempdimb}}
+ \pgfpathcurveto
+ {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}}
+ {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}}
+ {\pgfqpoint{\pgfutil@tempdima}{-0.125\pgflinewidth}}
+ \pgfusepathqstroke
+ \pgfsetlinewidth{+\pgf@orig@linewidth}
+ \pgfsetroundcap
+ \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by0.6\pgflinewidth}{0pt}}
+ \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{0pt}}
+ \pgfusepathqstroke
+}%
+
+
+% An approximation to the new (past 1992) Computer Modern math arrow
+% heads. This would be a better version of "to", so consider saying
+% to/.tips=Computer Modern Rightarrow
+
+\pgfdeclarearrow{
+ name = Computer Modern Rightarrow,
+ defaults = {
+ length = +1.6pt 2.2, % 0pt 5.2
+ width' = +0pt 2.096774,
+ line width = 0pt 1 1,
+ round
+ },
+ setup code =
+ {
+ % inner length:
+ \pgfutil@tempdima\pgfarrowlength
+ \advance\pgfutil@tempdima by-\pgfarrowlinewidth
+ \pgfutil@tempdimb\pgfarrowwidth
+ \advance\pgfutil@tempdimb by-\pgfarrowlinewidth
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfutil@tempdima
+ \pgfarrowssavethe\pgfutil@tempdimb
+ % Front miter:
+ \ifpgfarrowroundjoin%
+ \else%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgfutil@tempdima}{\pgf@sys@tonumber\pgfutil@tempdimb}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x49.44662\pgf@x%
+ \advance\pgf@x by1pt% \pgfarrowlinewidth^2 + (0.41019/0.0583333 \pgftempdim@a / \pgfutil@tempdimb) \pgfarrowlinewidth^2
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter
+ \pgf@xc.5\pgf@xc
+ \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter
+ \pgf@xa3.51591\pgf@xa% xa is extra harpoon miter
+ \fi%
+ % The extend:
+ \pgfarrowssettipend{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}%
+ \pgfarrowssetvisualbackend{.5\pgfarrowlinewidth}%
+ \ifpgfarrowreversed%
+ \ifpgfarrowharpoon%
+ \pgfarrowssetlineend{.5\pgfarrowlinewidth}%
+ \else%
+ \pgfarrowssetlineend{-.5\pgfarrowlinewidth}%
+ \fi%
+ \else%
+ \pgfarrowssetlineend{-.5\pgfarrowlinewidth}%
+ \fi%
+ \pgfarrowssetbackend{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}%
+ % The hull:
+ % Tip:
+ \pgfarrowshullpoint{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{.5\pgfarrowlinewidth}%
+ \pgfarrowshullpoint{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{-.5\pgfarrowlinewidth}%
+ % Upper end:
+ \pgfarrowsupperhullpoint{-\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}%
+ \pgfarrowsupperhullpoint{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}%
+ % Lower end:
+ \ifpgfarrowharpoon
+ \pgfarrowshullpoint{-\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}%
+ \pgfarrowshullpoint{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by-.5\pgfarrowlinewidth}%
+ \fi
+ },
+ drawing code =
+ {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \pgfpathmoveto
+ {\pgfqpoint{-\pgfutil@tempdima}{.5\pgfutil@tempdimb}}
+ \pgfpathcurveto
+ {\pgfqpoint{-0.81731\pgfutil@tempdima}{.2\pgfutil@tempdimb}}
+ {\pgfqpoint{-0.41019\pgfutil@tempdima}{0.05833333\pgfutil@tempdimb}}
+ {\pgfpointorigin}
+ \ifpgfarrowharpoon
+ \pgfpathlineto
+ {\pgfqpoint{\ifpgfarrowreversed.5\else-\fi\pgfarrowlinewidth}{0pt}}
+ \else
+ \pgfpathcurveto
+ {\pgfqpoint{-0.41019\pgfutil@tempdima}{-0.05833333\pgfutil@tempdimb}}
+ {\pgfqpoint{-0.81731\pgfutil@tempdima}{-.2\pgfutil@tempdimb}}
+ {\pgfqpoint{-\pgfutil@tempdima}{-.5\pgfutil@tempdimb}}
+ \fi
+ \pgfusepathqstroke
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \ifpgfarrowharpoon h\fi
+ \ifpgfarrowharpoon r\fi
+ \ifpgfarrowroundjoin j\fi%
+ \ifpgfarrowroundcap c\fi%
+ },
+}%
+
+
+
+% The arrow tip of an \implies arrow, to be used with an inner
+% line. Cannot be configured otherwise.
+
+\pgfdeclarearrow{
+ name = Implies,
+ setup code = {
+ \pgf@xa\pgfinnerlinewidth
+ \pgfutil@tempdima.25\pgflinewidth
+ \advance\pgfutil@tempdima by.25\pgf@xa%
+ \pgfutil@tempdimb.5\pgflinewidth
+ \advance\pgfutil@tempdimb by-.5\pgf@xa%
+ \pgfarrowssettipend{2.06\pgfutil@tempdima\advance\pgf@x by.5\pgfutil@tempdimb}
+ \pgfarrowssetbackend{-1.36\pgfutil@tempdima\advance\pgf@x by.5\pgfutil@tempdimb}
+ \pgfarrowsupperhullpoint{-1.4\pgfutil@tempdima}{2.8\pgfutil@tempdima}
+ \pgfarrowsupperhullpoint{2\pgfutil@tempdima}{.5\pgfutil@tempdimb}
+ \pgfarrowssavethe\pgfutil@tempdima
+ \pgfarrowssavethe\pgfutil@tempdimb
+ },
+ drawing code = {
+ \pgftransformxshift{.06\pgfutil@tempdima}
+ \pgfsetlinewidth{\pgfutil@tempdimb}
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundcap
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfpoint{-1.4\pgfutil@tempdima}{2.65\pgfutil@tempdima}}
+ \pgfpathcurveto
+ {\pgfpoint{-0.75\pgfutil@tempdima}{1.25\pgfutil@tempdima}}
+ {\pgfpoint{1\pgfutil@tempdima}{0.05\pgfutil@tempdima}}
+ {\pgfpoint{2\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto
+ {\pgfpoint{1\pgfutil@tempdima}{-0.05\pgfutil@tempdima}}
+ {\pgfpoint{-.75\pgfutil@tempdima}{-1.25\pgfutil@tempdima}}
+ {\pgfpoint{-1.4\pgfutil@tempdima}{-2.65\pgfutil@tempdima}}
+ \pgfusepathqstroke
+ },
+ parameters = {\the\pgfarrowlength}
+}%
+
+
+
+
+%
+%
+% Geometric arrow tips
+%
+%
+
+
+% Generic "latex-like" arrow tip. This is the basic arrow tip used in
+% latex's picture environment. You can configure its length and width.
+
+\pgfdeclarearrow{
+ name = Latex,
+ defaults = {
+ length = +3pt 4.5 .8,% +2.8pt 3 0.8,
+ width' = +0pt .75,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ % Cap the line width at 1/4th distance from inset to tip
+ \pgf@x.2\pgfarrowlength
+ \ifdim\pgf@x<\pgfarrowlinewidth
+ \pgfarrowlinewidth\pgf@x
+ \fi
+ \pgfarrowssavethe\pgfarrowlinewidth%
+ % Compute front miter length:
+ \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowlength}{\pgf@sys@tonumber\pgfarrowwidth}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x9\pgf@x%
+ \advance\pgf@x by1pt%
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@xc\pgfmathresult\pgfarrowlinewidth%
+ \pgf@xa\pgf@temp@quot\pgfarrowlinewidth
+ % Inner length (pgfutil@tempdima) is now arrowlength - front miter
+ % - 0.5 linewidth (back thickness)
+ \pgfutil@tempdima\pgfarrowlength%
+ \advance\pgfutil@tempdima by-.5\pgf@xc%
+ \advance\pgfutil@tempdima by-.5\pgfarrowlinewidth%
+ % harpoon miter correction
+ \pgfarrowssetbackend{-.5\pgfarrowlinewidth}
+ \ifpgfarrowreversed
+ \ifdim\pgfinnerlinewidth>0pt
+ \pgfarrowssetlineend{0pt}
+ \else
+ \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.5\pgflinewidth}
+ \fi
+ \else
+ \pgfarrowssetlineend{0pt}
+ \fi
+ \ifpgfarrowroundjoin
+ \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth\ifpgfarrowharpoon\advance\pgf@x by1.5\pgf@xa\fi}
+ \fi
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfutil@tempdima
+ % Now, compute back tip miter limit:
+ \pgf@process{\pgfpointnormalised{\pgfqpoint{.3\pgfarrowlength}{.2333333\pgfarrowwidth}}}%
+ \advance\pgf@y by1pt%
+ \pgf@yc\pgf@y\pgf@xc\pgf@x%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@yc}{\pgf@sys@tonumber\pgf@xc}%
+ \pgfutil@tempdimb\pgfmathresult\pgfarrowlinewidth%
+ \pgfutil@tempdimb-.5\pgfutil@tempdimb%
+ \advance\pgfutil@tempdimb by.5\pgfarrowwidth%
+ \pgfarrowssavethe\pgfutil@tempdimb%
+ % The hull:
+ \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by1.5\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
+ \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\ifpgfarrowharpoon\advance\pgf@y by-.5\pgfarrowlinewidth\fi}%
+ \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}%
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \pgfpathmoveto {\pgfqpoint{\pgfutil@tempdima}{0pt}}
+ \pgfpathcurveto {\pgfqpoint{.877192\pgfutil@tempdima}{.077922\pgfutil@tempdimb}}
+ {\pgfqpoint{.337381\pgfutil@tempdima}{.519480\pgfutil@tempdimb}}
+ {\pgfqpoint{0pt}{\pgfutil@tempdimb}}
+ \ifpgfarrowharpoon
+ \pgfpathlineto {\pgfpointorigin}
+ \else
+ \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdimb}}
+ \pgfpathcurveto {\pgfqpoint{.337381\pgfutil@tempdima}{-.519480\pgfutil@tempdimb}}
+ {\pgfqpoint{.877192\pgfutil@tempdima}{-.077922\pgfutil@tempdimb}}
+ {\pgfqpoint{\pgfutil@tempdima}{0pt}}
+ \fi
+ \pgfpathclose
+ \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowopen o\fi%
+ \ifpgfarrowroundjoin j\fi%
+ },
+}%
+
+
+
+% A basic stealth-fighter-like pointed arrow
+
+\pgfdeclarearrow{
+ name = Stealth,
+ defaults = {
+ length = +3pt 4.5 .8,
+ width' = +0pt .75,
+ inset' = +0pt 0.325,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ % Cap the line width at 1/4th distance from inset to tip
+ \pgf@x\pgfarrowlength
+ \advance\pgf@x by-\pgfarrowinset
+ \pgf@x.25\pgf@x
+ \ifdim\pgf@x<\pgfarrowlinewidth
+ \pgfarrowlinewidth\pgf@x
+ \fi
+ % Compute front miter length:
+ \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowlength}{\pgf@sys@tonumber\pgfarrowwidth}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x4\pgf@x%
+ \advance\pgf@x by1pt%
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter
+ \pgf@xc.5\pgf@xc
+ \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter
+ % Compute back miter length:
+ \pgf@ya.5\pgfarrowwidth%
+ \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowlength}{\pgfmath@tonumber\pgf@ya}%
+ \pgf@yb\pgfmathresult pt%
+ \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgf@ya}%
+ \pgf@ya\pgfmathresult pt%
+ \advance\pgf@yb by-\pgf@ya%
+ \pgf@yb.5\pgf@yb% half angle in yb
+ \pgfmathtan@{\pgf@sys@tonumber\pgf@yb}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@yc\pgfmathresult\pgfarrowlinewidth%
+ \pgf@yc.5\pgf@yc%
+ \advance\pgf@ya by\pgf@yb%
+ \pgfmathsincos@{\pgf@sys@tonumber\pgf@ya}%
+ \pgf@ya\pgfmathresulty\pgf@yc% ya is the back miter
+ \pgf@yb\pgfmathresultx\pgf@yc% yb is the top miter
+ \ifdim\pgfarrowinset=0pt%
+ \pgf@ya.5\pgfarrowlinewidth% easy: back miter is half linewidth
+ \fi
+ % Compute inset miter length:
+ \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowinset}{\pgf@sys@tonumber\pgfarrowwidth}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x4\pgf@x%
+ \advance\pgf@x by1pt%
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is inset miter
+ \pgf@yc.5\pgf@yc%
+ % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter
+ \pgfutil@tempdima\pgfarrowlength%
+ \advance\pgfutil@tempdima by-\pgf@xc%
+ \advance\pgfutil@tempdima by-\pgf@ya%
+ \pgfutil@tempdimb.5\pgfarrowwidth%
+ \advance\pgfutil@tempdimb by-\pgf@yb%
+ % harpoon miter correction
+ \ifpgfarrowroundjoin
+ \pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssetbackend{0pt}
+ \fi
+ \ifpgfarrowharpoon
+ \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x
+ by\pgf@yc\advance\pgf@x by.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x by\pgf@yc\advance\pgf@x by-.25\pgfarrowlinewidth}
+ \ifpgfarrowreversed
+ \ifdim\pgfinnerlinewidth>0pt
+ \pgfarrowssetlineend{\pgfarrowinset}
+ \else
+ \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by-.25\pgfarrowlinewidth}
+ \fi
+ \fi
+ \fi
+ \ifpgfarrowroundjoin
+ \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi}
+ \fi
+ % The hull:
+ \pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
+ \pgfarrowsupperhullpoint{0pt}{.5\pgfarrowwidth}%
+ \pgfarrowshullpoint{\pgfarrowinset}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else 0pt\fi}%
+ % Adjust inset
+ \pgfarrowssetvisualbackend{\pgfarrowinset}
+ \advance\pgfarrowinset by\pgf@yc%
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfutil@tempdima
+ \pgfarrowssavethe\pgfutil@tempdimb
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgf@ya
+ \pgfarrowssavethe\pgfarrowinset
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by\pgf@ya}{0pt}}
+ \pgfpathlineto{\pgfqpoint{\pgf@ya}{\pgfutil@tempdimb}}
+ \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{0pt}}
+ \ifpgfarrowharpoon \else
+ \pgfpathlineto{\pgfqpoint{\pgf@ya}{-\pgfutil@tempdimb}}
+ \fi
+ \pgfpathclose
+ \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \the\pgfarrowinset,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowopen o\fi%
+ \ifpgfarrowroundjoin j\fi%
+ },
+}%
+
+
+
+% A Kite is like a Stealth, only the inset counts in the other direction
+
+\pgfdeclarearrow{
+ name = Kite,
+ defaults = {
+ length = +3.6pt +5.4,
+ width' = +0pt +0.5,
+ inset' = +0pt 0.25,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ % Cap the line width at 1/4th of the length
+ \pgf@x.4\pgfarrowlength
+ \ifdim\pgf@x<\pgfarrowlinewidth
+ \pgfarrowlinewidth\pgf@x
+ \fi
+ \pgf@x.4\pgfarrowwidth
+ \ifdim\pgf@x<\pgfarrowlinewidth
+ \pgfarrowlinewidth\pgf@x
+ \fi
+ % Compute front miter length:
+ \pgf@xa\pgfarrowlength%
+ \advance\pgf@xa by-\pgfarrowinset%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgfarrowwidth}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x4\pgf@x%
+ \advance\pgf@x by1pt%
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter
+ \pgf@xc.5\pgf@xc
+ \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter
+ % Compute back miter length:
+ \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowinset}{\pgf@sys@tonumber\pgfarrowwidth}%
+ \let\pgf@temp@quot\pgfmathresult%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@x4\pgf@x%
+ \advance\pgf@x by1pt%
+ \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is back miter
+ \pgf@yc.5\pgf@yc
+ \pgf@ya\pgf@temp@quot\pgfarrowlinewidth% ya is extra harpoon miter
+ % Compute top miter length:
+ {%
+ \pgfutil@tempdimb.5\pgfarrowwidth%
+ \pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset%
+ \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfutil@tempdima}{\pgfmath@tonumber\pgfutil@tempdimb}%
+ \pgf@yb\pgfmathresult pt%
+ \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgfutil@tempdimb}%
+ \pgf@ya\pgfmathresult pt%
+ \advance\pgf@yb by\pgf@ya%
+ \pgf@yb.5\pgf@yb% half angle in yb
+ \ifdim\pgf@yb=45pt%
+ \def\pgfmathresult{1.414213}%
+ \else%
+ \pgfmathsin@{\pgf@sys@tonumber\pgf@yb}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \fi%
+ \pgf@yc\pgfmathresult\pgfarrowlinewidth%
+ \pgf@yc.5\pgf@yc%
+ \pgf@ya-\pgf@ya%
+ \advance\pgf@ya by-90pt%
+ \advance\pgf@ya by\pgf@yb%
+ \pgfmathsincos@{\pgf@sys@tonumber\pgf@ya}%
+ \pgf@xb\pgfmathresultx\pgf@yc% ya is the back miter
+ \pgf@yb\pgfmathresulty\pgf@yc% yb is the top miter
+ \expandafter\expandafter\expandafter%
+ }\expandafter\expandafter\expandafter\pgf@xb\expandafter\the\expandafter\pgf@xb\expandafter\pgf@yb\the\pgf@yb%
+ % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter
+ \pgfutil@tempdima\pgfarrowlength%
+ \advance\pgfutil@tempdima by-\pgf@xc%
+ \pgfutil@tempdimb.5\pgfarrowwidth%
+ \advance\pgfutil@tempdimb by\pgf@yb%
+ % Set back end
+ \ifpgfarrowroundjoin
+ \pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssetbackend{0pt}
+ \fi
+ % harpoon miter correction
+ \ifpgfarrowreversed
+ \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth\advance\pgf@x by\pgfarrowlinewidth}
+ \else
+ \pgfarrowssetlineend{\pgf@yc\advance\pgf@x by\pgflinewidth\advance\pgf@x by-\pgfarrowlinewidth}
+ \fi
+ \ifpgfarrowroundjoin
+ \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi}
+ \fi
+ % The hull:
+ \pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
+ \pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgfarrowwidth}%
+ \pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
+ % Adjust the inset:
+ \advance\pgfarrowinset by\pgf@xb%
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfutil@tempdima
+ \pgfarrowssavethe\pgfutil@tempdimb
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgf@yc
+ \pgfarrowssavethe\pgfarrowinset
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{\pgfarrowlinewidth}\fi
+ \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{0pt}}
+ \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdimb}}
+ \pgfpathlineto{\pgfqpoint{\pgf@yc}{0pt}}
+ \ifpgfarrowharpoon \else
+ \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdimb}}
+ \fi
+ \pgfpathclose
+ \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \the\pgfarrowinset,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowopen o\fi%
+ \ifpgfarrowroundjoin j\fi%
+ },
+}%
+
+
+
+
+% A simple rectangle shape
+
+\pgfdeclarearrow{
+ name = Square,
+ defaults = {
+ length = +2.12132pt +2.828427,
+ width' = +0pt +1,
+ line width = +0pt +1 +1,
+ },
+ setup code = {
+ % Cap the line width at 1/2th of the length
+ \pgf@x.5\pgfarrowlength
+ \ifdim\pgf@x<\pgfarrowlinewidth
+ \pgfarrowlinewidth\pgf@x
+ \fi
+ \ifpgfarrowreversed
+ \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssetlineend{.5\pgfarrowlinewidth}
+ \fi
+ \pgfarrowssettipend{\pgfarrowlength}
+ % The hull:
+ \pgfarrowshullpoint{\pgfarrowlength}{.5\pgfarrowwidth}
+ \pgfarrowshullpoint{0pt}{.5\pgfarrowwidth}
+ \pgfarrowshullpoint{\pgfarrowlength}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}
+ \pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowwidth
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \pgfpathmoveto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}}
+ \pgfpathlineto{\pgfqpoint{.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}}
+ \pgfpathlineto{\pgfqpoint{.5\pgfarrowlinewidth}{\ifpgfarrowharpoon0pt\else-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth\fi}}
+ \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}{\ifpgfarrowharpoon0pt\else-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth\fi}}
+ \pgfpathclose
+ \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowopen o\fi%
+ \ifpgfarrowroundjoin j\fi%
+ },
+}%
+
+
+% A simple rectangle shape
+
+\pgfdeclarearrow{
+ name = Circle,
+ defaults = {
+ length = +2.39365pt +3.191538,
+ width' = +0pt 1,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ % Cap the line width at 1/2th of the length
+ \pgf@x.5\pgfarrowlength
+ \ifdim\pgf@x<\pgfarrowlinewidth
+ \pgfarrowlinewidth\pgf@x
+ \fi
+ \ifpgfarrowreversed
+ \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}
+ \else
+ \pgfarrowssetlineend{.5\pgfarrowlinewidth}
+ \fi
+ \pgfarrowssettipend{\pgfarrowlength}
+ % The hull:
+ \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{.75\pgfarrowlength}{.5\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{.25\pgfarrowlength}{.5\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{0pt}{.25\pgfarrowwidth}
+ \ifpgfarrowharpoon%
+ \pgfarrowshullpoint{0pt}{-.5\pgfarrowlinewidth}
+ \pgfarrowshullpoint{\pgfarrowlength}{-.5\pgfarrowlinewidth}
+ \fi%
+ % The following are needed in the code:
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowwidth
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ \ifpgfarrowharpoon
+ \pgfpathmoveto{\pgfqpoint{\pgfarrowlength\advance\pgf@x
+ by-.5\pgfarrowlinewidth}{0pt}}
+ {%
+ \pgf@xa.5\pgfarrowlength
+ \advance\pgf@xa by-.5\pgfarrowlinewidth
+ \pgftransformxscale{+\the\pgf@xa}
+ \pgf@xa.5\pgfarrowwidth
+ \advance\pgf@xa by-.5\pgfarrowlinewidth
+ \pgftransformyscale{+\the\pgf@xa}
+ \pgfpatharc{0}{180}{1pt}
+ }
+ \pgfpathclose
+ \else%
+ \pgfpathellipse{\pgfqpoint{.5\pgfarrowlength}{0pt}}{\pgfqpoint{.5\pgfarrowlength\advance\pgf@x
+ by-.5\pgfarrowlinewidth}{0pt}}{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y
+ by-.5\pgfarrowlinewidth}}
+ \fi
+ \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowopen o\fi%
+ \ifpgfarrowroundjoin j\fi%
+ },
+}%
+
+% Round cap
+
+\pgfdeclarearrow{
+ name = Round Cap,
+ defaults = {
+ length = +0pt .5
+ },
+ setup code = {
+ \ifpgfarrowreversed
+ \pgfarrowssettipend{\pgfarrowlength}
+ \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by.5\pgflinewidth}
+ \else
+ \pgfarrowssettipend{\pgfarrowlength}
+ \pgfarrowssetlineend{-.5\pgflinewidth}
+ \fi
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
+ \pgfarrowsupperhullpoint{\pgfarrowlength}{.5\pgflinewidth}
+ },
+ drawing code = {
+ \ifpgfarrowreversed
+ \pgftransformxscale{-1}
+ \pgftransformxshift{-\pgfarrowlength}
+ \fi
+ \pgfutil@tempdima.5\pgflinewidth
+ \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}}
+ \ifpgfarrowreversed
+ \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}}
+ \begingroup
+ \pgftransformxshift{\pgfarrowlength}
+ \pgftransformxscale{-1}
+ \fi
+ \pgfpathcurveto {\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}}
+ {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}}
+ {\pgfqpoint{\pgfarrowlength}{0pt}}
+ \pgfpathcurveto {\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}}
+ {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}}
+ {\pgfqpoint{0pt}{-\pgfutil@tempdima}}
+ \ifpgfarrowreversed
+ \endgroup
+ \fi
+ \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfill
+ },
+ parameters = {\the\pgfarrowlength}
+}%
+
+
+
+\pgfdeclarearrow{
+ name = Butt Cap,
+ defaults = {
+ length = +0pt .5
+ },
+ setup code = {
+ \pgfarrowssettipend{\pgfarrowlength}
+ \pgfarrowssetlineend{-.5\pgflinewidth}
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
+ \pgfarrowsupperhullpoint{\pgfarrowlength}{.5\pgflinewidth}
+ },
+ drawing code = {
+ \pgfutil@tempdima.5\pgflinewidth
+ \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{-\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfill
+ },
+ parameters = {\the\pgfarrowlength}
+}%
+
+
+
+\pgfkeys{
+ /pgf/arrow keys/.cd,
+ cap angle/.code={%
+ \pgfmathsetlength\pgf@x{#1}%
+ \pgf@x.5\pgf@x
+ \pgfmathtan@{\pgf@sys@tonumber\pgf@x}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@x\pgfmathresult pt%
+ \pgf@x.5\pgf@x%
+ \edef\pgf@marshal{\noexpand\pgfarrowsaddtooptions{\noexpand\pgfarrowslinewidthdependent{+0pt}{\pgf@sys@tonumber\pgf@x}{0}\pgfarrowlength\pgf@x}}
+ \pgf@marshal
+ }
+}%
+
+
+\pgfdeclarearrow{
+ name = Triangle Cap,
+ defaults = {
+ length = +0pt .5
+ },
+ setup code = {
+ \ifpgfarrowreversed
+ \pgfarrowssettipend{\pgfarrowlength}
+ \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by.5\pgflinewidth}
+ \else
+ \pgfarrowssettipend{\pgfarrowlength}
+ \pgfarrowssetlineend{-.5\pgflinewidth}
+ \fi
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
+ \pgfarrowshullpoint{\pgfarrowlength}{0pt}
+ },
+ drawing code = {
+ \ifpgfarrowreversed
+ \pgftransformxscale{-1}
+ \pgftransformxshift{-\pgfarrowlength}
+ \fi
+ \pgfutil@tempdima.5\pgflinewidth
+ \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}}
+ \ifpgfarrowreversed
+ \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}}
+ \begingroup
+ \pgftransformxshift{\pgfarrowlength}
+ \pgftransformxscale{-1}
+ \fi
+ \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{0pt}}
+ \ifpgfarrowreversed
+ \endgroup
+ \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{-\pgfutil@tempdima}}
+ \fi
+ \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfill
+ },
+ parameters = {\the\pgfarrowlength}
+}%
+
+
+
+\pgfdeclarearrow{
+ name = Fast Triangle,
+ defaults = {
+ length = +0pt .5,
+ inset = +0pt .5,
+ },
+ setup code = {
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}
+ \ifpgfarrowreversed\pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}\fi
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowinset
+ \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
+ \pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgflinewidth}
+ \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}{0pt}
+ },
+ drawing code = {
+ \pgfutil@tempdima.5\pgflinewidth
+ \pgfpathmoveto {\pgfqpoint{0pt}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{\pgfarrowinset\advance\pgf@x by\pgfarrowlength}{0pt}}
+ \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{0pt}}
+ \pgfpathclose
+ \pgfusepathqfill
+ },
+ parameters = {\the\pgfarrowlength,\the\pgfarrowinset}
+}%
+
+
+\pgfdeclarearrow{
+ name = Fast Round,
+ defaults = {
+ length = +0pt .5,
+ inset = +0pt .5,
+ },
+ setup code = {
+ \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}
+ \ifpgfarrowreversed\pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}\fi
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowinset
+ \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
+ \pgfarrowsupperhullpoint{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}{.5\pgflinewidth}
+ },
+ drawing code = {
+ \pgfutil@tempdima.5\pgflinewidth
+ \pgfpathmoveto {\pgfqpoint{0pt}{\pgfutil@tempdima}}
+ \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdima}}
+ {
+ \pgftransformxshift{\pgfarrowinset}
+ \pgfpathcurveto{\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}}
+ {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}}
+ {\pgfqpoint{\pgfarrowlength}{0pt}}
+ \pgfpathcurveto{\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}}
+ {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}}
+ {\pgfqpoint{0pt}{-\pgfutil@tempdima}}
+ }
+ \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}}
+ \pgfpathcurveto {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}}
+ {\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}}
+ {\pgfqpoint{\pgfarrowlength}{0pt}}
+ \pgfpathcurveto {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}}
+ {\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}}
+ {\pgfqpoint{0pt}{\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfill
+ },
+ parameters = {\the\pgfarrowlength,\the\pgfarrowinset}
+}%
+
+
+
+
+%
+%
+% Other arrow tips.
+%
+%
+
+
+\pgfkeys{
+ /pgf/arrow keys/.cd,
+ n/.code={%
+ \pgfmathparse{#1}%
+ \expandafter\pgf@lib@meta@strip@dot\pgfmathresult.\relax%
+ }
+}%
+\def\pgf@lib@meta@strip@dot#1.#2\relax{%
+ \pgfarrowsaddtooptions{\def\pgfarrown{#1}}%
+}%
+
+\def\pgfarrown{4}%
+
+\pgfdeclarearrow{
+ name = Rays,
+ defaults = {
+ length = +3pt 4,
+ width' = +0pt 1,
+ line width = +0pt 1 1,
+ },
+ setup code = {
+ \pgfmathdivide@{360}{\pgfarrown}%
+ \let\pgfarrow@inc\pgfmathresult%
+ % Compute tips:
+ \pgf@xa\pgfarrow@inc pt%
+ \ifodd\pgfarrown\pgf@ya.25\pgf@xa\else\pgf@ya.5\pgf@xa\fi%
+ \pgfmathsincos@{\pgf@sys@tonumber\pgf@ya}%
+ \pgf@x.5\pgfarrowlength%
+ \pgf@xa\pgfmathresultx\pgf@x%
+ \ifpgfarrowroundcap
+ \advance\pgf@xa by.5\pgfarrowlinewidth
+ \else
+ \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgfmathresultx\pgfarrowlength}{\pgfmathresulty\pgfarrowwidth}}}%
+ \pgf@x.5\pgfarrowlinewidth%
+ \advance\pgf@xa by\pgf@sys@tonumber{\pgf@y}\pgf@x%
+ \fi%
+ \pgfarrowssettipend{\pgf@xa}
+ \pgfarrowssetbackend{-\pgf@xa}
+ % Hull is always 8-point hull, except for tip
+ % The following are needed in the code:
+ \pgfarrowsupperhullpoint{\pgf@xa}{.25\pgfarrowwidth}
+ \pgfarrowsupperhullpoint{.25\pgfarrowlength}{.5\pgfarrowwidth\ifpgfarrowroundcap\advance\pgf@y by.5\pgfarrowlinewidth\fi}
+ \pgfarrowsupperhullpoint{-.25\pgfarrowlength}{.5\pgfarrowwidth\ifpgfarrowroundcap\advance\pgf@y by.5\pgfarrowlinewidth\fi}
+ \pgfarrowsupperhullpoint{-\pgf@xa}{.25\pgfarrowwidth}
+ \ifpgfarrowharpoon
+ \pgfarrowshullpoint{-.5\pgfarrowlength\ifpgfarrowroundcap\advance\pgf@x by-.5\pgfarrowlinewidth\fi}{-.5\pgfarrowlinewidth}
+ \pgfarrowshullpoint{.5\pgfarrowlength\ifpgfarrowroundcap\advance\pgf@x by.5\pgfarrowlinewidth\fi}{-.5\pgfarrowlinewidth}
+ \fi
+ \pgfarrowssavethe\pgfarrowlinewidth
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgfarrowwidth
+ \pgfarrowssave\pgfarrow@inc
+ \pgfarrowssave\pgfarrown
+ },
+ drawing code = {
+ \pgfsetdash{}{+0pt}
+ \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi
+ \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
+ {%
+ \pgfgettransform\pgf@temp@trans
+ \pgftransformxscale{+.5\pgfarrowlength}
+ \pgftransformyscale{+.5\pgfarrowwidth}
+ \pgf@xa\pgfarrow@inc pt%
+ \ifodd\pgfarrown\pgf@ya.25\pgf@xa\else\pgf@ya.5\pgf@xa\fi%
+ \ifpgfarrowharpoon\pgf@yb180pt\else\pgf@yb360pt\fi
+ \pgfutil@loop%
+ \ifdim\pgf@ya<\pgf@yb%
+ \pgfpathmoveto{\pgfpointpolar{+\pgf@ya}{+1pt}}
+ \pgfpathlineto{\pgfpointorigin}
+ \ifpgfarrowharpoon\ifdim\pgf@ya>\pgf@xa\else{\pgfsettransform\pgf@temp@trans\pgfpathlineto{\pgfqpoint{-.5\pgflinewidth}{0pt}}}\fi\fi
+ \advance\pgf@ya by\pgf@xa\relax%
+ \pgfutil@repeat%
+ }
+ \pgfusepathqstroke
+ },
+ parameters = {
+ \the\pgfarrowlinewidth,%
+ \the\pgfarrowlength,%
+ \the\pgfarrowwidth,%
+ \pgfarrown,%
+ \ifpgfarrowharpoon h\fi%
+ \ifpgfarrowroundcap c\fi%
+ }
+}%
+
+
+
+% Shorthands and Aliases:
+
+\pgfkeys{
+ LaTeX /.tip = {Latex},
+ Triangle /.tip = {Stealth[inset=+0pt, angle=+60:+2.7pt +3.6]},
+ Rectangle /.tip = {Square[length=+3pt +4.5,width'=+0pt +.5]},
+ Ellipse /.tip = {Circle[length=+3.3pt +4.95, width'=+0pt +0.5]},
+ Diamond /.tip = {Kite[inset'=+0pt .5]},
+ Turned Square /.tip = {Kite[length=+3pt 4,width'= +0pt 1,inset'= +0pt 0.5]},
+ To /.tip = {Computer Modern Rightarrow},
+ Bar /.tip = {Tee Barb[length=+0pt]},
+ Bracket /.tip = {Tee Barb[inset'=+0pt +1,length=+0.75pt +1]},
+ Parenthesis /.tip = {Arc Barb[arc=+120,length=+1.725pt +2.3]}
+}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.spaced.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.spaced.code.tex
new file mode 100644
index 0000000000..f125afddca
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryarrows.spaced.code.tex
@@ -0,0 +1,92 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryarrows.spaced.code.tex}
+
+
+\usepgflibrary{arrows}%
+
+
+% This library offers "spaced" versions of existing arrows, where a
+% bit of additional space is inserted at the tip. This often looks
+% better than the normal arrow.
+%
+% These arrows are called "spaced whatever" where "whatever" is the
+% original name of the arrow.
+
+
+\pgfarrowsdeclarecombine*{spaced to}{spaced to}{to}{to}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced to reversed}{spaced to reversed}{to reversed}{to reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced implies}{spaced implies}{implies}{implies}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced latex}{spaced latex}{latex}{latex}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced latex reversed}{spaced latex reversed}{latex reversed}{latex reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced latex'}{spaced latex'}{latex'}{latex'}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced latex' reversed}{spaced latex' reversed}{latex' reversed}{latex' reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced stealth}{spaced stealth}{stealth}{stealth}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced stealth reversed}{spaced stealth reversed}{stealth reversed}{stealth reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced stealth'}{spaced stealth'}{stealth'}{stealth'}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced stealth' reversed}{spaced stealth' reversed}{stealth' reversed}{stealth' reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 90}{spaced triangle 90}{triangle 90}{triangle 90}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 90 reversed}{spaced triangle 90 reversed}{triangle 90 reversed}{triangle 90 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 60}{spaced triangle 60}{triangle 60}{triangle 60}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 60 reversed}{spaced triangle 60 reversed}{triangle 60 reversed}{triangle 60 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 45}{spaced triangle 45}{triangle 45}{triangle 45}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 45 reversed}{spaced triangle 45 reversed}{triangle 45 reversed}{triangle 45 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open triangle 90}{spaced open triangle 90}{open triangle 90}{open triangle 90}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open triangle 90 reversed}{spaced open triangle 90 reversed}{open triangle 90 reversed}{open triangle 90 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open triangle 60}{spaced open triangle 60}{open triangle 60}{open triangle 60}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open triangle 60 reversed}{spaced open triangle 60 reversed}{open triangle 60 reversed}{open triangle 60 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open triangle 45}{spaced open triangle 45}{open triangle 45}{open triangle 45}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open triangle 45 reversed}{spaced open triangle 45 reversed}{open triangle 45 reversed}{open triangle 45 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced angle 90}{spaced angle 90}{angle 90}{angle 90}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced angle 90 reversed}{spaced angle 90 reversed}{angle 90 reversed}{angle 90 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced angle 60}{spaced angle 60}{angle 60}{angle 60}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced angle 60 reversed}{spaced angle 60 reversed}{angle 60 reversed}{angle 60 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced angle 45}{spaced angle 45}{angle 45}{angle 45}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced angle 45 reversed}{spaced angle 45 reversed}{angle 45 reversed}{angle 45 reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced hooks}{spaced hooks}{hooks}{hooks}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced hooks reversed}{spaced hooks reversed}{hooks reversed}{hooks reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced o}{spaced o}{o}{o}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced *}{spaced *}{*}{*}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced diamond}{spaced diamond}{diamond}{diamond}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open diamond}{spaced open diamond}{open diamond}{open diamond}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced square}{spaced square}{square}{square}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced open square}{spaced open square}{open square}{open square}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced serif cm}{spaced serif cm}{serif cm}{serif cm}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced left to}{spaced left to}{left to}{left to}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced left to reversed}{spaced left to reversed}{left to reversed}{left to reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced right to}{spaced right to}{right to}{right to}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced right to reversed}{spaced right to reversed}{right to reversed}{right to reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced left hook}{spaced left hook}{left hook}{left hook}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced left hook reversed}{spaced left hook reversed}{left hook reversed}{left hook reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced right hook}{spaced right hook}{right hook}{right hook}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced right hook reversed}{spaced right hook reversed}{right hook reversed}{right hook reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced round cap}{spaced round cap}{round cap}{round cap}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced butt cap}{spaced butt cap}{butt cap}{butt cap}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 90 cap}{spaced triangle 90 cap}{triangle 90 cap}{triangle 90 cap}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced triangle 90 cap reversed}{spaced triangle 90 cap reversed}{triangle 90 cap reversed}{triangle 90 cap reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced fast cap}{spaced fast cap}{fast cap}{fast cap}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced fast cap reversed}{spaced fast cap reversed}{fast cap reversed}{fast cap reversed}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced (}{spaced )}{(}{)}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced )}{spaced (}{)}{(}{space}{space}%
+\pgfarrowsdeclarecombine*{spaced |}{spaced |}{|}{|}{space}{space}%
+
+\pgfdeclarearrow{
+ name = spaced [-spaced ],
+ means = square bracket[].space
+}%
+
+\pgfdeclarearrow{
+ name = spaced ]-spaced [,
+ means = square bracket[reversed].space
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibrarycurvilinear.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibrarycurvilinear.code.tex
new file mode 100644
index 0000000000..12f26ccbdf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibrarycurvilinear.code.tex
@@ -0,0 +1,379 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarycurvilinear.code.tex}
+
+%
+% This file defines commands for computing points in curvilinear
+% coordinate systems.
+%
+
+
+%
+% Curvilinear coordinate systems defined in terms of a Bezier curve.
+%
+% For the following coordinate systems, you must first provide a
+% Bezier curve (using, as always, four points), which will be set for
+% the current scope. When the curve is "installed" some expensive
+% precomputations are done; subsequent calls to
+% \pgfpointcurvilinearxxx based on this Bezier curve will be
+% relatively quick.
+%
+
+
+
+% Install a Bezier curve
+%
+% #1 = start point
+% #2 = first control point
+% #3 = second control point
+% #4 = end point
+%
+% Description:
+%
+% Subsequent calls to functions like
+% \pgfpointcurvilinearbezierorthogonal will be relative to the curve
+% installed using this command. The main job of this macro is a
+% precomputation for computing length along the curve.
+% All lengths along the Bezier curve are approximated using a lookup table
+% of four time/length points. For this, an approximate time for length
+% 1pt is computed first, and then the length for twice this time, four
+% times this time, and eight times this time are approximated. A
+% distance-to-time conversion is then done by a linear interpolation
+% of distance-to-time for these four points. Note that all of these
+% computations are not particularly precise, but a compromise trading
+% speed against precision. Also note that the results will only be
+% best near the start of the curve and may be far off near the end if
+% that end is degenerate (second control point very near to end
+% point).
+%
+% Example:
+%
+% \pgfsetcurvilinearbeziercurve
+% {\pgfpoint{0mm}{10mm}}
+% {\pgfpoint{5.5mm}{10mm}}
+% {\pgfpoint{10mm}{5.5mm}}
+% {\pgfpoint{10mm}{0mm}} % nearly a quarter circle
+% \pgfpointcurvilinearbezierorthogonal{5mm}{5mm}
+% % should be 5mm along the circle, put at
+% % distance 15mm from the origin (5mm from the circle line).
+
+\def\pgfsetcurvilinearbeziercurve#1#2#3#4{%
+ \pgf@process{#1}%
+ \edef\pgf@curvilinear@line@a{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@xa=-\pgf@x%
+ \pgf@ya=-\pgf@y%
+ \pgf@process{#2}%
+ \edef\pgf@curvilinear@line@b{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@xb=-\pgf@x%
+ \pgf@yb=-\pgf@y%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@lenab\pgfmathresult%
+ \pgf@process{#3}%
+ \edef\pgf@curvilinear@line@c{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@xc=-\pgf@x%
+ \pgf@yc=-\pgf@y%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@lenbc\pgfmathresult%
+ \pgf@process{#4}%
+ \edef\pgf@curvilinear@line@d{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@lencd\pgfmathresult
+ %
+ \pgf@x=\pgf@curvilinear@lenab pt%
+ \advance\pgf@x by\pgf@curvilinear@lenbc pt%
+ \advance\pgf@x by\pgf@curvilinear@lencd pt%
+ \pgfmathreciprocal@{\pgf@sys@tonumber\pgf@x}%
+ \pgf@curvilinear@time@a\pgfmathresult pt%
+ \pgf@process{\pgfpointcurveattime{\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}%
+ \pgf@xb=-\pgf@x%
+ \pgf@yb=-\pgf@y%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \pgf@curvilinear@length@a\pgfmathresult pt%
+ \ifdim\pgf@curvilinear@length@a>1pt\relax%
+ % Ok, too large, let us make this smaller
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@curvilinear@length@a}%
+ \pgf@curvilinear@time@a\pgfmathresult pt%
+ \pgf@process{\pgfpointcurveattime{\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}
+ \pgf@xb=-\pgf@x%
+ \pgf@yb=-\pgf@y%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \pgf@curvilinear@length@a\pgfmathresult pt%
+ \fi%
+ % Compute three positions:
+ \pgf@process{\pgfpointcurveattime{2\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}
+ \pgf@xa=-\pgf@x%
+ \pgf@ya=-\pgf@y%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \pgf@curvilinear@length@b\pgfmathresult pt%
+ \advance\pgf@curvilinear@length@b by\pgf@curvilinear@length@a%
+ \pgf@process{\pgfpointcurveattime{4\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}
+ \pgf@xb=-\pgf@x%
+ \pgf@yb=-\pgf@y%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \pgf@curvilinear@length@c\pgfmathresult pt%
+ \advance\pgf@curvilinear@length@c by\pgf@curvilinear@length@b%
+ \pgf@process{\pgfpointcurveattime{8\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ \pgf@curvilinear@length@d\pgfmathresult pt%
+ \advance\pgf@curvilinear@length@d by\pgf@curvilinear@length@c%
+ \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@initial%
+ \let\pgf@curvilinear@comp@b\pgf@curvilinear@comp@b@initial%
+ \let\pgf@curvilinear@comp@c\pgf@curvilinear@comp@c@initial%
+ \let\pgf@curvilinear@comp@d\pgf@curvilinear@comp@d@initial%
+ \let\pgf@curvilinear@comp@e\pgf@curvilinear@comp@e@initial%
+ \let\pgf@curvilinear@point\pgf@curvilinear@curve@point%
+}%
+\newdimen\pgf@curvilinear@time@a
+\newdimen\pgf@curvilinear@length@a
+\newdimen\pgf@curvilinear@length@b
+\newdimen\pgf@curvilinear@length@c
+\newdimen\pgf@curvilinear@length@d
+
+
+\def\pgf@curvilinear@comp@a@initial{%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@curvilinear@length@a}%
+ \let\pgf@curvilinear@quot@a\pgfmathresult%
+ \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@cont%
+ \pgf@curvilinear@comp@a@cont%
+}%
+\def\pgf@curvilinear@comp@a@cont{%
+ \pgf@x\pgf@curvilinear@quot@a\pgf@x%
+}%
+
+\def\pgf@curvilinear@comp@b@initial{%
+ \pgf@y=\pgf@curvilinear@length@b%
+ \advance\pgf@y by-\pgf@curvilinear@length@a%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@quot@b\pgfmathresult%
+ \pgf@y\pgfmathresult\pgf@curvilinear@length@a%
+ \pgf@y-\pgf@y%
+ \advance\pgf@y by\pgf@curvilinear@time@a%
+ \edef\pgf@curvilinear@correct@b{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@comp@b\pgf@curvilinear@comp@b@cont%
+ \pgf@curvilinear@comp@b@cont%
+}%
+\def\pgf@curvilinear@comp@b@cont{%
+ \pgf@x\pgf@curvilinear@quot@b\pgf@x%
+ \advance\pgf@x by\pgf@curvilinear@correct@b pt%
+}%
+
+\def\pgf@curvilinear@comp@c@initial{%
+ \pgf@y=\pgf@curvilinear@length@c%
+ \advance\pgf@y by-\pgf@curvilinear@length@b%
+ \pgf@y.5\pgf@y%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@quot@c\pgfmathresult%
+ \pgf@y\pgf@curvilinear@quot@c\pgf@curvilinear@length@b%
+ \pgf@y-\pgf@y%
+ \advance\pgf@y by2\pgf@curvilinear@time@a%
+ \edef\pgf@curvilinear@correct@c{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@comp@c\pgf@curvilinear@comp@c@cont%
+ \pgf@curvilinear@comp@c@cont%
+}%
+\def\pgf@curvilinear@comp@c@cont{%
+ \pgf@x\pgf@curvilinear@quot@c\pgf@x%
+ \advance\pgf@x by\pgf@curvilinear@correct@c pt%
+}%
+
+\def\pgf@curvilinear@comp@d@initial{%
+ \pgf@y=\pgf@curvilinear@length@d%
+ \advance\pgf@y by-\pgf@curvilinear@length@c%
+ \pgf@y.25\pgf@y%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@quot@d\pgfmathresult%
+ \pgf@y\pgf@curvilinear@quot@d\pgf@curvilinear@length@c%
+ \pgf@y-\pgf@y%
+ \advance\pgf@y by4\pgf@curvilinear@time@a%
+ \edef\pgf@curvilinear@correct@d{\pgf@sys@tonumber\pgf@y}%
+ \let\pgf@curvilinear@comp@d\pgf@curvilinear@comp@d@cont%
+ \pgf@curvilinear@comp@d@cont%
+}%
+\def\pgf@curvilinear@comp@d@cont{%
+ \pgf@x\pgf@curvilinear@quot@d\pgf@x%
+ \advance\pgf@x by\pgf@curvilinear@correct@d pt%
+}%
+
+\def\pgf@curvilinear@comp@e@initial{%
+ \pgfmathmultiply@{8}{\pgf@sys@tonumber\pgf@curvilinear@time@a}%
+ \expandafter\pgfmathdivide@\expandafter{\pgfmathresult}{\pgf@sys@tonumber\pgf@curvilinear@length@d}%
+ \let\pgf@curvilinear@quot@e\pgfmathresult%
+ \let\pgf@curvilinear@comp@e\pgf@curvilinear@comp@e@cont%
+ \pgf@curvilinear@comp@e@cont%
+}%
+\def\pgf@curvilinear@comp@e@cont{%
+ \pgf@x\pgf@curvilinear@quot@e\pgf@x%
+}%
+
+
+% Convert a distance into a time
+%
+% #1 = a distance
+%
+% Description:
+%
+% After having called \pgfsetcurvilinearbeziercurve, you can use this
+% macro to convert a distance into a time along the curve set in that
+% command. The result will be stored in \pgf@x. It will only be
+% reasonably precise for small nonnegative #1 (in particular, #1
+% should not be more than about half the length of the curve).
+
+\def\pgfcurvilineardistancetotime#1{%
+ \pgfmathsetlength{\pgf@x}{#1}%
+ \ifdim\pgf@x<\pgf@curvilinear@length@c\relax%
+ \ifdim\pgf@x<\pgf@curvilinear@length@a\relax%
+ \pgf@curvilinear@comp@a%
+ \else\ifdim\pgf@x<\pgf@curvilinear@length@b\relax%
+ \pgf@curvilinear@comp@b%
+ \else%
+ \pgf@curvilinear@comp@c%
+ \fi\fi%
+ \else\ifdim\pgf@x<\pgf@curvilinear@length@d\relax%
+ \pgf@curvilinear@comp@d%
+ \else%
+ \pgf@curvilinear@comp@e%
+ \fi\fi%
+}%
+
+
+
+% Compute a "Bezier-orthogonal" point for use in a nonlinear transformation.
+%
+% #1 = x
+% #2 = y
+%
+% Description:
+%
+% In this coordinate system, the x-axis "goes along" the Bezier curve
+% installed using \pgfsetcurvilinearbeziercurve
+% and the y-axis is always perpendicular to the (Bezier) curve at the
+% given x-coordinate. Formally, given a pair (x,y), let B(x) be the point on
+% the Bezier curve B at distance x from the start of the curve. Let
+% T(x) be the tangent of B at B(x) and let P(x) be the (normalized)
+% vector perpendicular to T(x). Then (x,y) would be mapped to B(x) +
+% y*P(x). As an example, if B is a circle, then the corresponding
+% curvilinear coordinate system is (essentially, except for an offset in
+% the y value) the polar coordinate system.
+%
+% In addition to setting \pgf@x and \pgf@y, \pgf@xa/ya will be set to
+% a tangent along the curve at the given point and \pgf@xb/yb to a
+% tangent orthogonal to the curve.
+
+\def\pgfpointcurvilinearbezierorthogonal#1#2{%
+ \pgfmathsetmacro\pgf@curvilinear@yfactor{#2}%
+ \pgfcurvilineardistancetotime{#1}%
+ \pgfpointcurveattime{\pgf@x}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}
+ \pgf@xc\pgf@x% save
+ \pgf@yc\pgf@y% save
+ % compute normal:
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \ifdim\pgf@xb<0.0001pt\ifdim\pgf@xb>-0.0001pt\ifdim\pgf@yb<0.0001pt\ifdim\pgf@yb>-0.0001pt\pgf@diff@curvi@ac\fi\fi\fi\fi
+ \pgf@process{\pgfpointnormalised{\pgf@x=\pgf@yb\pgf@y=-\pgf@xb}}
+ \pgf@x\pgf@curvilinear@yfactor\pgf@x%
+ \pgf@y\pgf@curvilinear@yfactor\pgf@y%
+ \advance\pgf@x by\pgf@xc%
+ \advance\pgf@y by\pgf@yc%
+}%
+
+\def\pgf@diff@curvi@ac{%
+ \pgf@curvilinear@line@a%
+ \pgf@xa\pgf@x\pgf@ya\pgf@y%
+ \pgf@curvilinear@line@c%
+ \pgf@xb\pgf@x\pgf@yb\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \ifdim\pgf@xb<0.0001pt\ifdim\pgf@xb>-0.0001pt\ifdim\pgf@yb<0.0001pt\ifdim\pgf@yb>-0.0001pt% still degenerate!
+ \pgf@curvilinear@line@d%
+ \pgf@xb\pgf@x\pgf@yb\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \fi\fi\fi\fi%
+ \pgf@xb-\pgf@xb%
+ \pgf@yb-\pgf@yb%
+}%
+
+
+
+% Compute a "Bezier-polar" point.
+%
+% #1 = x
+% #2 = y
+%
+% Description:
+%
+% Let (r:d) be the point (x,y) in polar coordinates, that is, r is the
+% angle and d the distance of (x,y) to the origin. The point returned
+% by \pgfpointcurvilinearbezierpolar is now defined as follows: First,
+% we compute that point at distance d along the Bezier curve B. Let
+% B(d) be this point. Then, we rotate this point around the start of
+% the curve (B(0)) by r degrees.
+%
+% As an example, consider a triangle with one tip at the origin and
+% the other tips as (4cm,3cm) and (4cm,-3cm). Then this triangle would be
+% transformed as follows: We take the first 5cm of the Bezier curve
+% and rotate it by roughly 37 degrees to the left and by 37 degrees to
+% the right.
+%
+% Note that this command is pretty expensive.
+
+\def\pgfpointcurvilinearbezierpolar#1#2{%
+ \pgfmathsetlength\pgfutil@tempdima{#1}%
+ \pgfmathsetlength\pgfutil@tempdimb{#2}%
+ % Compute angle:
+ \pgfpointnormalised{\pgfqpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}%
+ \ifdim\pgfutil@tempdimb=0pt\relax\ifdim\pgfutil@tempdima=0pt\pgf@x1pt\pgf@y0pt\fi\fi%
+ \ifdim\pgfutil@tempdima<0pt%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ \fi%
+ \pgf@ya=-\pgf@y%
+ \pgfsettransformentries%
+ {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{0pt}{0pt}%
+ \pgftransformshift{\pgfpointscale{-1}{\pgf@curvilinear@line@a}}%
+ \pgfmathveclen@{\pgf@sys@tonumber\pgfutil@tempdima}{\pgf@sys@tonumber\pgfutil@tempdimb}%
+ \ifdim\pgfutil@tempdima<0pt%
+ \edef\pgfmathresult{-\pgfmathresult}%
+ \fi%
+ \pgfcurvilineardistancetotime{\pgfmathresult}%
+ % Now, transform:
+ \pgf@process{%
+ \pgfpointadd{%
+ \pgfpointtransformed{%
+ \pgfpointcurveattime%
+ {\pgf@x}%
+ {\pgf@curvilinear@line@a}%
+ {\pgf@curvilinear@line@b}%
+ {\pgf@curvilinear@line@c}%
+ {\pgf@curvilinear@line@d}%
+ }%
+ }%
+ \pgf@curvilinear@line@a%
+ }%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryfadings.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryfadings.code.tex
new file mode 100644
index 0000000000..c8ce556b40
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryfadings.code.tex
@@ -0,0 +1,57 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryfadings.code.tex}
+
+
+% Axial fadings
+
+\pgfdeclarehorizontalshading{pgf@lib@fade@east}{100bp}
+{color(0bp)=(pgftransparent!0); color(25bp)=(pgftransparent!0);
+ color(75bp)=(pgftransparent!100); color(100bp)=(pgftransparent!100)}%
+
+\pgfdeclarehorizontalshading{pgf@lib@fade@west}{100bp}
+{color(0bp)=(pgftransparent!100); color(25bp)=(pgftransparent!100);
+ color(75bp)=(pgftransparent!0); color(100bp)=(pgftransparent!0)}%
+
+\pgfdeclareverticalshading{pgf@lib@fade@north}{100bp}
+{color(0bp)=(pgftransparent!0); color(25bp)=(pgftransparent!0);
+ color(75bp)=(pgftransparent!100); color(100bp)=(pgftransparent!100)}%
+
+\pgfdeclareverticalshading{pgf@lib@fade@south}{100bp}
+{color(0bp)=(pgftransparent!100); color(25bp)=(pgftransparent!100);
+ color(75bp)=(pgftransparent!0); color(100bp)=(pgftransparent!0)}%
+
+\pgfdeclarefading{east}{\pgfuseshading{pgf@lib@fade@east}}%
+\pgfdeclarefading{west}{\pgfuseshading{pgf@lib@fade@west}}%
+\pgfdeclarefading{north}{\pgfuseshading{pgf@lib@fade@north}}%
+\pgfdeclarefading{south}{\pgfuseshading{pgf@lib@fade@south}}%
+
+
+% Circular fadings
+
+\pgfdeclareradialshading{tikz@lib@fade@circle@10}{\pgfpointorigin}{
+ color(0pt)=(pgftransparent!0); color(22.5bp)=(pgftransparent!0);
+ color(25bp)=(pgftransparent!100); color(50bp)=(pgftransparent!100)}%
+\pgfdeclarefading{circle with fuzzy edge 10 percent}{\pgfuseshading{tikz@lib@fade@circle@10}}%
+
+\pgfdeclareradialshading{tikz@lib@fade@circle@15}{\pgfpointorigin}{
+ color(0pt)=(pgftransparent!0); color(21.25bp)=(pgftransparent!0);
+ color(25bp)=(pgftransparent!100); color(50bp)=(pgftransparent!100)}%
+\pgfdeclarefading{circle with fuzzy edge 15 percent}{\pgfuseshading{tikz@lib@fade@circle@15}}%
+
+\pgfdeclareradialshading{tikz@lib@fade@circle@20}{\pgfpointorigin}{
+ color(0pt)=(pgftransparent!0); color(20bp)=(pgftransparent!0);
+ color(25bp)=(pgftransparent!100); color(50bp)=(pgftransparent!100)}%
+\pgfdeclarefading{circle with fuzzy edge 20 percent}{\pgfuseshading{tikz@lib@fade@circle@20}}%
+
+\pgfdeclareradialshading{tikz@lib@fade@fuzzy@15}{\pgfpointorigin}{
+ color(0pt)=(pgftransparent!100); color(21.25bp)=(pgftransparent!100); color(23.125bp)=(pgftransparent!0);
+ color(25bp)=(pgftransparent!100); color(50bp)=(pgftransparent!100)}%
+\pgfdeclarefading{fuzzy ring 15 percent}{\pgfuseshading{tikz@lib@fade@fuzzy@15}}%
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryfixedpointarithmetic.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryfixedpointarithmetic.code.tex
new file mode 100644
index 0000000000..b10c7b795c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryfixedpointarithmetic.code.tex
@@ -0,0 +1,656 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Free Documentation License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+\pgfkeys{/pgf/.cd,
+ fixed point arithmetic/.code={%
+ \pgfmathfp@plots@install%
+ \pgfmathfp@parser@install%
+ \let\pgfmathparse=\pgfmathfpparse%
+ \pgfkeys{/pgf/fixed point/.cd, #1}%
+ },%
+ fixed point/.cd,
+ scale results/.code={%
+ \pgfmathfpparse{#1}%
+ \let\pgfmathfpscale=\pgfmathresult%
+ }%
+}%
+
+\def\pgfmathfpscale{1}%
+
+\def\pgfmathfpparse{%
+ \begingroup%
+ \let\pgfmathpostparse=\relax%
+ \pgfmath@catcodes%
+ \pgfmath@quickparsefalse%
+ \pgfmathfpparse@}%
+
+\def\pgfmathfpparse@#1{%
+ \edef\pgfmathfp@expression{#1}%
+ \expandafter\pgfmathfpparse@@\pgfmathfp@expression\pgfmathfp@}%
+
+\def\pgfmathfp@char@asterisk{*}%
+\def\pgfmathfpparse@@#1#2\pgfmathfp@{%
+ \def\pgfmathfp@test{#1}%
+ \ifx\pgfmathfp@test\pgfmathfp@char@asterisk%
+ \edef\pgfmathfp@expression{\pgfmathfpscale#1#2}%
+ \else%
+ \edef\pgfmathfp@expression{#1#2}%
+ \fi%
+ \expandafter\pgfmathparse@\expandafter{\pgfmathfp@expression}%
+ % \endgroup provided by \pgfpathmarse@end
+}%
+
+% Crude handling of file plots
+%
+\pgfkeys{/pgf/fixed point/.cd,
+ scale file plot x/.code=\pgfmathfpparse{#1}\edef\pgfmathfpplotscalex{\pgfmathresult*},
+ scale file plot y/.code=\pgfmathfpparse{#1}\edef\pgfmathfpplotscaley{\pgfmathresult*},
+ scale file plot z/.code=\pgfmathfpparse{#1}\edef\pgfmathfpplotscalez{\pgfmathresult*},
+}%
+
+\def\pgfmathfp@plots@install{%
+ \let\pgfmathfpplotscalex=\pgfutil@empty
+ \let\pgfmathfpplotscaley=\pgfutil@empty
+ \let\pgfmathfpplotscalez=\pgfutil@empty
+ \let\pgf@parsexyline=\pgfmathfp@parsexyline%
+ \let\pgf@parsexyzline=\pgfmathfp@parsexyzline%
+}%
+
+\def\pgfmathfp@parsexyline#1 #2 #3\pgf@stop{%
+ \edef\pgfmathfp@marshal{%
+ \noexpand\pgfplotstreampoint{\noexpand\pgfpointxy{\pgfmathfpplotscalex#1}{\pgfmathfpplotscaley#2}}%
+ }%
+ \pgfmathfp@marshal%
+}%
+
+\def\pgfmathfp@parsexyzline#1 #2 #3 #4\pgf@stop{%
+ \edef\pgfmathfp@marshal{%
+ \noexpand\pgfplotstreampoint{%
+ \noexpand\pgfpointxyz{\pgfmathfpplotscalex#1}{\pgfmathfpplotscaley#2}{\pgfmathfpplotscalez#3}%
+ }%
+ }%
+ \pgfmathfp@marshal%
+}%
+
+%
+\def\pgfmathfp@parser@install{%
+ %
+ \expandafter\ifx\csname FP@version\endcsname\relax%
+ \pgferror{You need to say `\string\usepackage{fp}' to use %
+ fixed point arithmetic}%
+ \else%
+ %
+ % Don't want messages.
+ %
+ \FPmessagesfalse%
+ \FPdebugfalse%
+ %
+ % Install float commands...
+ %
+ \let\pgfmathadd@=\pgfmathfpadd@%
+ \let\pgfmathsubtract@=\pgfmathfpsubtract@%
+ \let\pgfmathmultiply@=\pgfmathfpmultiply@%
+ \let\pgfmathdivide@=\pgfmathfpdivide@%
+ \let\pgfmathabs@=\pgfmathfpabs@%
+ \let\pgfmathneg@=\pgfmathfpneg@%
+ \let\pgfmathround@=\pgfmathfpround@%
+ \let\pgfmathfloor@=\pgfmathfpfloor@%
+ \let\pgfmathceil@=\pgfmathfpceil@%
+ \let\pgfmathmod@=\pgfmathfpmod@%
+ \let\pgfmathmax@=\pgfmathfpmax@%
+ \let\pgfmathmin@=\pgfmathfpmin@%
+ \let\pgfmathsin@=\pgfmathfpsin@%
+ \let\pgfmathcos@=\pgfmathfpcos@%
+ \let\pgfmathtan@=\pgfmathfptan@%
+ \let\pgfmathdeg@=\pgfmathfpdeg@%
+ \let\pgfmathrad@=\pgfmathfprad@%
+ \let\pgfmathatan@=\pgfmathfpatan@%
+ \let\pgfmathasin@=\pgfmathfpasin@%
+ \let\pgfmathacos@=\pgfmathfpacos@%
+ \let\pgfmathcot@=\pgfmathfpcot@%
+ \let\pgfmathsec@=\pgfmathfpsec@%
+ \let\pgfmathcosec@=\pgfmathfpcosec@%
+ \let\pgfmathpow@=\pgfmathfppow@%
+ \let\pgfmathexp@=\pgfmathfpexp@%
+ \let\pgfmathln@=\pgfmathfpln@%
+ \let\pgfmathsqrt@=\pgfmathfpsqrt@%
+ \let\pgfmath@pi=\pgfmathfppi@%
+ \let\pgfmathveclen@=\pgfmathfpveclen@%
+ \let\pgfmathe@=\pgfmathfpe@%
+ %
+ \let\pgfmathlessthan@=\pgfmathfplessthan@%
+ \let\pgfmathgreaterthan@=\pgfmathfpgreaterthan@%
+ \let\pgfmathequalto@=\pgfmathfpequalto@%
+ %
+ \let\pgfmathrnd=\pgfmathfprnd%
+ \let\pgfmathrand=\pgfmathfprand%
+ \let\pgfmathsetseed=\pgfmathfpsetseed%
+ %
+ \let\pgfmathscientific=\pgfmathfpscientific%
+ \fi%
+}%
+
+\def\pgfmathfpe@{let\pgfmathresult=\FPe}%
+\def\pgfmathfppi@{let\pgfmathresult=\FPpi}%
+
+
+% Scientific notation.
+
+\def\pgfmathfpscientific#1#2{%
+ \begingroup%
+ \FPpow\pgfmathresult{10}{#2}\unskip% Needed.
+ \FPmul\pgfmathresult{#1}{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% Comparison stuff...
+
+% lessthan
+%
+\def\pgfmathfplessthan#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfplessthan@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfplessthan@#1#2{%
+ \begingroup%
+ \FPiflt{#1}{#2}%
+ \def\pgfmathresult{1.0}%
+ \else%
+ \def\pgfmathresult{0.0}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% greaterthan
+%
+\def\pgfmathfpgreaterthan#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpgreaterthan@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpgreaterthan@#1#2{%
+ \begingroup%
+ \FPifgt{#1}{#2}%
+ \def\pgfmathresult{1.0}%
+ \else%
+ \def\pgfmathresult{0.0}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% equalto
+%
+\def\pgfmathfpequalto#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpequalto@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpequalto@#1#2{%
+ \begingroup%
+ \FPifeq{#1}{#2}%
+ \def\pgfmathresult{1.0}%
+ \else%
+ \def\pgfmathresult{0.0}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+
+% Basic arithmetic stuff...
+
+% add
+%
+\def\pgfmathfpadd#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpadd@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpadd@#1#2{%
+ \begingroup%
+ \FPadd\pgfmathresult{#1}{#2}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% subtract
+%
+\def\pgfmathfpsubtract#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpsubtract@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpsubtract@#1#2{%
+ \begingroup%
+ \FPsub\pgfmathresult{#1}{#2}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% multiply
+%
+\def\pgfmathfpmultiply#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpmultiply@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpmultiply@#1#2{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{#2}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% divide
+%
+\def\pgfmathfpdivide#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpdivide@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpdivide@#1#2{%
+ \begingroup%
+ \FPdiv\pgfmathresult{#1}{#2}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% abs
+%
+\def\pgfmathfpabs#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpabs@{\pgfmathresult}%
+}%
+\def\pgfmathfpabs@#1{%
+ \begingroup%
+ \FPabs\pgfmathresult{#1}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% neg
+%
+\def\pgfmathfpneg#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpneg@{\pgfmathresult}%
+}%
+\def\pgfmathfpneg@#1{%
+ \begingroup%
+ \FPneg\pgfmathresult{#1}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup%
+}%
+
+% round
+%
+\def\pgfmathfpround#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpround@{\pgfmathresult}%
+}%
+\def\pgfmathfpround@#1{%
+ \begingroup%
+ \FPround\pgfmathresult{#1}{0}%
+ \edef\pgfmathresult{\pgfmathresult.0}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% floor
+%
+\def\pgfmathfpfloor#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpfloor@{\pgfmathresult}%
+}%
+\def\pgfmathfpfloor@#1{%
+ \begingroup%
+ \FPtrunc\pgfmathresult{#1}{0}%
+ \FPifneg{#1}%
+ \FPsub\pgfmathresult{\pgfmathresult}{1}%
+ \fi%
+ \edef\pgfmathresult{\pgfmathresult.0}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% ceil
+%
+\def\pgfmathfpceil#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpceil@{\pgfmathresult}%
+}%
+\def\pgfmathfpceil@#1{%
+ \begingroup%
+ \FPtrunc\pgfmathresult{#1}{0}%
+ \FPifpos{#1}%
+ \FPadd\pgfmathresult{\pgfmathresult}{1}%
+ \fi%
+ \edef\pgfmathresult{\pgfmathresult.0}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% mod
+%
+\def\pgfmathfpmod#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpmod@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpmod@#1#2{%
+ \begingroup%
+ \FPdiv\pgfmathresult{#1}{#2}%
+ \FPtrunc\pgfmathresult{\pgfmathresult}{0}%
+ \FPmul\pgfmathresult{\pgfmathresult}{#2}%
+ \FPsub\pgfmathresult{#1}{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% max
+%
+\def\pgfmathfpmax#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpmax@@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpmax@#1{%
+ \pgfmathfpmax@@#1%
+}%
+\def\pgfmathfpmax@@#1#2{%
+ \begingroup%
+ \FPifgt{#1}{#2}%
+ \def\pgfmathresult{#1}%
+ \else%
+ \def\pgfmathresult{#2}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% min
+%
+\def\pgfmathfpmin#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpmin@@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpmin@#1{%
+ \pgfmathfpmin@@#1%
+}%
+\def\pgfmathfpmin@@#1#2{%
+ \begingroup%
+ \FPiflt{#1}{#2}%
+ \def\pgfmathresult{#1}%
+ \else%
+ \def\pgfmathresult{#2}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% Functions...
+
+% pow
+%
+\def\pgfmathfppow#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfppow@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfppow@#1#2{%
+ \begingroup%
+ \FPpow\pgfmathresult{#1}{#2}\unskip%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% exp
+%
+\def\pgfmathfpexp#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpexp@{\pgfmathresult}%
+}%
+\def\pgfmathfpexp@#1{%
+ \begingroup%
+ \FPexp\pgfmathresult{#1}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% ln
+%
+\def\pgfmathfpln#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpln@{\pgfmathresult}%
+}%
+\def\pgfmathfpln@#1{%
+ \begingroup%
+ \FPln\pgfmathresult{#1}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% sqrt
+%
+\def\pgfmathfpsqrt#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpsqrt@{\pgfmathresult}%
+}%
+\def\pgfmathfpsqrt@#1{%
+ \begingroup%
+ \FProot\pgfmathresult{#1}{2}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% veclen
+%
+\def\pgfmathfpveclen#1#2{%
+ \pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpveclen@{\pgfmathresult}{\pgfmath@result}%
+}%
+\def\pgfmathfpveclen@#1#2{%
+ \begingroup%
+ \FPmul\pgfmath@result{#1}{#1}%
+ \FPmul\pgfmath@@result{#2}{#2}%
+ \FPadd\pgfmathresult{\pgfmath@result}{\pgfmath@@result}%
+ \FProot\pgfmathresult{\pgfmathresult}{2}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% Trigonometric stuff...
+
+% sin
+%
+\def\pgfmathfpsin#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpsin@{\pgfmathresult}%
+}%
+\def\pgfmathfpsin@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{0.017453292519943295}%
+ \FPsin\pgfmathresult{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% cos
+%
+\def\pgfmathfpcos#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpcos@{\pgfmathresult}%
+}%
+\def\pgfmathfpcos@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{0.017453292519943295}%
+ \FPcos\pgfmathresult{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% tan
+%
+\def\pgfmathfptan#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfptan@{\pgfmathresult}%
+}%
+\def\pgfmathfptan@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{0.017453292519943295}%
+ \FPtan\pgfmathresult{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% acos
+%
+\def\pgfmathfpacos#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpacos@{\pgfmathresult}%
+}%
+\def\pgfmathfpacos@#1{%
+ \begingroup%
+ \FParccos\pgfmathresult{#1}%
+ \FPmul\pgfmathresult{\pgfmathresult}{57.295779513082320885}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% asin
+%
+\def\pgfmathfpasin#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpasin@{\pgfmathresult}%
+}%
+\def\pgfmathfpasin@#1{%
+ \begingroup%
+ \FParcsin\pgfmathresult{#1}%
+ \FPmul\pgfmathresult{\pgfmathresult}{57.295779513082320885}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% atan
+%
+\def\pgfmathfpatan#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpatan@{\pgfmathresult}%
+}%
+\def\pgfmathfpatan@#1{%
+ \begingroup%
+ \FParctan\pgfmathresult{#1}%
+ \FPmul\pgfmathresult{\pgfmathresult}{57.295779513082320885}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% cot
+%
+\def\pgfmathfpcot#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpcot@{\pgfmathresult}%
+}%
+\def\pgfmathfpcot@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{0.017453292519943295}%
+ \FPcot\pgfmathresult{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% sec
+%
+\def\pgfmathfpsec#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpsec@{\pgfmathresult}%
+}%
+\def\pgfmathfpsec@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{0.017453292519943295}%
+ \FPcos\pgfmathresult{\pgfmathresult}%
+ \FPdiv\pgfmathresult{1}{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% cosec
+%
+\def\pgfmathfpcosec#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpcosec@{\pgfmathresult}%
+}%
+\def\pgfmathfpcosec@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{0.017453292519943295}%
+ \FPsin\pgfmathresult{\pgfmathresult}%
+ \FPdiv\pgfmathresult{1}{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% deg
+%
+\def\pgfmathfpdeg#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfpdeg@{\pgfmathresult}%
+}%
+\def\pgfmathfpdeg@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{57.295779513082320885}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% rad
+%
+\def\pgfmathfprad#1{%
+ \pgfmathfpparse{#1}%
+ \pgfmathfprad@{\pgfmathresult}%
+}%
+\def\pgfmathfprad@#1{%
+ \begingroup%
+ \FPmul\pgfmathresult{#1}{0.01745329251994325}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% Random stuff...
+
+\def\pgfmathfpsetseed#1{%
+ \pgfmathfpparse{#1}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \FPseed\pgfmathresult\relax\pgfmath@%
+}%
+
+% rnd
+%
+\def\pgfmathfprnd{%
+ \begingroup%
+ \FPrandom\pgfmathresult%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+
+% rand
+%
+\def\pgfmathfprand{%
+ \begingroup%
+ \FPrandom\pgfmathresult%
+ \FPmul\pgfmathresult{2}{\pgfmathresult}%
+ \FPsub\pgfmathresult{\pgfmathresult}{1}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryfpu.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryfpu.code.tex
new file mode 100644
index 0000000000..a93fa7f90a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryfpu.code.tex
@@ -0,0 +1,2392 @@
+% Copyright 2008/2019 by Christian Feuersaenger
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU General Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\newif\ifpgfmathfloatparseactive
+\newif\ifpgfmathfloat@scaleactive
+
+% public macro which invokes '#1' if the fpu is installed and ready and '#2'
+% otherwise.
+\def\pgflibraryfpuifactive#1#2{%
+ \ifpgfmathfloatparseactive
+ #1%
+ \else
+ #2%
+ \fi
+}%
+
+\pgfqkeys{/pgf}{
+ % enable the FPU parser if it is not yet active
+ %
+ % It will be deactivated after the current TeX group
+ fpu/.is choice,
+ fpu/true/.code={%
+ \ifpgfmathfloatparseactive
+ \else
+ \pgfutil@ifundefined{pgfmathdeclarefunction}{%
+ % Ohoh - we are running on a TeX distribution with
+ % PGF 2.00 which doesn't have the new math engine.
+ % I can provide special treatment here, provided that
+ % all float commands are still able to run (that means
+ % more information needs to be copied from the pgf cvs
+ % to pgf 2.00 - for example pgfmathfloat.code.tex).
+ %
+ % I employ this to work with pgfplots and pgf 2.00
+ % using all new features.
+ \pgfmathfloat@parser@install@pgf@two@null@null%
+ }{%
+ \pgfmathfloat@parser@install%
+ }%
+ \pgfmathfloatparseactivetrue
+ % improve compatibility with Marks FP library:
+ \pgfkeysalso{/pgf/fixed point arithmetic/.prefix style={/pgf/fpu=false}}%
+ \fi
+ },%
+ fpu/false/.code={%
+ \ifpgfmathfloatparseactive
+ \pgfmathfloat@uninstall%
+ \pgfmathfloatparseactivefalse
+ \fi
+ },%
+ fpu/.default=true,
+ % Use this to introduce a result scaling.
+ % Every expression in which the prefix '*' occurs
+ % will be multiplied with the result and converted to fixed point
+ % representation.
+ fpu/scale results/.code={%
+ \ifpgfmathfloatparseactive
+ \pgfmathparse{#1}%
+ \else
+ \pgfmathfloatparsenumber{#1}%
+ \fi
+ \let\pgfmathfloatscale=\pgfmathresult%
+ },%
+ % determines the output format of each complete expression parsing
+ % process. If 'scale results' is active, 'fixed' is assumed
+ % automatically.
+ fpu/output format/.is choice,
+ fpu/output format/float/.code= {%
+ \def\pgfmathfloatparse@output@choice{Y}%
+ \let\pgfmathfloatparse@output=\relax
+ },
+ fpu/output format/sci/.code= {%
+ \def\pgfmathfloatparse@output@choice{S}%
+ \def\pgfmathfloatparse@output{\pgfmathfloattosci@{\pgfmathresult}}%
+ },
+ fpu/output format/fixed/.code= {%
+ \def\pgfmathfloatparse@output@choice{F}%
+ \def\pgfmathfloatparse@output{\pgfmathfloattofixed@{\pgfmathresult}}%
+ },
+ fpu/output format/float,
+ fpu/rel thresh/.code={%
+ \pgfmathfloatparsenumber{#1}%
+ \let\pgfmathfloat@relthresh=\pgfmathresult
+ },
+ fpu/rel thresh=1e-4,
+ fpu/install only/.code={
+ \edef\pgf@list{#1}%
+ \pgfutil@for\pgf@temp:=\pgf@list\do{%
+ \expandafter\pgfmath@float@install@singlefunction\expandafter{%
+ \romannumeral-`0\expandafter\pgfutil@trimspaces\expandafter{\pgf@temp}}%
+ }%
+ },
+}%
+
+\pgfmathfloatcreate{1}{1.0}{0}\let\pgfmathfloatscale=\pgfmathresult
+
+\let\pgfmathfloatone=\pgfmathresult
+
+% This is the replacement parser invocation.
+% It does two things which are different to \pgfmathparse:
+% 1. it disables any dimension dependent scalings,
+% 2. it implements the 'scale results' feature.
+\def\pgfmathfloatparse{%
+ \begingroup%
+ % disable any dimension-dependant scalings:
+ \let\pgfmathpostparse=\relax%
+ \pgfmath@catcodes%
+ \pgfmath@quickparsefalse%
+ \ifpgfmathfloatparseactive\else
+ \pgfmathfloat@parser@install
+ \fi
+ \pgfmathfloatparse@}%
+
+% for pgf 2.00 :
+\def\pgfmathfloatparse@pgf@two@null@null{%
+ \pgfmath@quickparsefalse%
+ \pgfmathfloatparse@}%
+
+\def\pgfmathfloatparse@#1{%
+ \edef\pgfmathfloat@expression{#1}%
+ \expandafter\pgfmathfloatparse@@\pgfmathfloat@expression\pgfmathfloat@
+ \ifpgfmathfloat@scaleactive
+ \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfmathfloatscale}%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \else
+ \pgfmathfloatparse@output
+ \fi
+ \ignorespaces
+}%
+
+\def\pgfmathfloat@char@asterisk{*}%
+\def\pgfmathfloatparse@@#1#2\pgfmathfloat@{%
+ \def\pgfmathfloat@test{#1}%
+ \ifx\pgfmathfloat@test\pgfmathfloat@char@asterisk%
+ \def\pgfmathfloat@expression{#2}%
+ \pgfmathfloat@scaleactivetrue
+ \fi%
+ \expandafter\pgfmathparse@\expandafter{\pgfmathfloat@expression}%
+ % \endgroup provided by \pgfpathmarse@end
+}%
+
+% Crude handling of file plots
+%
+\pgfkeys{/pgf/fpu/.cd,
+ scale file plot x/.code=\pgfmathfloatparse{#1}\edef\pgfmathfloatplotscalex{\pgfmathresult*},
+ scale file plot y/.code=\pgfmathfloatparse{#1}\edef\pgfmathfloatplotscaley{\pgfmathresult*},
+ scale file plot z/.code=\pgfmathfloatparse{#1}\edef\pgfmathfloatplotscalez{\pgfmathresult*}
+}%
+
+\def\pgfmathfloat@uninstall@appendcmd#1{%
+ \expandafter\gdef\expandafter\pgfmathfloat@uninstall\expandafter{\pgfmathfloat@uninstall #1}%
+}%
+
+% If the uninstall command is already assembled, it will skip the
+% uninstall assemblation.
+\def\pgfmathfloat@plots@checkuninstallcmd{%
+ \pgfutil@ifundefined{pgfmathfloat@uninstall}{%
+ \global\let\pgfmathfloat@uninstall=\pgfutil@empty
+ }{%
+ % We already HAVE an uninstall command (prepared globally).
+ % So: don't waste time assembling one!
+ \def\pgfmathfloat@uninstall@appendcmd##1{}%
+ \def\pgfmathfloat@prepareuninstallcmd##1{}%
+ }%
+}%
+
+% This assembles an uninstall command globally ON FIRST USAGE.
+% See \pgfmathfloat@plots@checkuninstallcmd
+\def\pgfmathfloat@prepareuninstallcmd#1{%
+ % and store backup information (globally - I don't want to do that
+ % all the time when the FPU is used!):
+ \expandafter\global\expandafter\let\csname pgfmathfloat@backup@\string#1\endcsname=#1%
+ \expandafter\gdef\expandafter\pgfmathfloat@uninstall\expandafter{\pgfmathfloat@uninstall
+ \expandafter\let\expandafter#1\csname pgfmathfloat@backup@\string#1\endcsname%
+ }%
+}%
+
+\def\pgfmathfloat@install#1=#2{%
+ \pgfmathfloat@prepareuninstallcmd{#1}%
+ \let#1=#2%
+}%
+\def\pgfmathfloat@install@csname#1#2{%
+ \expandafter\pgfmathfloat@prepareuninstallcmd\csname #1\endcsname%
+ \pgfutil@namelet{#1}{#2}%
+}%
+\def\pgfmathfloat@install@unimplemented#1{%
+ \expandafter\pgfmathfloat@prepareuninstallcmd\csname pgfmath#1@\endcsname%
+ \expandafter\def\csname pgfmath#1@\endcsname##1{\pgfmathfloat@notimplemented{#1}}%
+}%
+\def\pgfmathfloat@plots@install{%
+ \let\pgfmathfloatplotscalex=\pgfutil@empty
+ \let\pgfmathfloatplotscaley=\pgfutil@empty
+ \let\pgfmathfloatplotscalez=\pgfutil@empty
+ \pgfmathfloat@install\pgf@parsexyline=\pgfmathfloat@parsexyline%
+ \pgfmathfloat@install\pgf@parsexyzline=\pgfmathfloat@parsexyzline%
+}%
+\def\pgfmathfloat@parsexyline#1 #2 #3\pgf@stop{%
+ \edef\pgfmathfloat@marshal{%
+ \noexpand\pgfplotstreampoint{\noexpand\pgfpointxy{\pgfmathfloatplotscalex#1}{\pgfmathfloatplotscaley#2}}%
+ }%
+ \pgfmathfloat@marshal%
+}%
+\def\pgfmathfloat@parsexyzline#1 #2 #3 #4\pgf@stop{%
+ \edef\pgfmathfloat@marshal{%
+ \noexpand\pgfplotstreampoint{%
+ \noexpand\pgfpointxyz{\pgfmathfloatplotscalex#1}{\pgfmathfloatplotscaley#2}{\pgfmathfloatplotscalez#3}%
+ }%
+ }%
+ \pgfmathfloat@marshal%
+}%
+
+%
+\def\pgfmathfloat@parser@install@functions{%
+ % Install float commands...
+ %
+ \pgfmathfloat@install\pgfmathadd@=\pgfmathfloatadd@%
+ \pgfmathfloat@install\pgfmathsubtract@=\pgfmathfloatsubtract@%
+ \pgfmathfloat@install\pgfmathneg@=\pgfmathfloatneg@%
+ \pgfmathfloat@install\pgfmathmultiply@=\pgfmathfloatmultiply@%
+ \pgfmathfloat@install\pgfmathdivide@=\pgfmathfloatdivide@%
+ \pgfmathfloat@install\pgfmathabs@=\pgfmathfloatabs@%
+ \pgfmathfloat@install\pgfmathsign@=\pgfmathfloatsign@%
+ \pgfmathfloat@install\pgfmathround@=\pgfmathfloatround@%
+ \pgfmathfloat@install\pgfmathfloor@=\pgfmathfloatfloor@%
+ \pgfmathfloat@install\pgfmathceil@=\pgfmathfloatceil@
+ \pgfmathfloat@install\pgfmathint@=\pgfmathfloatint@
+ \pgfmathfloat@install\pgfmathmod@=\pgfmathfloatmod@%
+ \pgfmathfloat@install\pgfmathmax@=\pgfmathfloatmax@%
+ \pgfmathfloat@install\pgfmathmin@=\pgfmathfloatmin@%
+ \pgfmathfloat@install\pgfmathsin@=\pgfmathfloatsin@%
+ \pgfmathfloat@install\pgfmathcos@=\pgfmathfloatcos@%
+ \pgfmathfloat@install\pgfmathtan@=\pgfmathfloattan@%
+ \pgfmathfloat@install\pgfmathdeg@=\pgfmathfloatdeg@%
+ \pgfmathfloat@install\pgfmathrad@=\pgfmathfloatrad@%
+ \pgfmathfloat@install\pgfmathatan@=\pgfmathfloatatan@%
+ \pgfmathfloat@install\pgfmathasin@=\pgfmathfloatasin@%
+ \pgfmathfloat@install\pgfmathacos@=\pgfmathfloatacos@%
+ \pgfmathfloat@install\pgfmathcot@=\pgfmathfloatcot@%
+ \pgfmathfloat@install\pgfmathsec@=\pgfmathfloatsec@%
+ \pgfmathfloat@install\pgfmathcosec@=\pgfmathfloatcosec@%
+ \pgfmathfloat@install\pgfmathexp@=\pgfmathfloatexp@%
+ \pgfmathfloat@install\pgfmathln@=\pgfmathfloatln@%
+ \pgfmathfloat@install@csname{pgfmathlog10@}{pgfmathfloatlog10@}%
+ \pgfmathfloat@install@csname{pgfmathlog2@}{pgfmathfloatlog2@}%
+ \pgfmathfloat@install\pgfmathsqrt@=\pgfmathfloatsqrt@%
+ \pgfmathfloat@install\pgfmath@pi=\pgfmathfloatpi@%
+ \pgfmathfloat@install\pgfmathpi=\pgfmathfloatpi@%
+ \pgfmathfloat@install\pgfmathe@=\pgfmathfloate@%
+ \pgfmathfloat@install\pgfmathe=\pgfmathfloate@%
+ \pgfmathfloat@install\pgfmathlessthan@=\pgfmathfloatlessthan@%
+ \pgfmathfloat@install\pgfmathnotless@=\pgfmathfloatnotless@%
+ \pgfmathfloat@install\pgfmathnotgreater@=\pgfmathfloatnotgreater@%
+ \pgfmathfloat@install\pgfmathless@=\pgfmathfloatlessthan@%
+ \pgfmathfloat@install\pgfmathgreaterthan@=\pgfmathfloatgreaterthan@%
+ \pgfmathfloat@install\pgfmathgreater@=\pgfmathfloatgreaterthan@%
+ \pgfmathfloat@install\pgfmathifthenelse@=\pgfmathfloatifthenelse@%
+ \pgfmathfloat@install\pgfmathequal@=\pgfmathfloatequal@%
+ \pgfmathfloat@install\pgfmathequalto@=\pgfmathfloatequal@%
+ \pgfmathfloat@install\pgfmathnotequal@=\pgfmathfloatnotequal@%
+ \pgfmathfloat@install\pgfmathnotequalto@=\pgfmathfloatnotequal@%
+ \pgfmathfloat@install\pgfmathpow@=\pgfmathfloatpow@
+ \pgfmathfloat@install\pgfmathrand@=\pgfmathfloatrand@
+ \pgfmathfloat@install\pgfmathrand=\pgfmathfloatrand@
+ \pgfmathfloat@install\pgfmathrnd@=\pgfmathfloatrnd@
+ \pgfmathfloat@install\pgfmathrnd=\pgfmathfloatrnd@
+ \pgfmathfloat@install\pgfmathtrue@=\pgfmathfloattrue@
+ \pgfmathfloat@install\pgfmathfalse@=\pgfmathfloatfalse@
+ \pgfmathfloat@install\pgfmathnot@=\pgfmathfloatnot@
+ \pgfmathfloat@install\pgfmathhex@=\pgfmathfloathex@
+ \pgfmathfloat@install\pgfmathHex@=\pgfmathfloatHex@
+ \pgfmathfloat@install\pgfmathoct@=\pgfmathfloatoct@
+ \pgfmathfloat@install\pgfmathbin@=\pgfmathfloatbin@
+ \pgfmathfloat@install\pgfmathand@=\pgfmathfloatand@
+ \pgfmathfloat@install\pgfmathor@=\pgfmathfloator@
+ \pgfmathfloat@install\pgfmathfactorial@=\pgfmathfloatfactorial@
+ \pgfmathfloat@install\pgfmathveclen@=\pgfmathfloatveclen@
+ \pgfmathfloat@install\pgfmathcosh@=\pgfmathfloatcosh@
+ \pgfmathfloat@install\pgfmathsinh@=\pgfmathfloatsinh@
+ \pgfmathfloat@install\pgfmathtanh@=\pgfmathfloattanh@
+ \pgfmathfloat@install\pgfmath@iftrue=\pgfmathfloat@iftrue%
+ \expandafter\pgfmathfloat@install\csname pgfmathatan2@\endcsname=\pgfmathfloatatantwo@
+ \pgfmathfloat@install@unimplemented{isprime}%
+ \pgfmathfloat@install@unimplemented{iseven}%
+ \pgfmathfloat@install@unimplemented{isodd}%
+ \pgfmathfloat@install@unimplemented{gcd}%
+ \pgfmathfloat@install@unimplemented{frac}%
+ \pgfmathfloat@install@unimplemented{random}%
+ \pgfmathfloat@install@unimplemented{setseed}%
+ \pgfmathfloat@install@unimplemented{Mod}%
+ \pgfmathfloat@install@unimplemented{div}%
+ \pgfmathfloat@install@unimplemented{real}%
+% \pgfmathfloat@install@unimplemented{height}%
+ %
+ %
+ \pgfmathfloat@install\pgfmathscientific=\pgfmathfloatscientific%
+}%
+
+\def\pgfmath@float@install@singlefunction#1{%
+ \ifcsname pgfmath@function@#1\endcsname\else
+ \pgfmath@error{The function `#1' does not exist}{}%
+ \fi
+ \pgfmath@toks={}%
+ \pgfmathloop
+ \ifnum\pgfmathcounter>\csname pgfmath@operation@#1@arity\endcsname\relax%
+ \else
+ \expandafter\pgfmath@addto@toks\expandafter{\pgfmath@char@hash}%
+ \expandafter\pgfmath@addto@toks\expandafter{\pgfmathcounter}%
+ \repeatpgfmathloop
+ \edef\pgfmath@head{\noexpand\def\expandafter\noexpand\csname pgfmath#1@\endcsname\the\pgfmath@toks}%
+ \pgfmath@toks={}%
+ \def\pgfmath@arguments{}%
+ \pgfmathloop
+ \ifnum\pgfmathcounter>\csname pgfmath@operation@#1@arity\endcsname\relax%
+ \else
+ \pgfmath@addto@toks{\pgfmathfloatparsenumber}%
+ \expandafter\expandafter\expandafter\pgfmath@addto@toks
+ \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter
+ {\expandafter\pgfmath@char@hash\pgfmathcounter}}%
+ \pgfmath@addto@toks{\let}%
+ \expandafter\pgfmath@addto@toks\expandafter{%
+ \csname pgfmath@argument@\pgfmathcounter\endcsname=\pgfmathresult}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
+ \pgfmath@arguments\expandafter\expandafter\expandafter{\expandafter
+ \pgfmath@arguments\expandafter{\csname pgfmath@argument@\pgfmathcounter\endcsname}}%
+ \repeatpgfmathloop
+ \expandafter\pgfmath@addto@toks\expandafter{\csname pgfmathfloat#1@\expandafter\endcsname\pgfmath@arguments}%
+ \pgfmath@addto@toks{\pgfmathfloattofixed{\pgfmathresult}}%
+ \edef\pgfmath@body{{\the\pgfmath@toks}}%
+ \expandafter\pgfmath@head\pgfmath@body
+}
+
+\def\pgfmathfloat@iftrue{%
+ \if Y\pgfmathfloatparse@output@choice
+ \let\pgfmathfloat@@iftrue@v=\pgfmathfloatone
+ \let\pgfmathfloat@@iftrue@next=\pgfmathfloat@iftrue@
+ \else
+ \if S\pgfmathfloatparse@output@choice
+ \def\pgfmathfloat@@iftrue@v{1.0e0}%
+ \let\pgfmathfloat@@iftrue@next=\pgfmathfloat@iftrue@
+ \else
+ \def\pgfmath@next{\pgfutilifstartswith{1.0}}%
+ \expandafter\pgfmath@next\expandafter{\pgfmathresult}{%
+ \ifdim\pgfmathresult pt=1.0pt %
+ \let\pgfmathfloat@@iftrue@next=\pgfutil@firstoftwo
+ \else
+ \let\pgfmathfloat@@iftrue@next=\pgfutil@secondoftwo
+ \fi
+ }{%
+ \let\pgfmathfloat@@iftrue@next=\pgfutil@secondoftwo
+ }%
+ \fi
+ \fi
+ \pgfmathfloat@@iftrue@next%
+}%
+\def\pgfmathfloat@iftrue@{%
+ \ifx\pgfmathresult\pgfmathfloat@@iftrue@v
+ \let\pgfmath@next=\pgfutil@firstoftwo
+ \else
+ \let\pgfmath@next=\pgfutil@secondoftwo
+ \fi
+ \pgfmath@next%
+}%
+
+\def\pgfmathfloat@parser@install{%
+ \pgfmathfloat@plots@checkuninstallcmd
+ \pgfmathfloat@plots@install%
+ \pgfmathfloat@parser@install@functions
+ %
+ %
+ %
+ % The following methods actually enable the parser to work with
+ % the internal floating point number representation.
+ %
+ % The idea is as follows:
+ % 1. Every operand must be given in internal float representation.
+ % 2. The internal float repr can be distinguished by a normal
+ % number. This is accomplished by introducing a new "exponent"
+ % token.
+ % 3. The stack-push-operation checks whether the argument is a
+ % float. If not, it is parsed properly before pushing it.
+ \pgfmath@tokens@make{exponent}{\pgfmathfloat@POSTFLAGSCHAR}%
+ \pgfmathfloat@uninstall@appendcmd{%
+ \expandafter\let\csname pgfmath@token@exponent@\pgfmathfloat@POSTFLAGSCHAR\endcsname=\relax
+ }%
+ \let\pgfmath@basic@parse@exponent=\pgfmath@parse@exponent%
+ \let\pgfmath@basic@stack@push@operand=\pgfmath@stack@push@operand
+ \pgfmathfloat@install\pgfmath@stack@push@operand=\pgfmathfloat@stack@push@operand
+ \pgfmathfloat@install\pgfmath@parse@operand@quote=\pgfmathfloat@parse@operand@quote
+ \pgfmathfloat@install\pgfmath@parse@exponent=\pgfmathfloat@parse@float@or@exponent
+ %
+ \pgfmathfloat@install\pgfmathparse=\pgfmathfloatparse%
+ %\pgfmathfloat@install\pgfmathparse@trynumber@token=\pgfmathfloat@parse@trynumber@token
+ \pgfmathfloat@install\pgfmathparse@expression@is@number=\pgfmathfloat@parse@expression@is@number
+}%
+
+% This here might bring speed improvements... if implemented
+% correctly.
+% However, this heuristics might fail in cases like "1+1" vs "1e+1" ...
+%\def\pgfmathfloat@parse@trynumber@token{numericfpu}
+%\pgfmath@tokens@make{numericfpu}{eE+-Y.0123456789}
+
+\def\pgfmathfloat@parse@expression@is@number{%
+ \pgfmathfloatparsenumber{\pgfmath@expression}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup
+ \ignorespaces
+}%
+
+\def\pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG#1{%
+ \edef\pgfmathfloat@loc@TMPa{%
+ \noexpand\def\expandafter\noexpand\csname pgfmath@parsefunction@#1\endcsname{%
+ \noexpand\let\noexpand\pgfmath@parsepostgroup\expandafter\noexpand\csname pgfmath@parsefunction@#1@\endcsname%
+ \noexpand\expandafter\noexpand\pgfmath@parse@}%
+ \noexpand\def\expandafter\noexpand\csname pgfmath@parsefunction@#1@\endcsname{%
+ \noexpand\expandafter\expandafter\noexpand\csname pgfmath#1@\endcsname\noexpand\expandafter{\noexpand\pgfmathresult}%
+ \noexpand\pgfmath@postfunction%
+ }%
+ }%
+ \pgfmathfloat@loc@TMPa
+}%
+\def\pgfmathfloat@parser@install@pgf@two@null@null{%
+ \pgfmathfloat@plots@checkuninstallcmd
+ \pgfmathfloat@plots@install%
+ \pgfmathfloat@parser@install@functions
+ \let\pgfmathrand@=\pgfmath@basic@rand@
+ \let\pgfmathrnd@=\pgfmath@basic@rnd@
+ \pgfmathfloat@install\pgfmathmax@=\pgfmathfloatmaxtwo%
+ \pgfmathfloat@install\pgfmathmin@=\pgfmathfloatmintwo%
+ \pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG{factorial}%
+ \pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG{hex}%
+ \pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG{bin}%
+ \pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG{oct}%
+ \pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG{tanh}%
+ \pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG{sinh}%
+ \pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG{cosh}%
+ %
+ % The following methods actually enable the parser to work with
+ % the internal floating point number representation.
+ %
+ % The idea is as follows:
+ % 1. Every operand must be given in internal float representation.
+ % 2. The internal float repr can be distinguished by a normal
+ % number. This is accomplished by introducing a new "exponent"
+ % token.
+ % 3. The stack-push-operation checks whether the argument is a
+ % float. If not, it is parsed properly before pushing it.
+ \let\pgfmath@basic@parsedecimalpoint=\pgfmath@parsedecimalpoint%
+ \let\pgfmath@basic@stack@push@operand=\pgfmath@stackpushoperand
+ \pgfmathfloat@install\pgfmath@stackpushoperand=\pgfmathfloat@stack@push@operand
+ \pgfmathfloat@install\pgfmath@parsedecimalpoint=\pgfmathfloat@parsedecimalpoint@pgf@two@null@null
+ \pgfmathfloat@install\pgfmath@endparse=\pgfmathfloat@endparse@pgf@two@null@null
+ \pgfmathfloat@install\pgfmath@endparsegroup=\pgfmathfloat@endparsegroup@pgf@two@null@null
+ \pgfmathfloat@install\pgfmath@postfunction=\pgfmathfloat@postfunction@pgf@two@null@null
+ \pgfmathfloat@install\pgfmath@@parseoperandgroup=\pgfmathfloat@@parseoperandgroup
+ %
+ \pgfmathfloat@install\pgfmathparse=\pgfmathfloatparse@pgf@two@null@null%
+}%
+
+\pgfutil@ifundefined{pgfmathdeclarefunction}{%
+ % BACKWARDS COMPATIBILITY: We have PGF 2.00 :
+ \def\pgfmathdeclarepseudoconstant#1#2{%
+ \begingroup
+ \toks0=\expandafter{\csname pgfmath#1@\endcsname}%
+ \toks1={\pgfmath@postfunction}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }%
+ \xdef\pgfmathfloat@glob@TMPb{\the\toks0 }%
+ \endgroup
+ \expandafter\let\csname pgfmath@parsefunction@#1\endcsname=\pgfmathfloat@glob@TMP
+ \expandafter\let\csname pgfmath#1\endcsname=\pgfmathfloat@glob@TMPb
+ \expandafter\def\csname pgfmath#1@\endcsname{#2}%
+ }%
+ \let\pgfmathredeclarepseudoconstant=\pgfmathdeclarepseudoconstant
+}{%
+ \pgfutil@ifundefined{pgfmathdeclarepseudoconstant}{%
+ \def\pgfmathdeclarepseudoconstant#1#2{\pgfmathdeclarefunction*{#1}{0}{#2}}
+ }{}%
+}%
+
+\pgfmathdeclarepseudoconstant{inf}{\def\pgfmathresult{inf}}%
+\pgfmathdeclarepseudoconstant{INF}{\def\pgfmathresult{inf}}%
+\pgfmathdeclarepseudoconstant{Inf}{\def\pgfmathresult{inf}}%
+\pgfmathdeclarepseudoconstant{infty}{\def\pgfmathresult{inf}}%
+\pgfmathdeclarepseudoconstant{nan}{\def\pgfmathresult{nan}}%
+\pgfmathdeclarepseudoconstant{NaN}{\def\pgfmathresult{nan}}%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Hacks to the basic level pgf math engine:
+%
+% WARNING: These methods rely heavily on the internal float representation!
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% for pgf2.00 :
+\def\pgfmathfloat@parsedecimalpoint@pgf@two@null@null#1{%
+ \expandafter\ifx\pgfmathfloat@POSTFLAGSCHAR#1% check whether it is a float
+ \let\pgfmath@next=\pgfmathfloat@return@float@pgf@two@null@null%
+ \else
+ \def\pgfmath@next{\pgfmath@basic@parsedecimalpoint#1}%
+ \fi
+ \pgfmath@next
+}%
+% for pgf2.00:
+\def\pgfmathfloat@return@float@pgf@two@null@null#1]{%
+ \edef\pgfmathresult{\the\c@pgfmath@parsecounta\pgfmathfloat@POSTFLAGSCHAR#1]}%
+ \let\pgfmath@resulttemp=\pgfmathresult
+ \pgfmath@parseoperator%
+}%
+% for pgf2.00:
+\def\pgfmathfloat@endparse@pgf@two@null@null#1\pgfmath@empty{%
+ \pgfmath@processalloperations%
+ \pgfmath@stackpop{\pgfmathresult}%
+ % delete the final unit scalings
+ \pgfmath@smuggleone{\pgfmathresult}%
+ \endgroup%
+ \ignorespaces%
+}%
+% for pgf2.00:
+\def\pgfmathfloat@endparsegroup@pgf@two@null@null{%
+ \pgfmath@processalloperations%
+ \pgfmath@stackpop{\pgfmathresult}%
+ % eliminated register usage here...
+ \pgfmath@smuggleone{\pgfmathresult}%
+ \endgroup%
+ \pgfmath@parsepostgroup%
+}%
+% for pgf2.00:
+\def\pgfmathfloat@postfunction@pgf@two@null@null{%
+ \let\pgfmath@parsepostgroup\pgfmath@parseoperator%
+ \ifnum\pgfmath@sign1<0
+ \pgfmathfloatneg@{\pgfmathresult}%
+ \let\pgfmath@sign\pgfutil@empty
+ \fi
+ \pgfmath@parseoperator}%
+% for pgf2.00:
+\def\pgfmathfloat@@parseoperandgroup{%
+ \let\pgfmath@postparsegroup\pgfmath@parseoperator%
+ \ifnum\pgfmath@sign1<0
+ \pgfmathfloatneg@{\pgfmathresult}%
+ \let\pgfmath@sign\pgfutil@empty
+ \fi
+ \pgfmath@parseoperator%
+}%
+
+
+
+
+
+
+% PRECONDITION:
+% either
+% <number>e
+% ^
+% -> read the exponent.
+% or
+% <sign>\pgfmathfloat@POSTFLAGSCHAR
+% ^
+% -> we have a parsed floating point number -> read it.
+\def\pgfmathfloat@parse@float@or@exponent{%
+ \if\pgfmath@token \pgfmathfloat@POSTFLAGSCHAR%
+ % Ok, we actually HAVE a pre-parsed floating point number!
+ % Return it.
+ \expandafter\pgfmathfloat@return@float\expandafter\pgfmath@token@next
+ \else
+ % We have a standard number in scientific format. Parse it.
+ \expandafter\pgfmath@basic@parse@exponent
+ \fi
+}%
+\def\pgfmathfloat@return@float#1]{%
+ \edef\pgfmathresult{\pgfmath@number \pgfmathfloat@POSTFLAGSCHAR#1]}%
+ \expandafter\pgfmath@basic@stack@push@operand\expandafter{\pgfmathresult}%
+ \pgfmath@parse@@operator%
+}%
+
+\def\pgfmathfloat@parse@operand@quote#1"{%
+ \edef\pgfmathresult{\pgfmath@fpu@stringmarker #1}%
+ \expandafter\pgfmath@basic@stack@push@operand\expandafter{\pgfmathresult}%
+ \pgfmath@parse@@operator%
+}
+
+\def\pgfmath@fpu@stringmarker{@@str@@:}%
+
+% This extends the functionality of the basic level operand stack: it
+% assures every element on the stack is a float.
+\def\pgfmathfloat@stack@push@operand#1{%
+ \pgfutil@ifnextchar\bgroup{%
+ \let\pgfmathfloat@stack@push@operand@list@=\pgfutil@empty
+ \pgfmathfloat@stack@push@operand@list
+ }{%
+ \pgfmathfloat@stack@push@operand@single
+ }%
+ #1\relax
+}%
+
+\def\pgfmathfloat@stack@push@operand@single#1\relax{%
+ \expandafter\pgfutil@in@\pgfmathfloat@POSTFLAGSCHAR{#1}%
+ \ifpgfutil@in@
+ \pgfmath@basic@stack@push@operand{#1}%
+ \else
+ \expandafter\pgfutil@in@\expandafter{\pgfmath@fpu@stringmarker}{#1}%
+ \ifpgfutil@in@
+ \pgfmathfloat@stack@push@operand@single@str#1\relax
+ \else
+ \pgfmathfloatparsenumber{#1}%
+ \expandafter\pgfmath@basic@stack@push@operand\expandafter{\pgfmathresult}%
+ \fi
+ \fi
+}%
+
+\expandafter\def\expandafter\pgfmathfloat@stack@push@operand@single@str\pgfmath@fpu@stringmarker #1\relax{%
+ \pgfmath@basic@stack@push@operand{#1}%
+}%
+
+\def\pgfmathfloat@stack@push@operand@GOBBLE#1\relax{}%
+\def\pgfmathfloat@stack@push@operand@list#1{%
+ \expandafter\pgfutil@in@ \pgfmathfloat@POSTFLAGSCHAR{#1}%
+ \ifpgfutil@in@
+ \expandafter\def\expandafter\pgfmathfloat@stack@push@operand@list@\expandafter{%
+ \pgfmathfloat@stack@push@operand@list@{#1}%
+ }%
+ \else
+ \pgfmathfloatparsenumber{#1}%
+ \begingroup
+ \toks0=\expandafter{\pgfmathfloat@stack@push@operand@list@}%
+ \toks1=\expandafter{\pgfmathresult}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 {\the\toks1}}%
+ \endgroup
+ \let\pgfmathfloat@stack@push@operand@list@=\pgfmathfloat@glob@TMP
+ \fi
+ \pgfutil@ifnextchar\relax{%
+ \expandafter\pgfmath@basic@stack@push@operand\expandafter{\pgfmathfloat@stack@push@operand@list@}%
+ \pgfmathfloat@stack@push@operand@GOBBLE
+ }{%
+ \pgfmathfloat@stack@push@operand@list
+ }%
+}%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% --- END --- Hacks to the basic level pgf math engine
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Here starts the implementation of the floating point
+% routines.
+%
+% They can be used even if the FPU parser is not active.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Remember the basic math commands. They will be invoked as subroutines in floating point routines.
+\let\pgfmath@basic@add@=\pgfmathadd@
+\let\pgfmath@basic@subtract@=\pgfmathsubtract@
+\let\pgfmath@basic@multiply@=\pgfmathmultiply@
+\let\pgfmath@basic@divide@=\pgfmathdivide@
+\let\pgfmath@basic@reciprocal@=\pgfmathreciprocal@
+\let\pgfmath@basic@abs@=\pgfmathabs@
+\let\pgfmath@basic@round@=\pgfmathround@
+\let\pgfmath@basic@rand@=\pgfmathrand@
+\let\pgfmath@basic@rnd@=\pgfmathrnd@
+\let\pgfmath@basic@setseed@=\pgfmathsetseed@
+\let\pgfmath@basic@random@=\pgfmathrandom@
+\let\pgfmath@basic@floor@=\pgfmathfloor@
+\let\pgfmath@basic@ceil@=\pgfmathceil@
+\let\pgfmath@basic@mod@=\pgfmathmod@
+\let\pgfmath@basic@max@=\pgfmathmax@
+\let\pgfmath@basic@min@=\pgfmathmin@
+\let\pgfmath@basic@sin@=\pgfmathsin@
+\let\pgfmath@basic@cos@=\pgfmathcos@
+\let\pgfmath@basic@tan@=\pgfmathtan@
+\let\pgfmath@basic@deg@=\pgfmathdeg@
+\let\pgfmath@basic@rad@=\pgfmathrad@
+\let\pgfmath@basic@atan@=\pgfmathatan@
+\let\pgfmath@basic@asin@=\pgfmathasin@
+\let\pgfmath@basic@acos@=\pgfmathacos@
+\let\pgfmath@basic@cot@=\pgfmathcot@
+\let\pgfmath@basic@sec@=\pgfmathsec@
+\let\pgfmath@basic@cosec@=\pgfmathcosec@
+\let\pgfmath@basic@pow@=\pgfmathpow@
+\let\pgfmath@basic@exp@=\pgfmathexp@
+\let\pgfmath@basic@ln@=\pgfmathln@
+\let\pgfmath@basic@sqrt@=\pgfmathsqrt@
+\let\pgfmath@basic@@pi=\pgfmath@pi
+\let\pgfmath@basic@veclen@=\pgfmathveclen@
+\let\pgfmath@basic@e@=\pgfmathe@
+\let\pgfmath@basic@lessthan@=\pgfmathlessthan@
+\let\pgfmath@basic@greaterthan@=\pgfmathgreaterthan@
+\let\pgfmath@basic@equalto@=\pgfmathequalto@
+\let\pgfmath@basic@equal@=\pgfmathequal@
+\let\pgfmath@basic@true@=\pgfmathtrue@
+\let\pgfmath@basic@false@=\pgfmathfalse@
+
+\def\pgfmathfloatscientific#1#2{%
+ \edef\pgfmathresult{#1e#2}%
+ \expandafter\pgfmathfloatparsenumber\expandafter{\pgfmathresult}%
+}%
+% Compares #1 with #2 and sets \pgfmathresult either to 1.0 or 0.0.
+%
+% It also sets the boolean \ifpgfmathfloatcomparison (globally).
+\def\pgfmathfloatlessthan@#1#2{%
+%\def\pgfmathfloatlessthan#1#2#3\and#4#5#6{%
+ \global\pgfmathfloatcomparisonfalse
+ \begingroup
+ \edef\pgfmathfloat@loc@TMPa{#1}%
+ \edef\pgfmathfloat@loc@TMPb{#2}%
+ \expandafter\pgfmathfloat@decompose\pgfmathfloat@loc@TMPa\relax\pgfmathfloat@a@S\pgfmathfloat@a@M\pgfmathfloat@a@E
+ \expandafter\pgfmathfloat@decompose\pgfmathfloat@loc@TMPb\relax\pgfmathfloat@b@S\pgfmathfloat@b@M\pgfmathfloat@b@E
+ \ifcase\pgfmathfloat@a@S
+ % x = 0 -> (x<y <=> y >0)
+ \ifcase\pgfmathfloat@b@S
+ % y = 0
+ \or% y > 0
+ \global\pgfmathfloatcomparisontrue
+ \or% y < 0
+ \or% y = nan
+ \or% y = + infty
+ \global\pgfmathfloatcomparisontrue
+ \or% y = -infty
+ \fi
+ \or
+ % x > 0 -> (x<y <=> ( y > 0 && |x| < |y|) )
+ \ifcase\pgfmathfloat@b@S
+ % y = 0
+ \or% y>0:
+ \pgfmathfloatlessthan@positive
+ \or% y < 0
+ \or% y = nan
+ \or% y = + infty
+ \global\pgfmathfloatcomparisontrue
+ \or% y = -infty
+ \fi
+ \or
+ % x < 0 -> (x<y <=> (y >= 0 || |x| > |y|) )
+ \ifcase\pgfmathfloat@b@S
+ % y = 0
+ \global\pgfmathfloatcomparisontrue
+ \or%y > 0
+ \global\pgfmathfloatcomparisontrue
+ \or% 'y<0':
+ \pgfmathfloatgreaterthan@positive
+ \or% y = nan
+ \or% y = + infty
+ \global\pgfmathfloatcomparisontrue
+ \or% y = -infty
+ \fi
+ \or
+ % x = nan.
+ \or
+ % x = +infty
+ \or
+ % x = -infty
+ \ifnum\pgfmathfloat@b@S=3
+ \else
+ \global\pgfmathfloatcomparisontrue
+ \fi
+ \fi
+ \endgroup
+ \ifpgfmathfloatcomparison
+ \def\pgfmathresult{1.0}%
+ \else
+ \def\pgfmathresult{0.0}%
+ \fi
+}%
+\let\pgfmathfloatlessthan=\pgfmathfloatlessthan@
+\let\pgfmathfloatless@=\pgfmathfloatlessthan@
+
+% ! (#1 < #2) <=> (#1 >= #2)
+\def\pgfmathfloatnotless@#1#2{%
+ \pgfmathfloatless@{#1}{#2}%
+ \ifpgfmathfloatcomparison
+ \def\pgfmathresult{0.0}%
+ \else
+ \def\pgfmathresult{1.0}%
+ \fi
+}%
+% ! (#1 > #2) <=> (#1 <= #2)
+\def\pgfmathfloatnotgreater@#1#2{%
+ \pgfmathfloatless@{#2}{#1}%
+ \ifpgfmathfloatcomparison
+ \def\pgfmathresult{0.0}%
+ \else
+ \def\pgfmathresult{1.0}%
+ \fi
+}%
+
+% compares \pgfmathfloat@a@[SME] < \pgfmathfloat@b@[SME]
+\def\pgfmathfloatlessthan@positive{%
+ \ifnum\pgfmathfloat@a@E<\pgfmathfloat@b@E
+ \global\pgfmathfloatcomparisontrue
+ \else
+ \ifnum\pgfmathfloat@a@E=\pgfmathfloat@b@E
+ \ifdim\pgfmathfloat@a@M<\pgfmathfloat@b@M
+ \global\pgfmathfloatcomparisontrue
+ \fi
+ \fi
+ \fi
+}%
+
+% compares \pgfmathfloat@a@[SME] > \pgfmathfloat@b@[SME]
+\def\pgfmathfloatgreaterthan@positive{%
+ \ifnum\pgfmathfloat@a@E>\pgfmathfloat@b@E
+ \global\pgfmathfloatcomparisontrue
+ \else
+ \ifnum\pgfmathfloat@a@E=\pgfmathfloat@b@E
+ \ifdim\pgfmathfloat@a@M>\pgfmathfloat@b@M
+ \global\pgfmathfloatcomparisontrue
+ \fi
+ \fi
+ \fi
+}%
+
+
+\def\pgfmathfloatgreaterthan@#1#2{\pgfmathfloatlessthan@{#2}{#1}}%
+\let\pgfmathfloatgreaterthan=\pgfmathfloatgreaterthan@
+\let\pgfmathfloatgreater@=\pgfmathfloatgreaterthan@
+
+\def\pgfmathfloatmax@#1{%
+ \begingroup
+ \pgfmathfloatcreate{2}{1.0}{2147483644}%
+ \let\pgfmathmaxsofar=\pgfmathresult
+ \pgfmathfloatmax@@#1{}%
+}%
+\def\pgfmathfloatmax@@#1{%
+ \def\pgfmath@temp{#1}%
+ \ifx\pgfmath@temp\pgfmath@empty%
+ \expandafter\pgfmathfloatmax@@@%
+ \else%
+ \pgfmathfloatlessthan{\pgfmathmaxsofar}{#1}%
+ \ifpgfmathfloatcomparison
+ \edef\pgfmathmaxsofar{#1}%
+ \fi
+ \expandafter\pgfmathfloatmax@@%
+ \fi%
+}%
+\def\pgfmathfloatmax@@@{%
+ \let\pgfmathresult=\pgfmathmaxsofar
+ \pgfmath@smuggleone{\pgfmathresult}%
+ \endgroup
+}%
+\def\pgfmathfloatmin@#1{%
+ \begingroup
+ \pgfmathfloatcreate{1}{1.0}{2147483644}%
+ \let\pgfmathminsofar=\pgfmathresult
+ \pgfmathfloatmin@@#1{}%
+}%
+\def\pgfmathfloatmin@@#1{%
+ \def\pgfmath@temp{#1}%
+ \ifx\pgfmath@temp\pgfmath@empty%
+ \expandafter\pgfmathfloatmin@@@%
+ \else%
+ \pgfmathfloatlessthan{#1}{\pgfmathminsofar}%
+ \ifpgfmathfloatcomparison
+ \edef\pgfmathminsofar{#1}%
+ \fi
+ \expandafter\pgfmathfloatmin@@%
+ \fi%
+}%
+\def\pgfmathfloatmin@@@{%
+ \let\pgfmathresult=\pgfmathminsofar
+ \pgfmath@smuggleone{\pgfmathresult}%
+ \endgroup
+}%
+
+\def\pgfmathfloatmaxtwo#1#2{%
+ \pgfmathfloatlessthan{#1}{#2}%
+ \ifpgfmathfloatcomparison
+ \edef\pgfmathresult{#2}%
+ \else
+ \edef\pgfmathresult{#1}%
+ \fi
+}%
+\let\pgfmathfloatmax=\pgfmathfloatmaxtwo
+
+\def\pgfmathfloatmintwo#1#2{%
+ \pgfmathfloatlessthan{#1}{#2}%
+ \ifpgfmathfloatcomparison
+ \edef\pgfmathresult{#1}%
+ \else
+ \edef\pgfmathresult{#2}%
+ \fi
+}%
+\let\pgfmathfloatmin=\pgfmathfloatmintwo
+
+% Renormalizes #1 to extended precision mantissa, meaning
+% 100 <= m < 1000
+% instead of 1 <= m < 10.
+%
+% The 'extended precision' means we have higher accuracy when we apply pgfmath operations to mantissas.
+%
+% The input argument is expected to be a normalized floating point number; the output argument is a non-normalized floating point number (well, normalized to extended precision).
+%
+% The operation is supposed to be very fast.
+%
+% @see \pgfmathfloatsetextprecision
+%
+% There is a routine for internal usage,
+% \pgfmathfloattoextentedprecision@a. It also provides exponent and
+% sign of #1 in output arguments and may be used to increase speed.
+\def\pgfmathfloattoextentedprecision#1{%
+ \begingroup
+ \pgfmathfloattoextentedprecision@a{#1}%
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\pgfmathresult}{\the\pgfmathfloat@a@E}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+\def\pgfmathfloattoextentedprecision@@zero#1\pgfmathfloat@EOI{%
+ \edef\pgfmathresult{#1}%
+}%
+\def\pgfmathfloattoextentedprecision@@one#1.#2#3\pgfmathfloat@EOI{%
+ \edef\pgfmathresult{#1#2.#3}%
+}%
+\def\pgfmathfloattoextentedprecision@@two#1.#2#3#4\pgfmathfloat@EOI{%
+ \edef\pgfmathresult{#1#2#3.#4}%
+}%
+\def\pgfmathfloattoextentedprecision@@three#1.#2#3#4#5\pgfmathfloat@EOI{%
+ \edef\pgfmathresult{#1#2#3#4.#5}%
+}%
+
+% Sets extended precision to 10^#1.
+%
+% The different choices are
+%
+% - 0: normalization 0 <= m < 1 (disable extended precision)
+% - 1: normalization 10 <= m < 100
+% - 2: normalization 100 <= m < 1000 (default)
+% - 3: normalization 1000 <= m < 10000
+%
+% #1 is the exponent, #1 = 0,1,2 or 3.
+%
+% This setting applies to \pgfmathfloattoextentedprecision and friends.
+\def\pgfmathfloatsetextprecision#1{%
+ \ifcase#1\relax
+ \let\pgfmathfloattoextentedprecision@@=\pgfmathfloattoextentedprecision@@zero
+ \def\pgfmathfloatextprec@shift{0}%
+ \or
+ \let\pgfmathfloattoextentedprecision@@=\pgfmathfloattoextentedprecision@@one
+ \def\pgfmathfloatextprec@shift{1}%
+ \or
+ \let\pgfmathfloattoextentedprecision@@=\pgfmathfloattoextentedprecision@@two
+ \def\pgfmathfloatextprec@shift{2}%
+ \else
+ \let\pgfmathfloattoextentedprecision@@=\pgfmathfloattoextentedprecision@@three
+ \def\pgfmathfloatextprec@shift{3}%
+ \fi
+}%
+\pgfmathfloatsetextprecision{2}%
+
+% Does the "hard" work for \pgfmathfloattoextentedprecision. It
+% provides additional outputs.
+%
+% INPUT:
+% #1 normalized floating point number. Maybe a macro (it will be expanded ONCE)
+%
+% OUTPUT:
+% - \pgfmathresult : the mantissa in extended precision
+% - \pgfmathfloat@a@S : the sign of #1
+% - \pgfmathfloat@a@E : the exponent of #1, adjusted for extended precision
+% - \pgfmathfloat@a@Mtok : undefined (its contents will be destroyed.
+%
+\def\pgfmathfloattoextentedprecision@a#1{%
+ \edef\pgfmathresult{#1}%
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifnum\pgfmathfloat@a@S<3
+ \advance\pgfmathfloat@a@E by-\pgfmathfloatextprec@shift\relax% compensate for shift
+ \expandafter\pgfmathfloattoextentedprecision@@\the\pgfmathfloat@a@Mtok 000\pgfmathfloat@EOI
+ \fi
+}%
+
+
+% Similar to \pgfmathfloattoextentedprecision@a, this one here fills the '@b' registers.
+\def\pgfmathfloattoextentedprecision@b#1{%
+ \edef\pgfmathresult{#1}%
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@b@S\pgfmathfloat@a@Mtok\pgfmathfloat@b@E
+ \ifnum\pgfmathfloat@b@S<3
+ \advance\pgfmathfloat@b@E by-\pgfmathfloatextprec@shift\relax
+ \expandafter\pgfmathfloattoextentedprecision@@\the\pgfmathfloat@a@Mtok 00\pgfmathfloat@EOI
+ \fi
+}%
+
+% Addition of two floating point numbers using 8 significant digits.
+\def\pgfmathfloatadd@#1#2{%
+ \begingroup
+ %
+ % renormalize argument to 100 <= m < 1000 for extended accuracy:
+ \pgfmathfloattoextentedprecision@a{#1}%
+ \let\pgfmathfloat@arga=\pgfmathresult
+ %
+ \pgfmathfloattoextentedprecision@b{#2}%
+ \let\pgfmathfloat@argb=\pgfmathresult
+ %
+ \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases.
+ \ifcase\pgfmathfloat@a@S
+ \edef\pgfmathresult{#2}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \or
+ \edef\pgfmathfloat@arga{-\pgfmathfloat@arga}%
+ \else
+ \pgfmathfloatcomparisonfalse
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{0.0}{0}%
+ \fi
+ \ifcase\pgfmathfloat@b@S
+ \edef\pgfmathresult{#1}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \or
+ \edef\pgfmathfloat@argb{-\pgfmathfloat@argb}%
+ \else
+ \pgfmathfloatcomparisonfalse
+ \pgfmathfloatcreate{\the\pgfmathfloat@b@S}{0.0}{0}%
+ \fi
+ \ifpgfmathfloatcomparison
+ % Shift lesser mantisse to fit the larger one:
+ \ifnum\pgfmathfloat@a@E<\pgfmathfloat@b@E
+ \pgfmathfloatadd@shift{\pgfmathfloat@arga}{\pgfmathfloat@a@E}{\pgfmathfloat@b@E}%
+ \else
+ \pgfmathfloatadd@shift{\pgfmathfloat@argb}{\pgfmathfloat@b@E}{\pgfmathfloat@a@E}%
+ \fi
+ % add them!
+ \pgfmath@basic@add@{\pgfmathfloat@arga}{\pgfmathfloat@argb}%
+ % renormalize sum. This is the only part were an expensive routine comes into play:
+ \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}%
+ \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+% #1= floating point number
+% #2= TeX code to execute if #1 == 0
+% #3= TeX code to execute if #1 != 0
+\def\pgfmathfloatifzero#1#2#3{%
+ \pgfmathfloatgetflagstomacro{#1}\pgfmathfloat@loc@TMPa
+ \if\pgfmathfloat@loc@TMPa0 #2\else#3\fi
+}%
+
+\def\pgfmathfloatiffinite#1#2#3{%
+ \pgfmathfloatgetflagstomacro{#1}\pgfmathfloatiffinite@
+ \ifnum\pgfmathfloatiffinite@>2 #3\else #2\fi
+}%
+
+\def\pgfmathfloatifthenelse@#1#2#3{%
+ \pgfmathfloatifflags{#1}{0}{%
+ \edef\pgfmathresult{#3}%%
+ }{%
+ \edef\pgfmathresult{#2}%
+ }%
+}%
+\def\pgfmathfloatequal@#1#2{%
+ \pgfmathfloatifapproxequalrel{#1}{#2}{%
+ \def\pgfmathresult{1}%
+ \pgfmathfloatcomparisontrue
+ }{%
+ \def\pgfmathresult{0}%
+ \pgfmathfloatcomparisonfalse
+ }%
+}%
+\let\pgfmathfloatequalto@=\pgfmathfloatequal@
+
+\def\pgfmathfloatnotequal@#1#2{%
+ \pgfmathfloatifapproxequalrel{#1}{#2}{%
+ \def\pgfmathresult{0}%
+ \pgfmathfloatcomparisonfalse
+ }{%
+ \def\pgfmathresult{1}%
+ \pgfmathfloatcomparisontrue
+ }%
+}%
+\let\pgfmathfloatnotequalto@=\pgfmathfloatnotequal@
+
+% Computes the relative error between #1 and #2 (assuming #2 != 0) and
+% invokes #3 if the relative error is below `/pgf/fpu/rel thresh' and
+% #4 if that is not the case.
+\long\def\pgfmathfloatifapproxequalrel#1#2#3#4{%
+ \begingroup
+ \pgfmathfloatparsenumber{#1}%
+ \let\pgfmathfloatarga=\pgfmathresult
+ \pgfmathfloatparsenumber{#2}%
+ \let\pgfmathfloatargb=\pgfmathresult
+ \pgfmathfloatrelerror@\pgfmathfloatarga\pgfmathfloatargb
+ \let\pgfmathfloatarga=\pgfmathresult
+ \pgfmathfloatlessthan@\pgfmathfloatarga\pgfmathfloat@relthresh
+ \ifpgfmathfloatcomparison
+ \def\pgfmathfloat@loc@TMPa{#3}%
+ \else
+ \def\pgfmathfloat@loc@TMPa{#4}%
+ \fi
+ \expandafter\endgroup
+ \pgfmathfloat@loc@TMPa
+}%
+
+% Invokes code '#3' if the flags of the floating point number '#1'
+% match the flag provided in '#2'.
+%
+% \pgfmathfloatcreate{1}{1.0}{2}
+% \pgfmathfloatifflags{\pgfmathresult}{0}{It's zero!}{It's not zero!}%
+% \pgfmathfloatifflags{\pgfmathresult}{1}{It's positive!}{It's not positive!}%
+% \pgfmathfloatifflags{\pgfmathresult}{2}{It's negative!}{It's not negative!}%
+% or, equivalently
+% \pgfmathfloatifflags{\pgfmathresult}{+}{It's positive!}{It's not positive!}%
+% \pgfmathfloatifflags{\pgfmathresult}{-}{It's negative!}{It's not negative!}%
+% it also supports #2=u which means 'unbounded'
+\def\pgfmathfloatifflags#1#2#3#4{%
+ \if#2-%
+ \pgfmathfloatifflags{#1}{2}{#3}{#4}%
+ \else
+ \if#2+%
+ \pgfmathfloatifflags{#1}{1}{#3}{#4}%
+ \else
+ \pgfmathfloatgetflagstomacro{#1}\pgfmathfloat@loc@TMPa
+ \if#2u%
+ \ifnum\pgfmathfloat@loc@TMPa>2
+ #3\relax
+ \else
+ #4\relax
+ \fi
+ \else
+ \if\pgfmathfloat@loc@TMPa#2%
+ #3\relax
+ \else
+ #4\relax
+ \fi
+ \fi
+ \fi
+ \fi
+}%
+
+% #1=mantissa which needs to be shifted (with smaller exponent)
+% #2=smaller exponent
+% #3=larger exponent
+%
+% ATTENTION: this helper method DESTROYS contents of \pgfmathfloat@a@S.
+\def\pgfmathfloatadd@shift#1#2#3{%
+ \pgf@xa=#1 pt%
+ \pgfmathfloat@a@S=#3\relax
+ \advance\pgfmathfloat@a@S by-#2\relax
+ \ifcase\pgfmathfloat@a@S
+ \or
+ \divide\pgf@xa by10\relax
+ \or
+ \divide\pgf@xa by100\relax
+ \or
+ \divide\pgf@xa by1000\relax
+ \or
+ \divide\pgf@xa by10000\relax
+ \or
+ \divide\pgf@xa by10000\relax
+ \divide\pgf@xa by10\relax
+ \or
+ \divide\pgf@xa by10000\relax
+ \divide\pgf@xa by100\relax
+ \or
+ \divide\pgf@xa by10000\relax
+ \divide\pgf@xa by1000\relax
+ \or
+ \divide\pgf@xa by10000\relax
+ \divide\pgf@xa by10000\relax
+ \else
+ \pgf@xa=0pt%
+ \fi
+ #2=#3\relax
+ \edef#1{\pgf@sys@tonumber\pgf@xa}%
+}%
+
+\let\pgfmathfloatadd=\pgfmathfloatadd@
+
+
+% Subtracts two floating point numbers.
+\def\pgfmathfloatsubtract@#1#2{%
+ \begingroup
+ \edef\pgfmathresult{#2}%
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@b@S\pgfmathfloat@a@Mtok\pgfmathfloat@b@E
+ \ifcase\pgfmathfloat@b@S
+ \edef\pgfmathresult{#1}%
+ \or
+ \pgfmathfloatcreate{2}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@b@E}%
+ \let\pgfmathfloatsub@arg=\pgfmathresult
+ \pgfmathfloatadd@{#1}{\pgfmathfloatsub@arg}%
+ \or
+ \pgfmathfloatcreate{1}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@b@E}%
+ \let\pgfmathfloatsub@arg=\pgfmathresult
+ \pgfmathfloatadd@{#1}{\pgfmathfloatsub@arg}%
+ \else
+ \pgfmathfloatcreate{\the\pgfmathfloat@b@S}{0.0}{0}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+\let\pgfmathfloatsubtract=\pgfmathfloatsubtract@
+
+% Scales a floating point number #1 with a fixed point number #2 using pgfmathmultiply.
+%
+% Use this method if #2 is small number.
+\def\pgfmathfloatmultiplyfixed@#1#2{%
+ \begingroup
+ %
+ % renormalize argument to 100 <= m < 1000 for extended accuracy:
+ \pgfmathfloattoextentedprecision@a{#1}%
+ \let\pgfmathfloat@arga=\pgfmathresult
+ %
+ \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases.
+ \ifcase\pgfmathfloat@a@S
+ \edef\pgfmathresult{#1}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \or
+ \edef\pgfmathfloat@arga{-\pgfmathfloat@arga}%
+ \else
+ \pgfmathfloatcomparisonfalse
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{0.0}{0}%
+ \fi
+ \ifpgfmathfloatcomparison
+ \pgfmath@basic@multiply@{\pgfmathfloat@arga}{#2}%
+ % renormalize product. This is the only part were an expensive routine comes into play:
+ \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}%
+ \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+\let\pgfmathfloatmultiplyfixed=\pgfmathfloatmultiplyfixed@
+
+
+\def\pgfmathfloatmultiply@#1#2{%
+ \begingroup
+ \pgfmathfloatsetextprecision{1}%
+ \pgfmathfloattoextentedprecision@a{#1}%
+ \let\pgfmathfloat@arga=\pgfmathresult
+ %
+ \pgfmathfloattoextentedprecision@b{#2}%
+ \let\pgfmathfloat@argb=\pgfmathresult
+ %
+ \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases.
+ \ifcase\pgfmathfloat@a@S
+ % 0
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or% +
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \def\pgfmathresult@S{1}%
+ \or
+ \def\pgfmathresult@S{2}%
+ \else
+ \expandafter\pgfmathfloatcreate\the\pgfmathfloat@b@S{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \or% -
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \def\pgfmathresult@S{2}%
+ \or
+ \def\pgfmathresult@S{1}%
+ \or
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \or% nan
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or% +infty
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \or% -infty
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \fi
+ \ifpgfmathfloatcomparison
+ \pgfmath@basic@multiply@{\pgfmathfloat@arga}{\pgfmathfloat@argb}%
+ \advance\pgfmathfloat@a@E by\pgfmathfloat@b@E
+ % renormalize sum. This is the only part were an expensive routine comes into play:
+ \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}%
+ \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}%
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \pgfmathfloatcreate{\pgfmathresult@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatmultiply=\pgfmathfloatmultiply@
+
+% Defines \pgfmathresult to be #1 / #2 for two floating point numbers.
+%
+% It employs the basic math engine internally to divide mantissas.
+\def\pgfmathfloatdivide@#1#2{%
+ \begingroup
+ \pgfmathfloatsetextprecision{1}% is not too important, I think. After all, 0.1 <= #1/#2 < 10 or so due to normalization (no matter, which)
+ \edef\pgfmathfloat@arga{#1}%
+ \pgfmathfloattoextentedprecision@a{\pgfmathfloat@arga}%
+ \let\pgfmathfloat@arga=\pgfmathresult
+ %
+ \edef\pgfmathfloat@argb{#2}%
+ \pgfmathfloattoextentedprecision@b{\pgfmathfloat@argb}%
+ \let\pgfmathfloat@argb=\pgfmathresult
+ %
+ \pgfmathfloatcomparisontrue% re-use this boolean here to handle special cases.
+ \ifcase\pgfmathfloat@a@S
+ % 0
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or% +
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \def\pgfmathresult@S{1}%
+ \or
+ \def\pgfmathresult@S{2}%
+ \or
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \else
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \or% -
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \def\pgfmathresult@S{2}%
+ \or
+ \def\pgfmathresult@S{1}%
+ \or
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \else
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \or% nan
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or% +infty
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}% what is inf/inf ?
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}% or inf/-inf ?
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \or% -infty
+ \ifcase\pgfmathfloat@b@S
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{5}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \or
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \pgfmathfloatcomparisonfalse
+ \fi
+ \fi
+ \ifpgfmathfloatcomparison
+ \pgfmath@basic@divide@{\pgfmathfloat@arga}{\pgfmathfloat@argb}%
+ \advance\pgfmathfloat@a@E by-\pgfmathfloat@b@E
+ % renormalize. This is the only part were an expensive float routine comes into play:
+ \edef\pgfmathresult{\pgfmathresult e\the\pgfmathfloat@a@E}%
+ \expandafter\pgfmathfloatqparsenumber\expandafter{\pgfmathresult}%
+ % And re-insert the proper sign:
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \pgfmathfloatcreate{\pgfmathresult@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatdivide=\pgfmathfloatdivide@
+
+\def\pgfmathfloatreciprocal@#1{%
+ \begingroup
+ % FIXME optimize
+ \edef\pgfmathfloat@loc@TMPa{#1}%
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \pgfmathfloatdivide@{\pgfmathresult}{\pgfmathfloat@loc@TMPa}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+% Computes sqrt(#1) in floating point arithmetics.
+%
+% It employs sqrt( m * 10^e ) = sqrt(m) * sqrt(10^e).
+\def\pgfmathfloatsqrt@#1{%
+ \begingroup
+ \pgfmathfloatsetextprecision{3}%
+ \edef\pgfmathfloat@arga{#1}%
+ \pgfmathfloattoextentedprecision@a{\pgfmathfloat@arga}%
+ \let\pgfmathfloat@arga=\pgfmathresult
+ %
+ \ifcase\pgfmathfloat@a@S
+ % 0
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \or% +
+ \pgfmath@basic@sqrt@{\pgfmathfloat@arga}%
+ \ifodd\pgfmathfloat@a@E
+ \ifnum\pgfmathfloat@a@E>0
+ \expandafter\pgfmath@basic@multiply@\expandafter{\pgfmathresult}{3.16227766}% * sqrt(10)
+ \else
+ \expandafter\pgfmath@basic@multiply@\expandafter{\pgfmathresult}{0.316227766}% * sqrt(0.1)
+ \fi
+ \fi
+ \divide\pgfmathfloat@a@E by2 % sqrt(10^e) = 10^{e/2} (see above for odd e)
+ % renormalize sum. This is the only part were an expensive routine comes into play:
+ \edef\pgfmathfloat@arga{\pgfmathresult e\the\pgfmathfloat@a@E}%
+ \pgfmathfloatqparsenumber{\pgfmathfloat@arga}%
+ \or% -
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \or% nan
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \or% +infty
+ \pgfmathfloatcreate{4}{0.0}{0}%
+ \or% -infty
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatsqrt=\pgfmathfloatsqrt@
+
+% Returns the integer part of the floating point number #1.
+%
+% The result is returned as floating point as well.
+%
+% This operation is not limited to TeX's range of count registers (it
+% works symbolly)
+%
+% @see \pgfmathfloattoint
+% POSTCONDITION: \pgfmathresult contains the result and
+% \pgfmathfloatintwasnoop=1 if there was nothing to do
+% \pgfmathfloatintwasnoop=0 if there where non-zero digits after the period
+% \pgfmathfloatintwasnoop=2 if there where digits after the period. The digits will be stored in \pgfmathfloatintremainder in this case.
+\def\pgfmathfloatint@#1{%
+ \begingroup
+ \edef\pgfmathfloatint@input{#1}%
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathfloatint@input\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \gdef\pgfmathfloatintwasnoop{1}%
+ \gdef\pgfmathfloatintremainder{}%
+ \ifcase\pgfmathfloat@a@S
+ % 0: nothing to do.
+ \or% +
+ \expandafter\pgfmathfloatint@@\the\pgfmathfloat@a@Mtok\pgfmathfloat@EOI
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \or% -
+ \expandafter\pgfmathfloatint@@\the\pgfmathfloat@a@Mtok\pgfmathfloat@EOI
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \else
+ % nothing to do
+ \fi
+ %\message{ XXXXX int(\pgfmathfloatint@input) = \pgfmathresult -> was no op = \pgfmathfloatintwasnoop\space (remainder \pgfmathfloatintremainder)^^J}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\def\pgfmathfloatint@@#1.{%
+ \ifnum\pgfmathfloat@a@E<0
+ \pgfmathfloat@a@S=0
+ \pgfmathfloat@a@Mtok={0.0}%
+ \pgfmathfloat@a@E=0
+ \gdef\pgfmathfloatintwasnoop{0}%
+ \expandafter\pgfmathfloatint@@loop@gobble
+ \else
+ \pgfmathfloat@a@Mtok={#1.}%
+ \pgfmathfloat@b@E=\pgfmathfloat@a@E
+ \expandafter\pgfmathfloatint@@loop
+ \fi
+}%
+\def\pgfmathfloatint@@loop#1{%
+ \def\pgfmathfloatint@@loop@{#1}%
+ \ifx\pgfmathfloatint@@loop@\pgfmathfloat@EOI
+ \gdef\pgfmathfloatintwasnoop{1}%
+ \let\pgfmathfloatint@@loop@next=\relax
+ \else
+ \ifnum\pgfmathfloat@b@E=0
+ \def\pgfmathfloatint@@loop@next{\pgfmathfloatint@@loop@gobble#1}%
+ \else
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}%
+ \advance\pgfmathfloat@b@E by-1
+ \let\pgfmathfloatint@@loop@next=\pgfmathfloatint@@loop
+ \fi
+ \fi
+ \pgfmathfloatint@@loop@next
+}%
+\def\pgfmathfloatint@@loop@gobble#1\pgfmathfloat@EOI{%
+ \if0\pgfmathfloatintwasnoop
+ \else
+ \gdef\pgfmathfloatintwasnoop{2}%
+ \gdef\pgfmathfloatintremainder{#1}%
+ \fi
+}%
+\let\pgfmathfloatint=\pgfmathfloatint@
+
+\def\pgfmathfloatfloor#1{%
+ \edef\pgfmath@orig{#1}%
+ \pgfmathfloatint@{#1}%
+ \pgfmathfloatifflags{\pgfmath@orig}{2}{%
+ \let\pgfmath@trunc=\pgfmathresult
+ \ifcase\pgfmathfloatintwasnoop\relax
+ % ah - we stripped something! Round DOWN
+ \pgfmathfloatcreate{2}{1.0}{0}% -1
+ \expandafter\pgfmathfloatadd@\expandafter{\pgfmathresult}{\pgfmath@trunc}%
+ \or
+ % was no-op
+ \let\pgfmathresult=\pgfmath@trunc
+ \else
+ % ok, we have to inspect the remainder:
+ \pgfmathfloatparsenumber{0.\pgfmathfloatintremainder}%
+ \pgfmathfloatifflags{\pgfmathresult}{1}{%
+ % ah - we stripped a non-zero remainder! Round DOWN
+ \pgfmathfloatcreate{2}{1.0}{0}% -1
+ \expandafter\pgfmathfloatadd@\expandafter{\pgfmathresult}{\pgfmath@trunc}%
+ }{%
+ % was no-op
+ \let\pgfmathresult=\pgfmath@trunc
+ }%
+ \fi
+ }{}%
+}%
+\let\pgfmathfloatfloor@=\pgfmathfloatfloor
+
+\def\pgfmathfloatceil#1{%
+ \edef\pgfmath@orig{#1}%
+ \pgfmathfloatint@{#1}%
+ \pgfmathfloatifflags{\pgfmath@orig}{1}{%
+ \let\pgfmath@trunc=\pgfmathresult
+ \ifcase\pgfmathfloatintwasnoop\relax
+ % ah - we stripped something! Round UP
+ \pgfmathfloatcreate{1}{1.0}{0}% +1
+ \expandafter\pgfmathfloatadd@\expandafter{\pgfmathresult}{\pgfmath@trunc}%
+ \or
+ % was no-op
+ \let\pgfmathresult=\pgfmath@trunc
+ \else
+ % ok, we have to inspect the remainder:
+ \pgfmathfloatparsenumber{0.\pgfmathfloatintremainder}%
+ \pgfmathfloatifflags{\pgfmathresult}{1}{%
+ % ah - we stripped a non-zero remainder! Round UP
+ \pgfmathfloatcreate{1}{1.0}{0}% +1
+ \expandafter\pgfmathfloatadd@\expandafter{\pgfmathresult}{\pgfmath@trunc}%
+ }{%
+ % was no-op
+ \let\pgfmathresult=\pgfmath@trunc
+ }%
+ \fi
+ }{}%
+}%
+\let\pgfmathfloatceil@=\pgfmathfloatceil
+
+\def\pgfmathfloat@notimplemented#1{%
+ \pgfmath@error{Sorry, the operation '#1' has not yet been implemented in the floating point unit}{}%
+ \pgfmathfloatcreate{0}{0.0}{0}%
+}%
+
+% Divides or multiplies the input number by 10^#4 using an arithmetic
+% left/right shift.
+%
+% Input:
+% #1 a normalised floating point number.
+% #2 a positive or negative integer number denoting the shift.
+%
+% Example:
+% \pgfmathfloatshift{11e3}{4}%
+% -> pgfmathresult = 11e7
+\def\pgfmathfloatshift@#1#2{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \advance\pgfmathfloat@a@E by#2\relax
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatshift=\pgfmathfloatshift@
+
+% Defines \pgfmathresult to be |#1|, the absolute value of the
+% normalized floating point number #1.
+\def\pgfmathfloatabs@#1{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifcase\pgfmathfloat@a@S
+ % 0: do nothing.
+ \or
+ % +: ok, is positive.
+ \or
+ % -: multiply with -1:
+ \pgfmathfloat@a@S=1
+ \or
+ % nan: do nothing.
+ \or
+ % +infty: ok.
+ \or
+ % -infty: multiply with -1:
+ \pgfmathfloat@a@S=4
+ \fi
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+%
+% Defines \pgfmathresult to be sign(#1)
+\def\pgfmathfloatsign@#1{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifcase\pgfmathfloat@a@S
+ % 0:
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \or
+ % +: ok, is positive.
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \or
+ % -:
+ \pgfmathfloatcreate{2}{1.0}{0}%
+ \or
+ % nan: do nothing.
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \or
+ % +infty:.
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \or
+ % -infty:
+ \pgfmathfloatcreate{2}{1.0}{0}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatsign=\pgfmathfloatsign@
+
+% Computes the absolute error |#1 - #2| into \pgfmathresult.
+\def\pgfmathfloatabserror@#1#2{%
+ \pgfmathfloatsubtract@{#1}{#2}%
+ \pgfmathfloatabs@{\pgfmathresult}%
+}%
+\let\pgfmathfloatabserror=\pgfmathfloatabserror@
+
+% Computes the relative error |#1 - #2|/|#2| into \pgfmathresult,
+% assuming #2 != 0.
+\def\pgfmathfloatrelerror@#1#2{%
+ \pgfmathfloatsubtract@{#1}{#2}%
+ \let\pgfmathfloat@subtract=\pgfmathresult
+ \pgfmathfloatifflags{#2}{0}{%
+ \let\pgfmathresult=\pgfmathfloat@subtract
+ }{%
+ \pgfmathfloatdivide@{\pgfmathfloat@subtract}{#2}%
+ }%
+ \pgfmathfloatabs@{\pgfmathresult}%
+}%
+\let\pgfmathfloatrelerror=\pgfmathfloatrelerror@
+
+% Computes \pgfmathresult = #1 mod #2 using truncated division.
+%
+\def\pgfmathfloatmod@#1#2{%
+ \begingroup
+ \pgfmathfloattoint{#1}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathfloattoint{#2}%
+ \let\pgfmathfloat@loc@TMPb=\pgfmathresult
+ \c@pgfmath@counta=\pgfmathfloat@loc@TMPa\relax
+ \divide\c@pgfmath@counta by\pgfmathfloat@loc@TMPb\relax
+ \expandafter\pgfmathfloatparsenumber\expandafter{\the\c@pgfmath@counta}%
+ %
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{#2}%
+ \let\pgfmathfloat@loc@TMPb=\pgfmathresult
+ \pgfmathfloatsubtract@{#1}{\pgfmathfloat@loc@TMPb}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatmod=\pgfmathfloatmod@
+
+
+% A modification of \pgfmathfloatmod@ where #3 = 1/#2 is already
+% known. This may be faster.
+\def\pgfmathfloatmodknowsinverse@#1#2#3{%
+ \pgfmathfloatmod@{#1}{#2}%
+ %--------------------------------------------------
+ % \begingroup
+ % % FIXME : is this function correct? \pgfmathfloatmod had a
+ % % rounding flaw...
+ % \pgfmathfloatmultiply@{#1}{#3}%
+ % \pgfmathfloatint@{\pgfmathresult}%
+ % \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ % \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{#2}%
+ % \let\pgfmathfloat@loc@TMPb=\pgfmathresult
+ % \pgfmathfloatsubtract@{#1}{\pgfmathfloat@loc@TMPb}%
+ % \pgfmath@smuggleone\pgfmathresult
+ % \endgroup
+ %--------------------------------------------------
+}%
+\let\pgfmathfloatmodknowsinverse=\pgfmathfloatmodknowsinverse@
+
+\def\pgfmathfloatpi@{%
+ \pgfmathfloatcreate{1}{3.14159265358979}{0}%
+}%
+\let\pgfmathfloatpi=\pgfmathfloatpi@
+
+\def\pgfmathfloate@{%
+ \pgfmathfloatcreate{1}{2.71828182845905}{0}%
+}%
+\let\pgfmathfloate=\pgfmathfloate@
+
+% Converts #1 from radians to degrees.
+\def\pgfmathfloatdeg@#1{%
+ \expandafter\ifx\csname pgfmfltdeg@factor\endcsname\relax
+ % Lazy evaluation:
+ \pgfmathfloatcreate{1}{5.72957795130823}{1}%
+ \global\let\pgfmfltdeg@factor=\pgfmathresult
+ \fi
+ \pgfmathfloatmultiply@{#1}\pgfmfltdeg@factor%
+}%
+\let\pgfmathfloatdeg=\pgfmathfloatdeg@
+
+% Converts #1 from degree to radians.
+\def\pgfmathfloatrad@#1{%
+ \expandafter\ifx\csname pgfmfltrad@factor\endcsname\relax
+ % Lazy evaluation:
+ \pgfmathfloatcreate{1}{1.74532925199433}{-2}%
+ \global\let\pgfmfltrad@factor=\pgfmathresult
+ \fi
+ \pgfmathfloatmultiply@{#1}\pgfmfltrad@factor%
+}%
+\let\pgfmathfloatrad=\pgfmathfloatrad@
+
+% Computes #1(#2) where #1 is a trigonometric function, i.e.
+% #1(#2) = #1( #2 + r*360 )
+%
+% #1 is a one-argument macro which assigns \pgfmathresult.
+\def\pgfmathfloatTRIG@#1#2{%
+ \if0\pgfmath@trig@format@choice
+ % trig format=deg
+ \expandafter\ifx\csname pgfmathfloatTRIG@NUM\endcsname\relax%
+ % Lazy evaluation:
+ \pgfmathfloatcreate{1}{3.6}{2}%
+ \global\let\pgfmathfloatTRIG@NUM=\pgfmathresult
+ \pgfmathfloatcreate{1}{2.77777777777778}{-3}%
+ \global\let\pgfmathfloatTRIG@NUM@INV=\pgfmathresult
+ \fi
+ \pgfmathfloatmodknowsinverse@{#2}{\pgfmathfloatTRIG@NUM}{\pgfmathfloatTRIG@NUM@INV}%
+ \else
+ % trig format=rad
+ \expandafter\ifx\csname pgfmathfloatTRIG@rad@NUM\endcsname\relax%
+ % Lazy evaluation:
+ \pgfmathfloatcreate{1}{6.28318530717959}{0}%
+ \global\let\pgfmathfloatTRIG@rad@NUM=\pgfmathresult
+ \pgfmathfloatcreate{1}{1.59154943091895}{-1}%
+ \global\let\pgfmathfloatTRIG@rad@NUM@INV=\pgfmathresult
+ \fi
+ \pgfmathfloatmodknowsinverse@{#2}{\pgfmathfloatTRIG@rad@NUM}{\pgfmathfloatTRIG@rad@NUM@INV}%
+ \fi
+ \pgfmathfloattofixed@{\pgfmathresult}%
+ \expandafter#1\expandafter{\pgfmathresult}%
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+}%
+
+\def\pgfmathfloatsin@#1{\pgfmathfloatTRIG@\pgfmath@basic@sin@{#1}}%
+\let\pgfmathfloatsin=\pgfmathfloatsin@
+\def\pgfmathfloatcos@#1{\pgfmathfloatTRIG@\pgfmath@basic@cos@{#1}}%
+\let\pgfmathfloatcos=\pgfmathfloatcos@
+\def\pgfmathfloattan@#1{%
+ % compute sin(#1) / cos(#1)
+ \begingroup
+ \pgfmathfloatcos@{#1}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathfloatsin@{#1}%
+ \expandafter\pgfmathfloatdivide@\expandafter{\pgfmathresult}{\pgfmathfloat@loc@TMPa}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloattan=\pgfmathfloattan@
+
+\def\pgfmathfloatcot@#1{%
+ % compute cos(#1) / sin(#1)
+ \begingroup
+ \pgfmathfloatsin@{#1}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathfloatcos@{#1}%
+ \expandafter\pgfmathfloatdivide@\expandafter{\pgfmathresult}{\pgfmathfloat@loc@TMPa}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatcot=\pgfmathfloatcot@
+
+\def\pgfmathfloatatan@#1{%
+ \begingroup
+ \expandafter\ifx\csname pgfmathfloatatan@TMP\endcsname\relax%
+ \pgfmathfloatcreate{1}{1.6}{4}%
+ \global\let\pgfmathfloatatan@TMP=\pgfmathresult
+ \pgfmathfloatcreate{2}{1.6}{4}%
+ \global\let\pgfmathfloatatan@TMPB=\pgfmathresult
+ \fi
+ \pgfmathfloatgreaterthan@{#1}{\pgfmathfloatatan@TMP}%
+ \ifpgfmathfloatcomparison
+ \pgfmathiftrigonometricusesdeg{%
+ \pgfmathfloatcreate{1}{9.0}{1}%
+ }{%
+ \pgfmathfloatcreate{1}{1.570796326794}{0}%
+ }%
+ \else
+ \pgfmathfloatlessthan{#1}{\pgfmathfloatatan@TMPB}%
+ \ifpgfmathfloatcomparison
+ \pgfmathiftrigonometricusesdeg{%
+ \pgfmathfloatcreate{2}{9.0}{1}%
+ }{%
+ \pgfmathfloatcreate{2}{1.570796326794}{0}%
+ }%
+ \else
+ \pgfmathfloattofixed@{#1}%
+ \expandafter\pgfmath@basic@atan@\expandafter{\pgfmathresult}%
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ \fi
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloatatan=\pgfmathfloatatan@
+
+\def\pgfmathfloatatantwo#1#2{%
+ % Note: first parameter is y (!), second is x (!)
+ \begingroup%
+ \let\pgfmath@trig@format@choice@@=\pgfmath@trig@format@choice
+ \def\pgfmath@trig@format@choice{0}%
+ %
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \expandafter\pgfmathfloat@decompose#2\relax\pgfmathfloat@b@S\pgfmathfloat@b@M\pgfmathfloat@b@E
+ \ifnum\pgfmathfloat@a@S=0
+ % ok, #1 = 0. Substitute by 1e-16 such that the next \ifnum catches it:
+ \pgfmathfloat@a@E=-16 %
+ \fi
+ %
+ \ifnum\pgfmathfloat@a@E<-3 %
+ \ifnum\pgfmathfloat@b@S=2 %
+ % #2 < 0
+ \pgfmathfloatcreate{1}{1.8}{2}% +180
+ \else
+ \ifnum\pgfmathfloat@b@S=1 %
+ % #2 >0
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \else
+ % + or - 90, just use the sign of #1:
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{9.0}{1}%
+ \fi
+ \fi
+ \else%
+ \pgfmathfloatabs@{#1}\let\pgfmath@tempa\pgfmathresult%
+ \pgfmathfloatabs@{#2}\let\pgfmath@tempb\pgfmathresult%
+ \pgfmathfloatgreaterthan@{\pgfmath@tempa}{\pgfmath@tempb}%
+ \ifpgfmathfloatcomparison
+ \pgfmathfloatdivide@{#2}{\pgfmath@tempa}%
+ \expandafter\pgfmathfloatatan@\expandafter{\pgfmathresult}%
+ \let\pgfmath@tempa=\pgfmathresult
+ \pgfmathfloatcreate{1}{9.0}{1}%
+ \let\pgfmath@tempb=\pgfmathresult
+ \pgfmathfloatsubtract@{\pgfmath@tempb}{\pgfmath@tempa}%
+ \else%
+ \pgfmathfloatdivide@{\pgfmath@tempa}{#2}%
+ \expandafter\pgfmathfloatatan@\expandafter{\pgfmathresult}%
+ \expandafter\pgfmathfloatifflags\expandafter{\pgfmathresult}{2}{%
+ \let\pgfmath@tempa=\pgfmathresult
+ \pgfmathfloatcreate{1}{1.8}{2}%
+ \let\pgfmath@tempb=\pgfmathresult
+ \pgfmathfloatadd@{\pgfmath@tempa}{\pgfmath@tempb}%
+ }{}%
+ \fi%
+ %
+ \pgfmathfloatifflags{#1}{-}{%
+ % #1 < 0:
+ \pgfmathfloatmultiplyfixed@{\pgfmathresult}{-1}%
+ }{}%
+ \fi%
+ \if1\pgfmath@trig@format@choice@@
+ % trig format=rad
+ \pgfmathfloat@scale@deg@to@rad\pgfmathresult
+ \fi
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}%
+\let\pgfmathfloatatantwo@=\pgfmathfloatatantwo
+\expandafter\let\csname pgfmathfloatatan2\endcsname=\pgfmathfloatatantwo
+\expandafter\let\csname pgfmathfloatatan2@\endcsname=\pgfmathfloatatantwo@
+
+\def\pgfmathfloat@scale@deg@to@rad#1{%
+ \edef\pgfmathfloat@loc@TMPb{#1}%
+ \pgfmathfloatcreate{1}{1.74532925199433}{-2}% = pi / 180
+ \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@loc@TMPb}%
+}%
+
+\def\pgfmathfloatsec@#1{\pgfmathfloatTRIG@\pgfmath@basic@cos@{#1}\pgfmathfloatreciprocal@{\pgfmathresult}}%
+\let\pgfmathfloatsec=\pgfmathfloatsec@
+\def\pgfmathfloatcosec@#1{\pgfmathfloatTRIG@\pgfmath@basic@sin@{#1}\pgfmathfloatreciprocal@{\pgfmathresult}}%
+\let\pgfmathfloatcosec=\pgfmathfloatcosec@
+
+% Expands #2 using \edef and invokes #1 with the resulting string.
+%
+% DEPRECATED
+% Example:
+% \pgfmath@y=7.9pt
+% \pgfmathlog@invoke@expanded\pgfmathexp@{{\pgf@sys@tonumber{\pgfmath@y}}}%
+% will invoke
+% \pgfmathexp@{7.9}
+\def\pgfmathlog@invoke@expanded#1#2{%
+ \edef\pgfmath@resulttemp{#2}%
+ \expandafter#1\pgfmath@resulttemp
+}%
+
+\def\pgfmathfloatln@#1{%
+ \pgfmathlog@float{#1}%
+ \ifx\pgfmathresult\pgfutil@empty
+ \pgfmathfloatcreate{3}{0.0}{0}%
+ \else
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ \fi
+}%
+\let\pgfmathfloatln=\pgfmathfloatln@
+
+\expandafter\def\csname pgfmathfloatlog10@\endcsname#1{%
+ \pgfmathfloatln@{#1}%
+ \let\pgfmathfloat@log@e=\pgfmathresult
+ \pgfmathfloatcreate{1}{4.34294481903252}{-1}% 1/ln(10)
+ \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@e}%
+}%
+\pgfutil@namelet{pgfmathfloatlog10}{pgfmathfloatlog10@}%
+
+\expandafter\def\csname pgfmathfloatlog2@\endcsname#1{%
+ \pgfmathfloatln@{#1}%
+ \let\pgfmathfloat@log@e=\pgfmathresult
+ \pgfmathfloatcreate{1}{1.44269504088896}{0}% 1/ln(2)
+ \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@e}%
+}%
+\pgfutil@namelet{pgfmathfloatlog2}{pgfmathfloatlog2@}%
+
+\expandafter\let\expandafter\pgfmathfloatlogtwo\csname pgfmathfloatlog2\endcsname
+\expandafter\let\expandafter\pgfmathfloatlogtwo@\csname pgfmathfloatlog2@\endcsname
+\expandafter\let\expandafter\pgfmathfloatlogten\csname pgfmathfloatlog10\endcsname
+\expandafter\let\expandafter\pgfmathfloatlogten@\csname pgfmathfloatlog10@\endcsname
+
+% Computes log(x) into \pgfmathresult.
+%
+% This allows numbers such at 10000000 or 5.23e-10 to be represented
+% properly, although TeX-registers would produce overflow/underflow
+% errors in these cases.
+%
+% The natural logarithm is computed using log(X*10^Y) = log(X) + log(10)*Y
+%
+% FIXME This routine is only kept for backwards compatibility!
+% It does not work as expected because
+% 1. it calls \pgfmathfloatparsenumber
+% 2. it returns the result as fixed point number
+% Use \pgfmathln@ instead!
+\def\pgfmathlog@#1{%
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathlog@float{\pgfmathresult}%
+}%
+\let\pgfmathlog=\pgfmathlog@
+\def\pgfmathlog@float#1{%
+ \begingroup%
+ % compute #1 = M*10^E with normalised mantissa M = [+-]*[1-9].XXXXX
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifnum\pgfmathfloat@a@S=1
+ % Now, compute log(#1) = log(M) + E*log(10)
+ \expandafter\pgfmath@basic@ln@\expandafter{\the\pgfmathfloat@a@Mtok}%
+ \pgfmathfloat@b@M=\pgfmathresult pt%
+ \pgfmathfloat@a@M=2.302585pt% = log(10)
+ \multiply\pgfmathfloat@a@M by\pgfmathfloat@a@E\relax
+ \advance\pgfmathfloat@b@M by\pgfmathfloat@a@M
+ \edef\pgfmathresult{\pgf@sys@tonumber{\pgfmathfloat@b@M}}%
+ \else
+ \let\pgfmathresult=\pgfutil@empty%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup%
+}%
+
+
+% Computes exp(#1) in floating point.
+%
+% The algorithm employs the identity
+% exp(x) = exp(x - log(10^k) + log(10^k)
+% = 10^k exp( x - k*log 10 )
+% with k chosen such that exp( x - k*log10) can be computed with the
+% basic level math engine.
+%
+% The precision (relative error) is between 10^{-4} and 10^{-6}. For
+% #1 = 700, it is even 10^{-3}. I will need to improve that someday.
+\def\pgfmathfloatexp@#1{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifcase\pgfmathfloat@a@S
+ % #1 = 0:
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \or% #1 > 0
+ \pgfmathfloatexp@@{#1}%
+ \or% #1 < 0
+ \pgfmathfloatexp@@{#1}%
+ \else
+ \edef\pgfmathresult{#1}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\def\pgfmathfloatexp@@#1{%
+ % Employ the identity
+ % exp(x) = exp(x - log(10^k) + log(10^k)) = 10^k exp( x - k *log(10))
+ %
+ % I'd like to have x - k*log(10) <= 1
+ % => compute k := int( (x - 1) * 1/log(10) )
+ % that should suffice since \pgfmathexp@ should be
+ % accurate enough for those numbers.
+ %
+ % please note that we can do all this in TeX registers.
+ % exp(700) is almost the maximum of double precision
+ % anyway, and exp(16000) is certainly the largest we will
+ % ever need.
+ \pgfmathfloattofixed@{#1}%
+ \pgf@xa=\pgfmathresult pt
+ \pgf@xa=0.434294481\pgf@xa\relax
+ \edef\pgfmathfloat@loc@TMPa{\pgf@sys@tonumber{\pgf@xa}}%
+ \expandafter\pgfmathfloatexp@@toint\pgfmathfloat@loc@TMPa\relax
+ \pgf@xa=2.302585092pt
+ \multiply\pgf@xa by-\pgfmathfloat@k\relax
+ \advance\pgf@xa by\pgfmathresult pt
+ \edef\pgfmathfloat@loc@TMPa{\pgf@sys@tonumber{\pgf@xa}}%
+%\message{computing exp(\pgfmathresult) = 10^\pgfmathfloat@k * exp(\pgfmathfloat@loc@TMPa)...}%
+ \pgfmath@basic@exp@{\pgfmathfloat@loc@TMPa}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathfloatparsenumber{\pgfmathfloat@loc@TMPa}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathfloatshift@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@k}%
+}%
+% determine 'k'. This is a heuristics. The exponential series
+% converges best for |x| <= 1. However, the fixed point arithmetics
+% for tex results in best results for large |x|. Well, I'll need to
+% tune this here.
+\def\pgfmathfloatexp@@toint#1.#2\relax{%
+ \c@pgf@counta=#1\relax
+ \ifnum\c@pgf@counta<0
+\advance\c@pgf@counta by-1 % FIXME . this is a test for optimizations.
+ \c@pgf@countb=#2\relax
+ \ifnum\c@pgf@countb>0
+ \advance\c@pgf@counta by-1
+ \fi
+ \fi
+ \edef\pgfmathfloat@k{\the\c@pgf@counta}%
+}%
+\let\pgfmathfloatexp=\pgfmathfloatexp@
+
+\def\pgfmathfloatround@#1{%
+ \begingroup
+ \pgfkeysvalueof{/pgf/number format/precision/.@cmd}0\pgfeov
+ \pgfmathfloattofixed{#1}%
+ \pgfmathroundto{\pgfmathresult}%
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+
+\def\pgfmathfloatneg@#1{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifcase\pgfmathfloat@a@S\relax
+ % 0:
+ \edef\pgfmathresult{#1}%
+ \or
+ % +:
+ \pgfmathfloatcreate{2}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \or
+ % -:
+ \pgfmathfloatcreate{1}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \or
+ % nan:
+ \edef\pgfmathresult{#1}%
+ \or
+ % +infty:
+ \pgfmathfloatcreate{5}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \or
+ % -infty:
+ \pgfmathfloatcreate{4}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+
+\def\pgfmathfloatpow@#1#2{%
+ \begingroup%
+ \expandafter\pgfmathfloat@decompose@tok#2\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifcase\pgfmathfloat@a@S\relax
+ % #1 ^ 0 = 1
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \or
+ % #2 > 0
+ \pgfmathfloatpow@@{#1}{#2}%
+ \or
+ % #2 < 0
+ \pgfmathfloatpow@@{#1}{#2}%
+ \or
+ % #2 = nan
+ \edef\pgfmathresult{#2}%
+ \or
+ % #2 = inf
+ \edef\pgfmathresult{#2}%
+ \or
+ % #2 = -inf
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+% computes #1^#2
+% PRECONDITIONS
+% - #2 is positive.
+\def\pgfmathfloatpow@@#1#2{%
+ \pgfmathfloattofixed@{#2}%
+ \afterassignment\pgfmath@x%
+ \expandafter\c@pgfmath@counta\pgfmathresult pt\relax%
+ \ifdim\pgfmath@x=0pt %
+ % loop "manually"; we have an integer exponent!
+ \ifnum\c@pgfmath@counta<0
+ \pgfmathfloatreciprocal@{#1}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \c@pgfmath@counta=-\c@pgfmath@counta
+ \else
+ \edef\pgfmathfloat@loc@TMPa{#1}%
+ \fi
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \let\pgfmathfloat@loc@TMPb=\pgfmathresult
+ \pgfmathloop
+ \ifnum\c@pgfmath@counta>0\relax%
+ \ifodd\c@pgfmath@counta%
+ \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPb}{\pgfmathfloat@loc@TMPa}%
+ \let\pgfmathfloat@loc@TMPb=\pgfmathresult
+ \fi
+ \ifnum\c@pgfmath@counta>1\relax%
+ \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPa}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \fi%
+ \divide\c@pgfmath@counta by2\relax%
+ \repeatpgfmathloop%
+ \else
+ \pgfmathfloatgetflags{#1}\c@pgfmath@counta
+ \ifnum0=\c@pgfmath@counta
+ % ah: 0^x
+ \pgfmathfloatgetflags{#2}\c@pgfmath@counta
+ \ifnum0=\c@pgfmath@counta
+ % ah: 0^0
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \else
+ % ah: 0^x with x!=0:
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ \fi
+ \else
+ % employ #1^#2 = exp( #2 * ln(#1) )
+ \pgfmathfloatln@{#1}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \edef\pgfmathfloat@loc@TMPb{#2}%
+ \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPb}%
+ \pgfmathfloatexp@{\pgfmathresult}%
+ \fi
+ \fi
+}%
+
+\def\pgfmathfloat@definemethodfrombasic@NOARG#1{%
+ \pgfutil@ifundefined{pgfmath@basic@#1@}{%
+ \pgfutil@namelet{pgfmath@basic@#1@}{pgfmath#1@}%
+ }{}%
+ \edef\pgfmathfloat@glob@TMP{%
+ \expandafter\noexpand\csname pgfmath@basic@#1@\endcsname
+ \noexpand\pgfmathfloatparsenumber{\noexpand\pgfmathresult}%
+ }%
+ \expandafter\let\csname pgfmathfloat#1@\endcsname=\pgfmathfloat@glob@TMP%
+ \expandafter\let\csname pgfmathfloat#1\endcsname=\pgfmathfloat@glob@TMP%
+}%
+\def\pgfmathfloat@definemethodfrombasic@ONEARG#1{%
+ \pgfutil@ifundefined{pgfmath@basic@#1@}{%
+ \pgfutil@namelet{pgfmath@basic@#1@}{pgfmath#1@}%
+ }{}%
+ \edef\pgfmathfloat@glob@TMP##1{%
+ \noexpand\pgfmathfloattofixed{##1}%
+ \noexpand\expandafter
+ \expandafter\noexpand\csname pgfmath@basic@#1@\endcsname\noexpand\expandafter%
+ {\noexpand\pgfmathresult}%
+ \noexpand\pgfmathfloatparsenumber{\noexpand\pgfmathresult}%
+ }%
+ \expandafter\let\csname pgfmathfloat#1@\endcsname=\pgfmathfloat@glob@TMP%
+ \expandafter\let\csname pgfmathfloat#1\endcsname=\pgfmathfloat@glob@TMP%
+}%
+\def\pgfmathfloat@definemethodfrombasic@TWOARGS#1{%
+ \pgfutil@ifundefined{pgfmath@basic@#1@}{%
+ \pgfutil@namelet{pgfmath@basic@#1@}{pgfmath#1@}%
+ }{}%
+ \edef\pgfmathfloat@glob@TMP##1##2{%
+ \noexpand\pgfmathfloattofixed{##2}%
+ \noexpand\let\noexpand\pgfmathfloat@loc@TMPa=\noexpand\pgfmathresult
+ \noexpand\pgfmathfloattofixed{##1}%
+ \noexpand\expandafter
+ \expandafter\noexpand\csname pgfmath@basic@#1@\endcsname\noexpand\expandafter%
+ {\noexpand\pgfmathresult}{\noexpand\pgfmathfloat@loc@TMPa}%
+ \noexpand\pgfmathfloatparsenumber{\noexpand\pgfmathresult}%
+ }%
+ \expandafter\let\csname pgfmathfloat#1@\endcsname=\pgfmathfloat@glob@TMP%
+ \expandafter\let\csname pgfmathfloat#1\endcsname=\pgfmathfloat@glob@TMP%
+}%
+\pgfmathfloat@definemethodfrombasic@NOARG{rand}%
+\pgfmathfloat@definemethodfrombasic@NOARG{rnd}%
+\pgfmathfloat@definemethodfrombasic@NOARG{false}%
+\pgfmathfloat@definemethodfrombasic@NOARG{true}%
+% arcsin, arccos
+\pgfmathfloat@definemethodfrombasic@ONEARG{asin}%
+\pgfmathfloat@definemethodfrombasic@ONEARG{acos}%
+\pgfmathfloat@definemethodfrombasic@ONEARG{not}%
+\pgfmathfloat@definemethodfrombasic@ONEARG{hex}%
+\pgfmathfloat@definemethodfrombasic@ONEARG{Hex}%
+\pgfmathfloat@definemethodfrombasic@ONEARG{oct}%
+\pgfmathfloat@definemethodfrombasic@ONEARG{bin}%
+\pgfmathfloat@definemethodfrombasic@TWOARGS{and}%
+\pgfmathfloat@definemethodfrombasic@TWOARGS{or}%
+
+\pgfutil@ifundefined{pgfmathdeclarefunction}{%
+ % special treatment: \pgfmathrand@ was not properly defined for pgf 2.00:
+ \let\pgfmath@basic@rand=\pgfmathrand
+ \let\pgfmath@basic@rand@=\pgfmathrand@
+ \def\pgfmathfloatrand@{%
+ \pgfmath@basic@rand
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ }%
+ \let\pgfmathfloatrand=\pgfmathfloatrand@%
+ %
+ % special treatment: \pgfmathrnd@ was not properly defined for pgf 2.00:
+ \let\pgfmath@basic@rnd=\pgfmathrnd
+ \let\pgfmath@basic@rnd@=\pgfmathrnd@
+ \def\pgfmathfloatrnd@{%
+ \pgfmath@basic@rnd
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ }%
+ \let\pgfmathfloatrnd=\pgfmathfloatrnd@%
+}{}%
+
+% Implements the factorial of '#1'.
+% This does only work if '#1 < 2^32'.
+\def\pgfmathfloatfactorial@#1{%
+ \begingroup
+ \pgfmathfloattofixed{#1}%
+ % collect integer part into a 32 bit register:
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgfmath@counta\pgfmathresult\relax\pgfmath@%
+ \pgfmathfloatcreate{1}{1.0}{0}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathloop
+ \ifnum\c@pgfmath@counta<2 %
+ \else
+ \expandafter\pgfmathfloatparsenumber\expandafter{\the\c@pgfmath@counta}%
+ \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfmathfloat@loc@TMPa}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \advance\c@pgfmath@counta by-1\relax%
+ \repeatpgfmathloop
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+% Implements the vector length of a 2D vector.
+%
+% ATTENTION: this does NOT use the improved code of the basic layer!
+% It simply computed sqrt( #1^2 + #2^2 )!
+\def\pgfmathfloatveclen@#1#2{%
+ \begingroup
+ \edef\pgfmathfloat@@a{#1}%
+ \pgfmathfloatmultiply@{\pgfmathfloat@@a}{\pgfmathfloat@@a}%
+ \let\pgfmathfloat@@a=\pgfmathresult
+ %
+ \edef\pgfmathfloat@@b{#2}%
+ \pgfmathfloatmultiply@{\pgfmathfloat@@b}{\pgfmathfloat@@b}%
+ \let\pgfmathfloat@@b=\pgfmathresult
+ %
+ \pgfmathfloatadd@{\pgfmathfloat@@a}{\pgfmathfloat@@b}%
+ \pgfmathfloatsqrt@{\pgfmathresult}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+\def\pgfmathfloatcosh@#1{%
+ \begingroup
+ \pgfmathfloatexp@{#1}%
+ \let\pgfmathfloat@@a=\pgfmathresult
+ %
+ \pgfmathfloatneg@{#1}%
+ \pgfmathfloatexp@{\pgfmathresult}%
+ %
+ \pgfmathfloatadd@{\pgfmathresult}{\pgfmathfloat@@a}%
+ \expandafter\pgfmathfloatmultiplyfixed@\expandafter{\pgfmathresult}{0.5}%
+ %
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\def\pgfmathfloatsinh@#1{%
+ \begingroup
+ \pgfmathfloatexp@{#1}%
+ \let\pgfmathfloat@@a=\pgfmathresult
+ %
+ \pgfmathfloatneg@{#1}%
+ \pgfmathfloatexp@{\pgfmathresult}%
+ %
+ \pgfmathfloatsubtract@{\pgfmathfloat@@a}{\pgfmathresult}%
+ \expandafter\pgfmathfloatmultiplyfixed@\expandafter{\pgfmathresult}{0.5}%
+ %
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\def\pgfmathfloattanh@#1{%
+ \begingroup
+ \pgfmathfloatsinh@{#1}%
+ \let\pgfmathfloat@@a=\pgfmathresult
+ %
+ \pgfmathfloatcosh@{#1}%
+ \let\pgfmathfloat@@b=\pgfmathresult
+ %
+ \pgfmathfloatdivide@{\pgfmathfloat@@a}{\pgfmathfloat@@b}%
+ %
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryintersections.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryintersections.code.tex
new file mode 100644
index 0000000000..2457157690
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryintersections.code.tex
@@ -0,0 +1,1172 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Free Documentation License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% Note: at the time of this writing, the library has quadratic runtime.
+% Experimentally, it performed well while computing ~12 intersections of two
+% plots, each with 600 samples. It failed when the number of samples exceeded 700.
+
+\usepgflibrary{fpu}%
+
+\newcount\pgf@intersect@solutions
+
+\newif\ifpgf@intersect@sort
+\newif\ifpgf@intersect@sort@by@second@path
+
+\def\pgfintersectionsortbyfirstpath{%
+ \pgf@intersect@sorttrue%
+ \pgf@intersect@sort@by@second@pathfalse%
+}%
+
+\def\pgfintersectionsortbysecondpath{%
+ \pgf@intersect@sorttrue%
+ \pgf@intersect@sort@by@second@pathtrue%
+}%
+
+% #1: the index. It starts at 1 and ends with \pgfintersectionsolutions (inclusive).
+% Invalid values will implicitly result in the origin.
+\def\pgfpointintersectionsolution#1{%
+ \ifnum#1<1\relax%
+ \pgfpoint@intersect@solution@orgin%
+ \else%
+ \ifnum#1>\pgfintersectionsolutions\relax%
+ \pgfpoint@intersect@solution@orgin%
+ \else%
+ \csname pgfpoint@intersect@solution@#1\endcsname%
+ \fi%
+ \fi%
+}%
+
+% Gets the segment indices of solution #1.
+%
+% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution)
+% #2: [output] a macro name which will contain the segment index of the first path which contains the solution
+% #3: [output] a macro name which will contain the segment index of the second path which contains the solution
+%
+% Example: \pgfintersectiongetsolutionsegmentindices{0}{\first}{\second}%
+%
+% -> \first may be 0 if point #0 is in the 0'th segment
+% -> \second may be 42 if point #0 is in the 42'th segment
+%
+% The "segment index" is actually close to the "time" of the solution.
+% If a solution is at "time" 42.2, it will have segment index 42.
+\def\pgfintersectiongetsolutionsegmentindices#1#2#3{%
+ \ifnum#1<1\relax%
+ \let#2=\pgfutil@empty
+ \let#3=\pgfutil@empty
+ \else%
+ \ifnum#1>\pgfintersectionsolutions\relax%
+ \let#2=\pgfutil@empty
+ \let#3=\pgfutil@empty
+ \else%
+ \def\pgf@temp##1##2##3##4{%
+ \edef#2{##1}%
+ \edef#3{##2}%
+ }%
+ \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname
+ \expandafter\pgf@temp\pgf@tempb
+ \fi%
+ \fi%
+}%
+
+% Gets the time indices of solution #1.
+%
+% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution)
+% #2: [output] a macro name which will contain the time of the first path which contains the solution
+% It will never be empty.
+% #3: [output] a macro name which will contain the time of the second path which contains the solution
+% It will never be empty.
+%
+% Example: \pgfintersectiongetsolutiontimes{0}{\first}{\second}%
+%
+% -> \first may be 0.5 if point #0 is in just in the middle of the path
+% -> \second may be 42.8 if point #0 is in the 42'th segment (compare
+% \pgfintersectiongetsolutionsegmentindices) and is at 80% of the
+% 42'th segment
+%
+% Note that the precise time inside of a segment may be unavailable
+% (currently, it is only computed for curveto paths and not
+% necessarily for lineto). If the precise time is unavailable, this
+% call will return the value of
+% \pgfintersectiongetsolutionsegmentindices (which is a
+% "coarse-grained" time).
+\def\pgfintersectiongetsolutiontimes#1#2#3{%
+ \ifnum#1<1\relax%
+ \let#2=\pgfutil@empty
+ \let#3=\pgfutil@empty
+ \else%
+ \ifnum#1>\pgfintersectionsolutions\relax%
+ \let#2=\pgfutil@empty
+ \let#3=\pgfutil@empty
+ \else%
+ \def\pgf@temp##1##2##3##4{%
+ \edef#2{##3}%
+ \edef#3{##4}%
+ %
+ % check for fallback to segment indices:
+ \ifx#2\pgfutil@empty \edef#2{##1}\fi
+ \ifx#3\pgfutil@empty \edef#3{##2}\fi
+ }%
+ \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname
+ \expandafter\pgf@temp\pgf@tempb
+ \fi%
+ \fi%
+}%
+
+\def\pgfpoint@intersect@solution@orgin{%
+ \begingroup%
+ \pgftransforminvert%
+ \pgfpointorigin%
+ \pgf@pos@transform@glob
+ \global\pgf@x=\pgf@x%
+ \global\pgf@y=\pgf@y%
+ \endgroup%
+}%
+
+% #1 code which assigns the first path using \pgfsetpath.
+% #2 code which assigns the second path using \pgfsetpath.
+%
+% On output, the points, their properties, and the number of points are set.
+% Use \pgfintersectionsolutions which expands to the number of intersections
+\long\def\pgfintersectionofpaths#1#2{%
+ \begingroup%
+ \pgfinterruptpath%
+ #1%
+ \pgfgetpath\pgf@intersect@path@a%
+ \global\let\pgf@intersect@path@temp=\pgf@intersect@path@a%
+ \endpgfinterruptpath%
+ \endgroup%
+ \let\pgf@intersect@path@a=\pgf@intersect@path@temp%
+ %
+ \begingroup%
+ \pgfinterruptpath%
+ #2%
+ \pgfgetpath\pgf@intersect@path@b%
+ \global\let\pgf@intersect@path@temp=\pgf@intersect@path@b%
+ \endpgfinterruptpath%
+ \endgroup%
+ \let\pgf@intersect@path@b=\pgf@intersect@path@temp%
+ %
+ \pgf@intersect@solutions=0\relax%
+ \pgf@intersect@path@reset@a
+ %
+ \ifpgf@intersect@sort@by@second@path%
+ \let\pgf@intersect@temp=\pgf@intersect@path@a%
+ \let\pgf@intersect@path@a=\pgf@intersect@path@b%
+ \let\pgf@intersect@path@b=\pgf@intersect@temp%
+ \fi%
+ %
+ \pgfprocessround\pgf@intersect@path@a\pgf@intersect@path@a%
+ \pgfprocessround\pgf@intersect@path@b\pgf@intersect@path@b%
+ %
+ \let\pgf@intersect@token@after=\pgf@intersect@path@process@a%
+ \expandafter\pgf@intersectionofpaths\pgf@intersect@path@a\pgf@stop%
+ \edef\pgfintersectionsolutions{\the\pgf@intersect@solutions}%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgfintersectionsolutions\relax%
+ \else%
+ \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}%
+ {pgfpoint@g@intersect@solution@\pgfmathcounter}%
+ \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties{\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}}%
+ \pgf@marshal
+ \ifpgf@intersect@sort%
+ \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}%
+ {pgf@g@intersect@solution@\pgfmathcounter @time@a}%
+ \fi%
+ \repeatpgfmathloop%
+ \ifpgf@intersect@sort%
+ \pgfintersectionsolutionsortbytime%
+ \fi%
+}%
+
+\def\pgf@intersection@set@properties#1{%
+ \pgfutil@namedef{pgf@intersect@solution@props@\pgfmathcounter}{#1}%
+}%
+
+% #1 a global name prefix to store properties.
+\def\pgf@intersection@store@properties#1{%
+ % we store the time offsets as well and make them available programmatically:
+ % note that \pgf@intersect@time@a and \pgf@intersect@time@b may be empty.
+ %
+ % However, \pgf@intersect@time@offset and
+ % \pgf@intersect@time@offset@b are *always* valid. In fact,they
+ % resemble a part of the time: it holds
+ % 0 <= \pgf@intersect@time@a < 1
+ % and \pgf@intersect@time@offset > 0.
+ %
+ % If we have an intersection in segment 42 of path A,
+ % \pgf@intersect@time@offset will be 42. The time inside of that
+ % segment is given as number in the interval [0,1]. If it is 0.3,
+ % the total time will be 42.3 and that number will be stored as
+ % \pgf@intersect@time@a.
+ %
+ \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}{\pgf@intersect@time@a}{\pgf@intersect@time@b}}%
+}%
+
+\def\pgf@intersectionofpaths#1{%
+ \ifx#1\pgf@stop%
+ \let\pgf@intersect@next=\relax%
+ \else%
+ \ifx#1\pgfsyssoftpath@movetotoken%
+ \let\pgf@intersect@next=\pgf@intersect@token@moveto%
+ \else%
+ \ifx#1\pgfsyssoftpath@linetotoken%
+ \let\pgf@intersect@next=\pgf@intersect@token@lineto%
+ \else%
+ \ifx#1\pgfsyssoftpath@closepathtoken%
+ \let\pgf@intersect@next=\pgf@intersect@token@lineto%
+ \else%
+ \ifx#1\pgfsyssoftpath@curvetosupportatoken%
+ \let\pgf@intersect@next=\pgf@intersect@token@curveto%
+ \else%
+ \ifx#1\pgfsyssoftpath@rectcornertoken%
+ \let\pgf@intersect@next=\pgf@intersect@token@rect%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgf@intersect@next}%
+
+\def\pgf@intersect@token@moveto#1#2{%
+ \def\pgfpoint@intersect@start{\pgfqpoint{#1}{#2}}%
+ \pgf@intersectionofpaths%
+}%
+
+\def\pgf@intersect@token@lineto#1#2{%
+ \def\pgfpoint@intersect@end{\pgfqpoint{#1}{#2}}%
+ \def\pgf@intersect@type{line}%
+ \pgf@intersect@token@after%
+}%
+\def\pgf@intersect@token@curveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{%
+ \def\pgfpoint@intersect@firstsupport{\pgfqpoint{#1}{#2}}%
+ \def\pgfpoint@intersect@secondsupport{\pgfqpoint{#3}{#4}}%
+ \def\pgfpoint@intersect@end{\pgfqpoint{#5}{#6}}%
+ \def\pgf@intersect@type{curve}%
+ \pgf@intersect@token@after%
+}%
+
+\def\pgf@intersect@token@rect#1#2\pgfsyssoftpath@rectsizetoken#3#4{%
+ \pgf@xa=#1\relax%
+ \advance\pgf@xa by#3\relax%
+ \pgf@ya=#2\relax%
+ \advance\pgf@ya by#4\relax%
+ \edef\pgf@marshal{%
+ \noexpand\pgfsyssoftpath@movetotoken{#1}{#2}%
+ \noexpand\pgfsyssoftpath@linetotoken{#1}{\the\pgf@ya}%
+ \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{\the\pgf@ya}%
+ \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@xa}{#2}%
+ \noexpand\pgfsyssoftpath@closepathtoken{#1}{#2}%
+ }%
+ \expandafter\pgf@intersectionofpaths\pgf@marshal%
+}%
+
+\def\pgf@intersect@path@process@a{%
+ \pgf@intersect@path@getpoints@a%
+ \let\pgf@intersect@token@after=\pgf@intersect@path@process@b%
+ \pgf@intersect@path@reset@b
+ \expandafter\pgf@intersectionofpaths\pgf@intersect@path@b\pgf@stop%
+ \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@a%
+ \let\pgf@intersect@token@after=\pgf@intersect@path@process@a%
+ \c@pgf@counta=\pgf@intersect@time@offset\relax%
+ \advance\c@pgf@counta by1\relax%
+ \edef\pgf@intersect@time@offset{\the\c@pgf@counta}%
+ \pgf@intersectionofpaths%
+}%
+
+\def\pgf@intersect@path@reset@a{%
+ \def\pgf@intersect@time@offset{0}%
+ \def\pgf@intersect@time@a{}%
+}%
+
+\def\pgf@intersect@path@reset@b{%
+ \def\pgf@intersect@time@offset@b{0}%
+ \def\pgf@intersect@time@b{}%
+}%
+
+\def\pgf@intersect@path@getpoints@a{%
+ \let\pgfpoint@intersect@start@a=\pgfpoint@intersect@start%
+ \let\pgfpoint@intersect@end@a=\pgfpoint@intersect@end%
+ \let\pgfpoint@intersect@firstsupport@a=\pgfpoint@intersect@firstsupport%
+ \let\pgfpoint@intersect@secondsupport@a=\pgfpoint@intersect@secondsupport%
+ \let\pgf@intersect@type@a=\pgf@intersect@type%
+}%
+
+\def\pgf@intersect@path@process@b{%
+ \pgf@intersect@path@getpoints@b%
+ \csname pgf@intersect@\pgf@intersect@type@a @and@\pgf@intersect@type@b\endcsname%
+ \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@b%
+ \c@pgf@counta=\pgf@intersect@time@offset@b\relax%
+ \advance\c@pgf@counta by1\relax%
+ \edef\pgf@intersect@time@offset@b{\the\c@pgf@counta}%
+ \pgf@intersectionofpaths}%
+
+\def\pgf@intersect@path@getpoints@b{%
+ \let\pgfpoint@intersect@start@b=\pgfpoint@intersect@start%
+ \let\pgfpoint@intersect@end@b=\pgfpoint@intersect@end%
+ \let\pgfpoint@intersect@firstsupport@b=\pgfpoint@intersect@firstsupport%
+ \let\pgfpoint@intersect@secondsupport@b=\pgfpoint@intersect@secondsupport%
+ \let\pgf@intersect@type@b=\pgf@intersect@type%
+}%
+
+\def\pgf@intersect@line@and@line{%
+ \pgf@intersectionoflines{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}%
+ {\pgfpoint@intersect@start@b}{\pgfpoint@intersect@end@b}%
+}%
+
+\def\pgf@intersect@line@and@curve{%
+ \pgf@intersectionoflineandcurve%
+ {\pgf@process{\pgfpoint@intersect@start@a}}{\pgf@process{\pgfpoint@intersect@end@a}}%
+ {\pgf@process{\pgfpoint@intersect@start@b}}{\pgf@process{\pgfpoint@intersect@firstsupport@b}}%
+ {\pgf@process{\pgfpoint@intersect@secondsupport@b}}{\pgf@process{\pgfpoint@intersect@end@b}}%
+}%
+
+\def\pgf@intersect@curve@and@line{%
+ \pgf@intersectionofcurveandline%
+ {\pgf@process{\pgfpoint@intersect@start@a}}{\pgf@process{\pgfpoint@intersect@firstsupport@a}}%
+ {\pgf@process{\pgfpoint@intersect@secondsupport@a}}{\pgf@process{\pgfpoint@intersect@end@a}}%
+ {\pgf@process{\pgfpoint@intersect@start@b}}{\pgf@process{\pgfpoint@intersect@end@b}}%
+}%
+
+\def\pgf@intersect@curve@and@curve{%
+ \pgf@intersectionofcurves%
+ {\pgf@process{\pgfpoint@intersect@start@a}}{\pgf@process{\pgfpoint@intersect@firstsupport@a}}%
+ {\pgf@process{\pgfpoint@intersect@secondsupport@a}}{\pgf@process{\pgfpoint@intersect@end@a}}%
+ {\pgf@process{\pgfpoint@intersect@start@b}}{\pgf@process{\pgfpoint@intersect@firstsupport@b}}%
+ {\pgf@process{\pgfpoint@intersect@secondsupport@b}}{\pgf@process{\pgfpoint@intersect@end@b}}%
+}%
+
+
+\def\pgfintersectionoflines#1#2#3#4{%
+ \pgf@intersect@solutions=0\relax%
+ \pgf@intersectionoflines{#1}{#2}{#3}{#4}%
+}%
+
+\def\pgf@intersectionoflines#1#2#3#4{%
+ \pgf@iflinesintersect{#1}{#2}{#3}{#4}%
+ {%
+ \pgfextract@process\pgf@intersect@solution@candidate{%
+ % pgf@x and pgf@y are already assigned by \pgf@iflinesintersect
+ }%
+ \pgf@ifsolution@duplicate{\pgf@intersect@solution@candidate}{%
+ % ah - we a duplicate. Apparently, we have a hit on an
+ % endpoint.
+ }{%
+ \global\advance\pgf@intersect@solutions by1\relax%
+ \expandafter\global\expandafter\let\csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=\pgf@intersect@solution@candidate
+ \ifpgf@intersect@sort%
+ % save coordinates of the intersection
+ \pgf@process{\pgf@intersect@solution@candidate}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ % determine length of path
+ \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}}%
+ \edef\pgf@marshal{%
+ \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ }%
+ \pgf@marshal%
+ \let\pgf@intersect@length@a=\pgfmathresult%
+ % determine distance of intersection from start
+ \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}%
+ \edef\pgf@marshal{%
+ \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ }%
+ \pgf@marshal%
+ % scale the distance to the path length (path time)
+ \pgfmathdivide@{\pgfmathresult}{\pgf@intersect@length@a}%
+ \pgf@x=\pgfmathresult pt\relax%
+ % advance by the path segment (see definition of \pgf@intersection@store@properties)
+ \advance\pgf@x by\pgf@intersect@time@offset pt\relax%
+ \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@x}}%
+ % save numbered
+ \expandafter\global\expandafter\let\csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname=
+ \pgf@intersect@time@a
+ \else
+ \let\pgf@intersect@time@a=\pgfutil@empty
+ \fi%
+ \let\pgf@intersect@time@b=\pgfutil@empty
+ \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}%
+ }%
+ %
+ }{%
+ }%
+}%
+
+% Test if two lines L1 and L2 intersect.
+%
+% #1 - first point P1 on L1.
+% #2 - second point P2 on L1.
+% #3 - first point P3 on L2.
+% #2 - second point P4 on L2.
+% #5 - code executed if intersection occurs.
+% #6 - code executed if intersection does no occur.
+%
+% Let L1 be represented by P1+(P2-P1)s where 0<=s<=1
+% Let L2 be represented by P3+(P4-P3)t where 0<=t<=1
+%
+% Then L1 and L2 intersect at
+%
+% s = |x2-x1 x3-x1| / |x4-x3 x2-x1|
+% |y2-y1 y3-y1| |y4-y3 y2-y1|
+%
+% t = |x4-x3 x3-x1| / |x4-x3 x2-x1|
+% |y4-y3 y3-y1| |y4-y3 y2-y1|
+%
+% with 0<=s,t<=1
+%
+% s and t do not need to be calculated:
+%
+% Let s = A / C and t = B / C
+%
+% Then 0<=s<=1 if !(C=0) && ((A=0) || ((A>0) && !(C<A)) || ((A<0) && !(C>A)))
+% 0<=t<=1 if !(C=0) && ((B=0) || ((B>0) && !(C<B)) || ((B<0) && !(C>B)))
+%
+\newif\ifpgf@s
+\newif\ifpgf@t
+\def\pgfiflinesintersect#1#2#3#4{%
+ \begingroup%
+ \pgf@iflinesintersect{\pgf@process{#1}}{\pgf@process{#2}}{\pgf@process{#3}}{\pgf@process{#4}}%
+ {\aftergroup\pgfutil@firstoftwo}{\aftergroup\pgfutil@secondoftwo}%
+ \endgroup%
+}%
+
+% queried by pgfplots. Do not delete, only increase.
+\def\pgf@intersections@version{2}%
+
+% #1,#2: line 1
+% #3,#4: line 2
+\def\pgf@iflinesintersect#1#2#3#4{%
+ % first: check bounding boxes -- but somewhat increased such that we do not
+ % exclude "visible" hits due to rounding issues (i.e. use an upper bound):
+ \pgf@intersect@boundingbox@reset%
+ \pgf@intersect@boundingbox@update{#1}%
+ \pgf@intersect@boundingbox@update{#2}%
+ \pgf@intersect@boundingbox@assign@b%
+ %
+ \pgf@intersect@boundingbox@reset%
+ \pgf@intersect@boundingbox@update{#3}%
+ \pgf@intersect@boundingbox@update{#4}%
+ \pgf@intersect@boundingbox@assign@a%
+ %
+ \pgf@intersect@boundingbox@a%
+ \pgf@intersect@boundingbox@b%
+ %
+ \pgf@intersect@boundingbox@ifoverlap@upperbound{%
+ \pgf@iflinesintersect@{#1}{#2}{#3}{#4}%
+ }{%
+ \let\pgf@intersect@next=\pgfutil@secondoftwo%
+ }%
+ \pgf@intersect@next%
+}%
+
+% a helper routine which simply defines \pgf@intersect@next.
+%
+% In principle, this routine is capable of computing the entire intersection... but we only invoke it after checking for bounding box overlaps. This has two reasons:
+% 1. robustness. almost-parallel lines could cause "dimension too large" when solving the linear equation system
+% XXX : I still needed to replace the linear solver by one using the FPU. Perhaps I do not need the BB check anymore?
+% 2. performance. I hope it is faster to first check for BB (but this is not sure in TeX)
+%
+% #1,#2: line 1
+% #3,#4: line 2
+\def\pgf@iflinesintersect@#1#2#3#4{%
+ % we have two lines of sorts
+ % l_1(s) := #1 + s * (#2 - #1), 0<= s <= 1
+ % and
+ % l_2(t) := #3 + t * (#4 - #3), 0<= t <= 1
+ % ->
+ % set up LGS
+ % ( #2 - #1 ) *s + (#3-#4) * t = #3-#1
+ % we have a hit if 0<= s,t <= 1 .
+ #1\relax%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ #2\relax%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ #3\relax%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ #4\relax%
+ %
+ % will be overwritten, remember it:
+ \edef\pgf@intersect@A{%
+ \pgf@xa=\the\pgf@xa\space
+ \pgf@ya=\the\pgf@ya\space
+ }%
+ %
+ % B := (2-1)
+ \advance\pgf@xb by-\pgf@xa
+ \advance\pgf@yb by-\pgf@ya
+ %
+ % A := (3-1)
+ \advance\pgf@xa by-\pgf@xc
+ \advance\pgf@ya by-\pgf@yc
+ \pgf@xa=-\pgf@xa
+ \pgf@ya=-\pgf@ya
+ %
+ % C := (3-4)
+ \advance\pgf@xc by-\pgf@x
+ \advance\pgf@yc by-\pgf@y
+ %
+ \begingroup
+ % compute the |.|_1 norm of each of lines. We need to compute
+ % tolerance factors in order to decide if we have an intersection.
+ % line 1: compute |#2 - #1|_1 :
+ \ifdim\pgf@xb<0sp \pgf@xb=-\pgf@xb\fi
+ \ifdim\pgf@yb<0sp \pgf@yb=-\pgf@yb\fi
+ \advance\pgf@xb by\pgf@yb
+ \xdef\pgf@intersect@len@a{\pgf@sys@tonumber\pgf@xb}%
+ %
+ % line 2: compute |#3 - #4|_1 :
+ \ifdim\pgf@xc<0sp \pgf@xc=-\pgf@xc\fi
+ \ifdim\pgf@yc<0sp \pgf@yc=-\pgf@yc\fi
+ \advance\pgf@xc by\pgf@yc
+ \xdef\pgf@intersect@len@b{\pgf@sys@tonumber\pgf@xc}%
+ \endgroup
+ %
+ \edef\pgf@marshal{%
+ \noexpand\pgfutilsolvetwotwoleqfloat{%
+ {\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@xc}%
+ {\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@yc}%
+ }{%
+ {\pgf@sys@tonumber\pgf@xa}%
+ {\pgf@sys@tonumber\pgf@ya}%
+ }%
+ }%
+ \pgf@marshal
+ %
+ \let\pgf@intersect@next=\pgfutil@secondoftwo%
+ \ifx\pgfmathresult\pgfutil@empty
+ % matrix was singular.
+ \else
+ \def\pgf@marshal##1##2{%
+ \global\pgf@x=##1pt %
+ \global\pgf@y=##2pt %
+ }%
+ \expandafter\pgf@marshal\pgfmathresult
+ %
+ \def\pgf@marshal{XXXX}% this should never be read
+ % FIRST: check line 1:
+ \ifdim\pgf@x<0sp
+ % let it count as hit if
+ % || l_1(s) - l_1(0) || < eps
+ % <=> |s| * ||#2 - #1|| < eps
+ % and, since s< 0 here:
+ % <=> -s * ||#2 - #1|| < eps
+ \pgf@xa=-\pgf@intersect@len@a\pgf@x
+ \ifdim\pgf@xa<\pgfintersectiontolerance\relax
+ % close enough to first endpoint of line 1:
+ \def\pgf@marshal{1}%
+ \else
+ \def\pgf@marshal{0}%
+ \fi
+ \else
+ \ifdim\pgf@x>1pt
+ % let it count as hit if
+ % || l_1(s) - l_1(1) || < eps
+ % <=> |s-1| * ||#2 - #1|| < eps
+ % and, since s > 1 here:
+ % <=> s * ||#2 - #1|| - ||#2 - #1|| < eps
+ \pgf@xa=\pgf@intersect@len@a\pgf@x
+ \advance\pgf@xa by-\pgf@intersect@len@a pt %
+ \ifdim\pgf@xa<\pgfintersectiontolerance\relax
+ % close enough to second endpoint of line 1:
+ \def\pgf@marshal{1}%
+ \else
+ \def\pgf@marshal{0}%
+ \fi
+ \else
+ % 0<= s <= 1: we have an intersection within line 1.
+ \def\pgf@marshal{1}%
+ \fi
+ \fi
+ %
+ % SECOND: check line 2:
+ \if1\pgf@marshal
+ \ifdim\pgf@y<0sp
+ % see remarks for line 1. same applies here.
+ \pgf@xa=-\pgf@intersect@len@b\pgf@y
+ \ifdim\pgf@xa<\pgfintersectiontolerance\relax
+ % close enough to first endpoint of line 2:
+ \def\pgf@marshal{1}%
+ \else
+ \def\pgf@marshal{0}%
+ \fi
+ \else
+ \ifdim\pgf@y>1pt
+ % see remarks for line 1. same applies here.
+ \pgf@xa=\pgf@intersect@len@b\pgf@y
+ \advance\pgf@xa by-\pgf@intersect@len@b pt %
+ \ifdim\pgf@xa<\pgfintersectiontolerance\relax
+ % close enough to second endpoint of line 2:
+ \def\pgf@marshal{1}%
+ \else
+ \def\pgf@marshal{0}%
+ \fi
+ \else
+ % 0<= t <= 1: we have an intersection within line 2.
+ \def\pgf@marshal{1}%
+ \fi
+ \fi
+ \fi
+ %
+ \if1\pgf@marshal
+ % Ok, compute the intersection point and return it:
+ % we use (x,y) = A + s * (B-A)
+ % keep in mind that (s,t) == (\pgf@x,\pgf@y)
+ \pgf@intersect@A
+ \pgf@yc=\pgf@x
+ \global\pgf@x=\pgf@sys@tonumber\pgf@xb\pgf@yc
+ \global\pgf@y=\pgf@sys@tonumber\pgf@yb\pgf@yc
+ \global\advance\pgf@x by \pgf@xa
+ \global\advance\pgf@y by \pgf@ya
+ \let\pgf@intersect@next=\pgfutil@firstoftwo%
+ \fi
+ \fi
+}%
+
+
+
+
+\def\pgfintersectionoflineandcurve#1#2#3#4#5#6{%
+ \pgf@intersect@solutions=0\relax%
+ \pgf@intersectionoflineandcurve{#1}{#2}{#3}{#4}{#5}{#6}%
+}%
+
+\def\pgf@intersectionoflineandcurve#1#2#3#4#5#6{%
+ \pgf@intersectionofcurves%
+ {\pgf@process{#1}}%
+ {%
+ \pgf@process{%
+ \pgfpointadd{#1\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}%
+ {#2\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}%
+ }%
+ }%
+ {%
+ \pgf@process{%
+ \pgfpointadd{#1\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}%
+ {#2\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}%
+ }%
+ }%
+ {\pgf@process{#2}}%
+ {\pgf@process{#3}}%
+ {\pgf@process{#4}}%
+ {\pgf@process{#5}}%
+ {\pgf@process{#6}}%
+}%
+
+\def\pgf@intersectionofcurveandline#1#2#3#4#5#6{%
+ \pgf@intersectionofcurves%
+ {\pgf@process{#1}}%
+ {\pgf@process{#2}}%
+ {\pgf@process{#3}}%
+ {\pgf@process{#4}}%
+ {\pgf@process{#5}}%
+ {%
+ \pgf@process{%
+ \pgfpointadd{#5\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}%
+ {#6\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}%
+ }%
+ }%
+ {%
+ \pgf@process{%
+ \pgfpointadd{#5\relax\pgf@x=0.333333\pgf@x\pgf@y=0.333333\pgf@y}%
+ {#6\relax\pgf@x=0.666666\pgf@x\pgf@y=0.666666\pgf@y}%
+ }%
+ }%
+ {\pgf@process{#6}}%
+}%
+
+
+
+
+\def\pgfintersectiontolerance{0.1pt}%
+\def\pgfintersectiontoleranceupperbound{1pt}%
+\def\pgfintersectiontolerancefactor{0.1}%
+
+
+
+% Find the intersections of two bezier curves.
+%
+% #1 - #4 = curve 1.
+% #5 - #8 = curve 2.
+% #9 = the solution number.
+%
+% There is no guarantee of ordering of solutions. If there are
+% no solutions, the origin is returned.
+%
+\def\pgfpointintersectionofcurves#1#2#3#4#5#6#7#8#9{%
+ \pgf@intersect@solutions=0\relax%
+ \pgf@intersectionofcurves%
+ {\pgf@process{#1}}{\pgf@process{#2}}{\pgf@process{#3}}{\pgf@process{#4}}%
+ {\pgf@process{#5}}{\pgf@process{#6}}{\pgf@process{#7}}{\pgf@process{#8}}%
+ \pgfpointintersectionsolution{#9}%
+}%
+
+% Return any intersection points of two curves C1 and C2.
+% No order can be guaranteed for the solutions.
+%
+% #1, #2, #3, #4 - the points on C1
+% #5, #6, #7, #8 - the points on C2
+%
+% Returns:
+%
+% \pgf@intersect@solutions - the number of solutions.
+% \pgfpointintersectionsolution{<S>} - the point for solution S.
+%
+% (Sort of) use:
+%
+% intersection(C1,C2)
+% S = {};
+% intersection'(C1,C2);
+% return S;
+%
+% intersection'(C1,C2)
+% B1 = boundingbox(C1);
+% B2 = boundingbox(C2);
+% if intersect(B1,B2)
+% if (B1.width < q) and (B1.height < q) and
+% (B2.width < q) and (B2.height < q)
+% S = S + {average_of_all_points(B1,B2)}; \\ is there a better choice?
+% else
+% Q = subdivideLeft(C1);
+% R = subdivideRight(C1);
+% intersection'(C2,Q);
+% intersection'(C2,R);
+%
+% where q is a small value (tolerance).
+%
+\def\pgfintersectionofcurves#1#2#3#4#5#6#7#8{%
+ \pgf@intersect@solutions=0\relax%
+ \pgf@intersectionofcurves%
+ {\pgf@process{#1}}{\pgf@process{#2}}{\pgf@process{#3}}{\pgf@process{#4}}%
+ {\pgf@process{#5}}{\pgf@process{#6}}{\pgf@process{#7}}{\pgf@process{#8}}%
+}%
+\def\pgf@intersectionofcurves#1#2#3#4#5#6#7#8{%
+ \begingroup%
+ \dimendef\pgf@time@a=2\relax%
+ \dimendef\pgf@time@aa=4\relax%
+ \dimendef\pgf@time@b=6\relax%
+ \dimendef\pgf@time@bb=8\relax%
+ \pgf@time@a=0pt\relax%
+ \pgf@time@aa=1pt\relax%
+ \pgf@time@b=0pt\relax%
+ \pgf@time@bb=1pt\relax%
+ \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@b%
+ \let\pgf@curve@subdivde@after=\pgf@@intersectionofcurves%
+ \pgf@@intersectionofcurves{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
+ \endgroup%
+}%
+
+\def\pgf@intersect@boundingbox@assign@a{%
+ \edef\pgf@intersect@boundingbox@a{%
+ % lower left:
+ \noexpand\pgf@xb=\the\pgf@xa\space%
+ \noexpand\pgf@yb=\the\pgf@ya\space%
+ % upper right:
+ \noexpand\pgf@xc=\the\pgf@xb\space%
+ \noexpand\pgf@yc=\the\pgf@yb\space%
+ }%
+}%
+\def\pgf@intersect@boundingbox@assign@b{%
+ \edef\pgf@intersect@boundingbox@b{%
+ % lower left:
+ \noexpand\global\noexpand\pgf@x=\the\pgf@xa\space%
+ \noexpand\global\noexpand\pgf@y=\the\pgf@ya\space%
+ % upper right:
+ \noexpand\pgf@xa=\the\pgf@xb\space%
+ \noexpand\pgf@ya=\the\pgf@yb\space%
+ }%
+}%
+
+% see \pgf@intersect@boundingbox@assign@a and \pgf@intersect@boundingbox@assign@b for the naming conventions
+\def\pgf@intersect@boundingbox@ifoverlap{%
+ \def\pgf@intersect@next{\pgfutil@secondoftwo}%
+ %
+ \ifdim\pgf@xa<\pgf@xb%
+ \else%
+ \ifdim\pgf@x>\pgf@xc%
+ \else%
+ \ifdim\pgf@ya<\pgf@yb%
+ \else%
+ \ifdim\pgf@y>\pgf@yc%
+ \else%
+ \def\pgf@intersect@next{\pgfutil@firstoftwo}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \pgf@intersect@next
+}%
+\def\pgf@intersect@boundingbox@ifoverlap@upperbound{%
+ \begingroup
+ \def\pgf@intersect@next{\pgfutil@secondoftwo}%
+ %
+ \advance\pgf@xa by+\pgfintersectiontolerance\relax
+ \ifdim\pgf@xa<\pgf@xb%
+ \else%
+ \global\advance\pgf@x by-\pgfintersectiontolerance\relax
+ \ifdim\pgf@x>\pgf@xc%
+ \else%
+ \advance\pgf@ya by\pgfintersectiontolerance\relax
+ \ifdim\pgf@ya<\pgf@yb%
+ \else%
+ \global\advance\pgf@y by-\pgfintersectiontolerance\relax
+ \ifdim\pgf@y>\pgf@yc%
+ \else%
+ \def\pgf@intersect@next{\pgfutil@firstoftwo}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \expandafter
+ \endgroup
+ \pgf@intersect@next
+}%
+\def\pgf@intersect@boundingbox@ifoverlap@UNUSED{%
+ \let\pgf@intersect@next=\pgfutil@secondoftwo%
+ \ifdim\pgf@xa<\pgf@xb%
+ \else%
+ \ifdim\pgf@x>\pgf@xc%
+ \else%
+ \ifdim\pgf@ya<\pgf@yb%
+ \else%
+ \ifdim\pgf@y>\pgf@yc%
+ \else%
+ \let\pgf@intersect@next=\pgfutil@firstoftwo%
+ \fi
+ \fi
+ \fi
+ \fi
+ \pgf@intersect@next
+}%
+\def\pgf@@intersectionofcurves#1#2#3#4#5#6#7#8{%
+ \pgf@intersect@boundingbox@reset%
+ \pgf@intersect@boundingbox@update{#1}%
+ \pgf@intersect@boundingbox@update{#2}%
+ \pgf@intersect@boundingbox@update{#3}%
+ \pgf@intersect@boundingbox@update{#4}%
+ \pgf@intersect@boundingbox@assign@b%
+ %
+ \pgf@intersect@boundingbox@reset%
+ \pgf@intersect@boundingbox@update{#5}%
+ \pgf@intersect@boundingbox@update{#6}%
+ \pgf@intersect@boundingbox@update{#7}%
+ \pgf@intersect@boundingbox@update{#8}%
+ \pgf@intersect@boundingbox@assign@a%
+ %
+ \pgf@intersect@boundingbox@a%
+ \pgf@intersect@boundingbox@b%
+ %
+ \pgf@intersect@boundingbox@ifoverlap{%
+ \pgf@@@intersectionofcurves{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
+ }{%
+ % no overlap -- no intersection.
+ }%
+}%
+
+\def\pgf@@@intersectionofcurves#1#2#3#4#5#6#7#8{%
+ % compute DIFFERENCE vectors:
+ \advance\pgf@xc by-\pgf@xb%
+ \advance\pgf@yc by-\pgf@yb%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \let\pgf@intersect@subdivde=\relax%
+ % check if both difference vectors are point wise
+ % less than tolerance (i.e. |v|_infty < eps ).
+ % That means that both bounding boxes are "small enough"
+ \ifdim\pgf@xc<\pgfintersectiontolerance\relax%
+ \ifdim\pgf@xa<\pgfintersectiontolerance\relax%
+ \ifdim\pgf@yc<\pgfintersectiontolerance\relax%
+ \ifdim\pgf@ya<\pgfintersectiontolerance\relax%
+ \pgfextract@process\pgf@intersect@solution@candidate{%
+ % set (x,y) = mean(the 4 points of the two bounding boxes):
+ \pgf@intersect@boundingbox@a%
+ \pgf@intersect@boundingbox@b%
+ \pgf@x=0.25\pgf@x%
+ \advance\pgf@x by0.25\pgf@xa%
+ \advance\pgf@x by0.25\pgf@xb%
+ \advance\pgf@x by0.25\pgf@xc%
+ \pgf@y=0.25\pgf@y%
+ \advance\pgf@y by0.25\pgf@ya%
+ \advance\pgf@y by0.25\pgf@yb%
+ \advance\pgf@y by0.25\pgf@yc%
+ }%
+ % We must avoid duplicate solutions.
+ \let\pgf@intersect@subdivde=\pgf@stop%
+ \pgf@ifsolution@duplicate\pgf@intersect@solution@candidate{}%
+ {%
+ \global\advance\pgf@intersect@solutions by1\relax%
+ \begingroup
+ \advance\pgf@time@a by\pgf@time@aa%
+ \divide\pgf@time@a by2\relax%
+ \advance\pgf@time@a by\pgf@intersect@time@offset pt\relax%
+ \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@time@a}}%
+ %
+ \advance\pgf@time@b by\pgf@time@bb%
+ \divide\pgf@time@b by2\relax%
+ \advance\pgf@time@b by\pgf@intersect@time@offset@b pt\relax%
+ \edef\pgf@intersect@time@b{\pgfmath@tonumber{\pgf@time@b}}%
+ %
+ \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}%
+ \expandafter\global\expandafter\let%
+ \csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=%
+ \pgf@intersect@solution@candidate%
+ \ifpgf@intersect@sort%
+ \expandafter\xdef%
+ \csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname%
+ {\pgf@intersect@time@a}%
+ \fi%
+ \endgroup
+ }%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \ifx\pgf@intersect@subdivde\pgf@stop%
+ \else%
+ \pgf@intersect@subdivide@curve{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
+ \fi%
+}%
+
+\def\pgf@intersect@subdivide@curve@b#1#2#3#4#5#6#7#8{%
+ \begingroup%
+ \advance\pgf@time@bb by\pgf@time@b\relax%
+ \divide\pgf@time@bb by2\relax%
+ \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@a%
+ \pgf@curve@subdivide@left{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}%
+ \endgroup%
+ \begingroup%
+ \advance\pgf@time@b by\pgf@time@bb\relax%
+ \divide\pgf@time@b by2\relax%
+ \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@a%
+ \pgf@curve@subdivide@right{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}%
+ \endgroup%
+}%
+
+\def\pgf@intersect@subdivide@curve@a#1#2#3#4#5#6#7#8{%
+ \begingroup%
+ \advance\pgf@time@aa by\pgf@time@a\relax%
+ \divide\pgf@time@aa by2\relax%
+ \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@b%
+ \pgf@curve@subdivide@left{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}%
+ \endgroup%
+ \begingroup%
+ \advance\pgf@time@a by\pgf@time@aa\relax%
+ \divide\pgf@time@a by2\relax%
+ \let\pgf@intersect@subdivide@curve=\pgf@intersect@subdivide@curve@b%
+ \pgf@curve@subdivide@right{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}%
+ \endgroup%
+}%
+
+\def\pgf@intersect@boundingbox@reset{%
+ \pgf@xa=16000pt\relax%
+ \pgf@ya=16000pt\relax%
+ \pgf@xb=-16000pt\relax%
+ \pgf@yb=-16000pt\relax%
+}%
+
+\def\pgf@intersect@boundingbox@update#1{%
+ #1\relax%
+ \ifdim\pgf@x<\pgf@xa\pgf@xa=\pgf@x\fi%
+ \ifdim\pgf@y<\pgf@ya\pgf@ya=\pgf@y\fi%
+ \ifdim\pgf@x>\pgf@xb\pgf@xb=\pgf@x\fi%
+ \ifdim\pgf@y>\pgf@yb\pgf@yb=\pgf@y\fi%
+}%
+
+% The following subroutines are part of a conversion from pgfbasic
+% math to FPU. This transition is necessary due to the restricted
+% accuracy of pgfbasic. In order to limit the error rate of the
+% transition pgfbasic -> FPU, I chose to
+% keep the old "pattern" of sorts \advance\pgf@xa by0.5\pgf@y etc and
+% simply adapt to some FPU call.
+%
+% The following routines constitute the "adapter":
+
+\def\pgf@float@adapter@setxy{%
+ \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@x}\let\pgf@fpu@x=\pgfmathresult
+ \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@y}\let\pgf@fpu@y=\pgfmathresult
+}%
+\def\pgf@float@adapter@mult#1=#2*#3{%
+ \pgfmathfloatmultiplyfixed@{#3}{#2}%
+ \let#1=\pgfmathresult
+}%
+\def\pgf@float@adapter@advance#1by#2*#3{%
+ \pgfmathfloatmultiplyfixed@{#3}{#2}%
+ \let\pgfutil@temp=\pgfmathresult
+ \pgfmathfloatadd@{#1}{\pgfutil@temp}%
+ \let#1=\pgfmathresult
+}%
+
+\def\pgf@float@adapter@tostring#1{%
+ \pgfmathfloattofixed{#1}\edef#1{\pgfmathresult pt }%
+}%
+
+\def\pgf@curve@subdivide@left#1#2#3#4{%
+ %
+ % The left curve (from t=0 to t=.5)
+ %
+ \begingroup
+ #1\relax%
+ \pgfutil@tempdima=\pgf@x%
+ \pgfutil@tempdimb=\pgf@y%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@mult\pgf@fpu@xa=.5*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@ya=.5*\pgf@fpu@y%
+ \pgf@float@adapter@mult\pgf@fpu@xb=.25*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@yb=.25*\pgf@fpu@y%
+ \pgf@float@adapter@mult\pgf@fpu@xc=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yc=.125*\pgf@fpu@y%
+ #2\relax%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y%
+ \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y%
+ \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y%
+ #3\relax%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@advance\pgf@fpu@xb by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.25*\pgf@fpu@y%
+ \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y%
+ #4\relax%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@advance\pgf@fpu@xc by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.125*\pgf@fpu@y%
+ %
+ \pgf@float@adapter@tostring\pgf@fpu@xa
+ \pgf@float@adapter@tostring\pgf@fpu@ya
+ \pgf@float@adapter@tostring\pgf@fpu@xb
+ \pgf@float@adapter@tostring\pgf@fpu@yb
+ \pgf@float@adapter@tostring\pgf@fpu@xc
+ \pgf@float@adapter@tostring\pgf@fpu@yc
+ \edef\pgf@marshal{%
+ \noexpand\pgf@curve@subdivde@after%
+ {\noexpand\pgf@x=\the\pgfutil@tempdima\noexpand\pgf@y=\the\pgfutil@tempdimb}%
+ {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya}%
+ {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb}%
+ {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}%
+ }%
+ \expandafter
+ \endgroup
+ \pgf@marshal%
+}%
+
+\def\pgf@curve@subdivide@right#1#2#3#4{%
+ %
+ % The right curve (from t=0.5 to t=1)
+ %
+ \begingroup
+ #1\relax%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@mult\pgf@float@tmpa=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@float@tmpb=.125*\pgf@fpu@y%
+ #2\relax%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y%
+ \pgf@float@adapter@mult\pgf@fpu@xa=.25*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@ya=.25*\pgf@fpu@y%
+ #3\relax%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y%
+ \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y%
+ \pgf@float@adapter@mult\pgf@fpu@xb=.5*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yb=.5*\pgf@fpu@y%
+ #4\relax%
+ \pgf@float@adapter@setxy
+ \pgf@float@adapter@advance\pgf@float@tmpa by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.125*\pgf@fpu@y%
+ \pgf@float@adapter@advance\pgf@fpu@xa by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.25*\pgf@fpu@y%
+ \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y%
+ \let\pgf@fpu@xc=\pgf@fpu@x\let\pgf@fpu@yc=\pgf@fpu@y%
+ %
+ \pgf@float@adapter@tostring\pgf@float@tmpa
+ \pgf@float@adapter@tostring\pgf@float@tmpb
+ \pgf@float@adapter@tostring\pgf@fpu@xa
+ \pgf@float@adapter@tostring\pgf@fpu@ya
+ \pgf@float@adapter@tostring\pgf@fpu@xb
+ \pgf@float@adapter@tostring\pgf@fpu@yb
+ \pgf@float@adapter@tostring\pgf@fpu@xc
+ \pgf@float@adapter@tostring\pgf@fpu@yc
+ \edef\pgf@marshal{%
+ \noexpand\pgf@curve@subdivde@after%
+ {\noexpand\pgf@x=\pgf@float@tmpa\noexpand\pgf@y=\pgf@float@tmpb}%
+ {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya}%
+ {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb}%
+ {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}%
+ }%
+ \expandafter
+ \endgroup
+ \pgf@marshal%
+}%
+
+
+% A solution S1 is considered a duplicate of S2, if
+%
+% |x1 - x2|f < q and |y1 - y2|f < q
+%
+% where q is a small value (tolerance).
+%
+% #1 - the solution.
+%
+\def\pgf@ifsolution@duplicate#1{%
+ #1%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \let\pgf@intersect@next=\pgfutil@secondoftwo%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@intersect@solutions\relax%
+ \else%
+ \pgf@ifsolution@duplicate@{\pgfmathcounter}%
+ \repeatpgfmathloop%
+ \pgf@intersect@next%
+}%
+
+\def\pgf@ifsolution@duplicate@#1{%
+ \pgf@process{\csname pgfpoint@g@intersect@solution@#1\endcsname}%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \ifdim\pgf@x<0pt\relax\pgf@x=-\pgf@x\fi%
+ \ifdim\pgf@y<0pt\relax\pgf@y=-\pgf@y\fi%
+ %
+ \pgf@x=\pgfintersectiontolerancefactor\pgf@x%
+ \pgf@y=\pgfintersectiontolerancefactor\pgf@y%
+ \ifdim\pgf@x<\pgfintersectiontolerance\relax%
+ \ifdim\pgf@y<\pgfintersectiontolerance\relax%
+ \let\pgf@intersect@next=\pgfutil@firstoftwo%
+ \fi%
+ \fi%
+}%
+
+\newif\ifpgf@intersect@solutions@sortfinish
+
+% Sort solutions according to their time index.
+%
+\def\pgfintersectionsolutionsortbytime{%
+ \pgf@intersect@solutions@sortfinishtrue%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter<\pgfintersectionsolutions\relax%
+ \pgfutil@tempcnta=\pgfmathcounter%
+ \advance\pgfutil@tempcnta by1\relax%
+ \ifdim\csname pgf@intersect@solution@\pgfmathcounter @time@a\endcsname pt>%
+ \csname pgf@intersect@solution@\the\pgfutil@tempcnta @time@a\endcsname pt\relax%
+ \pgf@intersect@solutions@sortfinishfalse%
+ %
+ \pgfintersectionsolutionsortbytime@swap{pgfpoint@intersect@solution@\pgfmathcounter}%
+ {pgfpoint@intersect@solution@\the\pgfutil@tempcnta}%
+ %
+ \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@\pgfmathcounter @time@a}%
+ {pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}%
+ %
+ \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@props@\pgfmathcounter}%
+ {pgf@intersect@solution@props@\the\pgfutil@tempcnta}%
+ \fi%
+ \repeatpgfmathloop%
+ \ifpgf@intersect@solutions@sortfinish%
+ \else%
+ \expandafter\pgfintersectionsolutionsortbytime%
+ \fi%
+}%
+
+\def\pgfintersectionsolutionsortbytime@swap#1#2{%
+ \pgfutil@namelet{pgf@intersect@temp}{#1}%
+ \pgfutil@namelet{#1}{#2}%
+ \pgfutil@namelet{#2}{pgf@intersect@temp}%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibrarylindenmayersystems.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibrarylindenmayersystems.code.tex
new file mode 100644
index 0000000000..6fbdd86664
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibrarylindenmayersystems.code.tex
@@ -0,0 +1,229 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\newdimen\pgflsystemstep
+\newcount\c@pgf@lsystem@iteration
+
+\newif\ifpgf@lsystem@randomize@step
+\newif\ifpgf@lsystem@randomize@angle
+
+\pgfkeys{/pgf/lindenmayer system/.cd,%
+ step/.code={\pgfmathsetlength\pgflsystemstep{#1}},%
+ randomize step percent/.code={%
+ \pgfmathparse{#1}%
+ \let\pgflsystemrandomizesteppercent=\pgfmathresult%
+ \ifdim\pgfmathresult pt=0pt\relax%
+ \pgf@lsystem@randomize@stepfalse%
+ \else%
+ \pgf@lsystem@randomize@steptrue%
+ \fi%
+ },%
+ left angle/.code={\pgfmathparse{#1}\let\pgflsystemleftangle=\pgfmathresult},%
+ right angle/.code={\pgfmathparse{#1}\let\pgflsystemrightangle=\pgfmathresult},%
+ angle/.style={/pgf/lindenmayer system/left angle={#1}, /pgf/lindenmayer system/right angle={#1}},%
+ randomize angle percent/.code={%
+ \pgfmathparse{#1}%
+ \let\pgflsystemrandomizeanglepercent=\pgfmathresult%
+ \ifdim\pgfmathresult pt=0pt\relax%
+ \pgf@lsystem@randomize@anglefalse%
+ \else%
+ \pgf@lsystem@randomize@angletrue%
+ \fi%
+ }%
+}%
+
+\pgfkeys{/pgf/lindenmayer system/.cd,
+ step=5pt,%
+ randomize step percent=0,%
+ angle=90,%
+ randomize angle percent=0%
+}%
+
+\long\def\pgfdeclarelindenmayersystem#1#2{%
+ \pgfutil@ifundefined{pgf@lsystem@#1}%
+ {%
+ \begingroup%
+ \edef\pgf@lsystem@name{#1}%
+ \expandafter\global\expandafter\let\csname pgf@lsystem@#1\endcsname=\pgf@lsystem@name%
+ \let\symbol=\pgf@lsystem@symbol%
+ \let\rule=\pgf@lsystem@rule%
+ #2%
+ \endgroup%
+ }%
+ {\pgferror{Lindenmayer system `#1' is already defined}}%
+}%
+
+\def\pgf@lsystem@symbol#1#2{%
+ \expandafter\gdef\csname pgf@lsystem@\pgf@lsystem@name @symbol@#1\endcsname{#2}%
+}%
+
+\def\pgf@lsystem@rule#1{\expandafter\pgf@lsystem@rule@#1\pgf@stop}%
+\def\pgf@lsystem@rule@#1{\def\pgf@lsystem@rule@head{#1}\pgf@lsystem@rule@@}%
+\def\pgf@lsystem@rule@@#1->{% Now some `fooling around' to deal with unwanted spaces.
+ \let\pgf@lsystem@rule@body=\pgfutil@empty%
+ \pgfutil@ifnextchar x{\pgf@lsystem@rule@@@}{\pgf@lsystem@rule@@@}}%
+\def\pgf@lsystem@rule@@@#1{%
+ \ifx#1\pgf@stop%
+ \expandafter\global\expandafter\let%
+ \csname pgf@lsystem@\pgf@lsystem@name @rule@\pgf@lsystem@rule@head\endcsname=\pgf@lsystem@rule@body%
+ \else%
+ \edef\pgf@lsystem@rule@body{\pgf@lsystem@rule@body#1}%
+ \expandafter\pgf@lsystem@rule@@@%
+ \fi%
+}%
+
+\def\pgflindenmayersystem#1#2#3{%
+ \begingroup%
+ \edef\pgf@lsystem@name{#1}%
+ \edef\pgf@lsystem@axiom{#2}%
+ \pgfmathtruncatemacro\pgf@lsystem@order{#3}%
+ %
+ \let\pgf@lsystem@current@symbol=\relax%
+ %
+ \c@pgf@lsystem@iteration=0\relax%
+ %
+ \ifnum\pgf@lsystem@order=0\relax%
+ \expandafter\pgf@lsystem@draw\pgf@lsystem@axiom\pgf@stop
+ \let\pgf@lsystem@next=\pgf@lsystem@end%
+ \else%
+ \let\pgf@lsystem@next=\pgf@lsystem@run%
+ \fi%
+ \expandafter\pgf@lsystem@next\pgf@lsystem@axiom\pgf@lsystem@stop%
+}%
+
+\def\pgf@lsystem@run#1{%
+ \ifx#1\pgf@lsystem@stop%
+ \def\pgf@lsystem@token{\pgf@lsystem@stop}%
+ \let\pgf@lsystem@next=\pgf@lsystem@end%
+ \else%
+ \ifx#1\pgf@stop%
+ \advance\c@pgf@lsystem@iteration by-1\relax%
+ \let\pgf@system@token=\pgfutil@empty%
+ \let\pgf@lsystem@next=\pgf@lsystem@run%
+ \else%
+ % Does #1 appear on the RHS of a rule...?
+ \expandafter\let\expandafter\pgf@lsystem@token\expandafter=%
+ \csname pgf@lsystem@\pgf@lsystem@name @rule@#1\endcsname%
+ \ifx\pgf@lsystem@token\relax%
+ % ...nope. So draw it straight away.
+ \pgf@lsystem@draw#1\pgf@stop%
+ \let\pgf@lsystem@token=\pgfutil@empty%
+ \else%
+ % ...yep. So, if the order has been reached draw the LHS
+ % immediately. Otherwise add the LHS to the token stream
+ % and continue.
+ \advance\c@pgf@lsystem@iteration by1\relax%
+ \ifnum\c@pgf@lsystem@iteration=\pgf@lsystem@order%
+ \expandafter\pgf@lsystem@draw\pgf@lsystem@token \pgf@stop%
+ \advance\c@pgf@lsystem@iteration by-1\relax%
+ \let\pgf@lsystem@token=\pgfutil@empty%
+ \else%
+ \expandafter\def\expandafter\pgf@lsystem@token\expandafter{\pgf@lsystem@token \pgf@stop}%
+ \fi%
+ \fi%
+ \let\pgf@lsystem@next=\pgf@lsystem@run%
+ \fi%
+ \fi%
+ \expandafter\pgf@lsystem@next\pgf@lsystem@token}%
+
+\def\pgf@lsystem@end#1\pgf@lsystem@stop{\endgroup}%
+
+\def\pgf@lsystem@draw#1{%
+ \ifx#1\pgf@stop%
+ \let\pgf@lsystem@next=\relax%
+ \else%
+ \expandafter\let\expandafter\pgf@lsystem@current@symbol\expandafter=%
+ \csname pgf@lsystem@\pgf@lsystem@name @symbol@#1\endcsname%
+ \ifx\pgf@lsystem@current@symbol\relax% Try a default symbol.
+ \expandafter\let\expandafter\pgf@lsystem@current@symbol\expandafter=%
+ \csname pgf@lsystem@symbol@default@#1\endcsname%
+ \fi%
+ \let\pgf@lsystem@next=\pgf@lsystem@@draw%
+ \fi%
+ \pgf@lsystem@next}%
+
+\def\pgf@lsystem@@draw{%
+ \edef\pgflsystemcurrentstep{\the\pgflsystemstep}%
+ \let\pgflsystemcurrentrightangle=\pgflsystemrightangle%
+ \let\pgflsystemcurrentrightangle=\pgflsystemleftangle%
+ \pgf@lsystem@current@symbol%
+ \pgf@lsystem@draw}%
+
+\expandafter\def\csname
+pgf@lsystem@symbol@default@F\endcsname{\pgflsystemdrawforward}%
+\expandafter\def\csname
+pgf@lsystem@symbol@default@f\endcsname{\pgflsystemmoveforward}%
+\expandafter\def\csname
+pgf@lsystem@symbol@default@+\endcsname{\pgflsystemturnleft}%
+\expandafter\def\csname
+pgf@lsystem@symbol@default@-\endcsname{\pgflsystemturnright}%
+\expandafter\def\csname
+pgf@lsystem@symbol@default@[\endcsname{\pgflsystemsavestate}%
+\expandafter\def\csname
+pgf@lsystem@symbol@default@]\endcsname{\pgflsystemrestorestate}%
+
+\def\pgflsystemradonmizestep{%
+ \ifpgf@lsystem@randomize@step%
+ \pgfmathrand%
+ \pgf@x=\pgflsystemrandomizesteppercent pt\relax%
+ \pgf@x=\pgfmathresult\pgf@x%
+ \divide\pgf@x by20\relax%
+ \advance\pgf@x by\pgflsystemstep\relax%
+ \edef\pgflsystemcurrentstep{\the\pgf@x}%
+ \else%
+ \edef\pgflsystemcurrentstep{\the\pgflsystemstep}%
+ \fi%
+}%
+
+\def\pgflsystemdrawforward{%
+ \pgflsystemradonmizestep
+ \pgftransformxshift{+\pgflsystemcurrentstep}%
+ \pgfpathlineto{\pgfpointorigin}}%
+
+\def\pgflsystemmoveforward{%
+ \pgflsystemradonmizestep
+ \pgftransformxshift{+\pgflsystemcurrentstep}%
+ \pgfpathmoveto{\pgfpointorigin}}%
+
+\def\pgflsystemranomizerightangle{%
+ \ifpgf@lsystem@randomize@angle%
+ \pgf@x=\pgflsystemrandomizeanglepercent pt\relax%
+ \divide\pgf@x by20\relax%
+ \pgfmathrand%
+ \pgf@x=\pgfmathresult\pgf@x%
+ \advance\pgf@x by\pgflsystemrightangle pt\relax%
+ \edef\pgflsystemcurrentrightangle{\pgfmath@tonumber{\pgf@x}}%
+ \else%
+ \let\pgflsystemcurrentrightangle=\pgflsystemrightangle%
+ \fi%
+}%
+
+\def\pgflsystemranomizeleftangle{%
+ \ifpgf@lsystem@randomize@angle%
+ \pgf@x=\pgflsystemrandomizeanglepercent pt\relax%
+ \divide\pgf@x by20\relax%
+ \pgfmathrand%
+ \pgf@x=\pgfmathresult\pgf@x%
+ \advance\pgf@x by\pgflsystemleftangle pt\relax%
+ \edef\pgflsystemcurrentleftangle{\pgfmath@tonumber{\pgf@x}}%
+ \else%
+ \let\pgflsystemcurrentleftangle=\pgflsystemleftangle%
+ \fi%
+}%
+
+\def\pgflsystemturnright{%
+ \pgflsystemranomizerightangle
+ \pgftransformrotate{-\pgflsystemcurrentrightangle}}%
+
+\def\pgflsystemturnleft{%
+ \pgflsystemranomizeleftangle
+ \pgftransformrotate{\pgflsystemcurrentleftangle}}%
+
+\def\pgflsystemsavestate{\begingroup}%
+\def\pgflsystemrestorestate{\endgroup\pgfpathmoveto{\pgfpointorigin}}%
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.code.tex
new file mode 100644
index 0000000000..a2dba8e076
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.code.tex
@@ -0,0 +1,264 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarypatterns.code.tex}
+
+
+% Lines in different directions
+
+\pgfdeclarepatternformonly{horizontal lines}{\pgfpointorigin}{\pgfqpoint{100pt}{1pt}}{\pgfqpoint{100pt}{3pt}}%
+{%
+ \pgfsetlinewidth{0.4pt}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{0.5pt}}%
+ \pgfpathlineto{\pgfqpoint{100pt}{0.5pt}}%
+ \pgfusepath{stroke}%
+}%
+
+\pgfdeclarepatternformonly{vertical lines}{\pgfpointorigin}{\pgfqpoint{1pt}{100pt}}{\pgfqpoint{3pt}{100pt}}%
+{%
+ \pgfsetlinewidth{0.4pt}%
+ \pgfpathmoveto{\pgfqpoint{0.5pt}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0.5pt}{100pt}}%
+ \pgfusepath{stroke}%
+}%
+
+\pgfdeclarepatternformonly{north east lines}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{4pt}{4pt}}{\pgfqpoint{3pt}{3pt}}%
+{%
+ \pgfsetlinewidth{0.4pt}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{3.1pt}{3.1pt}}%
+ \pgfusepath{stroke}%
+}%
+
+\pgfdeclarepatternformonly{north west lines}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{4pt}{4pt}}{\pgfqpoint{3pt}{3pt}}%
+{%
+ \pgfsetlinewidth{0.4pt}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{3pt}}%
+ \pgfpathlineto{\pgfqpoint{3.1pt}{-0.1pt}}%
+ \pgfusepath{stroke}%
+}%
+
+% Crossed lines in different directions
+
+\pgfdeclarepatternformonly{grid}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{4pt}{4pt}}{\pgfqpoint{3pt}{3pt}}%
+{%
+ \pgfsetlinewidth{0.4pt}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{3.1pt}}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{3.1pt}{0pt}}%
+ \pgfusepath{stroke}%
+}%
+
+\pgfdeclarepatternformonly{crosshatch}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{4pt}{4pt}}{\pgfqpoint{3pt}{3pt}}%
+{%
+ \pgfsetlinewidth{0.4pt}%
+ \pgfpathmoveto{\pgfqpoint{3.1pt}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{3.1pt}}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{3.1pt}{3.1pt}}%
+ \pgfusepath{stroke}%
+}%
+
+
+% Dotted regions
+
+\pgfdeclarepatternformonly{dots}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{1pt}{1pt}}{\pgfqpoint{3pt}{3pt}}%
+{%
+ \pgfpathcircle{\pgfqpoint{0pt}{0pt}}{.5pt}%
+ \pgfusepath{fill}%
+}%
+
+\pgfdeclarepatternformonly{crosshatch dots}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{2.5pt}{2.5pt}}{\pgfqpoint{3pt}{3pt}}%
+{%
+ \pgfpathcircle{\pgfqpoint{0pt}{0pt}}{.5pt}%
+ \pgfpathcircle{\pgfqpoint{1.5pt}{1.5pt}}{.5pt}%
+ \pgfusepath{fill}%
+}%
+
+
+
+
+% Star shaped patterns
+
+\pgfdeclarepatternformonly{fivepointed stars}{\pgfpointorigin}{\pgfqpoint{3mm}{3mm}}{\pgfqpoint{3mm}{3mm}}%
+{%
+ \pgftransformshift{\pgfqpoint{1mm}{1mm}}%
+ \pgfpathmoveto{\pgfqpointpolar{18}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{162}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{306}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{90}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{234}{1mm}}%
+ \pgfpathclose%%
+ \pgfusepath{fill}%
+}%
+
+\pgfdeclarepatternformonly{sixpointed stars}{\pgfpointorigin}{\pgfqpoint{3mm}{3mm}}{\pgfqpoint{3mm}{3mm}}%
+{%
+ \pgftransformshift{\pgfqpoint{1mm}{1mm}}%
+ \pgfpathmoveto{\pgfqpointpolar{30}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{150}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{270}{1mm}}%
+ \pgfpathclose%
+ \pgfpathmoveto{\pgfqpointpolar{-30}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{-270}{1mm}}%
+ \pgfpathlineto{\pgfqpointpolar{-150}{1mm}}%
+ \pgfpathclose%
+ \pgfsetnonzerorule%
+ \pgfusepath{fill}%
+}%
+
+
+
+% Bricks
+
+\pgfdeclarepatternformonly{bricks}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{5mm}{5mm}}{\pgfqpoint{4mm}{4mm}}%
+{%
+ \pgfsetlinewidth{0.8pt}%
+ \pgfpathmoveto{\pgfqpoint{0mm}{1mm}}%
+ \pgfpathlineto{\pgfqpoint{4mm}{1mm}}%
+ \pgfpathmoveto{\pgfqpoint{0mm}{3mm}}%
+ \pgfpathlineto{\pgfqpoint{4mm}{3mm}}%
+ \pgfpathmoveto{\pgfqpoint{1mm}{0mm}}%
+ \pgfpathlineto{\pgfqpoint{1mm}{1mm}}%
+ \pgfpathmoveto{\pgfqpoint{3mm}{1mm}}%
+ \pgfpathlineto{\pgfqpoint{3mm}{3mm}}%
+ \pgfpathmoveto{\pgfqpoint{1mm}{3mm}}%
+ \pgfpathlineto{\pgfqpoint{1mm}{4mm}}%
+ \pgfusepath{stroke}%
+}%
+
+
+% Checkerboards
+
+\pgfdeclarepatternformonly{checkerboard}{\pgfpointorigin}{\pgfqpoint{4mm}{4mm}}{\pgfqpoint{4mm}{4mm}}%
+{%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{2mm}{2mm}}%
+ \pgfpathrectangle{\pgfqpoint{2mm}{2mm}}{\pgfqpoint{2mm}{2mm}}%
+ \pgfusepath{fill}%
+}%
+
+
+
+% Backgrounds
+
+\pgfdeclarepatterninherentlycolored{checkerboard light gray}
+{\pgfpointorigin}{\pgfqpoint{4mm}{4mm}}{\pgfqpoint{4mm}{4mm}}%
+{%
+% \pgfsetfillcolor{black!10}
+ \pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{4.1mm}{4.1mm}}% make
+ % slightly larger to ensure that tiles
+ % are really solid
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{black!20}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{2mm}{2mm}}%
+ \pgfpathrectangle{\pgfqpoint{2mm}{2mm}}{\pgfqpoint{2mm}{2mm}}%
+ \pgfusepath{fill}%
+}%
+
+\pgfdeclarepatterninherentlycolored{horizontal lines light gray}
+{\pgfpointorigin}{\pgfpoint{100pt}{4pt}}
+{\pgfpoint{100pt}{4pt}}
+{%
+ \pgfsetfillcolor{black!10}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{black!15}%
+ \pgfpathrectangle{\pgfpoint{0pt}{2pt}}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+}%
+
+\pgfdeclarepatterninherentlycolored{horizontal lines gray}
+{\pgfpointorigin}{\pgfpoint{100pt}{4pt}}
+{\pgfpoint{100pt}{4pt}}
+{%
+ \pgfsetfillcolor{black!30}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{black!35}%
+ \pgfpathrectangle{\pgfpoint{0pt}{2pt}}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+}%
+
+\pgfdeclarepatterninherentlycolored{horizontal lines dark gray}
+{\pgfpointorigin}{\pgfpoint{100pt}{4pt}}
+{\pgfpoint{100pt}{4pt}}
+{%
+ \pgfsetfillcolor{black!90}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{black!85}%
+ \pgfpathrectangle{\pgfpoint{0pt}{2pt}}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+}%
+
+\pgfdeclarepatterninherentlycolored{horizontal lines light blue}
+{\pgfpointorigin}{\pgfpoint{100pt}{4pt}}
+{\pgfpoint{100pt}{4pt}}
+{%
+ \pgfsetfillcolor{blue!10}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{blue!15}%
+ \pgfpathrectangle{\pgfpoint{0pt}{2pt}}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+}%
+
+\pgfdeclarepatterninherentlycolored{horizontal lines dark blue}
+{\pgfpointorigin}{\pgfpoint{100pt}{4pt}}
+{\pgfpoint{100pt}{4pt}}
+{%
+ \pgfsetfillcolor{blue!90}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{blue!85}%
+ \pgfpathrectangle{\pgfpoint{0pt}{2pt}}{\pgfpoint{100pt}{2.5pt}}%
+ \pgfusepath{fill}%
+}%
+
+
+\pgfdeclarepatterninherentlycolored{crosshatch dots gray}
+{\pgfpointorigin}{\pgfpoint{8pt}{8pt}}
+{\pgfpoint{8pt}{8pt}}
+{%
+ \pgfsetfillcolor{black!20}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{8pt}{8pt}}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{black!10}%
+ \pgfpathcircle{\pgfpoint{2pt}{1.75pt}}{1pt}%
+ \pgfpathcircle{\pgfpoint{6pt}{5.75pt}}{1pt}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{black!70}%
+ \pgfpathcircle{\pgfpoint{2pt}{2.25pt}}{1pt}%
+ \pgfpathcircle{\pgfpoint{6pt}{6.25pt}}{1pt}%
+ \pgfusepath{fill}%
+}%
+
+\pgfutil@definecolor{pgf@lightsteelblue}{rgb}{0.6875,0.765625,0.8671875}%
+\pgfutil@colorlet{pgf@darklightsteelblue}{black!50!pgf@lightsteelblue}%
+
+\pgfdeclarepatterninherentlycolored{crosshatch dots light steel blue}
+{\pgfpointorigin}{\pgfpoint{8pt}{8pt}}
+{\pgfpoint{8pt}{8pt}}
+{%
+ \pgfsetfillcolor{pgf@lightsteelblue}%
+ \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{8pt}{8pt}}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{pgf@darklightsteelblue!10}%
+ \pgfpathcircle{\pgfpoint{2pt}{1.75pt}}{1pt}%
+ \pgfpathcircle{\pgfpoint{6pt}{5.75pt}}{1pt}%
+ \pgfusepath{fill}%
+ \pgfsetfillcolor{pgf@darklightsteelblue!70}%
+ \pgfpathcircle{\pgfpoint{2pt}{2.25pt}}{1pt}%
+ \pgfpathcircle{\pgfpoint{6pt}{6.25pt}}{1pt}%
+ \pgfusepath{fill}%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.meta.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.meta.code.tex
new file mode 100644
index 0000000000..00de962abe
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibrarypatterns.meta.code.tex
@@ -0,0 +1,458 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\def\pgf@pat@type@uncolored{0}%
+\def\pgf@pat@type@colored{1}%
+\newif\ifpgf@pat@makepatternimmutable
+
+\pgfkeys{/pgf/patterns/.cd,
+ name/.store in=\pgf@pat@name,
+ number ../.store in=\pgf@pat@number,
+ type/.is choice,
+ type/uncolored/.code={\let\pgf@pat@type=\pgf@pat@type@uncolored},
+ type/colored/.code={\let\pgf@pat@type=\pgf@pat@type@colored},
+ type/form only/.style={/pgf/patterns/type=uncolored},
+ type/inherently colored/.style={/pgf/patterns/type=colored},
+ x/.store in=\pgf@pat@xvec,
+ y/.store in=\pgf@pat@yvec,
+ parameters/.store in=\pgf@pat@parameters,
+ defaults/.store in=\pgf@pat@defaults,
+ append to defaults/.code={%
+ \pgf@pat@addto@macro\pgf@pat@defaults{,#1}%
+ },
+ bottom left/.store in=\pgf@pat@bottomleft,
+ top right/.store in=\pgf@pat@topright,
+ tile size/.store in=\pgf@pat@tilesize,
+ tile transformation/.store in=\pgf@pat@transformation,
+ code/.store in=\pgf@pat@code,
+ set up code/.store in=\pgf@pat@declarebefore,
+ %
+ name=,
+ number ..=,
+ type=uncolored,
+ x=1cm, y=1cm,
+ parameters=,
+ defaults=,
+ bottom left=,
+ top right=,
+ tile size=,
+ tile transformation=,
+ code=,
+ set up code=,
+}%
+
+\def\pgf@pat@name@prefix{pgf@pattern@name@meta@}%
+
+\def\pgfifpatternundefined#1{%
+ \pgfutil@ifundefined{\pgf@pat@name@prefix#1}%
+}%
+
+\def\pgf@pat@adddef@to@macro#1#2{%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter#1%
+ \expandafter\expandafter\expandafter{\expandafter#1\expandafter%
+ \def\expandafter#2\expandafter{#2}}%
+}%
+
+\def\pgf@pat@addto@macro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}}%
+
+\def\pgf@pat@process#1{%
+ \pgf@process{#1}%
+}%
+
+\def\pgf@pat@doifnotempty#1{%
+ \ifx#1\pgfutil@empty%
+ \let\pgf@pat@next=\relax%
+ \else%
+ \let\pgf@pat@next=#1%
+ \fi%
+ \pgf@pat@next%
+}%
+
+\def\pgf@pat@processtransformations#1{#1}%
+\def\pgf@pat@processpoint#1{%
+ \pgf@process{#1}%
+}%
+
+
+\def\pgfdeclarepattern#1{%
+ \begingroup%
+ \nullfont%
+ \def\pgf@pat@options{,#1}%
+ \pgfkeys{/pgf/patterns/.cd,#1}%
+ \ifx\pgf@pat@name\pgfutil@empty
+ \pgferror{Declaring unnamed pattern}%
+ \fi
+ \ifx\pgf@pat@bottomleft\pgfutil@empty
+ \pgferror{Bottom left corner of the bounding box unset}%
+ \fi
+ \ifx\pgf@pat@topright\pgfutil@empty
+ \pgferror{Top right corner of the bounding box unset}%
+ \fi
+ \ifx\pgf@pat@tilesize\pgfutil@empty
+ \pgferror{Tile size unset}%
+ \fi
+ \ifx\pgf@pat@code\pgfutil@empty
+ \pgferror{Pattern code is empty}%
+ \fi
+ \pgf@declarepattern@meta%
+ \endgroup%
+}%
+\def\pgf@declarepattern@meta{%
+ \pgfifpatternundefined{\pgf@pat@name}{%
+ \ifx\pgf@pat@parameters\pgfutil@empty%
+ % No parameters, so pattern is declared now.
+ \pgf@pat@declare%
+ \edef\pgf@marshal{%
+ \noexpand\pgf@pat@addto@macro\noexpand\pgf@pat@options{,number ..=\pgf@pattern@number}}%
+ \pgf@marshal%
+ \fi%
+ % It is a bit inefficient that all the options for
+ % immutable patterns are saved when only the type
+ % and number are needed.
+ \expandafter\global\expandafter\let\csname\pgf@pat@name@prefix\pgf@pat@name\endcsname=\pgf@pat@options%
+ }{%
+ \pgferror{Pattern `\pgf@pat@name' already defined}%
+ }%
+}%
+\let\pgf@pat@declarebefore=\pgfutil@empty
+\let\pgf@pat@declareafter=\pgfutil@empty
+\let\pgf@pat@codebefore=\pgfutil@empty
+\let\pgf@pat@codeafter=\pgfutil@empty
+
+\def\pgf@pat@declare{%
+ \pgfsysprotocol@getcurrentprotocol\pgf@pattern@temp%
+ {%
+ % Set up x and y vectors. Should use a scope rather than TeX group?
+ % Vectors may be needed when the tile bounding box is
+ % calculated.
+ \pgfsetxvec{\pgfpoint{\pgf@pat@xvec}{+0pt}}%
+ \pgfsetyvec{\pgfpoint{+0pt}{\pgf@pat@yvec}}%
+ \pgf@pat@doifnotempty\pgf@pat@declarebefore%
+ \pgfinterruptpath%
+ \pgfpicturetrue%
+ \pgf@relevantforpicturesizetrue%
+ \pgftransformreset%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsys@beginscope%
+ \pgfinterruptboundingbox%
+ \pgfsetarrows{-}%
+ \pgf@pat@doifnotempty\pgf@pat@codebefore
+ \pgf@pat@code%
+ \pgf@pat@doifnotempty\pgf@pat@codeafter%
+ \endpgfinterruptboundingbox%
+ \pgfsys@endscope%
+ \pgfsysprotocol@getcurrentprotocol\pgf@pattern@code%
+ \global\let\pgf@pattern@code=\pgf@pattern@code%
+ \endpgfinterruptpath%
+ \pgf@pat@doifnotempty\pgf@pat@declareafter%
+ \pgf@pat@processpoint{\pgf@pat@bottomleft}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@pat@processpoint{\pgf@pat@topright}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@pat@processpoint{\pgf@pat@tilesize}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \begingroup%
+ \pgftransformreset%
+ \pgf@pat@processtransformations\pgf@pat@transformation%
+ \pgfgettransformentries\aa\ab\ba\bb\shiftx\shifty%
+ \global\edef\pgf@pattern@matrix{{\aa}{\ab}{\ba}{\bb}{\shiftx}{\shifty}}%
+ \endgroup%
+ % Now, build a name for the pattern
+ \pgfutil@tempcnta=\pgf@pattern@number\relax%
+ \advance\pgfutil@tempcnta by1\relax%
+ \xdef\pgf@pattern@number{\the\pgfutil@tempcnta}%
+ \xdef\pgf@marshal{\noexpand\pgfsys@declarepattern%
+ {\pgf@pattern@number}%
+ {\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}\pgf@pattern@matrix{\pgf@pattern@code}{\pgf@pat@type}}%
+ }%
+ \pgf@marshal%
+ \pgfsysprotocol@setcurrentprotocol\pgf@pattern@temp%
+}%
+
+\def\pgf@pat@checkname#1{%
+ \pgf@pat@@checkname#1[]\pgf@patstop}%
+
+\def\pgf@pat@@checkname#1[#2]#3\pgf@patstop{%
+ \expandafter\def\expandafter\pgf@pat@onlinename\expandafter{\romannumeral-`0\pgfutil@trimspaces{#1}}%
+ \def\pgf@pat@onlineoptions{#2}%
+}%
+
+
+\def\pgf@pat@unravel#1/{%
+ \pgfutil@ifnextchar\pgf@stop{\def\pgf@pat@unravelled{#1}}{\pgf@pat@unravel}}%
+
+\pgfkeys{/handlers/.pattern/.code={%
+ \expandafter\expandafter\expandafter\pgf@pat@unravel\pgfkeyscurrentpath/\pgf@stop%
+ \pgfpatternalias{#1}{\pgf@pat@unravelled}%
+}}%
+
+\def\pgfpatternalias#1#2{%
+ \begingroup%
+ \pgf@pat@checkname{#1}%
+ \expandafter\let\expandafter\pgf@pat@options\expandafter=%
+ \csname\pgf@pat@name@prefix\pgf@pat@onlinename\endcsname%
+ \pgf@pat@macroaskeys{/pgf/patterns/.cd}{\pgf@pat@options}%
+ \pgfutil@toks@\expandafter{\pgf@pat@onlineoptions}%
+ \edef\pgf@pat@tmp{append to defaults={\the\pgfutil@toks@}}%
+ \expandafter\pgf@pat@addto@macro\expandafter\pgf@pat@options\expandafter{\expandafter,\pgf@pat@tmp}%
+ \pgf@pat@addto@macro\pgf@pat@options{,name=#2}%
+ \expandafter\global\expandafter\let\csname\pgf@pat@name@prefix#2\endcsname=\pgf@pat@options%
+ \endgroup%
+}%
+
+
+\let\pgfsetfillpattern@old=\pgfsetfillpattern
+
+\def\pgf@pat@macroaskeys#1#2{%
+ \pgfutil@toks@\expandafter{#2}%
+ \edef\pgf@marshal{\noexpand\pgfkeys{,#1,\the\pgfutil@toks@}}%
+ \pgf@marshal%
+}%
+\def\pgfsetfillpattern#1#2{%
+ \pgf@pat@checkname{#1}%
+ \pgfutil@ifundefined{\pgf@pat@name@prefix\pgf@pat@onlinename}{%
+ \pgfsetfillpattern@old{\pgf@pat@onlinename}{#2}%
+ }{%
+ \let\pgf@pat@parameters=\pgfutil@empty%
+ % Get pattern parameters, type, and number
+ \expandafter\let\expandafter\pgf@pat@options\expandafter=%
+ \csname\pgf@pat@name@prefix\pgf@pat@onlinename\endcsname%
+ \pgf@pat@macroaskeys{/pgf/patterns/.cd}{\pgf@pat@options}%
+ \ifx\pgf@pat@parameters\pgfutil@empty%
+ % Immutable pattern. Do nothing.
+ \else%
+ % Mutable. Do a *lot*.
+ \begingroup%
+ \pgf@pat@macroaskeys{/pgf/pattern keys/.cd}{\pgf@pat@defaults}%
+ \pgf@pat@macroaskeys{/pgf/pattern keys/.cd}{\pgf@pat@onlineoptions}%
+ % ...to get the values of the current parameters...
+ \edef\pgf@pat@current@parameters{\pgf@pat@parameters}%
+ % ...and the internal pattern name.
+ \edef\pgf@pat@onlinename{\pgf@pat@onlinename\pgf@pat@current@parameters}%
+ \let\pgf@pat@name=\pgf@pat@onlinename%
+ \pgfutil@ifundefined{\pgf@pat@name@prefix\pgf@pat@onlinename}{%
+ %\ifpgf@pat@makepatternimmutable%
+ \let\pgf@pat@parameters=\pgfutil@empty%
+ %\fi%
+ \pgf@declarepattern@meta%
+ }{}%
+ \expandafter%
+ \endgroup%
+ \expandafter\def\expandafter\pgf@pat@onlinename\expandafter{\pgf@pat@onlinename}%
+ \expandafter\let\expandafter\pgf@pat@options\expandafter=%
+ \csname\pgf@pat@name@prefix\pgf@pat@onlinename\endcsname%
+ \pgf@pat@macroaskeys{/pgf/patterns/.cd}{\pgf@pat@options}%
+ \fi%
+ \ifx\pgf@pat@type\pgf@pat@type@uncolored%
+ \pgf@pat@setpatternuncolored{\pgf@pat@number}{#2}%
+ \else%
+ \pgfsys@setpatterncolored{\pgf@pat@number}%
+ \fi%
+ }%
+}%
+
+\def\pgf@pat@setpatternuncolored#1#2{%
+ \pgfutil@colorlet{pgf@tempcolor}{#2}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}%
+ \pgfutil@extractcolorspec{pgf@tempcolor}{\pgf@tempcolor}%
+ \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}%
+ \expandafter\pgf@pat@set@fill@patternuncolored\pgf@rgbcolor\relax{#1}%
+}%
+\def\pgf@pat@set@fill@patternuncolored#1,#2,#3\relax#4{%
+ \pgfsys@setpatternuncolored{#4}{#1}{#2}{#3}%
+}%
+
+% Predefined patterns
+
+\pgfdeclarepattern{
+ name=Lines,
+ parameters={
+ \pgfkeysvalueof{/pgf/pattern keys/distance},
+ \pgfkeysvalueof{/pgf/pattern keys/angle},
+ \pgfkeysvalueof{/pgf/pattern keys/xshift},
+ \pgfkeysvalueof{/pgf/pattern keys/yshift},
+ \pgfkeysvalueof{/pgf/pattern keys/line width},
+ },
+ bottom left={%
+ \pgfpoint
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ top right={%
+ \pgfpoint
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ tile size={%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}},
+ tile transformation={%
+ \pgftransformshift{%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/xshift}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/yshift}}}%
+ \pgftransformrotate{\pgfkeysvalueof{/pgf/pattern keys/angle}}},
+ defaults={
+ distance/.initial=3pt,
+ angle/.initial=0,
+ xshift/.initial=0pt,
+ yshift/.initial=0pt,
+ line width/.initial=\the\pgflinewidth,
+ },
+ code={%
+ \pgfsetlinewidth{\pgfkeysvalueof{/pgf/pattern keys/line width}}%
+ \pgfpathmoveto{\pgfpoint{-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}{0pt}}%
+ \pgfpathlineto{\pgfpoint{.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}{0pt}}%
+ \pgfusepath{stroke}%
+ },
+}
+
+\pgfdeclarepattern{
+ name=Hatch,
+ parameters={
+ \pgfkeysvalueof{/pgf/pattern keys/distance},
+ \pgfkeysvalueof{/pgf/pattern keys/angle},
+ \pgfkeysvalueof{/pgf/pattern keys/xshift},
+ \pgfkeysvalueof{/pgf/pattern keys/yshift},
+ \pgfkeysvalueof{/pgf/pattern keys/line width},
+ },
+ bottom left={%
+ \pgfpoint
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ top right={%
+ \pgfpoint
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ tile size={%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}},
+ tile transformation={%
+ \pgftransformshift{%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/xshift}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/yshift}}}%
+ \pgftransformrotate{\pgfkeysvalueof{/pgf/pattern keys/angle}}},
+ defaults={
+ distance/.initial=3pt,
+ angle/.initial=0,
+ xshift/.initial=0pt,
+ yshift/.initial=0pt,
+ line width/.initial=\the\pgflinewidth,
+ },
+ code={%
+ \pgfsetlinewidth{\pgfkeysvalueof{/pgf/pattern keys/line width}}%
+ \pgfpathmoveto{\pgfpoint{-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}{0pt}}%
+ \pgfpathlineto{\pgfpoint{.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}{0pt}}%
+ \pgfpathmoveto{\pgfpoint{0pt}{-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}}%
+ \pgfpathlineto{\pgfpoint{0pt}{.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}}%
+ \pgfusepath{stroke}%
+ },
+}
+
+\pgfdeclarepattern{
+ name=Dots,
+ parameters={
+ \pgfkeysvalueof{/pgf/pattern keys/distance},
+ \pgfkeysvalueof{/pgf/pattern keys/angle},
+ \pgfkeysvalueof{/pgf/pattern keys/xshift},
+ \pgfkeysvalueof{/pgf/pattern keys/yshift},
+ \pgfkeysvalueof{/pgf/pattern keys/radius},
+ },
+ bottom left={%
+ \pgfpoint
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ top right={%
+ \pgfpoint
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ tile size={%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}},
+ tile transformation={%
+ \pgftransformshift{%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/xshift}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/yshift}}}%
+ \pgftransformrotate{\pgfkeysvalueof{/pgf/pattern keys/angle}}},
+ defaults={
+ distance/.initial=3pt,
+ angle/.initial=0,
+ xshift/.initial=0pt,
+ yshift/.initial=0pt,
+ radius/.initial=.5pt,
+ },
+ code={%
+ \pgfpathcircle%
+ {\pgfpointorigin}%
+ {\pgfkeysvalueof{/pgf/pattern keys/radius}}
+ \pgfusepath{fill}%
+ },
+}
+
+\pgfdeclarepattern{
+ name=Stars,
+ parameters={
+ \pgfkeysvalueof{/pgf/pattern keys/distance},
+ \pgfkeysvalueof{/pgf/pattern keys/angle},
+ \pgfkeysvalueof{/pgf/pattern keys/xshift},
+ \pgfkeysvalueof{/pgf/pattern keys/yshift},
+ \pgfkeysvalueof{/pgf/pattern keys/radius},
+ \pgfkeysvalueof{/pgf/pattern keys/points},
+ },
+ bottom left={%
+ \pgfpoint
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {-.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ top right={%
+ \pgfpoint
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}%
+ {.5*(\pgfkeysvalueof{/pgf/pattern keys/distance})}},
+ tile size={%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/distance}}},
+ tile transformation={%
+ \pgftransformshift{%
+ \pgfpoint
+ {\pgfkeysvalueof{/pgf/pattern keys/xshift}}%
+ {\pgfkeysvalueof{/pgf/pattern keys/yshift}}}%
+ \pgftransformrotate{\pgfkeysvalueof{/pgf/pattern keys/angle}}},
+ defaults={
+ distance/.initial=3mm,
+ angle/.initial=0,
+ xshift/.initial=0pt,
+ yshift/.initial=0pt,
+ radius/.initial=1mm,
+ points/.initial=5,
+ },
+ code={%
+ \pgfmathsetmacro\a{180/(\pgfkeysvalueof{/pgf/pattern keys/points})}%
+ \pgfpathmoveto{\pgfpointpolar{90}{\pgfkeysvalueof{/pgf/pattern keys/radius}}}%
+ \foreach \i in {1,...,\pgfkeysvalueof{/pgf/pattern keys/points}}{%
+ \pgfpathlineto{\pgfpointpolar{90+2*\i*\a-\a}{.5*(\pgfkeysvalueof{/pgf/pattern keys/radius})}}%
+ \pgfpathlineto{\pgfpointpolar{90+2*\i*\a}{\pgfkeysvalueof{/pgf/pattern keys/radius}}}%
+ }%
+ \pgfpathclose%
+ \pgfusepath{fill}%
+ },
+}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryplothandlers.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryplothandlers.code.tex
new file mode 100644
index 0000000000..d0b9a388eb
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryplothandlers.code.tex
@@ -0,0 +1,1114 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryplothandlers.code.tex}
+
+
+% This handler converts each plot stream command into a curveto
+% command, except for the first, which is converted to the previously
+% specified action.
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfsetlinetofirstplotpoint
+% \pgfplothandlercurveto
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlercurveto}{}{%
+ point macro=\pgf@plot@curveto@handler@initial,
+ jump macro=\pgf@plot@smooth@next@moveto,
+ end macro=\pgf@plot@curveto@handler@finish
+}%
+
+\def\pgf@plot@smooth@next@moveto{%
+ \pgf@plot@curveto@handler@finish%
+ \global\pgf@plot@startedfalse%
+ \global\let\pgf@plotstreampoint\pgf@plot@curveto@handler@initial%
+}%
+
+\def\pgf@plot@curveto@handler@initial#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@plot@first@action{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \xdef\pgf@plot@curveto@first{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \global\let\pgf@plot@curveto@first@support=\pgf@plot@curveto@first%
+ \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@second%
+}%
+
+\def\pgf@plot@curveto@handler@second#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@curveto@second{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@third%
+ \global\pgf@plot@startedtrue%
+}%
+
+\def\pgf@plot@curveto@handler@third#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@curveto@current{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ % compute difference vector:
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgf@plot@curveto@first}
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ % compute support directions:
+ \pgf@xa=\pgf@plottension\pgf@xa%
+ \pgf@ya=\pgf@plottension\pgf@ya%
+ % first marshal:
+ \pgf@process{\pgf@plot@curveto@second}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \advance\pgf@xc by\pgf@xa%
+ \advance\pgf@yc by\pgf@ya%
+ \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@curveto@first@support}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@curveto@second}}%
+ {\pgf@marshal}%
+ % Prepare next:
+ \global\let\pgf@plot@curveto@first=\pgf@plot@curveto@second%
+ \global\let\pgf@plot@curveto@second=\pgf@plot@curveto@current%
+ \xdef\pgf@plot@curveto@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+}%
+
+\def\pgf@plot@curveto@handler@finish{%
+ \ifpgf@plot@started%
+ \pgfpathcurveto{\pgf@plot@curveto@first@support}{\pgf@plot@curveto@second}{\pgf@plot@curveto@second}%
+ \fi%
+}%
+
+
+% This commands sets the tension for smoothing of plots.
+%
+% #1 = tension of curves. A value of 1 will yield a circle when the
+% control points are at quarters of a circle. A smaller value
+% will result in a tighter curve. Default is 0.5.
+%
+% Example:
+%
+% \pgfsetplottension{0.2}
+
+\def\pgfsetplottension#1{%
+ \pgf@x=#1pt\relax%
+ \pgf@x=0.2775\pgf@x\relax%
+ \edef\pgf@plottension{\pgf@sys@tonumber\pgf@x}}%
+\pgfsetplottension{0.5}%
+
+
+% This handler converts the plot stream command into a curveto
+% command that is closed using a closepath.
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfplothandlerclosedcurve
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerclosedcurve}{}{%
+ point macro=\pgf@plot@closedcurve@handler@initial,
+ end macro=\pgf@plot@closedcurve@handler@finish,
+ jump macro=\pgf@plot@closedsmooth@next@moveto
+}%
+
+\def\pgf@plot@closedsmooth@next@moveto{%
+ \pgf@plot@closedcurve@handler@finish%
+ \global\pgf@plot@startedfalse%
+ \global\let\pgf@plotstreampoint\pgf@plot@closedcurve@handler@initial%
+}%
+
+\def\pgf@plot@closedcurve@handler@initial#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \xdef\pgf@plot@closedcurve@initial{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@second%
+ \global\pgf@plot@startedfalse%
+}%
+
+\def\pgf@plot@closedcurve@handler@second#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@closedcurve@after@initial{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ {\pgfpathmoveto{}}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@third%
+}%
+
+\def\pgf@plot@closedcurve@handler@third#1{%
+ \global\pgf@plot@startedtrue%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@closedcurve@current{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ % compute difference vector:
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgf@plot@closedcurve@initial}
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ % compute support directions:
+ \pgf@xa=\pgf@plottension\pgf@xa%
+ \pgf@ya=\pgf@plottension\pgf@ya%
+ % first marshal:
+ \pgf@process{\pgf@plot@closedcurve@after@initial}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \advance\pgf@xc by\pgf@xa%
+ \advance\pgf@yc by\pgf@ya%
+ \global\let\pgf@plot@closedcurve@first=\pgf@plot@closedcurve@after@initial%
+ \global\let\pgf@plot@closedcurve@second=\pgf@plot@closedcurve@current%
+ \xdef\pgf@plot@closedcurve@after@initial@presupport{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}%
+ \xdef\pgf@plot@closedcurve@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@fourth%
+}%
+
+\def\pgf@plot@closedcurve@handler@fourth#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@closedcurve@current{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ % compute difference vector:
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgf@plot@closedcurve@first}
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ % compute support directions:
+ \pgf@xa=\pgf@plottension\pgf@xa%
+ \pgf@ya=\pgf@plottension\pgf@ya%
+ % first marshal:
+ \pgf@process{\pgf@plot@closedcurve@second}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \advance\pgf@xc by\pgf@xa%
+ \advance\pgf@yc by\pgf@ya%
+ \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@closedcurve@first@support}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@closedcurve@second}}%
+ {\pgf@marshal}%
+ % Prepare next:
+ \global\let\pgf@plot@closedcurve@first=\pgf@plot@closedcurve@second%
+ \global\let\pgf@plot@closedcurve@second=\pgf@plot@closedcurve@current%
+ \xdef\pgf@plot@closedcurve@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+}%
+
+\def\pgf@plot@closedcurve@handler@finish{%
+ \ifpgf@plot@started
+ %
+ % first, draw line from 2nd last to last:
+ %
+ \pgf@process{\pgf@plot@closedcurve@initial}%
+ % compute difference vector:
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgf@plot@closedcurve@first}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ % compute support directions:
+ \pgf@xa=\pgf@plottension\pgf@xa%
+ \pgf@ya=\pgf@plottension\pgf@ya%
+ % first marshal:
+ \pgf@process{\pgf@plot@closedcurve@second}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \advance\pgf@xc by\pgf@xa%
+ \advance\pgf@yc by\pgf@ya%
+ \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@closedcurve@first@support}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@closedcurve@second}}%
+ {\pgf@marshal}%
+ \xdef\pgf@plot@closedcurve@first@support{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ %
+ % second, draw line from last point to start:
+ %
+ \pgf@process{\pgf@plot@closedcurve@after@initial}%
+ % compute difference vector:
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgf@plot@closedcurve@second}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ % compute support directions:
+ \pgf@xa=\pgf@plottension\pgf@xa%
+ \pgf@ya=\pgf@plottension\pgf@ya%
+ % first marshal:
+ \pgf@process{\pgf@plot@closedcurve@initial}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \advance\pgf@xc by\pgf@xa%
+ \advance\pgf@yc by\pgf@ya%
+ \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgf@plot@closedcurve@first@support}%
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgf@plot@closedcurve@initial}}%
+ {\pgf@marshal}%
+ %
+ % third, draw line from first to second point:
+ %
+ \edef\pgf@marshal{\noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ {\noexpand\pgf@plot@closedcurve@after@initial@presupport}{\noexpand\pgf@plot@closedcurve@after@initial}}%
+ {\pgf@marshal}%
+ \pgfpathclose%
+ \fi%
+}%
+
+
+
+
+
+% This handler converts each point in a stream into a line from the
+% $y$-axis to the given points coordinate, resulting in a
+% ``comb.''
+%
+% Example:
+%
+% \pgfplothandlerxcomb
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerxcomb}{}{%
+ start macro=\pgfplotxzerolevelstreamstart,
+ point macro=\pgf@plot@xcomb@handler,
+ end macro=\pgfplotxzerolevelstreamend,
+}%
+
+\def\pgf@plot@xcomb@handler#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \begingroup
+ \pgfplotxzerolevelstreamnext
+ \endgroup
+ \pgf@yb=\pgf@x
+ \pgfpathmoveto{\pgfqpoint{\pgf@yb}{\pgf@ya}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+}%
+
+
+% This handler converts each point in a stream into a line from the
+% $x$-axis straight up to the given points coordinate, resulting in a
+% ``comb.''
+%
+% Example:
+%
+% \pgfplothandlerycomb
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerycomb}{}{%
+ start macro=\pgfplotyzerolevelstreamstart,
+ point macro=\pgf@plot@ycomb@handler,
+ end macro=\pgfplotyzerolevelstreamend
+}%
+
+\def\pgf@plot@ycomb@handler#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \begingroup
+ \pgfplotyzerolevelstreamnext
+ \endgroup
+ \pgf@yb=\pgf@x
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+}%
+
+% PGF Bar or comb plots usually draw something from zero to the current plot's coordinate.
+%
+% The 'zero' offset can be changed using an input stream.
+%
+% There are two such streams which can be configured independently.
+% The first one returns "zeros" for coordinate x, the second one
+% returns "zeros" for coordinate y.
+%
+% \pgfplotxzerolevelstreamstart
+% \pgfplotxzerolevelstreamnext % assigns \pgf@x globally
+% \pgfplotxzerolevelstreamnext
+% \pgfplotxzerolevelstreamnext
+% \pgfplotxzerolevelstreamend
+%
+% and
+% \pgfplotyzerolevelstreamstart
+% \pgfplotyzerolevelstreamnext % assigns \pgf@x globally
+% \pgfplotyzerolevelstreamend
+%
+\def\pgfplotxzerolevelstreamstart{\pgf@plotxzerolevelstreamstart}%
+\def\pgfplotxzerolevelstreamend{\pgf@plotxzerolevelstreamend}%
+\def\pgfplotxzerolevelstreamnext{\pgf@plotxzerolevelstreamnext}
+\def\pgfplotyzerolevelstreamstart{\pgf@plotyzerolevelstreamstart}%
+\def\pgfplotyzerolevelstreamend{\pgf@plotyzerolevelstreamend}%
+\def\pgfplotyzerolevelstreamnext{\pgf@plotyzerolevelstreamnext}%
+
+% This zero level stream always returns '#1' (a dimension).
+\def\pgfplotxzerolevelstreamconstant#1{%
+ \edef\pgfplotxzerolevelstreamconstant@val{#1}%
+ \def\pgf@plotxzerolevelstreamstart{%
+ \global\let\pgf@plotxzerolevelstreamend=\relax
+ \gdef\pgf@plotxzerolevelstreamnext{\global\pgf@x=\pgfplotxzerolevelstreamconstant@val\relax}%
+ }%
+}%
+\pgfplotxzerolevelstreamconstant{0pt}%
+
+% This zero level stream always returns '#1'.
+\def\pgfplotyzerolevelstreamconstant#1{%
+ \edef\pgfplotyzerolevelstreamconstant@val{#1}%
+ \def\pgf@plotyzerolevelstreamstart{%
+ \global\let\pgf@plotyzerolevelstreamend=\relax
+ \gdef\pgf@plotyzerolevelstreamnext{\global\pgf@x=\pgfplotyzerolevelstreamconstant@val\relax}%
+ }%
+}%
+\pgfplotyzerolevelstreamconstant{0pt}%
+
+\def\pgfplotbarwidth{\pgfkeysvalueof{/pgf/bar width}}%
+\def\pgfplotbarshift{\pgfkeysvalueof{/pgf/bar shift}}%
+
+\pgfqkeys{/pgf}{%
+ bar width/.initial=10pt,
+ bar shift/.initial=0pt,
+ bar interval width/.initial=1,
+ bar interval shift/.initial=0.5,
+ %
+ % hook which is executed right before a new bar is begun.
+ at begin bar/.initial=,
+ % hook which is executed right after a bar path has been finished.
+ % In this context, the bar's path has not been used.
+ at end bar/.initial=,
+}%
+
+% This handler places a rectangle at each point in the plot stream, a
+% rectangle which touches the x-axis at one end and the current point
+% at the other end:
+% --(X)--
+% | |
+% | |
+% | |
+% --(0)--
+% Example:
+%
+% \pgfplothandlerybar
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerybar}{}{%
+ start={
+ \pgfmathparse{\pgfplotbarwidth}%
+ \xdef\pgfplotbarwidth@{\pgfmathresult pt}%
+ \pgfmathparse{\pgfplotbarshift}%
+ \xdef\pgfplotbarshift@{\pgfmathresult pt}%
+ \pgfplotyzerolevelstreamstart
+ },
+ end macro=\pgfplotyzerolevelstreamend,
+ point macro=\pgf@plot@ybar@handler
+}%
+
+\def\pgf@plot@ybar@handler#1{%
+ \pgfkeysvalueof{/pgf/at begin bar}%
+ \pgf@process{#1}%
+ \pgf@ya=\pgf@y
+ \expandafter\pgf@xb\pgfplotbarwidth@\relax
+ \pgf@xc=\pgf@x
+ \advance\pgf@xc by-.5\pgf@xb
+ \advance\pgf@xc by\pgfplotbarshift@\relax
+ \begingroup
+ \pgfplotyzerolevelstreamnext
+ \endgroup
+ \pgf@yb=\pgf@x
+ \advance\pgf@ya by-\pgf@yb
+ \pgfpathrectangle
+ {\pgfqpoint{\pgf@xc}{\pgf@yb}}%
+ {\pgfqpoint{\pgf@xb}{\pgf@ya}}%
+ \pgfkeysvalueof{/pgf/at end bar}%
+}%
+
+% This handler places a rectangle at each point in the plot stream, a
+% rectangle which touches the y-axis at one end and the current point
+% at the other end:
+% ---------
+% | |
+% (0) (X)
+% | |
+% ---------
+% Example:
+%
+% \pgfplothandlerxbar
+% \pgfplotxyfile{mytable}
+\pgfdeclareplothandler{\pgfplothandlerxbar}{}{%
+ start={
+ \pgfmathparse{\pgfplotbarwidth}%
+ \xdef\pgfplotbarwidth@{\pgfmathresult pt}%
+ \pgfmathparse{\pgfplotbarshift}%
+ \xdef\pgfplotbarshift@{\pgfmathresult pt}%
+ \pgfplotxzerolevelstreamstart
+ },
+ end macro=\pgfplotxzerolevelstreamend,
+ point macro=\pgf@plot@xbar@handler
+}%
+
+\def\pgf@plot@xbar@handler#1{%
+ \pgfkeysvalueof{/pgf/at begin bar}%
+ \pgf@process{#1}%
+ \pgf@ya=\pgf@x
+ \expandafter\pgf@xb\pgfplotbarwidth@\relax
+ \pgf@xc=\pgf@y
+ \advance\pgf@xc by-.5\pgf@xb
+ \advance\pgf@xc by\pgfplotbarshift@\relax
+ \begingroup
+ \pgfplotxzerolevelstreamnext
+ \endgroup
+ \pgf@yb=\pgf@x
+ \advance\pgf@ya by-\pgf@yb
+ \pgfpathrectangle
+ {\pgfqpoint{\pgf@yb}{\pgf@xc}}%
+ {\pgfqpoint{\pgf@ya}{\pgf@xb}}%
+ \pgfkeysvalueof{/pgf/at end bar}%
+}%
+
+% This handler is a variant of \pgfplothandlerybar which works with
+% intervals instead of points.
+%
+% Bars are drawn between successive input coordinates and the width is
+% determined relatively to the interval length.
+%
+% It looks like this:
+%
+% |---| |-----|
+% | | | |
+% | | | |
+% | | | |
+% (X)------(X)-----------(X)
+%
+% where (X) denotes the x-axis offsets of input coordinates.
+%
+% In more detail, if (x_i,y_i) and (x_{i+1},y_{i+1}) denote successive
+% input coordinates, the bar will be placed above the
+% interval [x_i,x_{i+1}], centered at
+%
+% x_i + \pgfkeysvalueof{/pgf/bar interval shift} * (x_{i+1} - x_i)
+%
+% with width
+%
+% \pgfkeysvalueof{/pgf/bar interval width} * (x_{i+1} - x_i).
+%
+% If you have N+1 input points, you will get N bars (one for each
+% interval). The y_i value of the last bar will be ignored.
+%
+% Example:
+%
+% \pgfplothandlerybarinterval
+% \pgfplotxyfile{mytable}
+\pgfdeclareplothandler{\pgfplothandlerybarinterval}{}{%
+ start={
+ \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}%
+ \xdef\pgfplotbarintervalwidth@{\pgfmathresult}%
+ \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}%
+ \xdef\pgfplotbarintervalshift@{\pgfmathresult}%
+ \pgfplotyzerolevelstreamstart
+ },
+ end macro=\pgfplotyzerolevelstreamend,
+ point macro=\pgf@plot@ybarinterval@handler@first
+}%
+
+\def\pgf@plot@ybarinterval@handler@first#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@x}%
+ \xdef\pgf@plot@barinterval@bar{\the\pgf@y}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@ybarinterval@handler%
+}%
+\def\pgf@plot@ybarinterval@handler#1{%
+ \pgfkeysvalueof{/pgf/at begin bar}%
+ \pgf@process{#1}%
+ \pgf@ya=\pgf@plot@barinterval@bar
+ \xdef\pgf@plot@barinterval@bar{\the\pgf@y}%
+ \pgf@xc=\pgf@plot@barinterval@intervalstart\relax
+ \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@x}%
+ \pgf@xb=\pgf@x
+ \advance\pgf@xb by-\pgf@xc
+ \advance\pgf@xc by\pgfplotbarintervalshift@\pgf@xb
+ \pgf@xb=\pgfplotbarintervalwidth@\pgf@xb
+ \advance\pgf@xc by-.5\pgf@xb% center
+ \begingroup
+ \pgfplotyzerolevelstreamnext
+ \endgroup
+ \pgf@yb=\pgf@x
+ \advance\pgf@ya by-\pgf@yb
+ \pgfpathrectangle
+ {\pgfqpoint{\pgf@xc}{\pgf@yb}}%
+ {\pgfqpoint{\pgf@xb}{\pgf@ya}}%
+ \pgfkeysvalueof{/pgf/at end bar}%
+}%
+
+% Like \pgfplothandlerybarinterval but for xbar.
+\pgfdeclareplothandler{\pgfplothandlerxbarinterval}{}{%
+ start={
+ \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}%
+ \xdef\pgfplotbarintervalwidth@{\pgfmathresult}%
+ \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}%
+ \xdef\pgfplotbarintervalshift@{\pgfmathresult}%
+ \pgfplotxzerolevelstreamstart
+ },
+ end macro=\pgfplotxzerolevelstreamend,
+ point macro=\pgf@plot@xbarinterval@handler@first
+}%
+
+\def\pgf@plot@xbarinterval@handler@first#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@y}%
+ \xdef\pgf@plot@barinterval@bar{\the\pgf@x}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@xbarinterval@handler%
+}%
+\def\pgf@plot@xbarinterval@handler#1{%
+ \pgfkeysvalueof{/pgf/at begin bar}%
+ \pgf@process{#1}%
+ \pgf@ya=\pgf@plot@barinterval@bar
+ \xdef\pgf@plot@barinterval@bar{\the\pgf@x}%
+ \pgf@xc=\pgf@plot@barinterval@intervalstart\relax
+ \xdef\pgf@plot@barinterval@intervalstart{\the\pgf@y}%
+ \pgf@xb=\pgf@y
+ \advance\pgf@xb by-\pgf@xc
+ \advance\pgf@xc by\pgfplotbarintervalshift@\pgf@xb
+ \pgf@xb=\pgfplotbarintervalwidth@\pgf@xb
+ \advance\pgf@xc by-.5\pgf@xb% center
+ \begingroup
+ \pgfplotxzerolevelstreamnext
+ \endgroup
+ \pgf@yb=\pgf@x
+ \advance\pgf@ya by-\pgf@yb
+ \pgfpathrectangle
+ {\pgfqpoint{\pgf@yb}{\pgf@xc}}%
+ {\pgfqpoint{\pgf@ya}{\pgf@xb}}%
+ \pgfkeysvalueof{/pgf/at end bar}%
+}%
+
+
+% This handler is very similar to \pgfplothandlerlineto, but it
+% produces CONSTANT connected pieces of the form
+%
+% x
+% |
+% x--- |
+% | x----
+% x-|
+%
+% Example:
+%
+% \pgfplothandlerconstantlineto
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerconstantlineto}{}{%
+ point macro=\pgf@plot@const@line@handler
+}%
+
+\def\pgf@plot@const@line@handler#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@y}%
+ \pgf@plot@first@action{}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@const@line@handler@@%
+}%
+\def\pgf@plot@const@line@handler@@#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@yb\pgf@plot@const@line@handler@last\relax
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@ya}%
+}%
+
+% A variant of \pgfplothandlerconstantlineto which places its mark on
+% the right line ends.
+%
+% |---x
+% ---x |
+% |--x
+% x
+%
+% Example:
+%
+% \pgfplothandlerconstantlinetomarkright
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerconstantlinetomarkright}{}{%
+ point macro=\pgf@plot@const@line@mark@right@handler
+}%
+
+\def\pgf@plot@const@line@mark@right@handler#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}%
+ \pgf@plot@first@action{}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@right@handler@@%
+}%
+\def\pgf@plot@const@line@mark@right@handler@@#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@yb\pgf@plot@const@line@handler@last\relax
+ \pgfpathlineto{\pgfqpoint{\pgf@yb}{\pgf@ya}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@xa}%
+}%
+
+% A variant of \pgfplothandlerconstantlineto which places its mark on
+% the middle of the line segment.
+%
+% ----x
+% |
+% --x--- |
+% | |--x----
+% x--
+%
+% Example:
+%
+% \pgfplothandlerconstantlinetomarkmid
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerconstantlinetomarkmid}{}{%
+ point macro=\pgf@plot@const@line@mark@mid@handler
+}%
+
+\def\pgf@plot@const@line@mark@mid@handler#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
+ \pgf@plot@first@action{}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@mid@handler@@%
+}%
+\def\pgf@plot@const@line@mark@mid@handler@@#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@plot@const@line@handler@last
+ \pgf@xc=.5\pgf@xa
+ \advance\pgf@xc by.5\pgf@x
+ \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@y}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@ya}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
+}%
+
+% This handler is in fact a variant of \pgfplothandlerconstantlineto,
+% but it does not draw vertical lines. It produces a sequence of
+% line-to and move-to operations such that plot marks are placed at
+% each right end:
+%
+% ---x
+% ---x
+% ---x
+% --x
+%
+% Example:
+%
+% \pgfplothandlerjumpmarkright
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerjumpmarkright}{}{%
+ point macro=\pgf@plot@jumpmarkright@handler
+}%
+
+\def\pgf@plot@jumpmarkright@handler#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}%
+ \pgf@plot@first@action{}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkright@handler@@%
+}%
+\def\pgf@plot@jumpmarkright@handler@@#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@yb\pgf@plot@const@line@handler@last\relax
+ \pgfpathmoveto{\pgfqpoint{\pgf@yb}{\pgf@ya}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@xa}%
+}%
+
+% This handler is in fact a variant of \pgfplothandlerconstantlineto,
+% but it does not draw vertical lines. It produces a sequence of
+% line-to and move-to operations such that plot marks are placed at
+% each left end:
+%
+% x---
+% x---
+% x---
+% x--
+%
+% Example:
+%
+% \pgfplothandlerjumpmarkleft
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerjumpmarkleft}{}{%
+ point macro=\pgf@plot@jumpmarkleft@handler
+}%
+\def\pgf@plot@jumpmarkleft@handler#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@y}%
+ \pgf@plot@first@action{}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkleft@handler@@%
+}%
+\def\pgf@plot@jumpmarkleft@handler@@#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@yb\pgf@plot@const@line@handler@last\relax
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \xdef\pgf@plot@const@line@handler@last{\the\pgf@ya}%
+}%
+
+% This handler is in fact a variant of
+% \pgfplothandlerconstantlinetomarkmid,
+% but it does not draw vertical lines. It produces a sequence of
+% line-to and move-to operations such that plot marks are placed like
+%
+% ----x
+%
+% --x--
+% --x----
+% x--
+%
+% Example:
+%
+% \pgfplothandlerjumpmarkmid
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerjumpmarkmid}{}{%
+ point macro=\pgf@plot@jump@mark@mid@handler
+}%
+
+\def\pgf@plot@jump@mark@mid@handler#1{%
+ \pgf@process{#1}%
+ \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
+ \pgf@plot@first@action{}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@jump@mark@mid@handler@@%
+}%
+\def\pgf@plot@jump@mark@mid@handler@@#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@plot@const@line@handler@last
+ \pgf@xc=.5\pgf@xa
+ \advance\pgf@xc by.5\pgf@x
+ \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@y}}%
+ \pgfpathmoveto{\pgfqpoint{\pgf@xc}{\pgf@ya}}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
+}%
+
+
+% This handler converts each point in a stream into a line from the
+% origin to the point's coordinate, resulting in a ``star''.
+%
+% Example:
+%
+% \pgfplothandlerpolarcomb
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerpolarcomb}{}{%
+ point macro=\pgf@plot@polarcomb@handler
+}%
+
+\def\pgf@plot@polarcomb@handler#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgfpathmoveto{\pgfpointorigin}%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+}%
+
+
+
+
+% This handler draws a given mark at each point.
+%
+% #1 = some code to be executed at each point (with the coordinate
+% system translated to that point).
+% Typically, this code will be \pgfuseplotmark{whatever}.
+%
+% Example:
+%
+% \pgfplothandlermark{\pgfuseplotmark{*}}
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlermark}{#1}{%
+ start={
+ \def\pgf@plot@mark{%
+ \ifnum\pgf@plot@mark@count<\pgf@plot@mark@repeat\relax%
+ \else%
+ \global\pgf@plot@mark@count=0\relax%
+ #1%
+ \fi%
+ }%
+ \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax%
+ \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax%
+ },
+ point macro=\pgf@plot@mark@handler
+}%
+
+\newcount\pgf@plot@mark@count
+\def\pgf@plot@mark@phase{0}%
+
+\def\pgf@plot@mark@handler#1{%
+ \global\advance\pgf@plot@mark@count by1\relax%
+ {\pgftransformshift{#1}\pgf@plot@mark}%
+}%
+
+
+% Set the repeat count for marks. For example, if 3 is given as a
+% value, only every third point will get a mark.
+%
+% #1 = repeat count
+%
+% Example:
+%
+% \pgfsetplotmarkrepeat{2}
+
+\def\pgfsetplotmarkrepeat#1{\def\pgf@plot@mark@repeat{#1}}%
+\pgfsetplotmarkrepeat{1}%
+
+
+% Set the phase for marks. For example, if 3 is the repeat and 3 is
+% the phase, already the first point will be marked.
+%
+% #1 = the index of the first point that should be marked.
+%
+% Example:
+%
+% \pgfsetplotmarkphase{3}
+
+\def\pgfsetplotmarkphase#1{\def\pgf@plot@mark@phase{#1}}%
+\pgfsetplotmarkphase{1}%
+
+
+
+% This handler draws a given mark at those points whose number is
+% given in the (pgffor-like) list.
+%
+% #1 = some code to be executed at each point (with the coordinate
+% system translated to that point).
+% Typically, this code will be \pgfuseplotmark{whatever}.
+% #2 = list of positions like "1,2,4,...,9,10"
+%
+% Example:
+%
+% \pgfplothandlermarklisted{\pgfuseplotmark{*}}{1,2,4,...,9}
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlermarklisted}{#1#2}{%
+ start={
+ \let\pgf@plot@mark@list=\pgfutil@empty%
+ \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}}
+ \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}%
+ \def\pgf@plot@mark{%
+ \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}%
+ \pgf@marshal%
+ \ifpgfutil@in@#1\fi%
+ }%
+ \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax%
+ \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax%
+ },
+ point macro=\pgf@plot@mark@handler
+}%
+
+% \def\pgfplothandlermarklisted#1#2{%
+% \let\pgf@plot@mark@list=\pgfutil@empty%
+% \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}}
+% \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}%
+% \pgf@plothandlermark{%
+% \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}%
+% \pgf@marshal%
+% \ifpgfutil@in@#1\fi}%
+% }%
+
+
+% Define a new plot mark for use with \pgfplotmark.
+%
+% #1 = a plot mark mnemonic
+% #2 = code for drawing the mark
+%
+% Example:
+%
+% \pgfdeclareplotmark{*}{\pgfpathcircle{\pgfpointorigin}{2pt}\pgfusepathqfill}
+
+\def\pgfdeclareplotmark#1#2{\expandafter\def\csname pgf@plot@mark@#1\endcsname{#2}}%
+
+
+% Set the size of plot marks. For circles, this will be the radius,
+% for other shapes it should be about half the width/height.
+%
+% Example:
+%
+% \pgfsetplotmarksize{1pt}
+
+\def\pgfsetplotmarksize#1{\pgfmathsetlength\pgfplotmarksize{#1}}%
+
+\newdimen\pgfplotmarksize
+\pgfplotmarksize=2pt
+
+
+% Insert a plot mark's code at the origin.
+%
+% #1 = plot mark mnemonic
+%
+% Example:
+%
+% \pgfuseplotmark{*}
+
+\def\pgfuseplotmark#1{\csname pgf@plot@mark@#1\endcsname}%
+
+
+% A stroke-filled circle mark
+
+\pgfdeclareplotmark{*}
+{%
+ \pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfplotmarksize}{0sp}}{\pgfqpoint{0sp}{\pgfplotmarksize}}%
+ \pgfusepathqfillstroke
+}%
+
+
+% A plus-sign like mark
+
+\pgfdeclareplotmark{+}
+{%
+ \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+
+% An x-shaped mark
+
+\pgfdeclareplotmark{x}
+{%
+ \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+% See pgflibraryplotmarks for more plot marks
+
+
+
+
+% This handler turns creates a series of straight line segments
+% between consecutive points, but leaving /pgf/gap around stream point
+% space.
+%
+% Example:
+%
+% \pgfplothandlergaplineto
+% \pgfplotxyfile{mytable}
+
+\pgfkeys{/pgf/gap around stream point/.initial=1.5pt}%
+
+\pgfdeclareplothandler{\pgfplothandlergaplineto}{}{%
+ point macro=\pgf@plot@gap@lineto@handler@initial,
+ jump macro=\pgf@plot@gap@next@moveto
+}%
+
+\def\pgf@plot@gap@next@moveto{%
+ \global\let\pgf@plotstreampoint=\pgf@plot@gap@lineto@handler@initial%
+}%
+
+\def\pgf@plot@gap@lineto@handler@initial#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \xdef\pgf@plot@gap@lineto@last{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \global\let\pgf@plotstreampoint=\pgf@plot@gap@lineto@handler%
+}%
+
+\def\pgf@plot@gap@lineto@handler#1{%
+ % Ok, compute normalized line vector
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \xdef\pgf@plot@gap@lineto@next{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \pgf@process{\pgfpointnormalised{\pgfpointdiff{\pgf@plot@gap@lineto@last}{\pgf@plot@gap@lineto@next}}}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfpathmoveto{\pgfpointadd{\pgfpointscale{\pgfkeysvalueof{/pgf/gap
+ around stream point}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}{\pgf@plot@gap@lineto@last}}%
+ \pgfpathlineto{\pgfpointadd{\pgfpointscale{\pgfkeysvalueof{/pgf/gap
+ around stream point}}{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}}{\pgf@plot@gap@lineto@next}}%
+ \global\let\pgf@plot@gap@lineto@last=\pgf@plot@gap@lineto@next%
+}%
+
+
+
+
+% This handler works like \pgfplothandlergaplineto, only the last
+% point is connected to the first point, creating a closed curve
+% space.
+%
+% Example:
+%
+% \pgfplothandlergapcycle
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlergapcycle}{}{%
+ point macro=\pgf@plot@gap@cycle@handler@initial,
+ jump macro=\pgf@plot@gapcycle@next@moveto,
+ end macro=\pgf@plot@gap@cycle@handler@finish,
+ start={\global\let\pgf@plot@gap@cycle@first\relax}
+}%
+
+\def\pgf@plot@gapcycle@next@moveto{%
+ \pgf@plot@gap@cycle@handler@finish%
+ \global\let\pgf@plot@gap@cycle@first=\relax%
+ \global\let\pgf@plotstreampoint=\pgf@plot@gap@cycle@handler@initial%
+}%
+
+\def\pgf@plot@gap@cycle@handler@initial#1{%
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \xdef\pgf@plot@gap@cycle@last{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \global\let\pgf@plot@gap@cycle@first=\pgf@plot@gap@cycle@last%
+ \global\let\pgf@plotstreampoint=\pgf@plot@gap@cycle@handler%
+}%
+
+\def\pgf@plot@gap@cycle@handler#1{%
+ % Ok, compute normalized line vector
+ \pgf@process{#1}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \xdef\pgf@plot@gap@cycle@next{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \pgf@process{\pgfpointnormalised{\pgfpointdiff{\pgf@plot@gap@cycle@last}{\pgf@plot@gap@cycle@next}}}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfpathmoveto{\pgfpointadd{\pgfpointscale{\pgfkeysvalueof{/pgf/gap
+ around stream point}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}{\pgf@plot@gap@cycle@last}}%
+ \pgfpathlineto{\pgfpointadd{\pgfpointscale{\pgfkeysvalueof{/pgf/gap
+ around stream point}}{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}}{\pgf@plot@gap@cycle@next}}%
+ \global\let\pgf@plot@gap@cycle@last=\pgf@plot@gap@cycle@next%
+}%
+
+\def\pgf@plot@gap@cycle@handler@finish{%
+ \ifx\pgf@plot@gap@cycle@first\relax%
+ \else
+ \pgf@plot@gap@cycle@handler{\pgf@plot@gap@cycle@first}%
+ \fi
+}%
+
+
+
+\endinput
+
+% Local Variables:
+% tab-width: 2
+% End:
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryplotmarks.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryplotmarks.code.tex
new file mode 100644
index 0000000000..0beb873c07
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryplotmarks.code.tex
@@ -0,0 +1,453 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryplotmarks.code.tex}
+
+
+% A stroked circle mark
+
+\pgfdeclareplotmark{o}
+{%
+ \pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfplotmarksize}{0sp}}{\pgfqpoint{0sp}{\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+
+% A Mercedes-line star
+
+\pgfdeclareplotmark{Mercedes star}
+{%
+ \pgfpathmoveto{\pgfqpointpolar{90}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfpointorigin}%
+ \pgfpathmoveto{\pgfqpointpolar{-30}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfpointorigin}%
+ \pgfpathmoveto{\pgfqpointpolar{-150}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfpointorigin}%
+ \pgfusepathqstroke
+}%
+
+\pgfdeclareplotmark{Mercedes star flipped}
+{%
+ \pgfpathmoveto{\pgfqpointpolar{-90}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfpointorigin}%
+ \pgfpathmoveto{\pgfqpointpolar{30}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfpointorigin}%
+ \pgfpathmoveto{\pgfqpointpolar{150}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfpointorigin}%
+ \pgfusepathqstroke
+}%
+
+
+
+
+% A six-pointed star mark
+
+\pgfdeclareplotmark{asterisk}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpointpolar{30}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{210}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpointpolar{-30}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{-210}{\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+
+% A five-pointed star mark
+
+\pgfdeclareplotmark{star}
+{%
+ \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+
+% An 10-pointed star mark
+
+\pgfdeclareplotmark{10-pointed star}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpointpolar{18}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpointpolar{-54}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpointpolar{234}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpointpolar{162}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+
+% An \oplus mark
+
+\pgfdeclareplotmark{oplus}
+{%
+ \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}%
+ \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+\pgfdeclareplotmark{oplus*}
+{%
+ \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}%
+ \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfusepathqfillstroke
+}%
+
+
+% An \otimes mark
+
+\pgfdeclareplotmark{otimes}
+{%
+ \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}%
+ \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+\pgfdeclareplotmark{otimes*}
+{%
+ \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}%
+ \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}%
+ \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}%
+ \pgfusepathqfillstroke
+}%
+
+
+% A vertical bar mark
+
+\pgfdeclareplotmark{|}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+
+
+% A horizontal bar mark
+
+\pgfdeclareplotmark{-}
+{%
+ \pgfpathmoveto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfusepathqstroke
+}%
+
+
+% A square stroked mark
+
+\pgfdeclareplotmark{square}
+{%
+ \pgfpathrectangle{\pgfqpoint{-\pgfplotmarksize}{-\pgfplotmarksize}}{\pgfqpoint{2\pgfplotmarksize}{2\pgfplotmarksize}}%
+ \pgfusepathqstroke
+}%
+
+% A square stroked-filled mark
+
+\pgfdeclareplotmark{square*}
+{%
+ \pgfpathrectangle{\pgfqpoint{-\pgfplotmarksize}{-\pgfplotmarksize}}{\pgfqpoint{2\pgfplotmarksize}{2\pgfplotmarksize}}%
+ \pgfusepathqfillstroke
+}%
+
+
+% A triangle mark
+
+\pgfdeclareplotmark{triangle}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{-30}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{-150}{\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+% A stroke-filled triangle mark
+
+\pgfdeclareplotmark{triangle*}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{-30}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{-150}{\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+
+
+% A diamond-shaped mark
+
+\pgfdeclareplotmark{diamond}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.75\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}}%
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+% A stroke-filled diamond-shaped mark
+
+\pgfdeclareplotmark{diamond*}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.75\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}}%
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+
+
+% A pentagon-shaped mark
+
+\pgfdeclareplotmark{pentagon}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+% A stroke-filled pentagon-shaped mark
+
+\pgfdeclareplotmark{pentagon*}
+{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+\newif\ifpgfmarktext@usetikznode
+\pgfkeys{
+ /pgf/text mark/.initial=p,
+ /pgf/text mark style/.initial=,
+ /pgf/text mark as node/.is if=pgfmarktext@usetikznode,
+ /pgf/text mark as node/.default=true,
+ %
+ % backw. compat: the extra search path confuses the '.unknown'
+ % handlers, so this here is deprecated:
+ /pgf/text mark/style/.style={/pgf/text mark style={#1}},%
+ /pgf/text mark/as node/.style={/pgf/text mark as node={#1}},%
+}%
+
+\pgfdeclareplotmark{text}
+{
+ \pgfkeysgetvalue{/pgf/text mark style}\pgfmarktext@style
+ \pgfkeysgetvalue{/pgf/text mark}\pgfmarktext@
+ \ifpgfmarktext@usetikznode
+ \expandafter\node\expandafter[\pgfmarktext@style]{\pgfmarktext@};
+ \else
+ \expandafter\pgftext\expandafter[\pgfmarktext@style]{\pgfmarktext@}%
+ \fi
+}%
+
+\pgfkeysdef{/pgf/mark color}{\def\pgf@mark@color{#1}}%
+\let\pgf@mark@color\pgfutil@empty
+
+\def\pgf@set@mark@color{%
+ \ifx\pgf@mark@color\pgfutil@empty
+ \pgfsys@color@rgb@fill{1}{1}{1}%
+ \else
+ \pgfsetfillcolor{\pgf@mark@color}%
+ \fi
+}%
+\def\pgf@mark@color@none{none}%
+
+% A half-down-filled and half-up-filled-white diamond-shaped mark
+% (the shape can be rotated by "mark options = {rotate = 90}")
+% created by Tomek
+
+\pgfdeclareplotmark{halfcircle}{%
+ \ifx\pgf@mark@color@none\pgf@mark@color
+ \else
+ \pgfscope
+ \pgf@set@mark@color
+ \pgfpathmoveto
+ {\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpatharc{180}{360}{\pgfplotmarksize}%
+ \pgfusepathqfill
+ \endpgfscope%
+ \fi
+ \pgfpathmoveto
+ {\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto
+ {\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathcircle{\pgfpointorigin}%
+ {\pgfplotmarksize}%
+ \pgfusepathqstroke
+}%
+\pgfdeclareplotmark{halfcircle*}{%
+ \pgfpathmoveto
+ {\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpatharc{0}{180}{\pgfplotmarksize}%
+ \pgfpathclose
+ \pgfusepathqfill
+ \ifx\pgf@mark@color@none\pgf@mark@color
+ \else
+ \pgfscope
+ \pgf@set@mark@color
+ \pgfpathmoveto
+ {\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpatharc{180}{360}{\pgfplotmarksize}%
+ \pgfusepathqfill
+ \endpgfscope%
+ \fi
+ \pgfpathcircle{\pgfpointorigin}%
+ {\pgfplotmarksize}%
+ \pgfusepathqstroke
+}%
+
+% A half-down-filled and half-up-filled-white diamond-shaped mark
+% created by Magnus Tewes
+
+\pgfdeclareplotmark{halfdiamond*}{%
+ \pgfpathmoveto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{.75\pgfplotmarksize}{0pt}}%
+ \pgfusepathqfill
+ \ifx\pgf@mark@color@none\pgf@mark@color
+ \else
+ \pgfscope
+ \pgf@set@mark@color
+ \pgfpathmoveto{\pgfqpoint{.75\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}}%
+ \pgfusepathqfill
+ \endpgfscope
+ \fi
+ \pgfpathmoveto{\pgfqpoint{.75\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+% A half-down-filled and half-up-filled-white tilted-squared-shaped mark
+% created by Magnus Tewes
+
+\pgfdeclareplotmark{halfsquare*}{%
+ \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfusepathqfill
+ \ifx\pgf@mark@color@none\pgf@mark@color
+ \else
+ \pgfscope
+ \pgf@set@mark@color
+ \pgfpathmoveto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfusepathqfill
+ \endpgfscope
+ \fi
+ \pgfpathmoveto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+% A half-right-filled and half-up-filled-white tilted-squared-shaped mark
+% created by Magnus Tewes
+
+\pgfdeclareplotmark{halfsquare right*}{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfusepathqfill
+ \ifx\pgf@mark@color@none\pgf@mark@color
+ \else
+ \pgfscope
+ \pgf@set@mark@color
+ \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfusepathqfill
+ \endpgfscope
+ \fi
+ \pgfpathmoveto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+% A half-left-filled and half-up-filled-white tilted-squared-shaped mark
+% created by Magnus Tewes
+
+\pgfdeclareplotmark{halfsquare left*}{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfusepathqfill
+ \ifx\pgf@mark@color@none\pgf@mark@color
+ \else
+ \pgfscope
+ \pgf@set@mark@color
+ \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfusepathqfill
+ \endpgfscope
+ \fi
+ \pgfpathmoveto{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}%
+ \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqstroke
+}%
+
+
+% A stroke-filled heart-shaped mark
+% created by Magnus Tewes
+\pgfdeclareplotmark{heart}{%
+ \pgfpathmoveto{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}}%
+ \pgfpathcurveto{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.66\pgfplotmarksize}}{\pgfqpoint{-.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}%
+ \pgfpathcurveto{\pgfqpoint{-.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}{\pgfqpoint{-\pgfplotmarksize}{-.75\pgfplotmarksize}}{\pgfqpoint{-\pgfplotmarksize}{0pt}}%
+ \pgfpathcurveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}{\pgfqpoint{-\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{-.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}%
+ \pgfpathcurveto{\pgfqpoint{-.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{0pt}{.5825\pgfplotmarksize}}{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathcurveto{\pgfqpoint{0pt}{0pt}}{\pgfqpoint{0pt}{.5825\pgfplotmarksize}}{\pgfqpoint{.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}%
+ \pgfpathcurveto{\pgfqpoint{.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{\pgfplotmarksize}{0pt}}%
+ \pgfpathcurveto{\pgfqpoint{\pgfplotmarksize}{0pt}}{\pgfqpoint{\pgfplotmarksize}{-.75\pgfplotmarksize}}{\pgfqpoint{.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}%
+ \pgfpathcurveto{\pgfqpoint{.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.66\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}}%
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryprofiler.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryprofiler.code.tex
new file mode 100644
index 0000000000..d6327db062
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryprofiler.code.tex
@@ -0,0 +1,530 @@
+%--------------------------------------------
+%
+% TeX profiling library
+%
+% Copyright 2018 by Christian Feuersänger.
+%
+% 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/>.
+%
+%--------------------------------------------
+
+\pgfutil@ifundefined{pdfelapsedtime}{%
+ % Ok, \pdfelapsedtime is not defined.
+ % Maybe we run luatex?
+ \pgfutil@ifluatex
+ % Yes. So we emulate the primitive by a macro.
+ % (see http://tex.stackexchange.com/q/32507/8425)
+ \def\pgfutil@pdfelapsedtime{%
+ \numexpr\pgfutil@directlua{%
+ tex.print(math.floor((os.clock())*65536+0.5))}\relax}
+ \else
+ % Raise an error
+ \pgferror{%
+ Library 'profiler' can only be used with pdftex Rev. >= 1.671
+ because it needs the \string\pdfelapsedtime\space command or
+ with luatex}%
+ \global\let\pgfutil@pdfelapsedtime=\c@pgf@counta
+ \fi}{%
+ % We run pdftex. That's ok.
+ \let\pgfutil@pdfelapsedtime\pdfelapsedtime}%
+
+
+% Defines a new profiler entry named `#1'.
+%
+% This allocates a set of counters.
+\def\pgfprofilenew#1{%
+ \pgfutil@ifundefined{c@pgfprofile@elapsedtotal@#1}{%
+ \expandafter\gdef\csname c@pgfprofile@elapsedtotal@#1\endcsname{0}%
+ \expandafter\gdef\csname c@pgfprofile@elapsedself@#1\endcsname{0}%
+ \expandafter\gdef\csname c@pgfprofile@numinvocations@#1\endcsname{0}%
+ \expandafter\gdef\csname c@pgfprofile@subtractforself@#1\endcsname{0}%
+ \expandafter\gdef\csname c@pgfprofile@semaphor@#1\endcsname{0}%
+ \expandafter\gdef\csname c@pgfprofile@elapsed@at@start@#1\endcsname{0}%
+ \pgfprofile@all@registered@list@add{#1}%
+ }{%
+ % it is already defined and registered. Shouldn't hurt, might
+ % even be a good feature.
+ }%
+}%
+
+\def\pgfprofile@TeX@DIALECT@toenvironment@begin#1{\csname #1\endcsname}%
+\def\pgfprofile@TeX@DIALECT@toenvironment@end#1{\csname end#1\endcsname}%
+
+\def\pgfprofile@@to@pgfretval#1{%
+ \expandafter\let\expandafter\pgfretval#1%
+}%
+
+% Defines a new profiler entry for the environment `#1'.
+%
+% This calls \pgfprofilenew and handles the begin/end of the
+% environment automatically.
+%
+% #1 the environment name (a string)
+%
+% Optionally in square brackets: the profiler entry name
+% \pgfprofilenewforenvironment{<environment name>}
+% \pgfprofilenewforenvironment[<profiler entry name>]{<environment name>}
+\def\pgfprofilenewforenvironment{\pgfutil@ifnextchar[{\pgfprofilenewforenvironment@}{\pgfprofilenewforenvironment@[]}}%
+\def\pgfprofilenewforenvironment@[#1]#2{%
+ \expandafter\pgfprofile@@to@pgfretval\pgfprofile@TeX@DIALECT@toenvironment@begin{#2}%
+ \ifx\pgfretval\relax
+ \pgferror{\string\pgfprofilenewforenvironment{#2} doesn't work: the environment `#2' is (not yet?) known or not known in this context}{}%
+ \else
+ \expandafter\global\expandafter\let\csname pgfprofile@orig@begin@#2\endcsname=\pgfretval
+ \expandafter\pgfprofile@@to@pgfretval\pgfprofile@TeX@DIALECT@toenvironment@end{#2}%
+ \expandafter\global\expandafter\let\csname pgfprofile@orig@end@#2\endcsname=\pgfretval
+ %
+ \def\pgfprofile@temp{#1}%
+ \ifx\pgfprofile@temp\pgfutil@empty
+ \pgfprofilenewforenvironment@@{\pgfprofileenv #2}{#2}%
+ \else
+ \pgfprofilenewforenvironment@@{#1}{#2}%
+ \fi
+ \fi
+}%
+\def\pgfprofilenewforenvironment@@#1#2{%
+ \pgfprofilenew{#1}%
+ \expandafter\expandafter\expandafter\gdef\pgfprofile@TeX@DIALECT@toenvironment@begin{#2}{%
+ \pgfprofilestart{#1}%
+ \csname pgfprofile@orig@begin@#2\endcsname
+ }%
+ \expandafter\expandafter\expandafter\gdef\pgfprofile@TeX@DIALECT@toenvironment@end{#2}{%
+ \csname pgfprofile@orig@end@#2\endcsname
+ \pgfprofileend{#1}%
+ }%
+}%
+
+
+\def\pgfprofilecs{<CS>}%
+\def\pgfprofileenv{<ENV>}%
+
+% Defines a new profiler entry for the control sequence '#1'.
+%
+% This calls \pgfprofilenew and enhances the control sequence with
+% support for timings.
+%
+% #1: the control sequence (with backslash!)
+% #2: the number of arguments (see below).
+%
+% The following commands are supported:
+% - commands which take one (optional) argument in square brackets,
+% - commands which take one (optional) argument in square brackets
+% followed by one optional argument which has to be delimited with
+% curly braces (use an empty argument for '#2' in this case),
+% - commands which take one (optional) argument in square brackets
+% and *exactly* #2 arguments afterwards.
+\def\pgfprofilenewforcommand{\pgfutil@ifnextchar[{\pgfprofilenewforcommand@}{\pgfprofilenewforcommand@[]}}%
+\def\pgfprofilenewforcommand@[#1]#2#3{%
+ \def\pgfprofile@temp{#3}%
+ \ifx\pgfprofile@temp\pgfutil@empty
+ \pgfprofilenewforcommandpattern[#1]{#2}{<autocheck>}{}%
+ \else
+ \ifcase#3\relax
+ \pgfprofilenewforcommandpattern[#1]{#2}{}{}%
+ \or
+ \pgfprofilenewforcommandpattern[#1]{#2}{##1}{{##1}}%
+ \or
+ \pgfprofilenewforcommandpattern[#1]{#2}{##1##2}{{##1}{##2}}%
+ \or
+ \pgfprofilenewforcommandpattern[#1]{#2}{##1##2##3}{{##1}{##2}{##3}}%
+ \or
+ \pgfprofilenewforcommandpattern[#1]{#2}{##1##2##3##4}{{##1}{##2}{##3}{##4}}%
+ \or
+ \pgfprofilenewforcommandpattern[#1]{#2}{##1##2##3##4##5}{{##1}{##2}{##3}{##4}{##5}}%
+ \or
+ \pgfprofilenewforcommandpattern[#1]{#2}{##1##2##3##4##5##6}{{##1}{##2}{##3}{##4}{##5}{##6}}%
+ \or
+ \pgfprofilenewforcommandpattern[#1]{#2}{##1##2##3##4##5##6##7}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}%
+ \else
+ \pgferror{library 'profiler' can't replace control sequences with '#3' arguments automatically, sorry.}{}%
+ \fi
+ \fi
+}%
+
+% \pgfprofilenewforcommandpattern[<profile entry name>]{<\CS>}{<definition pattern>}{<invocation pattern>}
+%
+% example:
+% \pgfprofilenewforcommandpattern{\pgfqkeys}{##1##2}{{##1}{##2}}
+%
+% \def\mymacro##1\to##2\in##3{ .... }
+% \pgfprofilenewforcommandpattern{\mymacro}{##1\to##2\in##3}{{##1}\to{##2}\in{##3}}
+\def\pgfprofilenewforcommandpattern{\pgfutil@ifnextchar[{\pgfprofilenewforcommandpattern@}{\pgfprofilenewforcommandpattern@[]}}%
+\def\pgfprofilenewforcommandpattern@[#1]#2#3#4{%
+ \def\pgfprofile@known{1}%
+ \ifx#2\undefined
+ \def\pgfprofile@known{0}%
+ \else
+ \ifx#2\relax
+ \def\pgfprofile@known{0}%
+ \fi
+ \fi
+ \if\pgfprofile@known0%
+ \pgferror{\string\pgfprofilenewforcommandpattern{\string#2} doesn't work: the command `\string#2' is (not yet?) known or not known in this context}%
+ \else
+ \begingroup
+ \pgfprofile@cs@to@name{#2}%
+ \let\pgfprofilenew@cmdname=\pgfretval
+ %
+ \def\pgfprofile@temp{#1}%
+ \ifx\pgfprofile@temp\pgfutil@empty
+ \edef\pgfprofilenew@profilerentryname{\pgfprofilecs\pgfprofilenew@cmdname}%
+ \else
+ \edef\pgfprofilenew@profilerentryname{#1}%
+ \fi
+ \expandafter\global\expandafter\let\csname pgfprofile@name@for@\pgfprofilenew@cmdname\endcsname=\pgfprofilenew@profilerentryname
+ \pgfprofilenew{\pgfprofilenew@profilerentryname}%
+ \expandafter\gdef\csname b@pgfprofile@show@\pgfprofilenew@profilerentryname\endcsname{0}%
+ %
+ \expandafter\global\expandafter\let\csname pgfprofile@orig@\pgfprofilenew@cmdname\endcsname=#2%
+ \toks0={#3}%
+ \edef\pgfprofile@temp{\the\toks0}%%
+ \def\pgfprofile@tempb{<autocheck>}%
+ \ifx\pgfprofile@temp\pgfprofile@tempb
+ \expandafter\global\expandafter\let\csname pgfprofile@repl@\pgfprofilenew@cmdname\endcsname=\pgfprofileinvokecommand@uptoonearg
+ \else
+ \expandafter\gdef\csname pgfprofile@repl@\pgfprofilenew@cmdname\endcsname#3{%
+ \pgfprofile@invokeorig{#4}%
+ }%
+ \fi
+ \xdef#2{\noexpand\pgfprofileinvokecommand{\pgfprofilenew@cmdname}}%
+ \endgroup
+ \fi
+}%
+
+\def\pgfprofileshowinvocationsfor#1{%
+ \pgfutil@ifundefined{b@pgfprofile@show@#1}{%
+ \pgferror{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}%
+ }{%
+ \expandafter\gdef\csname b@pgfprofile@show@#1\endcsname{1}%
+ \expandafter\gdef\csname b@pgfprofile@show@edef@#1\endcsname{0}%
+ }%
+}%
+\def\pgfprofileshowinvocationsexpandedfor#1{%
+ \pgfutil@ifundefined{b@pgfprofile@show@#1}{%
+ \pgferror{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}%
+ }{%
+ \expandafter\gdef\csname b@pgfprofile@show@#1\endcsname{1}%
+ \expandafter\gdef\csname b@pgfprofile@show@edef@#1\endcsname{1}%
+ }%
+}%
+
+\def\pgfprofile@no@optional@arg@text{<noarg>}%
+\def\pgfprofileinvokecommand#1{%
+ \pgfutil@ifnextchar[{\pgfprofileinvokecommand@{#1}}{\pgfprofileinvokecommand@{#1}[<noarg>]}%
+}%
+\def\pgfprofileinvokecommand@#1[#2]{%
+ \def\pgfprofileinvokecommand@cs{#1}%
+ \def\pgfprofileinvokecommand@optarg{#2}%
+ \edef\pgfprofileinvokecommand@profilerentryname{\csname pgfprofile@name@for@#1\endcsname}%
+ \csname pgfprofile@repl@#1\endcsname%
+}%
+
+% #1 contains ALL arguments, including any braces.
+\def\pgfprofile@invokeorig#1{%
+ % re-insert the control sequence name and the optional argument:
+ % this wasn't possible directly.
+ \begingroup
+ \toks1=\expandafter{\pgfprofileinvokecommand@optarg}%
+ \toks2={#1}%
+ \toks3=\expandafter{\csname pgfprofile@orig@\pgfprofileinvokecommand@cs\endcsname}%
+ %
+ \ifx\pgfprofileinvokecommand@optarg\pgfprofile@no@optional@arg@text
+ % no [] argument after original command:
+ \xdef\pgfprofile@invokeorig@doitfinally{\the\toks3 \the\toks2 }%%
+ \else
+ \xdef\pgfprofile@invokeorig@doitfinally{\the\toks3[\the\toks1]\the\toks2 }%
+ \fi
+ \if1\csname b@pgfprofile@show@\pgfprofileinvokecommand@profilerentryname\endcsname
+ \pgfprofile@orig@show
+ \fi
+ \endgroup
+ \edef\pgfprofile@temp{{\pgfprofileinvokecommand@cs}{\pgfprofileinvokecommand@profilerentryname}}%
+ \expandafter\pgfprofile@invokeorig@\pgfprofile@temp%
+}%
+\def\pgfprofile@orig@show{%
+ \toks4=\expandafter{\csname\pgfprofileinvokecommand@cs\endcsname}%
+ \ifx\pgfprofileinvokecommand@optarg\pgfprofile@no@optional@arg@text
+ \def\pgfprofile@orig@show@args{\the\toks2 }%
+ \else
+ \def\pgfprofile@orig@show@args{[\the\toks1] \the\toks2 }%
+ \fi
+ \if1\csname b@pgfprofile@show@edef@\pgfprofileinvokecommand@profilerentryname\endcsname
+ \edef\pgfprofile@orig@show@args{\pgfprofile@orig@show@args}%
+ \edef\pgfprofile@orig@show@args{\pgfprofile@orig@show@args}%
+ \fi
+ \pgf@typeout{pgflibraryprofiler: calling
+ \#\csname c@pgfprofile@numinvocations@\pgfprofileinvokecommand@profilerentryname\endcsname\space
+ (\the\toks4 \pgfprofile@orig@show@args)}%
+}%
+
+% #1: control sequence name (without backslash)
+% #2: profiler entry name
+\def\pgfprofile@invokeorig@#1#2{%
+ % this check should avoid save stack impact
+ \pgfprofileifisrunning{#2}{%
+ \pgfprofile@invokeorig@doitfinally%
+ }{%
+ \pgfprofilestart{#2}%
+ \pgfprofile@invokeorig@doitfinally%
+ \pgfprofileend{#2}%
+ }%
+}%
+
+
+\def\pgfprofileinvokecommand@uptoonearg{%
+ \pgfutil@ifnextchar\bgroup{\pgfprofileinvokecommand@onearg}{\pgfprofileinvokecommand@noarg}%
+}%
+\def\pgfprofileinvokecommand@onearg#1{%
+ \pgfprofile@invokeorig{{#1}}%
+}%
+\def\pgfprofileinvokecommand@noarg{%
+ \pgfprofile@invokeorig{}%
+}%
+
+
+
+% Starts / Resumes timing of the profiler entry named `#1'.
+%
+% The timing will continue until \pgfprofileend{#1} is called.
+%
+% Nested calls of \pgfprofilestart{#1} (with the same argument) will
+% result in the same result as if just one \pgfprofilestart command
+% has been issued.
+\def\pgfprofilestart#1{%
+ \pgfprofileifisrunning{#1}{%
+ \relax
+ }{%
+ \expandafter\xdef\csname c@pgfprofile@elapsed@at@start@#1\endcsname{\the\pgfutil@pdfelapsedtime}%
+ \expandafter\gdef\csname c@pgfprofile@subtractforself@#1\endcsname{0}%
+ \pgfprofile@advance{c@pgfprofile@numinvocations@#1}{1}%
+ \pgfprofilestackpush{#1}%
+ }%
+ \pgfprofile@advance{c@pgfprofile@semaphor@#1}{1}%
+}%
+
+% Stops / Interrupts timing of the profiler entry named `#1'.
+\def\pgfprofileend#1{%
+ \pgfprofile@advance{c@pgfprofile@semaphor@#1}{-1}%
+ \pgfprofileifisrunning{#1}{%
+ \relax
+ }{%
+ \begingroup
+ \c@pgf@countb=\pgfutil@pdfelapsedtime\relax
+ \advance\c@pgf@countb by-\csname c@pgfprofile@elapsed@at@start@#1\endcsname\relax
+ %
+ \pgfprofilestackpop\pgfretval
+ \edef\pgfprofile@temp{#1}%
+ \ifx\pgfprofile@temp\pgfretval
+ \else
+ \pgf@typeout{pgflibraryprofiler WARNING: possible error in self time computation...}%
+ \fi
+ \pgfprofilestackifempty{%
+ \relax
+ }{%
+ \pgfprofilestacktop\pgfretval
+ \pgfprofile@advance{c@pgfprofile@subtractforself@\pgfretval}{\c@pgf@countb}%
+ }%
+ %
+ \pgfprofile@advance{c@pgfprofile@elapsedtotal@#1}{\c@pgf@countb}%
+ \advance\c@pgf@countb by-\csname c@pgfprofile@subtractforself@#1\endcsname\relax
+ \pgfprofile@advance{c@pgfprofile@elapsedself@#1}{\c@pgf@countb}%
+ \endgroup
+ }%
+}%
+
+% invokes '#2' if '#1' is currently running and '#3' if not.
+\def\pgfprofileifisrunning#1#2#3{%
+ \ifnum\csname c@pgfprofile@semaphor@#1\endcsname=0 \def\pgfprofileifisrunning@next{#3}\else \def\pgfprofileifisrunning@next{#2}\fi
+ \pgfprofileifisrunning@next
+}%
+
+% Sets the profiler entry whose total time is used to compute all
+% other relative times.
+\def\pgfprofilesetrel#1{\edef\pgfprofile@rel{#1}}%
+
+% Stops all running timings and postprocesses them.
+\def\pgfprofilepostprocess{%
+ \begingroup
+ %
+ % prepare files.
+ \c@pgf@countb=\time
+ \divide\c@pgf@countb by60
+ \c@pgf@countd=\c@pgf@countb
+ \multiply\c@pgf@countd by60
+ \c@pgf@countc=\time
+ \advance\c@pgf@countc by-\c@pgf@countd
+ \immediate\openout\w@pgf@writea=\jobname.profiler.\the\year-\pgfprofiletotwodigitstr\month-\pgfprofiletotwodigitstr\day_\pgfprofiletotwodigitstr\c@pgf@countb h_\pgfprofiletotwodigitstr\c@pgf@countc m.dat
+ \immediate\write\w@pgf@writea{%
+ \pgfprofile@percent relative values are measured against the totaltime of `\pgfprofile@rel'.%
+ }%
+ \pgf@typeout{pgflibraryprofiler: relative values are measured against the totaltime of `\pgfprofile@rel'.}%
+ \immediate\write\w@pgf@writea{%
+ profilerentry\pgfprofile@TAB
+ totaltime[s]\pgfprofile@TAB
+ totaltime[percent]\pgfprofile@TAB
+ selftime[s]\pgfprofile@TAB
+ selftime[percent]\pgfprofile@TAB
+ numinvocations\pgfprofile@TAB}%
+ %
+ %
+ % compute main time and prepare computation of relative times:
+ \pgfprofileifisrunning{\pgfprofile@rel}{%
+ \pgfprofileend{\pgfprofile@rel}%
+ }{}%
+ \pgf@xa=\csname c@pgfprofile@elapsedtotal@\pgfprofile@rel\endcsname sp
+ \edef\pgfprofiletotaltime{\pgf@sys@tonumber\pgf@xa}%
+ \pgfmathreciprocal@{\pgfprofiletotaltime}%
+ \let\pgfprofiletotaltime@inv=\pgfmathresult
+ %
+ % postprocess each of them:
+ \pgfprofile@all@registered@list@foreach{%
+ \pgfprofileifisrunning{##1}{%
+ \pgfprofileend{##1}%
+ }{}%
+ \pgfprofilepostprocess@single{##1}%
+ }%
+ \immediate\write\w@pgf@writea{%
+ \pgfprofile@percent\space vim: ts=40 nowrap nostartofline
+ }%
+ \immediate\closeout\w@pgf@writea
+ \endgroup
+}%
+
+{%
+\catcode`\[=1 %
+\catcode`\]=2 %
+\catcode`\{=12 %
+\catcode`\}=12 %
+\catcode`\^^I=12
+\gdef\pgfprofile@lbrace[{]%
+\gdef\pgfprofile@rbrace[}]%
+\gdef\pgfprofile@TAB[^^I]%
+]
+{
+\catcode`\%=12 \gdef\pgfprofile@percent{%}}
+
+\def\pgfprofilepostprocess@single#1{%
+ \begingroup
+ \pgf@xa=\csname c@pgfprofile@elapsedtotal@#1\endcsname sp
+ \pgf@xb=\csname c@pgfprofile@elapsedself@#1\endcsname sp
+ \pgf@ya=\pgfprofiletotaltime@inv\pgf@xa
+ \pgf@yb=\pgfprofiletotaltime@inv\pgf@xb
+ \multiply\pgf@ya by100
+ \multiply\pgf@yb by100
+ \edef\pgfprofilecur@total{\pgf@sys@tonumber\pgf@xa}%
+ \edef\pgfprofilecur@self{\pgf@sys@tonumber\pgf@xb}%
+ \edef\pgfprofilecur@total@rel{\pgf@sys@tonumber\pgf@ya}%
+ \edef\pgfprofilecur@self@rel{\pgf@sys@tonumber\pgf@yb}%
+ \pgf@typeout{
+ pgflibraryprofiler(#1)
+ \pgfprofile@lbrace
+ total time=\pgfprofilecur@total sec; (\pgfprofilecur@total@rel\pgfprofile@percent)
+ self time=\pgfprofilecur@self sec; (\pgfprofilecur@self@rel\pgfprofile@percent)
+ invocations=\csname c@pgfprofile@numinvocations@#1\endcsname;
+ \pgfprofile@rbrace
+ }%
+ \immediate\write\w@pgf@writea{%
+ #1\pgfprofile@TAB
+ \pgfprofilecur@total\pgfprofile@TAB
+ \pgfprofilecur@total@rel\pgfprofile@TAB
+ \pgfprofilecur@self\pgfprofile@TAB
+ \pgfprofilecur@self@rel\pgfprofile@TAB
+ \csname c@pgfprofile@numinvocations@#1\endcsname\pgfprofile@TAB
+ }%
+ \endgroup
+}%
+% Invokes '#2' for each element of the command separated list '#1'.
+% the current list element is available as '#1' inside of '#2'.
+\long\def\pgfprofileforeachentryinCSV#1#2{%
+ \long\def\pgfprofileinvokeforeach@@##1{#2}%
+ \pgfprofileforeachentryinCSVisterminated@loop#1,\pgfeov
+}%
+\long\def\pgfprofileforeachentryinCSVisterminated@loop{%
+ \pgfutil@ifnextchar\pgfeov{\pgfutil@gobble}{\pgfprofileforeachentryinCSV@next}%
+}%
+\long\def\pgfprofileforeachentryinCSV@next#1,{%
+ \pgfprofileinvokeforeach@@{#1}%
+ \pgfprofileforeachentryinCSVisterminated@loop%
+}%
+
+\xdef\pgfprofile@all@registered@list{}%
+\xdef\pgfprofile@currently@running@list{}%
+
+\def\pgfprofile@all@registered@list@add#1{%
+ \ifx\pgfprofile@all@registered@list\pgfutil@empty
+ \xdef\pgfprofile@all@registered@list{#1}%
+ \else
+ \xdef\pgfprofile@all@registered@list{\pgfprofile@all@registered@list,#1}%
+ \fi
+}%
+
+\def\pgfprofile@all@registered@list@foreach#1{%
+ \expandafter\pgfprofileforeachentryinCSV\expandafter{\pgfprofile@all@registered@list}{#1}%
+}%
+
+\def\pgfprofile@advance#1#2{%
+ \begingroup
+ \c@pgf@counta=\csname #1\endcsname\relax
+ \advance\c@pgf@counta by#2\relax
+ \expandafter\xdef\csname #1\endcsname{\the\c@pgf@counta}%
+ \endgroup
+}%
+
+\def\pgfprofile@cs@to@name@#1#2\relax{\def\pgfretval{#2}}
+
+% defines '\pgfretval' to be the control sequences name of '#1' *without* the backslash.
+\def\pgfprofile@cs@to@name#1{%
+ \expandafter\pgfprofile@cs@to@name@\string#1\relax
+}%
+
+\newcount\c@pgfprofile@stacktop
+
+\c@pgfprofile@stacktop=-1
+\def\pgfprofilestackpush#1{%
+ \global\advance\c@pgfprofile@stacktop by1
+ \expandafter\xdef\csname pgfprofile@stack@\the\c@pgfprofile@stacktop\endcsname{#1}%
+}%
+% pops the current stack top to macro #1
+\def\pgfprofilestackpop#1{%
+ \pgfprofilestacktop#1%
+ \global\advance\c@pgfprofile@stacktop by-1
+}%
+% returns the stack's top to macro #1
+\def\pgfprofilestacktop#1{%
+ \expandafter\let\expandafter#1\csname pgfprofile@stack@\the\c@pgfprofile@stacktop\endcsname
+}%
+\def\pgfprofilestackifempty#1#2{%
+ \ifnum\c@pgfprofile@stacktop<0 #1\else #2\fi
+}%
+
+
+\def\pgfprofiletotwodigitstr#1{\ifnum#1<10 0\the#1\else\the#1\fi}%
+
+\pgfprofilenew{main job}%
+\pgfprofilestart{main job}%
+\expandafter\xdef\csname c@pgfprofile@elapsed@at@start@main job\endcsname{0}%
+\pgfprofilesetrel{main job}%
+
+\pgfutil@ifundefined{AtEndDocument}{%
+ % no latex. ok.
+}{%
+ % do latex specific stuff:
+ \pgfprofilenew{preamble}
+ \pgfprofilestart{preamble}
+ \expandafter\xdef\csname c@pgfprofile@elapsed@at@start@preamble\endcsname{0}%
+ \AtBeginDocument{\pgfprofileend{preamble}}%
+ %
+ \AtEndDocument{\pgfprofilepostprocess}%
+}%
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibraryshadings.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibraryshadings.code.tex
new file mode 100644
index 0000000000..81e0386a60
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibraryshadings.code.tex
@@ -0,0 +1,444 @@
+% Copyright 2019 by Till Tantau and others
+% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryshadings.code.tex}
+
+
+%
+% An hsv color wheel. Initial code graciously donated by Ken Starks.
+%
+
+\pgfdeclarefunctionalshading[black]{color wheel white center}
+{\pgfpoint{-50bp}{-50bp}}
+{\pgfpoint{50bp}{50bp}}
+{}
+{ % x y
+ 2 copy % ... x y x y
+ 2 copy abs exch abs add 0.0001 ge
+ {atan 360.0 div} % ... x y heading; heading being in
+ %the interval [0, 1.0]
+ { pop } % silently deal with error: return
+ % arbitrary heading of zero for origin
+ ifelse % because we will use it for 'Hue'
+ 3 1 roll % ... heading x y
+ dup mul % ... heading x y*y
+ exch dup mul % ... heading y*y x*x
+ add sqrt % ... heading ra_pt (distance from origin in points)
+ 25.0 div % scale it means a ra of 25bp
+ dup 1.0 ge % BOOLEAN. ready to clamp to interval [0, 1.0]
+ { pop 1.0 }{} ifelse % We shall use the scaled ra as 'Saturation'
+ %2.5 mul 0.25 sub % now, Ra in [0.1, 0.5] --> Saturation
+ % in [0.0, 1.0]. Saturation varies between the two radii
+ 1.0 % ... H S V ( with 'Value' set to literal constant of 1.0 )
+ % C version to use as model:
+ % H' = H * 6
+ % i = floor(H')
+ % f = H' - i
+ % P = V * (1.0 - S)
+ % Q = V * (1.0 - (S*f))
+ % T = V * (1.0 - (S * (1.0 - f)))
+ 3 2 roll 6.0 mul dup 4 1 roll % H' S V H'
+ floor cvr % H' S V i
+ dup 5 1 roll % i H' S V i
+ 3 index sub neg % i H' S V f
+ 1.0 3 index sub % i H' S V f (1.0 - S )
+ 2 index mul % i H' S V f P
+ 6 1 roll % P i H' S V f
+ dup 3 index mul neg 1.0 add % P i H' S V f ( 1.0 - (f*S))
+ 2 index mul % P i H' S V f Q
+ 7 1 roll % Q P i H' S V f
+ neg 1.0 add % Q P i H' S V (1.0 - f)
+ 2 index mul neg 1.0 add % Q P i H' S V (1.0 - S * (1.0 - f))
+ 1 index mul % Q P i H' S V T
+ 7 2 roll % V T Q P i H' S
+ pop pop % V T Q P i
+ %%%
+ % end of BLOCK B. The rest is just stack manipulation
+ dup 0.5 le % TEST II [ i == 0 ]
+ { % BLOCK C [ take stack to V T P ]
+ pop exch pop
+ }
+ { dup 1.5 le % TEST III [ i == 1 ]
+ { % BLOCK D [ take stack to Q V P ]
+ pop exch 4 1 roll exch pop
+ }
+ { dup 2.5 le % TEST IV [ i == 2 ]
+ { % BLOCK E [ take stack to P V T ]
+ pop 4 1 roll pop
+ }
+ { dup 3.5 le % TEST V [ i == 3 ]
+ { % BLOCK F [ take stack to P Q V ]
+ pop exch 4 2 roll pop
+ }
+ { dup 4.5 le % TEST VI [ i == 4 ]
+ { % BLOCK G [ take stack to T P V ]
+ pop exch pop 3 -1 roll
+ }
+ { % BLOCK H [ take stack to V P Q ]
+ pop 3 1 roll exch pop
+ }
+ ifelse
+ }
+ ifelse % for V
+ }
+ ifelse % for IV
+ }
+ ifelse % for III
+ }
+ ifelse % for II
+ \ifpgfshadingmodelcmyk
+ \pgffuncshadingrgbtocmyk
+ \fi
+ \ifpgfshadingmodelgray
+ \pgffuncshadingrgbtogray
+ \fi
+}%
+
+\pgfdeclarefunctionalshading[black]{color wheel black center}
+{\pgfpoint{-50bp}{-50bp}}
+{\pgfpoint{50bp}{50bp}}
+{}
+{ % x y
+ 2 copy % ... x y x y
+ 2 copy abs exch abs add 0.0001 ge
+ {atan 360.0 div} % ... x y heading; heading being in
+ %the interval [0, 1.0]
+ { pop } % silently deal with error: return
+ % arbitrary heading of zero for origin
+ ifelse % because we will use it for 'Hue'
+ 3 1 roll % ... heading x y
+ dup mul % ... heading x y*y
+ exch dup mul % ... heading y*y x*x
+ add sqrt % ... heading ra_pt (distance from origin in points)
+ 25.0 div % scale it means a ra of 25bp
+ dup 1.0 ge % BOOLEAN. ready to clamp to interval [0, 1.0]
+ { pop 1.0 }{} ifelse % We shall use the scaled ra as 'Saturation'
+ %2.5 mul 0.25 sub % now, Ra in [0.1, 0.5] --> Saturation
+ % in [0.0, 1.0]. Saturation varies between the two radii
+ 1.0 exch % ... H S V ( with 'Value' set to literal constant of 1.0 )
+ % C version to use as model:
+ % H' = H * 6
+ % i = floor(H')
+ % f = H' - i
+ % P = V * (1.0 - S)
+ % Q = V * (1.0 - (S*f))
+ % T = V * (1.0 - (S * (1.0 - f)))
+ 3 2 roll 6.0 mul dup 4 1 roll % H' S V H'
+ floor cvr % H' S V i
+ dup 5 1 roll % i H' S V i
+ 3 index sub neg % i H' S V f
+ 1.0 3 index sub % i H' S V f (1.0 - S )
+ 2 index mul % i H' S V f P
+ 6 1 roll % P i H' S V f
+ dup 3 index mul neg 1.0 add % P i H' S V f ( 1.0 - (f*S))
+ 2 index mul % P i H' S V f Q
+ 7 1 roll % Q P i H' S V f
+ neg 1.0 add % Q P i H' S V (1.0 - f)
+ 2 index mul neg 1.0 add % Q P i H' S V (1.0 - S * (1.0 - f))
+ 1 index mul % Q P i H' S V T
+ 7 2 roll % V T Q P i H' S
+ pop pop % V T Q P i
+ %%%
+ % end of BLOCK B. The rest is just stack manipulation
+ dup 0.5 le % TEST II [ i == 0 ]
+ { % BLOCK C [ take stack to V T P ]
+ pop exch pop
+ }
+ { dup 1.5 le % TEST III [ i == 1 ]
+ { % BLOCK D [ take stack to Q V P ]
+ pop exch 4 1 roll exch pop
+ }
+ { dup 2.5 le % TEST IV [ i == 2 ]
+ { % BLOCK E [ take stack to P V T ]
+ pop 4 1 roll pop
+ }
+ { dup 3.5 le % TEST V [ i == 3 ]
+ { % BLOCK F [ take stack to P Q V ]
+ pop exch 4 2 roll pop
+ }
+ { dup 4.5 le % TEST VI [ i == 4 ]
+ { % BLOCK G [ take stack to T P V ]
+ pop exch pop 3 -1 roll
+ }
+ { % BLOCK H [ take stack to V P Q ]
+ pop 3 1 roll exch pop
+ }
+ ifelse
+ }
+ ifelse % for V
+ }
+ ifelse % for IV
+ }
+ ifelse % for III
+ }
+ ifelse % for II
+ \ifpgfshadingmodelcmyk
+ \pgffuncshadingrgbtocmyk
+ \fi
+ \ifpgfshadingmodelgray
+ \pgffuncshadingrgbtogray
+ \fi
+}%
+
+\pgfdeclarefunctionalshading[black]{color wheel}
+{\pgfpoint{-50bp}{-50bp}}
+{\pgfpoint{50bp}{50bp}}
+{}
+{ % x y
+ 2 copy abs exch abs add 0.0001 ge
+ {atan 360.0 div} % ... x y heading; heading being in
+ %the interval [0, 1.0]
+ { pop } % silently deal with error: return
+ % arbitrary heading of zero for origin
+ ifelse % because we will use it for 'Hue'
+ 1.0 1.0 % ... H S V
+ % C version to use as model:
+ % H' = H * 6
+ % i = floor(H')
+ % f = H' - i
+ % P = V * (1.0 - S)
+ % Q = V * (1.0 - (S*f))
+ % T = V * (1.0 - (S * (1.0 - f)))
+ 3 2 roll 6.0 mul dup 4 1 roll % H' S V H'
+ floor cvr % H' S V i
+ dup 5 1 roll % i H' S V i
+ 3 index sub neg % i H' S V f
+ 1.0 3 index sub % i H' S V f (1.0 - S )
+ 2 index mul % i H' S V f P
+ 6 1 roll % P i H' S V f
+ dup 3 index mul neg 1.0 add % P i H' S V f ( 1.0 - (f*S))
+ 2 index mul % P i H' S V f Q
+ 7 1 roll % Q P i H' S V f
+ neg 1.0 add % Q P i H' S V (1.0 - f)
+ 2 index mul neg 1.0 add % Q P i H' S V (1.0 - S * (1.0 - f))
+ 1 index mul % Q P i H' S V T
+ 7 2 roll % V T Q P i H' S
+ pop pop % V T Q P i
+ %%%
+ % end of BLOCK B. The rest is just stack manipulation
+ dup 0.5 le % TEST II [ i == 0 ]
+ { % BLOCK C [ take stack to V T P ]
+ pop exch pop
+ }
+ { dup 1.5 le % TEST III [ i == 1 ]
+ { % BLOCK D [ take stack to Q V P ]
+ pop exch 4 1 roll exch pop
+ }
+ { dup 2.5 le % TEST IV [ i == 2 ]
+ { % BLOCK E [ take stack to P V T ]
+ pop 4 1 roll pop
+ }
+ { dup 3.5 le % TEST V [ i == 3 ]
+ { % BLOCK F [ take stack to P Q V ]
+ pop exch 4 2 roll pop
+ }
+ { dup 4.5 le % TEST VI [ i == 4 ]
+ { % BLOCK G [ take stack to T P V ]
+ pop exch pop 3 -1 roll
+ }
+ { % BLOCK H [ take stack to V P Q ]
+ pop 3 1 roll exch pop
+ }
+ ifelse
+ }
+ ifelse % for V
+ }
+ ifelse % for IV
+ }
+ ifelse % for III
+ }
+ ifelse % for II
+ \ifpgfshadingmodelcmyk
+ \pgffuncshadingrgbtocmyk
+ \fi
+ \ifpgfshadingmodelgray
+ \pgffuncshadingrgbtogray
+ \fi
+}%
+
+
+%
+% A bilinear interpolation.
+%
+
+\colorlet{lower left}{white}%
+\colorlet{lower right}{white}%
+\colorlet{upper left}{white}%
+\colorlet{upper right}{white}%
+
+\pgfdeclarefunctionalshading[lower left,lower right,upper left,upper right]{bilinear interpolation}
+{\pgfpointorigin}
+{\pgfpoint{100bp}{100bp}}
+{
+ \pgfshadecolortorgb{lower left}{\pgf@lib@shadings@ll}\pgfshadecolortorgb{lower right}{\pgf@lib@shadings@lr}
+ \pgfshadecolortorgb{upper right}{\pgf@lib@shadings@ur}\pgfshadecolortorgb{upper left}{\pgf@lib@shadings@ul}
+}{
+ 25 sub 50 div exch 25 sub 50 div 2 copy % Calculate y/100 x/100.
+% 100 div exch 100 div 2 copy % Calculate y/100 x/100.
+ neg 1 add exch neg 1 add % Calculate 1-y/100 1-x/100.
+ 3 1 roll 2 copy exch 5 2 roll 6 copy 6 copy % Set up stack.
+ \pgf@lib@shadings@llred mul exch \pgf@lib@shadings@lrred mul add mul % Process red component.
+ 4 1 roll
+ \pgf@lib@shadings@urred mul exch \pgf@lib@shadings@ulred mul add mul
+ add
+ 13 1 roll
+ \pgf@lib@shadings@llgreen mul exch \pgf@lib@shadings@lrgreen mul add mul % Process green component.
+ 4 1 roll
+ \pgf@lib@shadings@urgreen mul exch \pgf@lib@shadings@ulgreen mul add mul
+ add
+ 7 1 roll
+ \pgf@lib@shadings@llblue mul exch \pgf@lib@shadings@lrblue mul add mul % Process blue component.
+ 4 1 roll
+ \pgf@lib@shadings@urblue mul exch \pgf@lib@shadings@ulblue mul add mul
+ add
+ \ifpgfshadingmodelcmyk
+ \pgffuncshadingrgbtocmyk
+ \fi
+ \ifpgfshadingmodelgray
+ \pgffuncshadingrgbtogray
+ \fi
+}%
+
+
+%
+% A Mandelbrot set shading. Just for fun...
+%
+
+\pgfdeclarefunctionalshading[black]{Mandelbrot set}
+{\pgfpoint{-50bp}{-50bp}}
+{\pgfpoint{50bp}{50bp}}{}
+{
+ 12.5 div exch 12.5 div exch
+ 1 index 1 index
+ % Stack: c_r c_i z_r z_i
+ % Formula: z' = z^2 + c = (z_r + i z_i)^2 + c_r + i c_i
+ % = (z_r^2 - z_i^2 + c_r) + i (2 z_r z_i + c_i)
+ %
+ % First iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Second iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Third iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Fourth iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Check for break (to avoid too large numbers)
+ 1 index dup mul 1 index dup mul add
+ 4 lt {
+ % Fifth iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Sixth iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Seventh iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Check for break (to avoid too large numbers)
+ 1 index dup mul 1 index dup mul add
+ 4 lt {
+ % Eighth iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Ninth iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ % Tenth iteration
+ % 1. Compute z_r^2 -z_i^2 + c_r
+ 1 index dup mul % z_r^2
+ 1 index dup mul % z_i^2
+ sub % z_r^2 - z_i^2
+ 4 index add % z_r^2 -z_i^2 + c_r
+ % 2. Compute 2 z_r z_i + c_i
+ 3 1 roll
+ mul 2 mul % 2 z_r z_i
+ 2 index add % 2 z_r z_i + c_i
+ } { pop pop 1000.0 1000.0 } ifelse
+ } { pop pop 1000.0 1000.0 } ifelse
+ % Compute distance
+ dup mul exch
+ dup mul
+ add sqrt
+ dup 4 1 roll
+ 2 gt { pop pop 2.0 exch div 1.0 exch sub dup dup} {pop pop pop 0.0 0.0 0.0} ifelse
+ \ifpgfshadingmodelcmyk
+ \pgffuncshadingrgbtocmyk
+ \fi
+ \ifpgfshadingmodelgray
+ \pgffuncshadingrgbtogray
+ \fi
+}%
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibrarysnakes.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibrarysnakes.code.tex
new file mode 100644
index 0000000000..c45140535e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibrarysnakes.code.tex
@@ -0,0 +1,16 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarysnakes.code.tex}
+
+\pgfwarning{Snakes have been superseded by decorations. Use the decoration libraries instead of the snakes library}%
+
+\usepgflibrary{decorations.pathmorphing,decorations.pathreplacing,decorations.shapes}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibrarysvg.path.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibrarysvg.path.code.tex
new file mode 100644
index 0000000000..e802ca778e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibrarysvg.path.code.tex
@@ -0,0 +1,829 @@
+% Copyright 2019 by Till Tantau
+% Copyright 2019 by Jonathan P. Spratte
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarysvg.path.code.tex}
+
+
+\usepgfmodule{parser}%
+
+
+% Scan an SVG-Path
+%
+% #1 = the path
+%
+% Description:
+%
+% This command takes a path in the compressed SVG-syntax. It then
+% issues a sequences of appropriate \pgfpath commands for this
+% path. For a description of the compressed svg path syntax, see a
+% book on svg.
+%
+% The notion of a pixel used by svg makes no sense in pgf (actually
+% it does not really make sense in svg either, but never mind), and
+% instead of pixels "pt" is used as the basic unit. Use coordinate
+% transformation to change this.
+%
+% Example:
+%
+% \pgfpathsvg{M10 20 L 30-20 0 1}
+%
+% % this has the same effect as
+%
+% \pgfpathmoveto{\pgfpoint{10pt}{20pt}}
+% \pgfpathlineto{\pgfpint{30pt}{-20pt}}
+% \pgfpathlineto{\pgfpint{0pt}{1pt}}
+%
+
+\def\pgfpathsvg#1{%
+ \let\pgf@lib@svg@finish@prev\relax%
+ {%
+ \pgftransforminvert%
+ \pgf@process{\pgfpointtransformed{\pgfqpoint{\pgf@path@lastx}{\pgf@path@lasty}}}%
+ }%
+ \pgf@lib@svg@last@x\pgf@x%
+ \pgf@lib@svg@last@y\pgf@y%
+ \let\pgf@lib@svg@num=\pgfutil@empty%
+ \let\pgf@lib@svg@exp=\pgfutil@empty%
+ \pgfparserparse{svgpath}#1"%
+}%
+
+
+
+\newdimen\pgf@lib@svg@last@x
+\newdimen\pgf@lib@svg@last@y
+\newdimen\pgf@lib@svg@last@c@x
+\newdimen\pgf@lib@svg@last@c@y
+
+\newcount\pgf@lib@svg@count
+\newcount\pgf@lib@svg@max@num
+
+\newif\pgf@lib@svg@relative
+
+
+
+% For the smooth commands (S, s, T, t) we need to keep track of the
+% previous control points. This is done in the following two
+% variables. If they are empty, there was no previous control point of
+% the desired kind, in which case the specification prescribes that
+% the start point is used.
+
+\def\pgf@lib@svg@clear@bezier@quad{%
+ \let\pgf@lib@svg@bezier@last=\pgfutil@empty
+ \let\pgf@lib@svg@quad@last=\pgfutil@empty
+}%
+\pgf@lib@svg@clear@bezier@quad
+
+%
+% Here comes the DFA:
+%
+
+% Handle a moveto:
+
+\pgfparserdef{svgpath}{all}{the letter M}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@moveto}%
+}%
+
+\def\pgf@lib@svg@moveto{%
+ \pgf@lib@svg@clear@bezier@quad%
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{0}pt%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{1}pt%
+ \pgfpathmoveto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@lineto}%
+}%
+
+
+% Handle a relative moveto:
+
+\pgfparserdef{svgpath}{all}{the letter m}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@moveto@rel}%
+}%
+
+\def\pgf@lib@svg@moveto@rel{%
+ \pgf@lib@svg@clear@bezier@quad%
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{0}pt%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{1}pt%
+ \pgfpathmoveto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@lineto@rel}%
+}%
+
+
+% Handle a lineto:
+
+\pgfparserdef{svgpath}{all}{the letter L}
+{%
+ \pgf@lib@svg@finish@prev%
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@lineto}%
+}%
+
+\def\pgf@lib@svg@lineto{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ \pgf@lib@svg@clear@bezier@quad%
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{0}pt%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{1}pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@lineto}%
+ \fi
+}%
+
+
+% Handle a relative lineto:
+
+\pgfparserdef{svgpath}{all}{the letter l}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@lineto@rel}%
+}%
+
+\def\pgf@lib@svg@lineto@rel{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ \pgf@lib@svg@clear@bezier@quad%
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{0}pt%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{1}pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@lineto@rel}%
+ \fi
+}%
+
+
+% Handle a closepath:
+
+\pgfparserdef{svgpath}{all}{the letter Z}
+{%
+ \pgf@lib@svg@closepath
+}%
+
+\pgfparserdef{svgpath}{all}{the letter z}
+{%
+ \pgf@lib@svg@closepath
+}%
+
+\def\pgf@lib@svg@closepath{%
+ \pgf@lib@svg@finish@prev
+ \pgfpathclose
+ \let\pgf@lib@svg@finish@prev=\relax
+ \pgf@lib@svg@clear@bezier@quad%
+ \pgfparserswitch{initial}%
+}%
+
+
+% Ignore spaces if no other rules says differently:
+
+\pgfparserdef{svgpath}{all}{blank space \space}{}%
+
+
+
+
+% Handle a horizontal lineto:
+
+\pgfparserdef{svgpath}{all}{the letter H}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@hlineto}%
+}%
+
+\def\pgf@lib@svg@hlineto{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ \pgf@lib@svg@clear@bezier@quad%
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{0}pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@hlineto}%
+ \fi
+}%
+
+\pgfparserdef{svgpath}{all}{the letter h}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@hlineto@rel}%
+}%
+
+\def\pgf@lib@svg@hlineto@rel{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ \pgf@lib@svg@clear@bezier@quad%
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{0}pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@hlineto@rel}%
+ \fi
+}%
+
+
+% Handle a horizontal lineto:
+
+\pgfparserdef{svgpath}{all}{the letter V}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@vlineto}%
+}%
+
+\def\pgf@lib@svg@vlineto{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ \pgf@lib@svg@clear@bezier@quad%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{0}pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@vlineto}%
+ \fi
+}%
+
+\pgfparserdef{svgpath}{all}{the letter v}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@vlineto@rel}%
+}%
+
+\def\pgf@lib@svg@vlineto@rel{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ \pgf@lib@svg@clear@bezier@quad%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{0}pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \pgf@lib@svg@read@nums{1}{\pgf@lib@svg@vlineto@rel}%
+ \fi
+}%
+
+
+
+
+% Handle a Bezier curve:
+
+\pgfparserdef{svgpath}{all}{the letter C}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{6}{\pgf@lib@svg@curveto}%
+}%
+
+\def\pgf@lib@svg@curveto{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Clear quadratic last point and save new last control point:
+ \let\pgf@lib@svg@quad@last=\pgfutil@empty%
+ \edef\pgf@lib@svg@bezier@last{%
+ \noexpand\pgfqpoint{\pgf@lib@svg@get@num{2}pt}{\pgf@lib@svg@get@num{3}pt}}%
+ % Draw curve
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{4}pt%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{5}pt%
+ \pgfpathcurveto
+ {\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}%
+ {\pgfqpoint{\pgf@lib@svg@get@num{2}pt}{\pgf@lib@svg@get@num{3}pt}}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ % Go on
+ \pgf@lib@svg@read@nums{6}{\pgf@lib@svg@curveto}%
+ \fi
+}%
+
+
+\pgfparserdef{svgpath}{all}{the letter c}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{6}{\pgf@lib@svg@curveto@rel}%
+}%
+
+\def\pgf@lib@svg@curveto@rel{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Clear quadratic last point and save new last control point:
+ \let\pgf@lib@svg@quad@last=\pgfutil@empty%
+ \pgf@process{\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{2}pt}{\pgf@lib@svg@get@num{3}pt}}}%
+ \edef\pgf@lib@svg@bezier@last{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ % Draw curve
+ \pgfpathcurveto
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}}%
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{2}pt}{\pgf@lib@svg@get@num{3}pt}}}%
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{4}pt}{\pgf@lib@svg@get@num{5}pt}}}%
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{4}pt%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{5}pt%
+ \pgf@lib@svg@read@nums{6}{\pgf@lib@svg@curveto@rel}%
+ \fi
+}%
+
+
+
+
+
+\pgfparserdef{svgpath}{all}{the letter S}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@curveto@smooth}%
+}%
+
+\def\pgf@lib@svg@curveto@smooth{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Draw curve
+ % Compute first control point
+ \ifx\pgf@lib@svg@bezier@last\pgfutil@empty%
+ \def\pgf@lib@svg@first@cp{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \else
+ \def\pgf@lib@svg@first@cp{%
+ \pgfpointadd
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ {\pgfpointdiff
+ {\pgf@lib@svg@bezier@last}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ }%
+ }%
+ \fi
+ \pgfpathcurveto
+ {\pgf@lib@svg@first@cp}%
+ {\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}%
+ {\pgfqpoint{\pgf@lib@svg@get@num{2}pt}{\pgf@lib@svg@get@num{3}pt}}%
+ % Clear quadratic last point and save new last control point:
+ \let\pgf@lib@svg@quad@last=\pgfutil@empty%
+ \edef\pgf@lib@svg@bezier@last{%
+ \noexpand\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}%
+ % Update
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{2}pt%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{3}pt%
+ % Go on
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@curveto@smooth}%
+ \fi
+}%
+
+
+\pgfparserdef{svgpath}{all}{the letter s}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@curveto@rel@smooth}%
+}%
+
+\def\pgf@lib@svg@curveto@rel@smooth{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Draw curve
+ % Compute first control point
+ \ifx\pgf@lib@svg@bezier@last\pgfutil@empty%
+ \def\pgf@lib@svg@first@cp{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ \else
+ \def\pgf@lib@svg@first@cp{%
+ \pgfpointadd
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ {\pgfpointdiff
+ {\pgf@lib@svg@bezier@last}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ }%
+ }%
+ \fi
+ \pgfpathcurveto
+ {\pgf@lib@svg@first@cp}%
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}}%
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{2}pt}{\pgf@lib@svg@get@num{3}pt}}}%
+ % Clear quadratic last point and save new last control point:
+ \let\pgf@lib@svg@quad@last=\pgfutil@empty%
+ \pgf@process{\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}}%
+ \edef\pgf@lib@svg@bezier@last{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ % update
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{2}pt%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{3}pt%
+ % Go on
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@curveto@rel@smooth}%
+ \fi
+}%
+
+
+
+
+% Handle a quadratic curve:
+
+\pgfparserdef{svgpath}{all}{the letter Q}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@quad@curveto}%
+}%
+
+\def\pgf@lib@svg@quad@curveto{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Clear bezier last point and save new last control point:
+ \let\pgf@lib@svg@bezier@last=\pgfutil@empty%
+ \edef\pgf@lib@svg@quad@last{%
+ \noexpand\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}%
+ % Draw curve
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{2}pt%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{3}pt%
+ \pgfpathquadraticcurveto
+ {\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ % Go on
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@quad@curveto}%
+ \fi
+}%
+
+
+\pgfparserdef{svgpath}{all}{the letter q}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@quad@curveto@rel}%
+}%
+
+\def\pgf@lib@svg@quad@curveto@rel{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Clear quadratic last point and save new last control point:
+ \let\pgf@lib@svg@bezier@last=\pgfutil@empty%
+ \pgf@process{\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}}%
+ \edef\pgf@lib@svg@quad@last{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ % Draw curve
+ \pgfpathquadraticcurveto
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}}%
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{2}pt}{\pgf@lib@svg@get@num{3}pt}}}%
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{2}pt%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{3}pt%
+ \pgf@lib@svg@read@nums{4}{\pgf@lib@svg@quad@curveto@rel}%
+ \fi
+}%
+
+
+
+
+\pgfparserdef{svgpath}{all}{the letter T}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@quad@curveto@smooth}%
+}%
+
+\def\pgf@lib@svg@quad@curveto@smooth{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Draw curve
+ % Compute first control point
+ \pgf@process{%
+ \ifx\pgf@lib@svg@quad@last\pgfutil@empty%
+ \pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}%
+ \else
+ \pgfpointadd
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ {\pgfpointdiff
+ {\pgf@lib@svg@quad@last}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ }%
+ \fi
+ }%
+ \edef\pgf@lib@svg@first@cp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfpathquadraticcurveto
+ {\pgf@lib@svg@first@cp}%
+ {\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}%
+ % Clear quadratic last point and save new last control point:
+ \let\pgf@lib@svg@bezier@last=\pgfutil@empty%
+ \let\pgf@lib@svg@quad@last=\pgf@lib@svg@first@cp%
+ % Update
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{0}pt%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{1}pt%
+ % Go on
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@quad@curveto@smooth}%
+ \fi
+}%
+
+
+\pgfparserdef{svgpath}{all}{the letter t}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@quad@curveto@rel@smooth}%
+}%
+
+\def\pgf@lib@svg@quad@curveto@rel@smooth{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Draw curve
+ % Compute first control point
+ \pgf@process{%
+ \ifx\pgf@lib@svg@quad@last\pgfutil@empty%
+ \pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}%
+ \else
+ \pgfpointadd
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ {\pgfpointdiff
+ {\pgf@lib@svg@quad@last}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ }%
+ \fi
+ }%
+ \edef\pgf@lib@svg@first@cp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgfpathquadraticcurveto
+ {\pgf@lib@svg@first@cp}%
+ {\pgfpointadd{\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}{\pgfqpoint{\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}}}%
+ % Clear quadratic last point and save new last control point:
+ \let\pgf@lib@svg@bezier@last=\pgfutil@empty%
+ \let\pgf@lib@svg@quad@last=\pgf@lib@svg@first@cp%
+ % update
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{0}pt%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{1}pt%
+ % Go on
+ \pgf@lib@svg@read@nums{2}{\pgf@lib@svg@quad@curveto@rel@smooth}%
+ \fi
+}%
+
+
+
+% Handle an arcto:
+
+\pgfparserdef{svgpath}{all}{the letter A}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{7}{\pgf@lib@svg@arcto}%
+}%
+
+\def\pgf@lib@svg@arcto{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Clear bezier last point and save new last control point:
+ \pgf@lib@svg@clear@bezier@quad%
+ % Draw curve
+ \pgf@lib@svg@last@x=\pgf@lib@svg@get@num{5}pt%
+ \pgf@lib@svg@last@y=\pgf@lib@svg@get@num{6}pt%
+ \pgfpatharcto
+ {\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}%
+ {\pgf@lib@svg@get@num{2}}%
+ {\pgf@lib@svg@get@num{3}}%
+ {\pgf@lib@svg@get@num{4}}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ % Go on
+ \pgf@lib@svg@read@nums{7}{\pgf@lib@svg@arcto}%
+ \fi
+}%
+
+\pgfparserdef{svgpath}{all}{the letter a}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgf@lib@svg@read@nums{7}{\pgf@lib@svg@arcto@rel}%
+}%
+
+\def\pgf@lib@svg@arcto@rel{%
+ \ifnum\pgf@lib@svg@count=0\relax% nothing read
+ \else%
+ % Clear bezier last point and save new last control point:
+ \pgf@lib@svg@clear@bezier@quad%
+ % Draw curve
+ \advance\pgf@lib@svg@last@x by\pgf@lib@svg@get@num{5}pt%
+ \advance\pgf@lib@svg@last@y by\pgf@lib@svg@get@num{6}pt%
+ \pgfpatharcto
+ {\pgf@lib@svg@get@num{0}pt}{\pgf@lib@svg@get@num{1}pt}%
+ {\pgf@lib@svg@get@num{2}}%
+ {\pgf@lib@svg@get@num{3}}%
+ {\pgf@lib@svg@get@num{4}}%
+ {\pgfqpoint{\pgf@lib@svg@last@x}{\pgf@lib@svg@last@y}}%
+ % Go on
+ \pgf@lib@svg@read@nums{7}{\pgf@lib@svg@arcto@rel}%
+ \fi
+}%
+
+
+
+
+
+% Handle to end of the world
+
+\pgfparserdef{svgpath}{all}{the character "}
+{%
+ \pgf@lib@svg@finish@prev
+ \pgfparserswitch{final}%
+}%
+
+
+
+
+% Handle spacers for numbers
+
+\def\pgf@lib@svg@read@nums#1#2{% get #1 number symbols, then do #2
+ \pgf@lib@svg@count=0\relax
+ \pgf@lib@svg@max@num=#1\relax
+ \pgfparserswitch{num}%
+ \def\pgf@lib@svg@finish@prev{%
+ \ifx\pgf@lib@svg@num\pgfutil@empty%
+ \else%
+ \ifx\pgf@lib@svg@exp\pgfutil@empty
+ \else
+ \pgfmathfloatparsenumber{\pgf@lib@svg@num e\pgf@lib@svg@exp}%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \let\pgf@lib@svg@num=\pgfmathresult
+ \fi
+ \expandafter\let\csname pgf@lib@svg@num@\the\pgf@lib@svg@count\endcsname=\pgf@lib@svg@num
+ \advance\pgf@lib@svg@count by1\relax%
+ \let\pgf@lib@svg@num=\pgfutil@empty%
+ \let\pgf@lib@svg@exp=\pgfutil@empty%
+ \fi
+ #2%
+ }%
+}%
+
+\def\pgf@lib@svg@get@num#1{\csname pgf@lib@svg@num@#1\endcsname}%
+
+
+\pgfparserdef{svgpath}{num}{the character ,}
+{%
+ \pgf@lib@svg@handle@spacer
+}%
+\pgfparserlet{svgpath}{after.}{the character ,}[num]{the character ,}
+\pgfparserlet{svgpath}{exp},[num],
+\pgfparserlet{svgpath}{exp sign},[num],
+
+\pgfparserdef{svgpath}{num}{\meaning\pgfutil@sptoken}
+{%
+ \pgf@lib@svg@handle@spacer
+}%
+\pgfparserlet{svgpath}{after.}{blank space}[num]{blank space}
+\pgfparserlet{svgpath}{exp}{blank space},
+\pgfparserlet{svgpath}{exp sign}{blank space},
+
+\pgfparserdef{svgpath}{num}{the character -}
+{%
+ \pgf@lib@svg@handle@spacer
+ \def\pgf@lib@svg@num{-}%
+}%
+\pgfparserlet{svgpath}{after.}{the character -}[num]{the character -}
+\pgfparserlet{svgpath}{exp}-[num]-
+\pgfparserdef{svgpath}{num}{the character +}
+{%
+ \pgf@lib@svg@handle@spacer
+ \def\pgf@lib@svg@num{+}%
+}
+\pgfparserlet{svgpath}{after.}{the character +}[num]{the character +}
+\pgfparserlet{svgpath}{exp}+[num]+
+
+\def\pgf@lib@svg@handle@spacer{%
+ \ifx\pgf@lib@svg@num\pgfutil@empty%
+ % ignore
+ \else
+ \ifx\pgf@lib@svg@exp\pgfutil@empty
+ \else
+ \pgfmathfloatparsenumber{\pgf@lib@svg@num e\pgf@lib@svg@exp}%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \let\pgf@lib@svg@num=\pgfmathresult
+ \fi
+ \expandafter\let\csname pgf@lib@svg@num@\the\pgf@lib@svg@count\endcsname=\pgf@lib@svg@num
+ \advance\pgf@lib@svg@count by1\relax%
+ \ifnum\pgf@lib@svg@count=\pgf@lib@svg@max@num\relax%
+ \pgf@lib@svg@finish@prev%
+ \fi
+ \let\pgf@lib@svg@num=\pgfutil@empty%
+ \let\pgf@lib@svg@exp=\pgfutil@empty%
+ \pgfparserswitch{num}%
+ \fi
+}%
+
+
+% Handle digits
+
+\pgfparserdef{svgpath}{num}e
+ {%
+ \pgfparserswitch{exp sign}%
+ \let\pgf@lib@svg@exp=\pgfutil@empty
+ }
+\pgfparserlet{svgpath}{after.}e[num]e
+\pgfparserdef{svgpath}{exp sign}-
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp-}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}+
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp+}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}0
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp0}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}1
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp1}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}2
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp2}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}3
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp3}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}4
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp4}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}5
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp5}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}6
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp6}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}7
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp7}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}8
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp8}%
+ \pgfparserswitch{exp}%
+ }
+\pgfparserdef{svgpath}{exp sign}9
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp9}%
+ \pgfparserswitch{exp}%
+ }
+
+\pgfparserdef{svgpath}{exp}0
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp0}%
+ }
+\pgfparserdef{svgpath}{exp}1
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp1}%
+ }
+\pgfparserdef{svgpath}{exp}2
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp2}%
+ }
+\pgfparserdef{svgpath}{exp}3
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp3}%
+ }
+\pgfparserdef{svgpath}{exp}4
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp4}%
+ }
+\pgfparserdef{svgpath}{exp}5
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp5}%
+ }
+\pgfparserdef{svgpath}{exp}6
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp6}%
+ }
+\pgfparserdef{svgpath}{exp}7
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp7}%
+ }
+\pgfparserdef{svgpath}{exp}8
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp8}%
+ }
+\pgfparserdef{svgpath}{exp}9
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@exp\expandafter{\pgf@lib@svg@exp9}%
+ }
+
+\pgfparserdef{svgpath}{num}{the character .}
+ {%
+ \expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num.}%
+ \pgfparserswitch{after.}%
+ }%
+\pgfparserdef{svgpath}{after.}{the character .}
+ {%
+ \pgf@lib@svg@handle@spacer
+ \def\pgf@lib@svg@num{.}%
+ \pgfparserswitch{after.}%
+ }%
+\pgfparserlet{svgpath}{exp}{the character .}[after.]{the character .}
+
+\pgfparserdef{svgpath}{all}{the character 0}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num0}}%
+
+\pgfparserdef{svgpath}{all}{the character 1}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num1}}%
+
+\pgfparserdef{svgpath}{all}{the character 2}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num2}}%
+
+\pgfparserdef{svgpath}{all}{the character 3}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num3}}%
+
+\pgfparserdef{svgpath}{all}{the character 4}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num4}}%
+
+\pgfparserdef{svgpath}{all}{the character 5}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num5}}%
+
+\pgfparserdef{svgpath}{all}{the character 6}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num6}}%
+
+\pgfparserdef{svgpath}{all}{the character 7}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num7}}%
+
+\pgfparserdef{svgpath}{all}{the character 8}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num8}}%
+
+\pgfparserdef{svgpath}{all}{the character 9}
+{\expandafter\def\expandafter\pgf@lib@svg@num\expandafter{\pgf@lib@svg@num9}}%
diff --git a/graphics/pgf/base/tex/generic/libraries/pgflibrarytimelines.code.tex b/graphics/pgf/base/tex/generic/libraries/pgflibrarytimelines.code.tex
new file mode 100644
index 0000000000..0e9afce0f2
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/pgflibrarytimelines.code.tex
@@ -0,0 +1,197 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibrarytimelines.code.tex}
+
+
+% We need the animation module:
+
+\usepgfmodule{animations}%
+
+
+% Starts a fixed timeline
+%
+% Description:
+%
+% A (fixed) timeline defines for a specific number of seconds how a
+% different objects are animated. In contrast to a dynamic timeline,
+% the animation must be fixed beforehand, that is, in a fixed timeline
+% you can specify things like "be there after 2s and there after 4s
+% and be red after 5s" but not "be there after that other animation
+% has finished and then stay there until another animation has
+% finished or something has been clicked". Note that while a fixed
+% timeline describes a fixed sequence of animations, the starting
+% point of the timeline may depend for instance on when some button is
+% clicked; only when the timeline's animation gets started there is
+% nothing dynamic about it till its end (a timeline may be ended
+% prematurely, however).
+%
+% This command allows you to start a timeline. Once the timeline has
+% been started, you can call the following macro repeatedly:
+%
+% \pgftimelineentry{time}{object}{attribute}{value}
+%
+% The time is some time when the given attribute should have the given
+% value. The important thing is that the entries need not come in any
+% specific order; it is the job of the timeline library to sort them
+% into a sensible order.
+%
+% At the end of the timeline, you will have specified for a whole
+% bunch of objects and attributes their values at certain time
+% points. The macro \pgftimelineend will now call \pgfanimateattribute
+% for all attributes and objects mentioned in the timeline.
+%
+%
+% Internally, pgf keeps track of all objects in a timeline and all
+% attributes and sorts the times using a simple insertion sort (which
+% will be fastest when the times are given in increasing order as
+% happens most of the time).
+
+\def\pgftimelinebegin{%
+ \pgf@timeline@todo@saved=\pgf@timeline@todo%
+ \begingroup%
+ \advance\pgf@timeline@depth by1\relax%
+ \pgf@timeline@todo{}%
+}%
+
+\newcount\pgf@timeline@depth
+\newtoks\pgf@timeline@todo
+\newtoks\pgf@timeline@todo@saved
+
+
+% Ends a timeline
+%
+% Description:
+%
+% This command will scan \pgfanimateattribute for the objects and
+% attributes mentioned in the timeline.
+
+\def\pgftimelineend{%
+ \the\pgf@timeline@todo%
+ \endgroup%
+ \global\pgf@timeline@todo=\pgf@timeline@todo@saved%
+}%
+
+
+% Adds an entry to a timeline
+%
+% #1 = a time (evaluated using \pgfparsetime)
+% #2 = an object (a "whom" in the sense of pgfmoduleanimations, will
+% be expanded)
+% #3 = an attribute (in the sense of pgfmoduleanimations, will be expanded)
+% #4 = a value
+%
+% Description:
+%
+% Adds a new entry to the timeline. For a fixed #1, several calls to
+% this macro allow you to specify a key frame by specifying the
+% different values of the different attributes of the different
+% objects in the key frame.
+
+\def\pgftimelineentry#1#2#3#4{%
+ \begingroup%
+ \pgfparsetime{#1}%
+ \edef\pgf@timeline@whom{#2}%
+ \edef\pgf@timeline@attr{#3}%
+ \expandafter\let\expandafter\pgf@timeline@entry\csname pgf@tl@\pgf@timeline@whom @\pgf@timeline@attr @\the\pgf@timeline@depth\endcsname%
+ \ifx\pgf@timeline@entry\relax%
+ \edef\pgf@timeline@entry{\noexpand\pgf@timeline@setup{\pgf@timeline@whom}{\pgf@timeline@attr}}%
+ \fi%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@timeline@entry\expandafter\expandafter\expandafter%
+ {\expandafter\pgf@timeline@entry\expandafter\pgf@timeline@doentry\expandafter{\pgftimeresult}{#4}}%
+ \expandafter\global\expandafter\let\csname pgf@tl@\pgf@timeline@whom @\pgf@timeline@attr @\the\pgf@timeline@depth\endcsname\pgf@timeline@entry%
+ \global\pgf@timeline@todo\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgf@timeline@todo\expandafter\pgf@timeline@handle\csname pgf@tl@\pgf@timeline@whom @\pgf@timeline@attr @\the\pgf@timeline@depth\endcsname}%
+ \endgroup%
+}%
+
+
+\newtoks\pgf@timeline@sort@toks
+\countdef\pgf@timeline@sort@count=0\relax%
+\countdef\pgf@timeline@count@down=1\relax%
+\countdef\pgf@timeline@count@down@next=2\relax%
+
+% Handles one entry in a timeline
+
+\def\pgf@timeline@handle#1{%
+ \ifx#1\relax%
+ \else%
+ % Do an inserting sort. The time is kept in the dimension registers
+ % 1 to n, the value in the token registers 1 to n.
+ {%
+ \pgf@timeline@sort@count=1\relax%
+ #1% will start a group
+ % Now we collect the toks:
+ \pgf@timeline@count@down=1\relax%
+ \pgf@timeline@sort@toks{}%
+ \pgfutil@loop%
+ \ifnum\pgf@timeline@count@down<\pgf@timeline@sort@count\relax%
+ \edef\pgf@temp{\the\pgf@timeline@sort@toks\noexpand\pgf@timeline@donow{\the\dimen\pgf@timeline@count@down}{\the\toks\pgf@timeline@count@down}}%
+ \pgf@timeline@sort@toks\expandafter{\pgf@temp}%
+ \advance\pgf@timeline@count@down by1\relax%
+ \pgfutil@repeat%
+ % Do computations now
+ \pgf@timeline@compute@duration%
+ %
+ \edef\pgf@temp{\noexpand\pgf@timeline@call@attribute{\pgf@timeline@whom}{\pgf@timeline@attr}{\the\pgf@timeline@sort@toks}}
+ \expandafter%
+ \endgroup%
+ \pgf@temp%
+ }%
+ \global\let#1\relax% cleanup
+ \fi%
+}%
+
+\def\pgf@timeline@compute@duration{%
+ \advance\pgf@timeline@sort@count by-1\relax%
+ \pgfmathparse{\the\dimen\pgf@timeline@sort@count}%
+ \global\let\pgf@timeline@duration\pgfmathresult%
+}%
+
+
+\def\pgf@timeline@setup#1#2{%
+ \def\pgf@timeline@whom{#1}%
+ \def\pgf@timeline@attr{#2}%
+ \begingroup%
+}%
+
+\def\pgf@timeline@doentry#1#2{%
+ \dimen\pgf@timeline@sort@count=#1pt\relax%
+ \toks\pgf@timeline@sort@count{#2}%
+ \pgf@timeline@count@down\pgf@timeline@sort@count\relax%
+ \pgfutil@loop%
+ \ifnum\pgf@timeline@count@down>1\relax%
+ \pgf@timeline@count@down@next\pgf@timeline@count@down%
+ \advance\pgf@timeline@count@down@next by-1\relax%
+ \ifdim\dimen\pgf@timeline@count@down<\dimen\pgf@timeline@count@down@next\relax%
+ % Swap:
+ \toks0=\toks\pgf@timeline@count@down%
+ \dimen0=\dimen\pgf@timeline@count@down%
+ \toks\pgf@timeline@count@down=\toks\pgf@timeline@count@down@next%
+ \dimen\pgf@timeline@count@down=\dimen\pgf@timeline@count@down@next%
+ \toks\pgf@timeline@count@down@next=\toks0\relax%
+ \dimen\pgf@timeline@count@down@next=\dimen0\relax%
+ \pgf@timeline@count@down\pgf@timeline@count@down@next\relax%
+ \else%
+ \pgf@timeline@count@down1\relax%
+ \fi%
+ \pgfutil@repeat%
+ \advance\pgf@timeline@sort@count by1\relax%
+}%
+
+
+\def\pgf@timeline@call@attribute#1#2#3{%
+ \pgfanimateattributecode{#2}{\pgfkeys{/pgf/animation/whom={#1},/pgf/animation/duration=\pgf@timeline@duration}#3}%
+}%
+
+\def\pgf@timeline@donow#1#2{%
+ \pgfkeys{/pgf/animation/key time={#1/\pgf@timeline@duration}}%
+ \pgfkeys{/pgf/animation/value={#2}}%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.IEC.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.IEC.code.tex
new file mode 100644
index 0000000000..0d25e307e4
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.IEC.code.tex
@@ -0,0 +1,679 @@
+% Copyright 2018 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+%
+% Resistor shape based on a zig-zag-line
+%
+
+\pgfdeclareshape{var resistor IEC}
+{%
+ \inheritsavedanchors[from=rectangle ee]%
+ \inheritanchor[from=rectangle ee]{center}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+ \inheritanchorborder[from=rectangle ee]%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ % Middle line
+ \pgf@yc=.5\pgf@ya
+ \advance\pgf@yc by.5\pgf@yb
+ % Height
+ \pgf@xc=-.5\pgf@ya
+ \advance\pgf@xc by.5\pgf@yb
+ % Start point
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yc}}
+ % Lines
+ \advance\pgf@xb by.1pt%
+ \pgfutil@loop%
+ \advance\pgf@xa by4\pgf@xc\relax%
+ \ifdim\pgf@xa<\pgf@xb%
+ \advance\pgf@xa by-3\pgf@xc%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}%
+ \advance\pgf@xa by2\pgf@xc%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ \advance\pgf@xa by\pgf@xc%
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yc}}%
+ \pgfutil@repeat%
+ \advance\pgf@xb by-.1pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yc}}%
+ }%
+}%
+
+
+
+%
+% Inductor shape based on a bumpy line
+%
+
+\pgfdeclareshape{inductor IEC}
+{%
+ \savedanchor\northeast{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by .5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@y=\pgf@ya%
+ \advance\pgf@y by\pgf@yb%
+ }%
+ \savedanchor\southwest{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=-\pgf@xa%
+ \advance\pgf@x by -.5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgf@y=-\pgf@ya%
+ }%
+
+ \anchor{center}{\pgfpointorigin}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+
+ \anchorborder{%
+ \ifdim\pgf@y<0pt%
+ % tricky... simpilfy to the origin...
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\southwest}%
+ \advance\pgf@y by-0.5pt%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\pgfqpoint{-\pgf@xa}{-\pgf@ya}}}%
+ \else%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\northeast}}%
+ \fi%
+ }%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xa=-\pgf@x \pgf@ya=0pt
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ % Height
+ \pgf@xc=\pgf@yb%
+ % Start point
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{0pt}}
+ % Lines
+ \advance\pgf@xb by.1pt%
+ \pgfutil@loop%
+ \advance\pgf@xa by2\pgf@xc\relax%
+ \ifdim\pgf@xa<\pgf@xb%
+ \pgfpatharc{180}{0}{\pgf@xc}%
+ \pgfutil@repeat%
+ \advance\pgf@xb by-.1pt%
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{0pt}}%
+ }%
+}%
+
+
+
+
+%
+% Simple capacitor, consisting of two parallel lines
+%
+
+\pgfdeclareshape{capacitor IEC}
+{%
+ \inheritsavedanchors[from=rectangle ee]%
+ \inheritanchor[from=rectangle ee]{center}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+ \inheritanchorborder[from=rectangle ee]%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }%
+}%
+
+
+
+
+%
+% Simple ground, consisting of three lines, getting smaller
+%
+
+\pgfdeclareshape{ground IEC}
+{%
+ \inheritsavedanchors[from=rectangle ee]%
+ \inheritanchor[from=rectangle ee]{center}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+ \inheritanchorborder[from=rectangle ee]%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ % First line, simple
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ % Advance to middle
+ \pgfmathsetlength\pgf@xa{.5\pgf@xa+.5\pgf@xb}
+ % Make smaller
+ \pgfmathsetlength\pgf@yc{.16666\pgf@yb-.16666\pgf@ya}
+ \advance\pgf@ya by\pgf@yc
+ \advance\pgf@yb by-\pgf@yc
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ % Make even smaller
+ \advance\pgf@ya by\pgf@yc
+ \advance\pgf@yb by-\pgf@yc
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }%
+}%
+
+
+
+%
+% Battery, consisting of two parallel lines, one smaller than
+% the other
+%
+
+\pgfdeclareshape{battery IEC}
+{%
+ \inheritsavedanchors[from=rectangle ee]%
+ \inheritanchor[from=rectangle ee]{center}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+ \inheritanchorborder[from=rectangle ee]%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ % First line, simple
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ % Make smaller
+ \pgfmathsetlength\pgf@yc{.25\pgf@yb-.25\pgf@ya}
+ \advance\pgf@ya by\pgf@yc
+ \advance\pgf@yb by-\pgf@yc
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }%
+}%
+
+
+%
+% Special diodes
+%
+
+
+\pgfdeclareshape{breakdown diode IEC}
+{%
+ \inheritsavedanchors[from=rectangle ee]%
+ \inheritanchor[from=rectangle ee]{center}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+ \inheritanchorborder[from=rectangle ee]%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgf@xc=.5\pgf@xa \advance\pgf@xc by.5\pgf@xb
+ \pgf@yc=.5\pgf@ya
+ \advance\pgf@yc by .5\pgf@yb
+ % Triangles:
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@yc}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgfpathclose
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@yc}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ \pgfpathclose
+ }%
+
+
+ \beforebackgroundpath{
+ {
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgf@yc=.5\pgf@ya
+ \advance\pgf@yc by.5\pgf@yb
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yc}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yc}}
+ \pgfusepathqstroke
+ \pgf@xc=.5\pgf@xa
+ \advance\pgf@xc by.5\pgf@xb
+ \pgftransformshift{\pgfqpoint{\pgf@xc}{\pgf@yc}}
+ \pgf@yc=.5\pgf@yb
+ \advance\pgf@yc by-.5\pgf@ya
+ \pgftransformscale{\pgf@sys@tonumber{\pgf@yc}}
+ \pgfpathmoveto{\pgfqpoint{-.5pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{-1pt}}
+ \pgfpathlineto{\pgfqpoint{0pt}{1pt}}
+ \pgfpathlineto{\pgfqpoint{.5pt}{1pt}}
+ \pgfusepathqstroke
+ }
+ }%
+}%
+
+
+
+
+
+
+% Generic shapes
+%
+% When these shapes are used, you can set a key derived form the
+% shapes name to some code that will be executed as the before
+% background path. This means that the basic shape is fixed, but
+% things like a special line inside the shape or at the border can be
+% added without having to define a whole new shape.
+
+
+\pgfdeclareshape{generic circle IEC}
+{%
+ % This shape is a generic circle, to which you can add something to
+ % the before background path using the key
+ % /pgf/generic circle IEC/before background
+ % When this key is invoked, the transformation matrix will have been
+ % setup such that the circle's center is at the origin and that the
+ % position \pgfpoint{1pt}{0pt} lies exactly on the top of the circle
+ % (and, there, on the middle of the line).
+
+ \inheritsavedanchors[from=circle ee]%
+ \inheritanchorborder[from=circle ee]%
+ \inheritanchor[from=circle ee]{north}%
+ \inheritanchor[from=circle ee]{north west}%
+ \inheritanchor[from=circle ee]{north east}%
+ \inheritanchor[from=circle ee]{center}%
+ \inheritanchor[from=circle ee]{west}%
+ \inheritanchor[from=circle ee]{east}%
+ \inheritanchor[from=circle ee]{south}%
+ \inheritanchor[from=circle ee]{south west}%
+ \inheritanchor[from=circle ee]{south east}%
+ \inheritanchor[from=circle ee]{input}%
+ \inheritanchor[from=circle ee]{output}%
+ \inheritbackgroundpath[from=circle ee]%
+
+ \beforebackgroundpath{
+ {
+ \centerpoint%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgftransformshift{}
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \pgftransformscale{\pgf@sys@tonumber{\pgfutil@tempdima}}
+ \pgfkeysvalueof{/pgf/generic circle IEC/before background}
+ }
+ }%
+}%
+
+
+
+%
+% Generic diode, based on a rectangle
+%
+
+\pgfdeclareshape{generic diode IEC}
+{%
+ % This shape is a generic diode, to which you can add something to
+ % the before background path using the key
+ % /pgf/generic diode IEC/before background
+ % When this key is invoked, the transformation matrix will have been
+ % setup such that the center is at the tip of the diode. The
+ % position \pgfpoint{1pt}{0pt} lies exactly on the top of the
+ % (suggested) line before the diode.
+
+ \inheritsavedanchors[from=rectangle ee]%
+ \inheritanchor[from=rectangle ee]{center}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+ \inheritanchorborder[from=rectangle ee]%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ % Move tip back a little bit
+ \advance\pgf@xb by-.5\pgflinewidth
+ % Triangle triangle:
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgf@yc=.5\pgf@ya
+ \advance\pgf@yc by .5\pgf@yb
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yc}}
+ \pgfpathclose
+ }%
+
+
+ \beforebackgroundpath{
+ {
+ \pgf@process{\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgf@yc=.5\pgf@ya
+ \advance\pgf@yc by.5\pgf@yb
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yc}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yc}}
+ \pgfusepathqstroke
+ \pgftransformshift{\pgfqpoint{\pgf@xb}{\pgf@yc}}
+ \pgf@yc=.5\pgf@yb
+ \advance\pgf@yc by-.5\pgf@ya
+ \pgftransformscale{\pgf@sys@tonumber{\pgf@yc}}
+ \pgfkeysvalueof{/pgf/generic diode IEC/before background}
+ }
+ }%
+}%
+
+
+\pgfkeys{
+ /pgf/generic circle IEC/before background/.initial=,
+ /pgf/generic diode IEC/before background/.initial=,
+}%
+
+
+
+
+
+%
+% Contacts
+%
+
+\pgfdeclareshape{make contact IEC}
+{%
+ \savedanchor\northeast{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by .5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@y=\pgf@ya%
+ \advance\pgf@y by\pgf@yb%
+ }%
+ \savedanchor\southwest{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=-.5\pgf@xa%
+ \advance\pgf@x by -.5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgf@y=-\pgf@ya%
+ }%
+
+ \anchor{center}{\pgfpointorigin}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+
+ \anchorborder{%
+ \ifdim\pgf@y<0pt%
+ % tricky... simplify to the origin...
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\southwest}%
+ \advance\pgf@y by-0.5pt%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\pgfqpoint{-\pgf@xa}{-\pgf@ya}}}%
+ \else%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\northeast}}%
+ \fi%
+ }%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xa=-\pgf@x \pgf@ya=0pt
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ % Start point
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{0pt}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }%
+}%
+
+
+
+%
+% Contacts
+%
+
+\pgfdeclareshape{var make contact IEC}
+{%
+ \savedanchor\northeast{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by .5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@y=\pgf@ya%
+ \advance\pgf@y by\pgf@yb%
+ }%
+ \savedanchor\southwest{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=-.5\pgf@xa%
+ \advance\pgf@x by -.5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgf@y=-\pgf@ya%
+ \pgf@xc=0.083333\pgf@x%
+ \advance\pgf@y by\pgf@xc%
+ }%
+
+ \anchor{center}{\pgfpointorigin}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+
+ \anchorborder{%
+ \ifdim\pgf@y<0pt%
+ % tricky... simplify to the origin...
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\southwest}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\pgfqpoint{-\pgf@xa}{-\pgf@ya}}}%
+ \else%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\northeast}}%
+ \fi%
+ }%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\northeast}{
+ \pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xa=-\pgf@x \pgf@ya=0pt
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgf@xc=\pgf@xa
+ \pgfutil@tempdima=2\pgf@xb%
+ \pgfutil@tempdima=0.083333\pgfutil@tempdima%
+ \advance\pgf@xa by \pgfutil@tempdima
+ % Circle
+ {\pgfpathcircle{\pgfqpoint{\pgf@xa}{0pt}}{\pgfutil@tempdima}}
+ % Height
+ % Start point
+ \pgf@process{\pgfpointnormalised{\pgfpointdiff{\pgfqpoint{\pgf@xa}{0pt}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}}}
+ \pgf@xc=\pgf@x
+ \pgf@yc=\pgf@y
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xa}{0pt}}{%
+ \pgfpointscale{\pgfutil@tempdima}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }%
+}%
+
+
+
+\pgfdeclareshape{break contact IEC}
+{%
+ \savedanchor\northeast{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by .5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@y=\pgf@ya%
+ \advance\pgf@y by\pgf@yb%
+ }%
+ \savedanchor\southwest{%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x=-.5\pgf@xa%
+ \advance\pgf@x by -.5\pgf@xb%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgf@y=-\pgf@ya%
+ }%
+
+ \anchor{center}{\pgfpointorigin}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+
+ \anchorborder{%
+ \ifdim\pgf@y<0pt%
+ % tricky... simplify to the origin...
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\southwest}%
+ \advance\pgf@y by-0.5pt%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\pgfqpoint{-\pgf@xa}{-\pgf@ya}}}%
+ \else%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{\pgfpointborderrectangle{\pgfqpoint{\pgf@xc}{\the\pgf@yc}}{\northeast}}%
+ \fi%
+ }%
+
+ \backgroundpath{
+ \pgf@process{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ \pgf@xa=-\pgf@x \pgf@ya=0pt
+ \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ % Start point
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{0pt}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ % Break point
+ \pgf@xc=.2\pgf@xb
+ \advance\pgf@xc by-.2\pgf@xa
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{0pt}}
+ \advance\pgf@xb by-\pgf@xc
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{0pt}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }%
+}%
+
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex
new file mode 100644
index 0000000000..c8f95ff4bf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex
@@ -0,0 +1,170 @@
+% Copyright 2018 by Till Tantau and others Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+
+%
+% Base shapes
+%
+% These shapes are identical to the shapes without "ee", only an "input"
+% and an "output" anchor have been added at the left and right end.
+
+\pgfdeclareshape{rectangle ee}
+{%
+ \inheritsavedanchors[from=rectangle]%
+ \inheritanchorborder[from=rectangle]%
+ \inheritanchor[from=rectangle]{north}%
+ \inheritanchor[from=rectangle]{north west}%
+ \inheritanchor[from=rectangle]{north east}%
+ \inheritanchor[from=rectangle]{center}%
+ \inheritanchor[from=rectangle]{west}%
+ \inheritanchor[from=rectangle]{east}%
+ \inheritanchor[from=rectangle]{mid}%
+ \inheritanchor[from=rectangle]{mid west}%
+ \inheritanchor[from=rectangle]{mid east}%
+ \inheritanchor[from=rectangle]{base}%
+ \inheritanchor[from=rectangle]{base west}%
+ \inheritanchor[from=rectangle]{base east}%
+ \inheritanchor[from=rectangle]{south}%
+ \inheritanchor[from=rectangle]{south west}%
+ \inheritanchor[from=rectangle]{south east}%
+ \inheritbackgroundpath[from=rectangle]%
+ % New:
+ \anchor{input}{
+ \pgf@process{\northeast}%
+ \pgf@ya=.5\pgf@y%
+ \pgf@process{\southwest}%
+ \pgf@y=.5\pgf@y%
+ \advance\pgf@y by \pgf@ya%
+ }%
+ \anchor{output}{%
+ \pgf@process{\southwest}%
+ \pgf@ya=.5\pgf@y%
+ \pgf@process{\northeast}%
+ \pgf@y=.5\pgf@y%
+ \advance\pgf@y by \pgf@ya%
+ }%
+}%
+
+\pgfdeclareshape{circle ee}
+{%
+ \inheritsavedanchors[from=circle]%
+ \inheritanchorborder[from=circle]%
+ \inheritanchor[from=circle]{north}%
+ \inheritanchor[from=circle]{north west}%
+ \inheritanchor[from=circle]{north east}%
+ \inheritanchor[from=circle]{center}%
+ \inheritanchor[from=circle]{west}%
+ \inheritanchor[from=circle]{east}%
+ \inheritanchor[from=circle]{mid}%
+ \inheritanchor[from=circle]{mid west}%
+ \inheritanchor[from=circle]{mid east}%
+ \inheritanchor[from=circle]{base}%
+ \inheritanchor[from=circle]{base west}%
+ \inheritanchor[from=circle]{base east}%
+ \inheritanchor[from=circle]{south}%
+ \inheritanchor[from=circle]{south west}%
+ \inheritanchor[from=circle]{south east}%
+ \inheritbackgroundpath[from=circle]%
+ % New:
+ \anchor{input}{\centerpoint\advance\pgf@x by-\radius}%
+ \anchor{output}{\centerpoint\advance\pgf@x by\radius}%
+}%
+
+
+
+%
+% Current direction indicator. This shape uses the current setting of
+% the current direction arrow tip for the arrow. The shape is a
+% rectangle around the arrow tip.
+%
+
+\pgfdeclareshape{direction ee}
+{%
+ \savedanchor\northeast{
+ \pgf@x=0pt%
+ % Height is given by minimum height/2
+ \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@y=.5\pgf@y
+ }%
+ \savedanchor\southwest{
+ % Left border is given by left extend
+ \pgfarrowtotallength{\pgfkeysvalueof{/pgf/direction ee arrow}}%
+ \pgf@x=-\pgf@x%
+ % Height is given by minimum height/2
+ \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@y=-.5\pgf@y
+ }%
+
+ \inheritanchor[from=rectangle ee]{center}%
+ \inheritanchor[from=rectangle ee]{north}%
+ \inheritanchor[from=rectangle ee]{south}%
+ \inheritanchor[from=rectangle ee]{east}%
+ \inheritanchor[from=rectangle ee]{west}%
+ \inheritanchor[from=rectangle ee]{north east}%
+ \inheritanchor[from=rectangle ee]{north west}%
+ \inheritanchor[from=rectangle ee]{south east}%
+ \inheritanchor[from=rectangle ee]{south west}%
+ \inheritanchor[from=rectangle ee]{input}%
+ \inheritanchor[from=rectangle ee]{output}%
+ \inheritanchorborder[from=rectangle ee]%
+ \nodeparts{}% no text
+
+ \behindbackgroundpath{
+ \pgf@process{\southwest}
+ \pgf@xa=\pgf@x
+ \pgf@process{\northeast}
+ \pgf@xb=\pgf@x
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{0pt}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{0pt}}
+ \pgfusepathqstroke
+ }%
+
+ \beforebackgroundpath{
+ {
+ \pgfsys@beginscope
+ \pgfarrowdraw{\pgfkeysvalueof{/pgf/direction ee arrow}}%
+ \pgfsys@endscope
+ }
+ }%
+}%
+
+\pgfkeys{
+ /pgf/direction ee arrow/.initial=direction ee,
+}%
+
+
+
+% Special arrow for ee directions:
+
+\pgfarrowsdeclare{direction ee}{direction ee}
+{%
+ \pgfmathsetlength\pgfutil@tempdima{\pgfgetarrowoptions{direction ee}}%
+ \pgfutil@tempdima=.5\pgfutil@tempdima
+ \pgfarrowsleftextend{+-\pgfutil@tempdima}
+ \pgfarrowsrightextend{+\pgfutil@tempdima}
+}
+{
+ \pgfmathsetlength\pgfutil@tempdima{\pgfgetarrowoptions{direction ee}}%
+ \pgfsetdash{}{+0pt}
+ \pgfsetroundjoin
+ \pgfpathmoveto{\pgfqpoint{-0.5\pgfutil@tempdima}{0.38268343237\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{0\pgfutil@tempdima}}
+ \pgfpathlineto{\pgfqpoint{-0.5\pgfutil@tempdima}{-0.38268343237\pgfutil@tempdima}}
+ \pgfpathclose
+ \pgfusepathqfillstroke
+}%
+
+\pgfsetarrowoptions{direction ee}{4pt}%
+
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex
new file mode 100644
index 0000000000..4022cd605d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex
@@ -0,0 +1,739 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{shapes.gates.logic}%
+
+\pgfkeys{/pgf/.cd,
+ and gate IEC symbol/.initial=$\char`\&$,
+ nand gate IEC symbol/.initial=$\char`\&$,
+ or gate IEC symbol/.initial=$\geq1$,
+ nor gate IEC symbol/.initial=$\geq1$,
+ xor gate IEC symbol/.initial={$=1$},
+ xnor gate IEC symbol/.initial={$=1$},
+ not gate IEC symbol/.initial=1,
+ buffer gate IEC symbol/.initial=1,
+ logic gate IEC symbol align/.initial=top,
+ logic gate IEC symbol color/.initial=% no value
+}%
+
+\pgfkeys{/pgf/logic gate IEC symbol align/.cd,
+ top/.code=\pgftransformyshift{\innerhalfheight},
+ bottom/.code=\pgftransformyshift{-\innerhalfheight},
+ left/.code=\pgftransformxshift{-\innerhalfwidth},
+ right/.code=\pgftransformxshift{\innerhalfwidth},
+}%
+
+\def\pgf@lib@sh@logicgates@IEC@foregroundpath#1{%
+ \dimensions%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate IEC symbol align}}%
+ \edef\pgf@lib@sh@@temp{/pgf/logic gate IEC symbol align/.cd, \pgf@lib@sh@temp}%
+ \expandafter\pgfkeys\expandafter{\pgf@lib@sh@@temp}%
+ \expandafter\pgftext\expandafter[\pgf@lib@sh@temp]{%
+ \pgfkeysgetvalue{/pgf/logic gate IEC symbol color}{\pgf@lib@sh@temp}%
+ \ifx\pgf@lib@sh@temp\pgfutil@empty%
+ \else%
+ \expandafter\color\expandafter{\pgf@lib@sh@temp}%
+ \fi%
+ \pgfkeysvalueof{/pgf/#1 gate IEC symbol}%
+ }%
+ }%
+}%
+
+
+\def\pgf@lib@sh@logicgates@dimensions@IEC#1{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ %
+ % Adjust for the width of the gate symbol.
+ %
+ \setbox\pgf@hbox\hbox{%
+ % wrap in `\pgfinterruptpicture' to restore font, like how `\pgfnode` sets
+ % `\pgfnodeparttextbox`
+ \pgfinterruptpicture
+ {\pgfkeysvalueof{/pgf/#1 gate IEC symbol}}% add braces as color-aftergroup-fix TT
+ \endpgfinterruptpicture
+ }%
+ \pgf@xa.5\wd\pgf@hbox%
+ \pgf@ya.5\ht\pgf@hbox%
+ \advance\pgf@ya.5\dp\pgf@hbox%
+ \ifdim\pgf@x<\pgf@xa%
+ \pgf@x\pgf@xa%
+ \fi%
+ \ifdim\pgf@y<\pgf@ya%
+ \pgf@y\pgf@ya%
+ \fi%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ %
+ % Adjust for minimum height and width.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ %
+ % Adjust the height for the number of inputs.
+ %
+ \c@pgf@counta\pgf@lib@sh@logicgate@numinputs%
+ \advance\c@pgf@counta1\relax%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \pgf@yb2.0\pgf@yb%
+ \advance\pgf@yb\pgflinewidth%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/logic gate input sep}}%
+ \edef\inputsep{\the\pgf@yc}%
+ \addtosavedmacro\inputsep%
+ \ifdim\pgf@yb<\pgf@yc%
+ \pgf@yb\pgf@yc%
+ \fi%
+ \multiply\pgf@yb\c@pgf@counta%
+ \ifdim\pgf@y<.5\pgf@yb%
+ \pgf@y.5\pgf@yb%
+ \fi%
+ %
+ \pgf@xa\pgf@x%
+ \pgfmathaddtolength\pgf@xa{-\pgfkeysvalueof{/pgf/inner xsep}}%
+ \edef\innerhalfwidth{\the\pgf@xa}%
+ \addtosavedmacro\innerhalfwidth%
+ %
+ \pgf@ya\pgf@y%
+ \pgfmathaddtolength\pgf@ya{-\pgfkeysvalueof{/pgf/inner ysep}}%
+ \edef\innerhalfheight{\the\pgf@ya}%
+ \addtosavedmacro\innerhalfheight%
+ %
+ % Take into account the outer sep.
+ %
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ %
+ \edef\halfwidth{\the\pgf@x}%
+ \edef\halfheight{\the\pgf@y}%
+ \addtosavedmacro\halfwidth%
+ \addtosavedmacro\halfheight%
+}%
+
+\def\pgf@lib@sh@logicgate@IEC@inputanchor#1{%
+ \dimensions%
+ \centerpoint%
+ \advance\pgf@x-\halfwidth%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname%
+ \advance\pgf@x-\invertedradius%
+ \advance\pgf@x-\outerinvertedradius%
+ \fi%
+ %
+ \pgfutil@tempdima\halfheight%
+ \multiply\pgfutil@tempdima2\relax%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \multiply\pgfutil@tempdima#1\relax%
+ \advance\pgf@y\halfheight%
+ \advance\pgf@y-\pgfutil@tempdima%
+}%
+
+
+
+% Shape and gate IEC
+%
+\pgfdeclareshape{and gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@and gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@and gate IEC@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@and gate IEC@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An and gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{and}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid west}{%
+ \dimensions%
+ \midpoint%
+ \advance\pgf@x-\halfwidth}%
+ \anchor{mid east}{%
+ \dimensions%
+ \midpoint%
+ \advance\pgf@x\halfwidth}%
+ \anchor{base}{\basepoint}%
+ \anchor{base west}{%
+ \dimensions%
+ \basepoint%
+ \advance\pgf@x-\halfwidth}%
+ \anchor{base east}{%
+ \dimensions%
+ \basepoint%
+ \advance\pgf@x\halfwidth}%
+ \anchor{north}{\dimensions\centerpoint\advance\pgf@y\halfheight}%
+ \anchor{south}{\dimensions\centerpoint\advance\pgf@y-\halfheight}%
+ \anchor{east}{\dimensions\centerpoint\advance\pgf@x\halfwidth}%
+ \anchor{west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth}%
+ \anchor{north east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y\halfheight}%
+ \anchor{north west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y\halfheight}%
+ \anchor{south east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y-\halfheight}%
+ \anchor{south west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y-\halfheight}%
+ \anchor{output}{\dimensions\centerpoint\advance\pgf@x\halfwidth}%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \pgfmathaddtolength\pgf@xc{-\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@yc{-\pgfkeysvalueof{/pgf/outer xsep}}%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathrectangle{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}%
+ {%
+ \pgf@xc2.0\pgf@xc%
+ \pgf@yc2.0\pgf@yc%
+ \pgfqpoint{\pgf@xc}{\pgf@yc}%
+ }%
+ \pgfpathclose%
+ %
+ % Draw inputs.
+ %
+ \pgf@xc-\halfwidth%
+ \advance\pgf@xc-\invertedradius%
+ \pgf@yc\halfheight%
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ }%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{and}}%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \dimensions%
+ \pgfpointadd{\centerpoint}{\pgfpointborderrectangle{\externalpoint}{\pgfqpoint{\halfwidth}{\halfheight}}}%
+ }%
+}%
+
+
+
+
+
+% Shape nand gate IEC
+%
+\pgfdeclareshape{nand gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nand gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@nand gate IEC@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@nand gate IEC@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{A nand gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{nand}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=and gate IEC]{center}%
+ \inheritanchor[from=and gate IEC]{mid}%
+ \inheritanchor[from=and gate IEC]{mid west}%
+ \inheritanchor[from=and gate IEC]{mid east}%
+ \inheritanchor[from=and gate IEC]{base}%
+ \inheritanchor[from=and gate IEC]{base west}%
+ \inheritanchor[from=and gate IEC]{base east}%
+ \inheritanchor[from=and gate IEC]{north}%
+ \inheritanchor[from=and gate IEC]{south}%
+ \inheritanchor[from=and gate IEC]{east}%
+ \inheritanchor[from=and gate IEC]{west}%
+ \inheritanchor[from=and gate IEC]{north east}%
+ \inheritanchor[from=and gate IEC]{north west}%
+ \inheritanchor[from=and gate IEC]{south east}%
+ \inheritanchor[from=and gate IEC]{south west}%
+ \anchor{output}{%
+ \csname pgf@anchor@and gate IEC@east\endcsname%
+ \advance\pgf@x\invertedradius%
+ \advance\pgf@x\outerinvertedradius%
+ }%
+ \backgroundpath{%
+ \csname pgf@sh@bg@and gate IEC\endcsname%
+ \pgfpathcircle{%
+ \centerpoint%
+ \advance\pgf@x\halfwidth%
+ \advance\pgf@x\invertedradius%
+ }{+\invertedradius}%
+ }%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nand}}%
+ \inheritanchorborder[from=and gate IEC]%
+}%
+
+
+
+
+
+% Shape or gate IEC
+%
+\pgfdeclareshape{or gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@or gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@or gate IEC@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@or gate IEC@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An or gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{or}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=and gate IEC]{center}%
+ \inheritanchor[from=and gate IEC]{mid}%
+ \inheritanchor[from=and gate IEC]{mid west}%
+ \inheritanchor[from=and gate IEC]{mid east}%
+ \inheritanchor[from=and gate IEC]{base}%
+ \inheritanchor[from=and gate IEC]{base west}%
+ \inheritanchor[from=and gate IEC]{base east}%
+ \inheritanchor[from=and gate IEC]{north}%
+ \inheritanchor[from=and gate IEC]{south}%
+ \inheritanchor[from=and gate IEC]{east}%
+ \inheritanchor[from=and gate IEC]{west}%
+ \inheritanchor[from=and gate IEC]{north east}%
+ \inheritanchor[from=and gate IEC]{north west}%
+ \inheritanchor[from=and gate IEC]{south east}%
+ \inheritanchor[from=and gate IEC]{south west}%
+ \inheritanchor[from=and gate IEC]{output}%
+ \inheritbackgroundpath[from=and gate IEC]%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{or}}%
+ \inheritanchorborder[from=and gate IEC]%
+}%
+
+
+
+
+
+% Shape nor gate IEC
+%
+\pgfdeclareshape{nor gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nor gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@nor gate IEC@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@nor gate IEC@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{A nor gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{nor}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=and gate IEC]{center}%
+ \inheritanchor[from=and gate IEC]{mid}%
+ \inheritanchor[from=and gate IEC]{mid west}%
+ \inheritanchor[from=and gate IEC]{mid east}%
+ \inheritanchor[from=and gate IEC]{base}%
+ \inheritanchor[from=and gate IEC]{base west}%
+ \inheritanchor[from=and gate IEC]{base east}%
+ \inheritanchor[from=and gate IEC]{north}%
+ \inheritanchor[from=and gate IEC]{south}%
+ \inheritanchor[from=and gate IEC]{east}%
+ \inheritanchor[from=and gate IEC]{west}%
+ \inheritanchor[from=and gate IEC]{north east}%
+ \inheritanchor[from=and gate IEC]{north west}%
+ \inheritanchor[from=and gate IEC]{south east}%
+ \inheritanchor[from=and gate IEC]{south west}%
+ \inheritanchor[from=nand gate IEC]{output}%%
+ \inheritbackgroundpath[from=nand gate IEC]%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nor}}%
+ \inheritanchorborder[from=and gate IEC]%
+}%
+
+
+
+
+
+% Shape xor gate IEC
+%
+\pgfdeclareshape{xor gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xor gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{2}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@xor gate IEC@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@xor gate IEC@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An xor gate must have two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{xor}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=and gate IEC]{center}%
+ \inheritanchor[from=and gate IEC]{mid}%
+ \inheritanchor[from=and gate IEC]{mid west}%
+ \inheritanchor[from=and gate IEC]{mid east}%
+ \inheritanchor[from=and gate IEC]{base}%
+ \inheritanchor[from=and gate IEC]{base west}%
+ \inheritanchor[from=and gate IEC]{base east}%
+ \inheritanchor[from=and gate IEC]{north}%
+ \inheritanchor[from=and gate IEC]{south}%
+ \inheritanchor[from=and gate IEC]{east}%
+ \inheritanchor[from=and gate IEC]{west}%
+ \inheritanchor[from=and gate IEC]{north east}%
+ \inheritanchor[from=and gate IEC]{north west}%
+ \inheritanchor[from=and gate IEC]{south east}%
+ \inheritanchor[from=and gate IEC]{south west}%
+ \inheritanchor[from=and gate IEC]{output}%
+ \inheritbackgroundpath[from=and gate IEC]%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xor}}%
+ \inheritanchorborder[from=and gate IEC]%
+}%
+
+
+
+
+% Shape xnor gate IEC
+%
+
+\pgfdeclareshape{xnor gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xnor gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@xnor gate IEC@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@xnor gate IEC@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{A xnor gate must have two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{xnor}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=and gate IEC]{center}%
+ \inheritanchor[from=and gate IEC]{mid}%
+ \inheritanchor[from=and gate IEC]{mid west}%
+ \inheritanchor[from=and gate IEC]{mid east}%
+ \inheritanchor[from=and gate IEC]{base}%
+ \inheritanchor[from=and gate IEC]{base west}%
+ \inheritanchor[from=and gate IEC]{base east}%
+ \inheritanchor[from=and gate IEC]{north}%
+ \inheritanchor[from=and gate IEC]{south}%
+ \inheritanchor[from=and gate IEC]{east}%
+ \inheritanchor[from=and gate IEC]{west}%
+ \inheritanchor[from=and gate IEC]{north east}%
+ \inheritanchor[from=and gate IEC]{north west}%
+ \inheritanchor[from=and gate IEC]{south east}%
+ \inheritanchor[from=and gate IEC]{south west}%
+ \inheritanchor[from=nand gate IEC]{output}%
+ \inheritbackgroundpath[from=nand gate IEC]%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xnor}}%
+ \inheritanchorborder[from=and gate IEC]%
+}%
+
+
+
+
+% Shape buffer gate IEC
+%
+\pgfdeclareshape{buffer gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1}% Maximum 1 input.
+ %
+ \expandafter\gdef\csname pgf@anchor@buffer gate IEC@input\endcsname{%
+ \pgf@lib@sh@logicgate@IEC@inputanchor{1}%
+ }%
+ \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax%
+ \pgferror{A buffer gate must have one inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{xor}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=and gate IEC]{center}%
+ \inheritanchor[from=and gate IEC]{mid}%
+ \inheritanchor[from=and gate IEC]{mid west}%
+ \inheritanchor[from=and gate IEC]{mid east}%
+ \inheritanchor[from=and gate IEC]{base}%
+ \inheritanchor[from=and gate IEC]{base west}%
+ \inheritanchor[from=and gate IEC]{base east}%
+ \inheritanchor[from=and gate IEC]{north}%
+ \inheritanchor[from=and gate IEC]{south}%
+ \inheritanchor[from=and gate IEC]{east}%
+ \inheritanchor[from=and gate IEC]{west}%
+ \inheritanchor[from=and gate IEC]{north east}%
+ \inheritanchor[from=and gate IEC]{north west}%
+ \inheritanchor[from=and gate IEC]{south east}%
+ \inheritanchor[from=and gate IEC]{south west}%
+ \inheritanchor[from=and gate IEC]{output}%
+ \inheritbackgroundpath[from=and gate IEC]%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{buffer}}%
+ \inheritanchorborder[from=and gate IEC]%
+}%
+
+
+
+
+
+% Shape not gate IEC
+%
+\pgfdeclareshape{not gate IEC}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate IEC\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1}%
+ %
+ \pgfutil@ifundefined{pgf@anchor@not gate IEC@input}{%
+ \expandafter\gdef\csname pgf@anchor@not gate IEC@input\endcsname{%
+ \pgf@lib@sh@logicgate@IEC@inputanchor{1}%
+ }}{}%
+ \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax%
+ \pgferror{A not gate must have one input}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{%
+ \pgf@lib@sh@logicgates@dimensions@IEC{not}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=and gate IEC]{center}%
+ \inheritanchor[from=and gate IEC]{mid}%
+ \inheritanchor[from=and gate IEC]{mid west}%
+ \inheritanchor[from=and gate IEC]{mid east}%
+ \inheritanchor[from=and gate IEC]{base}%
+ \inheritanchor[from=and gate IEC]{base west}%
+ \inheritanchor[from=and gate IEC]{base east}%
+ \inheritanchor[from=and gate IEC]{north}%
+ \inheritanchor[from=and gate IEC]{south}%
+ \inheritanchor[from=and gate IEC]{east}%
+ \inheritanchor[from=and gate IEC]{west}%
+ \inheritanchor[from=and gate IEC]{north east}%
+ \inheritanchor[from=and gate IEC]{north west}%
+ \inheritanchor[from=and gate IEC]{south east}%
+ \inheritanchor[from=and gate IEC]{south west}%
+ \inheritanchor[from=nand gate IEC]{output}%
+ \inheritbackgroundpath[from=nand gate IEC]%
+ \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{not}}%
+ \inheritanchorborder[from=and gate IEC]%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex
new file mode 100644
index 0000000000..3f0d668ca0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex
@@ -0,0 +1,2525 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{shapes.gates.logic}%
+
+
+\newif\ifpgfgateanchorsuseboundingrectangle%
+
+
+% Keys for US/CDH logic gates.
+%
+\pgfkeys{
+ /pgf/logic gate anchors use bounding box/.is if=pgfgateanchorsuseboundingrectangle,%
+}%
+
+% An internal macro for calculating internal dimensions of
+% the US + CDH gates (excluding and gate US and nand gate US).
+%
+\def\pgf@lib@sh@logicgates@dimensions@orUS{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ %
+ % Adjust the height for the number of inputs.
+ %
+ \c@pgf@counta\pgf@lib@sh@logicgate@numinputs%
+ \advance\c@pgf@counta1\relax%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@ya\pgflinewidth%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/logic gate input sep}}%
+ \pgf@yb.5\pgf@yb%
+ \ifdim\pgf@ya<\pgf@yb%
+ \pgf@ya\pgf@yb%
+ \fi%
+ \multiply\pgf@ya\c@pgf@counta%
+ \ifdim\pgf@y<\pgf@ya%
+ \pgf@y\pgf@ya%
+ \fi%
+ %
+ \ifdim\pgf@x>\pgf@y%
+ \pgf@y\pgf@x%
+ \else%
+ \pgf@x\pgf@y%
+ \fi%
+ %
+ % Adjust for minimum height and width.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ \pgf@xb\pgf@x%
+ \advance\pgf@xb1.732051\pgf@y% 2y*cos(30)
+ \ifdim\pgf@xb<\pgf@xa%
+ \pgf@xb\pgf@xa%
+ \pgf@x0.366025\pgf@xb% xb / (1 + 2*cos(30))
+ \fi%
+ %
+ \ifdim\pgf@x>\pgf@y%
+ \pgf@y\pgf@x%
+ \else%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\halfside{\the\pgf@x}%
+ \addtosavedmacro\halfside%
+ %
+ % Take into account the outer sep.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \edef\outerxsep{\the\pgf@xa}%
+ \edef\outerysep{\the\pgf@ya}%
+ \addtosavedmacro\outerxsep%
+ \addtosavedmacro\outerysep%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ %
+ \edef\halfwidth{\the\pgf@x}%
+ \edef\halfheight{\the\pgf@y}%
+ \addtosavedmacro\halfwidth%
+ \addtosavedmacro\halfheight%
+ %
+ \pgfextract@process\tipanchor{%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@y-\pgf@ya%
+ \pgf@x-.16666\pgf@x%
+ \pgf@yb2.0\pgf@y%
+ \advance\pgf@x.866025\pgf@yb%
+ \advance\pgf@x1.154701\pgf@xa%
+ \pgf@y0pt%
+ }%
+ \addtosavedmacro\tipanchor%
+}%
+
+
+% An internal macro for calculating internal dimensions of
+% the and gate US and nand gate US.
+%
+\def\pgf@lib@sh@logicgates@dimensions@andUS{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ %
+ % Adjust the height for the number of inputs.
+ %
+ \c@pgf@counta\pgf@lib@sh@logicgate@numinputs%
+ \advance\c@pgf@counta1\relax%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@ya\pgflinewidth%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/logic gate input sep}}%
+ \pgf@yb.5\pgf@yb%
+ \ifdim\pgf@ya<\pgf@yb%
+ \pgf@ya\pgf@yb%
+ \fi%
+ \multiply\pgf@ya\c@pgf@counta%
+ \ifdim\pgf@y<\pgf@ya%
+ \pgf@y\pgf@ya%
+ \fi%
+ %
+ \ifdim\pgf@x>\pgf@y%
+ \pgf@y\pgf@x%
+ \else%
+ \pgf@x\pgf@y%
+ \fi%
+ %
+ % Adjust for minimum height and width.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ \pgf@xb2.5\pgf@x%
+ \ifdim\pgf@xb<\pgf@xa%
+ \pgf@xb\pgf@xa%
+ \pgf@x0.4\pgf@xb%
+ \fi%
+ %
+ \ifdim\pgf@x>\pgf@y%
+ \pgf@y\pgf@x%
+ \else%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\halfside{\the\pgf@x}%
+ \addtosavedmacro\halfside%
+ %
+ % Take into account the outer sep.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \edef\outerxsep{\the\pgf@xa}%
+ \edef\outerysep{\the\pgf@ya}%
+ \addtosavedmacro\outerxsep%
+ \addtosavedmacro\outerysep%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ %
+ \edef\halfwidth{\the\pgf@x}%
+ \edef\halfheight{\the\pgf@y}%
+ \addtosavedmacro\halfwidth%
+ \addtosavedmacro\halfheight%
+ %
+}%
+
+
+% Internal macro for calculation input anchors. Used by
+% both and gates and nand gates, and also the not gate and buffer.
+%
+\def\pgf@lib@sh@logicgate@AND@inputanchor#1{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-.166666\pgf@xa%
+ \advance\pgf@x-\halfwidth%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname%
+ \advance\pgf@x-\invertedradius%
+ \advance\pgf@x-\outerinvertedradius%
+ \fi%
+ %
+ \pgfutil@tempdima\halfside%
+ \multiply\pgfutil@tempdima2\relax%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \multiply\pgfutil@tempdima#1\relax%
+ \advance\pgf@y\halfside%
+ \advance\pgf@y-\pgfutil@tempdima%
+}%
+
+
+
+
+% Shape and gate US
+%
+\pgfdeclareshape{and gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@and gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@and gate US@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@and gate US@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@AND@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An and gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@andUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \csname pgf@anchor@and gate US@east\endcsname%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \pgf@x\pgf@xa}%
+ \anchor{mid west}{%
+ \csname pgf@anchor@and gate US@west\endcsname%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \pgf@x\pgf@xa}%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \csname pgf@anchor@and gate US@east\endcsname%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \pgf@x\pgf@xa}%
+ \anchor{base west}{%
+ \csname pgf@anchor@and gate US@west\endcsname%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \pgf@x\pgf@xa}%
+ \anchor{east}{%
+ \dimensions%
+ \pgf@xa\halfwidth%
+ \pgf@xb\pgf@xa%
+ \advance\pgf@xb-\outerxsep%
+ \centerpoint%
+ \advance\pgf@x.333333\pgf@xb%
+ \advance\pgf@x\pgf@xa%
+ }%
+ \anchor{output}{\csname pgf@anchor@and gate US@east\endcsname}%
+ \anchor{north east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@nand gate US@east\endcsname%
+ \advance\pgf@y\halfheight%
+ \else
+ \pgf@xa\halfwidth%
+ \pgf@ya\halfheight%
+ \pgf@xb\pgf@xa%
+ \advance\pgf@xb-\outerxsep%
+ \centerpoint%
+ \advance\pgf@x.333333\pgf@xb%
+ \advance\pgf@x.707106\pgf@xa%
+ \advance\pgf@y.707106\pgf@ya%
+ \fi%
+ }%
+ \anchor{south east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@nand gate US@east\endcsname%
+ \advance\pgf@y-\halfheight%
+ \else
+ \pgf@xa\halfwidth%
+ \pgf@ya\halfheight%
+ \pgf@xb\pgf@xa%
+ \advance\pgf@xb-\outerxsep%
+ \centerpoint%
+ \advance\pgf@x.333333\pgf@xb%
+ \advance\pgf@x.707106\pgf@xa%
+ \advance\pgf@y-.707106\pgf@ya%
+ \fi%
+ }%
+ \anchor{north}{%
+ \dimensions%
+ \centerpoint%
+ \advance\pgf@y\halfheight%
+ }%
+ \anchor{south}{%
+ \dimensions%
+ \centerpoint%
+ \advance\pgf@y-\halfheight%
+ }%
+ \anchor{south west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@y-\halfheight%
+ }%
+ \anchor{north west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@y\halfheight%
+ }%
+ \anchor{west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ }%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ \pgf@xb.333333\pgf@xc%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yc}}%
+ {%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{\pgf@yc}}%
+ \pgfpathclose%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@xa\halfside%
+ \pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-.5\pgflinewidth%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \pgfextract@process\externalpoint{\pgfpointadd{\centerpoint}{\externalpoint}}%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle\pgfmathresult%
+ \dimensions%
+ \pgf@xb\halfside%
+ \pgf@xc1.66666\pgf@xb%
+ \advance\pgf@xc\outerxsep%
+ \pgf@yc\halfheight%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@and gate US@north west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\centerpoint}{\centerpoint\advance\pgf@x.333333\pgf@xb\advance\pgf@y\pgf@yc}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@x.333333\pgf@xb%
+ }%
+ {0}{90}{+\halfwidth and +\halfheight}%
+ \else%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\centerpoint\advance\pgf@x.333333\pgf@xb\advance\pgf@y\pgf@yc}%
+ {\centerpoint\advance\pgf@x-\pgf@xc\advance\pgf@y\pgf@yc}%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\centerpoint\advance\pgf@x.333333\pgf@xb\advance\pgf@y-\pgf@yc}%
+ \ifdim\externalangle pt>\pgfmathresult pt\relax%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@x.333333\pgf@xb%
+ }%
+ {270}{360}{+\halfwidth and +\halfheight}%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@and gate US@south west\endcsname}%
+ \ifdim\externalangle pt>\pgfmathresult pt\relax%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\centerpoint\advance\pgf@x.333333\pgf@xb\advance\pgf@y-\pgf@yc}%
+ {\csname pgf@anchor@and gate US@south west\endcsname}%
+ \else%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@and gate US@north west\endcsname}%
+ {\csname pgf@anchor@and gate US@south west\endcsname}%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+
+
+
+% Shape nand gate US
+%
+\pgfdeclareshape{nand gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nand gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@nand gate US@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@nand gate US@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@AND@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{A nand gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@andUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \inheritanchor[from=and gate US]{mid}%
+ \inheritanchor[from=and gate US]{mid east}%
+ \inheritanchor[from=and gate US]{mid west}%
+ \inheritanchor[from=and gate US]{base}%
+ \inheritanchor[from=and gate US]{base east}%
+ \inheritanchor[from=and gate US]{base west}%
+ \anchor{output}{%
+ \dimensions
+ \pgfpointadd{\centerpoint}{%
+ \pgf@xa\halfside%
+ \pgf@x1.33333\pgf@xa%
+ \advance\pgf@x\invertedradius%
+ \advance\pgf@x\outerinvertedradius%
+ \advance\pgf@x\outerxsep%
+ \pgf@y0pt%
+ }%
+ }%
+ \inheritanchor[from=and gate US]{east}%
+ \inheritanchor[from=and gate US]{north east}%
+ \inheritanchor[from=and gate US]{south east}%
+ \inheritanchor[from=and gate US]{north}%
+ \inheritanchor[from=and gate US]{south}%
+ \inheritanchor[from=and gate US]{south west}%
+ \inheritanchor[from=and gate US]{north west}%
+ \inheritanchor[from=and gate US]{west}%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ \pgf@xb.333333\pgf@xc%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yc}}%
+ {%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{\pgf@yc}}%
+ \pgfpathclose%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@xa\halfside%
+ \pgf@x-1.166666\pgf@xa%
+ \advance\pgf@x-.5\pgflinewidth%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ %
+ % Draw the output inverter.
+ %
+ {%
+ \pgfpathcircle{%
+ \pgf@x1.33333\pgf@xc%
+ \advance\pgf@x\outerinvertedradius%
+ \pgf@y0pt%
+ }{+\invertedradius}%
+ }%
+ }%
+ }%
+ \inheritanchorborder[from=and gate US]%
+}%
+
+
+% Internal macro for calculation input anchors. Used by
+% or, nor xnor gates (US).
+%
+\def\pgf@lib@sh@logicgate@OR@inputanchor#1{%
+ \dimensions%
+ \pgf@ya\halfside%
+ \pgf@yb2.0\pgf@ya%
+ %
+ \pgfutil@tempdima\halfside%
+ \multiply\pgfutil@tempdima2\relax%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \multiply\pgfutil@tempdima#1\relax%
+ \pgf@yc\pgf@ya%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ %
+ \pgf@xb\pgf@yb%
+ \advance\pgf@yb-\halflinewidth%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@yb}}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ %
+ \pgf@xc-1.166666\pgf@ya%
+ \advance\pgf@xc-.866025\pgf@xb%
+ \advance\pgf@xc\pgfmathresult\pgf@yb%
+ \advance\pgf@xc\halflinewidth%
+ \advance\pgf@xc-\outerxsep%
+ %
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname%
+ \advance\pgf@xc-\invertedradius%
+ \advance\pgf@xc-\outerinvertedradius%
+ \fi%
+ %
+ \centerpoint%
+ \advance\pgf@x\pgf@xc%
+ \advance\pgf@y\pgf@yc%
+}%
+
+
+% Shape or gate US
+%
+\pgfdeclareshape{or gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@or gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@or gate US@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@or gate US@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@OR@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An or gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\halflinewidth{%
+ \pgf@x.5\pgflinewidth%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \csname pgf@anchor@or gate US@east\endcsname%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \pgf@x\pgf@xa}%
+ \anchor{mid west}{%
+ \csname pgf@anchor@or gate US@north west\endcsname%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \pgf@x\pgf@xa}%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \csname pgf@anchor@or gate US@east\endcsname%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \pgf@x\pgf@xa}%
+ \anchor{base west}{%
+ \csname pgf@anchor@or gate US@north west\endcsname%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \pgf@x\pgf@xa}%
+ \anchor{east}{%
+ \dimensions%
+ \pgfpointadd{\centerpoint}{\tipanchor}%
+ }%
+ \anchor{output}{\csname pgf@anchor@or gate US@east\endcsname}%
+ \anchor{north east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \tipanchor%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\halfheight%
+ \else%
+ \centerpoint%
+ \pgf@xa\halfwidth%
+ \pgf@ya\halfheight%
+ \pgf@xb\halfside%
+ \advance\pgf@x-.166666\pgf@xb%
+ \advance\pgf@xa\pgf@xb%
+ \advance\pgf@x.5\pgf@xa%
+ \advance\pgf@y-\pgf@xb%
+ \advance\pgf@ya\pgf@xb%
+ \advance\pgf@y.866025\pgf@ya%
+ \fi%
+ }%
+ \anchor{south east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \tipanchor%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y-\halfheight%
+ \else
+ \centerpoint%
+ \pgf@xa\halfwidth%
+ \pgf@ya\halfheight%
+ \pgf@xb\halfside%
+ \advance\pgf@x-.166666\pgf@xb%
+ \advance\pgf@xa\pgf@xb%
+ \advance\pgf@x.5\pgf@xa%
+ \advance\pgf@y\pgf@xb%
+ \advance\pgf@ya\pgf@xb%
+ \advance\pgf@y-.866025\pgf@ya%
+ \fi%
+ }%
+ \anchor{north}{%
+ \dimensions%
+ \centerpoint%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \advance\pgf@y\halfheight%
+ \else%
+ \pgf@ya\halfheight%
+ \advance\pgf@y.993043\pgf@ya%
+ \fi%
+ }%
+ \anchor{south}{%
+ \dimensions%
+ \centerpoint%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \advance\pgf@y-\halfheight%
+ \else%
+ \pgf@ya\halfheight%
+ \advance\pgf@y-.993043\pgf@ya%
+ \fi%
+ }%
+ \anchor{south west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x-1.732050\pgf@xa%
+ \advance\pgf@y-\halfheight%
+ }%
+ \anchor{north west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x-1.732050\pgf@xa%
+ \advance\pgf@y\halfheight%
+ }%
+ \anchor{west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \else%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@x0.267949\pgf@xa%
+ \fi%
+ }%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{-.16666\pgf@xc}{\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{30}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{-30}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \pgfpatharc{-30}{0}{+\pgf@yc}%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \pgfpatharc{0}{30}{+\pgf@yc}%
+ }%
+ \pgfpathclose%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@ya\halfside%
+ \pgf@yb2.0\pgf@ya%
+ \pgf@xa\pgf@yb%
+ \advance\pgf@yb-\halflinewidth%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@yb}}%
+ \let\sineangle\pgfmathresult%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ %
+ \pgf@x-1.166666\pgf@ya%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x\pgfmathresult\pgf@yb%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \pgfextract@process\externalpoint{\pgfpointadd{\centerpoint}{\externalpoint}}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle\pgfmathresult%
+ \dimensions%
+ \pgf@xc\halfside%
+ %
+ \pgf@xc-.166666\pgf@xc%
+ \ifdim\pgf@xa<\pgf@xc%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@or gate US@north west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {%
+ \pgfgateanchorsuseboundingrectangletrue%
+ \csname pgf@anchor@or gate US@north\endcsname%
+ }%
+ {\csname pgf@anchor@or gate US@north west\endcsname}%
+ \else%
+ \pgfmathsubtract@{360}{\pgfmathresult}%
+ \ifdim\externalangle pt>\pgfmathresult pt\relax%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {%
+ \pgfgateanchorsuseboundingrectangletrue%
+ \csname pgf@anchor@or gate US@south\endcsname%
+ }%
+ {\csname pgf@anchor@or gate US@south west\endcsname}%
+ \else%
+ \ifdim\pgf@ya>\pgf@yb%
+ \pgf@yc\halfheight%
+ \advance\pgf@yc\halfside%
+ \advance\pgf@yc-\outerxsep%
+ \pgfextract@process\point{%
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.166666\pgf@xa%
+ \pgf@xa2.0\pgf@xa%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ }%
+ {0}{90}{+\pgf@yc}%
+ }%
+ \else%
+ \pgf@yc\halfheight%
+ \advance\pgf@yc\halfside%
+ \advance\pgf@yc-\outerxsep%
+ \pgfextract@process\point{%
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.166666\pgf@xa%
+ \pgf@xa2.0\pgf@xa%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ }%
+ {270}{360}{+\pgf@yc}%
+ }%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgf@y=0pt\relax%
+ \csname pgf@anchor@and gate US@east\endcsname%
+ \else%
+ \pgf@xc\halfwidth%
+ \advance\pgf@xc\halfside%
+ \pgf@yc\halfheight%
+ \advance\pgf@yc\halfside%
+ \pgf@xb\halfside%
+ \pgf@xb-.166666\pgf@xb%
+ \ifdim\pgf@ya<0pt%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@y\halfside%
+ \advance\pgf@x\pgf@xb%
+ }%
+ {270}{330}{+\pgf@yc}%
+ \else%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@y-\halfside%
+ \advance\pgf@x\pgf@xb%
+ }%
+ {30}{90}{+\pgf@xc and +\pgf@yc}%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+
+
+% Shape nor gate US
+%
+\pgfdeclareshape{nor gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nor gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@nor gate US@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@nor gate US@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@OR@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{A nor gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\halflinewidth{%
+ \pgf@x.5\pgflinewidth%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \inheritanchor[from=or gate US]{center}%
+ \inheritanchor[from=or gate US]{mid}%
+ \inheritanchor[from=or gate US]{mid east}%
+ \inheritanchor[from=or gate US]{mid west}%
+ \inheritanchor[from=or gate US]{base}%
+ \inheritanchor[from=or gate US]{base east}%
+ \inheritanchor[from=or gate US]{base west}%
+ \inheritanchor[from=or gate US]{east}%
+ \inheritanchor[from=or gate US]{north east}%
+ \inheritanchor[from=or gate US]{south east}%
+ \inheritanchor[from=or gate US]{north}%
+ \inheritanchor[from=or gate US]{south}%
+ \inheritanchor[from=or gate US]{south west}%
+ \inheritanchor[from=or gate US]{north west}%
+ \inheritanchor[from=or gate US]{west}%
+ \anchor{output}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xc\halfside%
+ \pgf@yc\pgf@xc%
+ \advance\pgf@x-.166666\pgf@xc%
+ \pgf@yc2.0\pgf@yc%
+ \advance\pgf@x.866025\pgf@yc%
+ \advance\pgf@x\outerinvertedradius%
+ \advance\pgf@x\invertedradius%
+ \advance\pgf@x\outerxsep%
+ }%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{-.16666\pgf@xc}{\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{30}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{-30}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \pgfpatharc{-30}{0}{+\pgf@yc}%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \pgfpatharc{0}{30}{+\pgf@yc}%
+ }%
+ \pgfpathclose%
+ % Draw the output inverter.
+ %
+ {%
+ \pgfpathcircle{%
+ \pgf@x-.166666\pgf@xc%
+ \pgf@yc2.0\pgf@yc%
+ \advance\pgf@x.866025\pgf@yc%
+ \advance\pgf@x\outerinvertedradius%
+ \pgf@y0pt%
+ }{+\invertedradius}%
+ }%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@ya\halfside%
+ \pgf@yb2.0\pgf@ya%
+ \pgf@xa\pgf@yb%
+ \advance\pgf@yb-\halflinewidth%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@yb}}%
+ \let\sineangle\pgfmathresult%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ %
+ \pgf@x-1.166666\pgf@ya%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x\pgfmathresult\pgf@yb%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ }%
+ \inheritanchorborder[from=or gate US]%
+}%
+
+
+
+% Internal macro for calculation input anchors. Used by
+% xor and xnor gates (US).
+%
+\def\pgf@lib@sh@logicgate@XOR@inputanchor#1{%
+ \dimensions%
+ \pgf@ya\halfside%
+ \pgf@yb2.0\pgf@ya%
+ %
+ \pgfutil@tempdima\halfside%
+ \multiply\pgfutil@tempdima2\relax%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \multiply\pgfutil@tempdima#1\relax%
+ \pgf@yc\pgf@ya%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ %
+ \pgf@xb\pgf@yb%
+ \advance\pgf@yb-\halflinewidth%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@yb}}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ %
+ \pgf@xc-1.166666\pgf@ya%
+ \advance\pgf@xc-.866025\pgf@xb%
+ \advance\pgf@xc\pgfmathresult\pgf@yb%
+ \advance\pgf@xc\halflinewidth%
+ \advance\pgf@xc-\outerxsep%
+ %
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname%
+ \advance\pgf@xc-\invertedradius%
+ \advance\pgf@xc-\outerinvertedradius%
+ \fi%
+ %
+ \centerpoint%
+ \advance\pgf@x\pgf@xc%
+ \advance\pgf@y\pgf@yc%
+ \pgf@xa\halfside%
+ \advance\pgf@x-.333333\pgf@xa%
+}%
+
+
+
+
+
+% Shape xor gate US
+%
+\pgfdeclareshape{xor gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xor gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{2}%
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@xor gate US@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@xor gate US@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@XOR@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An xor gate must have at two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\halflinewidth{%
+ \pgf@x.5\pgflinewidth%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \inheritanchor[from=or gate US]{mid east}%
+ \anchor{mid west}{%
+ \csname pgf@anchor@xor gate US@north west\endcsname%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \pgf@x\pgf@xa}%
+ \anchor{base}{\basepoint}%
+ \inheritanchor[from=or gate US]{base east}%
+ \anchor{base west}{%
+ \csname pgf@anchor@xor gate US@north west\endcsname%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \pgf@x\pgf@xa}%
+ \inheritanchor[from=or gate US]{base}%
+ \inheritanchor[from=or gate US]{output}%
+ \inheritanchor[from=or gate US]{east}%
+ \inheritanchor[from=or gate US]{north east}%
+ \inheritanchor[from=or gate US]{south east}%
+ \inheritanchor[from=or gate US]{north}%
+ \inheritanchor[from=or gate US]{south}%
+ \anchor{south west}{%
+ \dimensions%
+ \pgf@xa\halfside%
+ \pgf@xa-3.232051\pgf@xa% (7/6 + 2*cos(30) + 1/3) * x
+ \pgf@xb\halfside%
+ \pgf@xb2.0\pgf@xb%
+ \advance\pgf@xb-\halflinewidth%
+ \advance\pgf@xa.866025\pgf@xb%
+ \pgf@ya.5\pgf@xb%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \advance\pgf@y-\halfheight%
+ \else%
+ \advance\pgf@y-\pgf@ya%
+ \fi%
+ }%
+ \anchor{north west}{%
+ \dimensions%
+ \pgf@xa\halfside%
+ \pgf@xa-3.232051\pgf@xa% (7/6 + 2*cos(30) + 1/3) * x
+ \pgf@xb\halfside%
+ \pgf@xb2.0\pgf@xb%
+ \advance\pgf@xb-\halflinewidth%
+ \advance\pgf@xa.866025\pgf@xb%
+ \pgf@ya.5\pgf@xb%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \advance\pgf@y\halfheight%
+ \else%
+ \advance\pgf@y\pgf@ya%
+ \fi%
+ }%
+ \anchor{west}{%
+ \dimensions%
+ \pgf@ya\halfside%
+ \pgf@yb2.0\pgf@ya%
+ %
+ \pgf@xb\pgf@yb%
+ \advance\pgf@yb-\halflinewidth%
+ \pgfmathdivide@{0}{\pgfmath@tonumber{\pgf@yb}}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ %
+ \pgf@xc-1.166666\pgf@ya%
+ \advance\pgf@xc-.866025\pgf@xb%
+ \advance\pgf@xc\pgfmathresult\pgf@yb%
+ \advance\pgf@xc\halflinewidth%
+ \advance\pgf@xc-\outerxsep%
+ %
+ \centerpoint%
+ \advance\pgf@x\pgf@xc%
+ \pgf@xa\halfside%
+ \advance\pgf@x-.333333\pgf@xa%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \pgf@xa2.0\pgf@xa%
+ \advance\pgf@x-0.133974\pgf@xa%
+ \fi%
+ }%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{-.16666\pgf@xc}{\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{30}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{-30}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ {%
+ \pgf@yc2.66666\pgf@yc%
+ \pgfpatharc{-22}{0}{+1.166666\pgf@yc and +\pgf@yc}%
+ }
+ {%
+ \pgf@yc2.66666\pgf@yc%
+ \pgfpatharc{0}{22}{+1.166666\pgf@yc and +\pgf@yc}%
+ }%
+ \pgfpathclose%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@ya\halfside%
+ \pgf@yb2.0\pgf@ya%
+ \pgf@xa\pgf@yb%
+ \advance\pgf@yb-\halflinewidth%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@yb}}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ %
+ \pgf@x-1.5\pgf@ya%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x\pgfmathresult\pgf@yb%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ %
+ % Now, some fooling around to stop the `tail' being filled.
+ % Technically it still is, but it isn't visible.
+ %
+ \pgf@xc\halfside%
+ \pgf@yc\halfside%
+ \pgfpathmoveto{\pgfqpoint{-1.5\pgf@xc}{-\pgf@yc}}%
+ \pgf@yc2.0\pgf@yc%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter<61\relax%
+ {%
+ \pgfextract@process\point{%
+ \pgfpointadd{%
+ \pgf@x\halfside%
+ \pgf@x-3.232051\pgf@x% (7/6 + 2*cos(30) + 1/3) * x
+ \pgf@y0pt%
+ }{%
+ \pgfpointpolar{\pgfmathcounter-30}{+\pgf@yc}%
+ }%
+ }%
+ \pgfpathlineto{\point}%
+ \pgfpathmoveto{\point}%
+ }
+ \repeatpgfmathloop%
+ }%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \pgfextract@process\externalpoint{\pgfpointadd{\centerpoint}{\externalpoint}}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle\pgfmathresult%
+ \dimensions%
+ \pgf@xc\halfside%
+ %
+ \pgf@xc-.166666\pgf@xc%
+ \ifdim\pgf@xa<\pgf@xc%
+ \pgfmathanglebetweenpoints{\centerpoint}%
+ {%
+ \pgfgateanchorsuseboundingrectangletrue%
+ \csname pgf@anchor@xor gate US@north west\endcsname%
+ }%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {%
+ \pgfgateanchorsuseboundingrectangletrue%
+ \csname pgf@anchor@xor gate US@north\endcsname%
+ }%
+ {%
+ \pgfgateanchorsuseboundingrectangletrue%
+ \csname pgf@anchor@xor gate US@north west\endcsname%
+ }%
+ \else%
+ \pgfmathsubtract@{360}{\pgfmathresult}%
+ \ifdim\externalangle pt>\pgfmathresult pt\relax%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {%
+ \pgfgateanchorsuseboundingrectangletrue%
+ \csname pgf@anchor@xor gate US@south\endcsname%
+ }%
+ {%
+ \pgfgateanchorsuseboundingrectangletrue%
+ \csname pgf@anchor@xor gate US@south west\endcsname%
+ }%
+ \else%
+ \ifdim\pgf@ya>\pgf@yb%
+ \pgf@yc\halfheight%
+ \advance\pgf@yc\halfside%
+ \advance\pgf@yc-\outerxsep%
+ \pgf@process{%
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.166666\pgf@xa%
+ \pgf@xa2.0\pgf@xa%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@x-.166666\pgf@xa%
+ }%
+ {0}{90}{+\pgf@yc}%
+ }%
+ \else%
+ \pgf@yc\halfheight%
+ \advance\pgf@yc\halfside%
+ \advance\pgf@yc-\outerxsep%
+ \pgf@process{%
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.166666\pgf@xa%
+ \pgf@xa2.0\pgf@xa%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@x-.166666\pgf@xa%
+ }%
+ {270}{360}{+\pgf@yc}%
+ }%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgf@y=0pt\relax%
+ \csname pgf@anchor@and gate US@east\endcsname%
+ \else%
+ \pgf@xc\halfwidth%
+ \advance\pgf@xc\halfside%
+ \pgf@yc\halfheight%
+ \advance\pgf@yc\halfside%
+ \pgf@xb\halfside%
+ \pgf@xb-.166666\pgf@xb%
+ \ifdim\pgf@ya<0pt%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@y\halfside%
+ \advance\pgf@x\pgf@xb%
+ }%
+ {270}{330}{+\pgf@yc}%
+ \else%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@y-\halfside%
+ \advance\pgf@x\pgf@xb%
+ }%
+ {30}{90}{+\pgf@xc and +\pgf@yc}%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+
+
+% Shape xnor gate US
+%
+\pgfdeclareshape{xnor gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xnor gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{2}%
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@xnor gate US@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@xnor gate US@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@XOR@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An xnor gate must have two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\halflinewidth{%
+ \pgf@x.5\pgflinewidth%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \inheritanchor[from=xor gate US]{mid east}%
+ \inheritanchor[from=xor gate US]{mid west}%
+ \anchor{base}{\basepoint}%%
+ \inheritanchor[from=xor gate US]{base east}%
+ \inheritanchor[from=xor gate US]{base west}%
+ \inheritanchor[from=xor gate US]{base}%
+ \inheritanchor[from=nor gate US]{output}%
+ \inheritanchor[from=xor gate US]{east}%
+ \inheritanchor[from=xor gate US]{north east}%
+ \inheritanchor[from=xor gate US]{south east}%
+ \inheritanchor[from=xor gate US]{north}%
+ \inheritanchor[from=xor gate US]{south}%
+ \inheritanchor[from=xor gate US]{south west}%
+ \inheritanchor[from=xor gate US]{north west}%
+ \inheritanchor[from=xor gate US]{west}%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{-.16666\pgf@xc}{\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{30}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{-30}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ {%
+ \pgf@yc2.66666\pgf@yc%
+ \pgfpatharc{-22}{0}{+1.166666\pgf@yc and +\pgf@yc}%
+ }
+ {%
+ \pgf@yc2.66666\pgf@yc%
+ \pgfpatharc{0}{22}{+1.166666\pgf@yc and +\pgf@yc}%
+ }%
+ \pgfpathclose%
+ %
+ % Draw the output inverter.
+ %
+ {%
+ \pgfpathcircle{%
+ \pgf@x-.166666\pgf@xc%
+ \pgf@yc2.0\pgf@yc%
+ \advance\pgf@x.866025\pgf@yc%
+ \advance\pgf@x\outerinvertedradius%
+ \pgf@y0pt%
+ }{+\invertedradius}%
+ }%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@ya\halfside%
+ \pgf@yb2.0\pgf@ya%
+ \pgf@xa\pgf@yb%
+ \advance\pgf@yb-\halflinewidth%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@yb}}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ %
+ \pgf@x-1.5\pgf@ya%
+ \advance\pgf@x-.866025\pgf@xa%
+ \advance\pgf@x\pgfmathresult\pgf@yb%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ %
+ % Now, some fooling around to stop the `tail' being filled.
+ %
+ \pgf@xc\halfside%
+ \pgf@yc\halfside%
+ \pgfpathmoveto{\pgfqpoint{-1.5\pgf@xc}{-\pgf@yc}}%
+ \pgf@yc2.0\pgf@yc%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter<61\relax%
+ {%
+ \pgfextract@process\point{%
+ \pgfpointadd{%
+ \pgf@x\halfside%
+ \pgf@x-3.232051\pgf@x% (7/6 + 2*cos(30) + 1/3) * x
+ \pgf@y0pt%
+ }{%
+ \pgfpointpolar{\pgfmathcounter-30}{+\pgf@yc}%
+ }%
+ }%
+ \pgfpathlineto{\point}%
+ \pgfpathmoveto{\point}%
+ }
+ \repeatpgfmathloop%
+ }%
+ }%
+ \inheritanchorborder[from=xor gate US]%
+}%
+
+
+
+
+
+
+% Shape not gate US
+%
+\pgfdeclareshape{not gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1}%
+ \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax%
+ \pgferror{A not gate must have one input}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\halflinewidth{%
+ \pgf@x.5\pgflinewidth%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \midpoint%
+ \pgfutil@tempdima\pgf@y%
+ \csname pgf@anchor@not gate US@east\endcsname%
+ \pgf@y\pgfutil@tempdima%
+ }%
+ \anchor{mid west}{%
+ \dimensions%
+ \pgf@xc\halfside%
+ \pgf@xc-.833333\pgf@xc%
+ \advance\pgf@xc-\outerxsep%
+ \midpoint%
+ \advance\pgf@x\pgf@xc%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \basepoint%
+ \pgfutil@tempdima\pgf@y%
+ \csname pgf@anchor@not gate US@east\endcsname%
+ \pgf@y\pgfutil@tempdima%
+ }%
+ \anchor{base west}{%
+ \dimensions%
+ \pgf@xc\halfside%
+ \pgf@xc-.833333\pgf@xc%
+ \advance\pgf@xc-\outerxsep%
+ \basepoint%
+ \advance\pgf@x\pgf@xc%
+ }%
+ \inheritanchor[from=and gate US]{base}%
+ \anchor{output}{%
+ \dimensions%
+ \pgf@xc\halfside%
+ \centerpoint%
+ \advance\pgf@x-.166666\pgf@xc%
+ \pgf@xc2.0\pgf@xc%
+ \advance\pgf@x.866025\pgf@xc%
+ \advance\pgf@x\invertedradius%
+ \advance\pgf@x\outerinvertedradius%
+ \advance\pgf@x\outerxsep%
+ }%
+ \anchor{east}{%
+ \dimensions%
+ \tipanchor%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ }%
+ \anchor{north}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@north west\endcsname%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y\pgf@ya%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@y1pt}%
+ {\csname pgf@anchor@not gate US@north west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ }%
+ \anchor{south}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@south west\endcsname%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y\pgf@ya%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@y-1pt}%
+ {\csname pgf@anchor@not gate US@south west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ }%
+ \anchor{south east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@south west\endcsname%
+ \pgf@ya\pgf@y%
+ \pgf@process{%
+ \dimensions%
+ \tipanchor%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ }%
+ \pgf@y\pgf@ya%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@x1pt\advance\pgf@y-1pt}%
+ {\csname pgf@anchor@not gate US@south west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ }%
+ \anchor{north east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@north west\endcsname%
+ \pgf@ya\pgf@y%
+ \pgf@process{%
+ \dimensions%
+ \tipanchor%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ }%
+ \pgf@y\pgf@ya%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@x1pt\advance\pgf@y1pt}%
+ {\csname pgf@anchor@not gate US@north west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ }%
+ \anchor{south west}{%
+ \dimensions%
+ \pgf@xa\halfside%
+ \centerpoint%
+ \advance\pgf@x-.833333\pgf@xa
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@y-1.166666\pgf@xa%
+ \pgf@ya\outerysep%
+ \advance\pgf@y-1.565\pgf@ya% Selected by trial and error.
+ }%
+ \anchor{north west}{%
+ \dimensions%
+ \pgf@xa\halfside%
+ \centerpoint%
+ \advance\pgf@x-.833333\pgf@xa
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@y1.166666\pgf@xa%
+ \pgf@ya\outerysep%
+ \advance\pgf@y1.565\pgf@ya% Selected by trial and error.
+ }%
+ \anchor{input}{%
+ \dimensions%
+ \pgf@lib@sh@logicgate@AND@inputanchor{1}%
+ \pgf@xc\halfside%
+ \advance\pgf@x.333333\pgf@xc%
+ }%
+ \anchor{west}{%
+ \dimensions%
+ \pgf@xc\halfside%
+ \pgf@xc-.833333\pgf@xc%
+ \advance\pgf@xc-\outerxsep%
+ \centerpoint%
+ \advance\pgf@x\pgf@xc%
+ }%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\tipanchor}%
+ \pgfpathlineto{\pgfqpoint{-.833333\pgf@xc}{1.166666\pgf@yc}}%
+ \pgfpathlineto{\pgfqpoint{-.833333\pgf@xc}{-1.166666\pgf@yc}}%
+ \pgfpathlineto{\tipanchor}%
+ %
+ % Draw the output inverter.
+ %
+ {%
+ \pgfpathcircle{%
+ \pgf@x-.166666\pgf@xc%
+ \pgf@yc2.0\pgf@yc%
+ \advance\pgf@x.866025\pgf@yc%
+ \advance\pgf@x\outerinvertedradius%
+ \pgf@y0pt%
+ }{+\invertedradius}%
+ }%
+ %
+ % Draw the input.
+ %
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-1\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@xa\halfside%
+ \pgf@x-.833333\pgf@xa%
+ \advance\pgf@x-.5\pgflinewidth%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y0pt%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ }%
+ }%
+ \anchorborder{%
+ \pgf@lib@gates@not@buffer@border{not gate US}
+ }%
+}%
+
+\def\pgf@lib@gates@not@buffer@border#1{
+ \pgfextract@process\externalpoint{}%
+ \pgfextract@process\externalpoint{\pgfpointadd{\centerpoint}{\externalpoint}}%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \ifx\pgfmathresult\pgf@lib@zero@text%
+ \csname pgf@anchor@#1@output\endcsname%
+ \else%
+ \ifx\pgfmathresult\pgf@lib@onehundredeighty@text%
+ \csname pgf@anchor@#1@input\endcsname%
+ \else%
+ \let\externalangle\pgfmathresult%
+ \dimensions%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@not gate US@north west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\csname pgf@anchor@not gate US@north west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@not gate US@south west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@not gate US@north west\endcsname}%
+ {\csname pgf@anchor@not gate US@south west\endcsname}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\csname pgf@anchor@not gate US@south west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+
+\def\pgf@lib@zero@text{0.0}%
+\def\pgf@lib@onehundredeighty@text{180.0}%
+
+
+
+
+% Shape buffer gate US.
+%
+\pgfdeclareshape{buffer gate US}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate US\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1}%
+ \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax%
+ \pgferror{A buffer gate must have one input}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\halflinewidth{%
+ \pgf@x.5\pgflinewidth%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \midpoint%
+ \pgfutil@tempdima\pgf@y%
+ \csname pgf@anchor@buffer gate US@east\endcsname%
+ \pgf@y\pgfutil@tempdima%
+ }%
+ \anchor{mid west}{%
+ \dimensions%
+ \pgf@xc\halfside%
+ \pgf@xc-.833333\pgf@xc%
+ \advance\pgf@xc-\outerxsep%
+ \midpoint%
+ \advance\pgf@x\pgf@xc%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \basepoint%
+ \pgfutil@tempdima\pgf@y%
+ \csname pgf@anchor@buffer gate US@east\endcsname%
+ \pgf@y\pgfutil@tempdima%
+ }%
+ \inheritanchor[from=not gate US]{base west}%
+ \inheritanchor[from=and gate US]{base}%
+ \anchor{output}{\csname pgf@anchor@buffer gate US@east\endcsname}%
+ \anchor{east}{%
+ \dimensions%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \anchor{north}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@north west\endcsname%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y\pgf@ya%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@y1pt}%
+ {\csname pgf@anchor@buffer gate US@north west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ }%
+ \anchor{south}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@south west\endcsname%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y\pgf@ya%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@y-1pt}%
+ {\csname pgf@anchor@not gate US@south west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ }%
+ \anchor{south east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@south west\endcsname%
+ \pgfutil@tempdima\pgf@y%
+ \csname pgf@anchor@buffer gate US@east\endcsname%
+ \pgf@y\pgfutil@tempdima%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@x1pt\advance\pgf@y-1pt}%
+ {\csname pgf@anchor@buffer gate US@south west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xc\outerxsep%
+ \advance\pgf@x2.350943\pgf@xc%
+ }%
+ }%
+ \fi%
+ }%
+ \anchor{north east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \csname pgf@anchor@not gate US@north west\endcsname%
+ \pgfutil@tempdima\pgf@y%
+ \csname pgf@anchor@buffer gate US@east\endcsname%
+ \pgf@y\pgfutil@tempdima%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\centerpoint\advance\pgf@x1pt\advance\pgf@y1pt}%
+ {\csname pgf@anchor@buffer gate US@north west\endcsname}%
+ {%
+ \pgfpointadd{\centerpoint}{%
+ \tipanchor%
+ \pgf@xa\outerxsep%
+ \advance\pgf@x2.350943\pgf@xa%
+ }%
+ }%
+ \fi%
+ }%
+ \inheritanchor[from=not gate US]{south west}%
+ \inheritanchor[from=not gate US]{north west}%
+ \inheritanchor[from=not gate US]{input}%
+ \inheritanchor[from=not gate US]{west}%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\tipanchor}%
+ \pgfpathlineto{\pgfqpoint{-.833333\pgf@xc}{1.166666\pgf@yc}}%
+ \pgfpathlineto{\pgfqpoint{-.833333\pgf@xc}{-1.166666\pgf@yc}}%
+ \pgfpathclose%
+ %
+ % Draw the input.
+ %
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-1\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@xa\halfside%
+ \pgf@x-.833333\pgf@xa%
+ \advance\pgf@x-.5\pgflinewidth%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y0pt%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ }%
+ }%
+ \anchorborder{%
+ \pgf@lib@gates@not@buffer@border{buffer gate US}
+ }%
+}%
+
+
+
+
+
+\pgfdeclareshape{and gate CDH}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@and gate CDH\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@and gate CDH@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@and gate CDH@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@AND@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{An and gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \csname pgf@anchor@and gate CDH@east\endcsname%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \pgf@x\pgf@xa}%
+ \anchor{mid west}{%
+ \csname pgf@anchor@and gate CDH@west\endcsname%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \pgf@x\pgf@xa}%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \csname pgf@anchor@and gate CDH@east\endcsname%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \pgf@x\pgf@xa}%
+ \anchor{base west}{%
+ \csname pgf@anchor@and gate CDH@west\endcsname%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \pgf@x\pgf@xa}%
+ \anchor{east}{%
+ \dimensions%
+ \pgfpointadd{\centerpoint}{\tipanchor}%
+ }%
+ \anchor{output}{\csname pgf@anchor@and gate CDH@east\endcsname}%
+ \anchor{north east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \tipanchor%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\halfheight%
+ \else%
+ \centerpoint%
+ \pgf@xa\halfwidth%
+ \pgf@ya\halfheight%
+ \pgf@xb\halfside%
+ \advance\pgf@x-.166666\pgf@xb%
+ \advance\pgf@xa\pgf@xb%
+ \advance\pgf@x.5\pgf@xa%
+ \advance\pgf@y-\pgf@xb%
+ \advance\pgf@ya\pgf@xb%
+ \advance\pgf@y.866025\pgf@ya%
+ \fi%
+ }%
+ \anchor{south east}{%
+ \dimensions%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \tipanchor%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y-\halfheight%
+ \else
+ \centerpoint%
+ \pgf@xa\halfwidth%
+ \pgf@ya\halfheight%
+ \pgf@xb\halfside%
+ \advance\pgf@x-.166666\pgf@xb%
+ \advance\pgf@xa\pgf@xb%
+ \advance\pgf@x.5\pgf@xa%
+ \advance\pgf@y\pgf@xb%
+ \advance\pgf@ya\pgf@xb%
+ \advance\pgf@y-.866025\pgf@ya%
+ \fi%
+ }%
+ \anchor{north}{%
+ \dimensions%
+ \centerpoint%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \advance\pgf@y\halfheight%
+ \else%
+ \pgf@ya\halfheight%
+ \advance\pgf@y.993043\pgf@ya%
+ \fi%
+ }%
+ \anchor{south}{%
+ \dimensions%
+ \centerpoint%
+ \ifpgfgateanchorsuseboundingrectangle%
+ \advance\pgf@y-\halfheight%
+ \else%
+ \pgf@ya\halfheight%
+ \advance\pgf@y-.993043\pgf@ya%
+ \fi%
+ }%
+ \anchor{south west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@y-\halfheight%
+ }%
+ \anchor{north west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ \advance\pgf@y\halfheight%
+ }%
+ \anchor{west}{%
+ \dimensions%
+ \centerpoint%
+ \pgf@xa\halfside%
+ \advance\pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-\outerxsep%
+ }%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{-.16666\pgf@xc}{\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{30}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{-30}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{\pgf@yc}}%
+ \pgfpathclose%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@xa\halfside%
+ \pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-.5\pgflinewidth%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \dimensions%
+ \pgf@xb\halfside%
+ %
+ \pgf@xb-.166666\pgf@xb%
+ \ifdim\pgf@xa<\pgf@xb%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointborderrectangle{\externalpoint}{%
+ \pgf@xc\halfside%
+ \pgf@xc.166666\pgf@xc%
+ \advance\pgf@xc\halfwidth%
+ \pgfqpoint{\pgf@xc}{\halfheight}%
+ }%
+ }%
+ \else%
+ \ifdim\pgf@y=0pt\relax%
+ \csname pgf@anchor@and gate CDH@east\endcsname%
+ \else%
+ \pgfextract@process\externalpoint{\pgfpointadd{\centerpoint}{\externalpoint}}%
+ \pgf@xc\halfwidth%
+ \advance\pgf@xc\halfside%
+ \pgf@yc\halfheight%
+ \advance\pgf@yc\halfside%
+ \ifdim\pgf@ya<0pt%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@y\halfside%
+ \advance\pgf@x\pgf@xb%
+ }%
+ {270}{330}{+\pgf@yc}%
+ \else%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \advance\pgf@y-\halfside%
+ \advance\pgf@x\pgf@xb%
+ }%
+ {30}{90}{+\pgf@xc and +\pgf@yc}%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+\pgfdeclareshape{nand gate CDH}{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nand gate CDH\endcsname{%
+ \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs.
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@nand gate CDH@input \pgfmathcounter}{%
+ \expandafter\xdef\csname pgf@anchor@nand gate CDH@input \pgfmathcounter\endcsname{%
+ \noexpand\pgf@lib@sh@logicgate@AND@inputanchor{\pgfmathcounter}%
+ }%
+ }{}%
+ \repeatpgfmathloop%
+ \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax%
+ \pgferror{A nand gate must have at least two inputs}%
+ \fi%
+ }%
+ \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}%
+ \saveddimen\invertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ }%
+ \saveddimen\outerinvertedradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}%
+ \advance\pgf@x.5\pgflinewidth%
+ }%
+ \savedmacro\dimensions{\pgf@lib@sh@logicgates@dimensions@orUS}%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \inheritanchor[from=and gate CDH]{mid east}%
+ \inheritanchor[from=and gate CDH]{mid west}%
+ \anchor{base}{\basepoint}%%
+ \inheritanchor[from=and gate CDH]{base east}%
+ \inheritanchor[from=and gate CDH]{base west}%
+ \anchor{output}{%
+ \dimensions
+ \pgfpointadd{\centerpoint}{%
+ \pgf@xa\halfside%
+ \pgf@x-.166666\pgf@xa%
+ \pgf@xb2.0\pgf@xa%
+ \advance\pgf@x.866025\pgf@xb%
+ \advance\pgf@x\invertedradius%
+ \advance\pgf@x\outerinvertedradius%
+ \advance\pgf@x\outerxsep%
+ \pgf@y0pt%
+ }%
+ }%
+ \inheritanchor[from=and gate CDH]{east}%
+ \inheritanchor[from=and gate CDH]{north east}%
+ \inheritanchor[from=and gate CDH]{south east}%
+ \inheritanchor[from=and gate CDH]{north}%
+ \inheritanchor[from=and gate CDH]{south}%
+ \inheritanchor[from=and gate CDH]{south west}%
+ \inheritanchor[from=and gate CDH]{north west}%
+ \inheritanchor[from=and gate CDH]{west}%
+ \backgroundpath{%
+ \dimensions%
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ \advance\pgf@xc-\outerxsep%
+ \advance\pgf@yc-\outerysep%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{-.16666\pgf@xc}{\pgf@yc}}%
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{90}{30}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ {%
+ \pgf@yc2.0\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpatharc{-30}{-90}{\the\pgf@yc}%
+ }%
+ \pgf@marshal%
+ }
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{-\pgf@yc}}%
+ \pgfpathlineto{\pgfqpoint{-1.16666\pgf@xc}{\pgf@yc}}%
+ \pgfpathclose%
+ %
+ % Draw the output inverter.
+ %
+ {%
+ \pgfpathcircle{%
+ \pgf@x-.166666\pgf@xc%
+ \pgf@yc2.0\pgf@yc%
+ \advance\pgf@x.866025\pgf@yc%
+ \advance\pgf@x\outerinvertedradius%
+ \pgf@y0pt%
+ }{+\invertedradius}%
+ }%
+ %
+ % Draw the inputs.
+ %
+ \pgfutil@tempdima2.0\pgf@yc%
+ \c@pgf@counta\numinputs%
+ \advance\c@pgf@counta1\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\numinputs%
+ \else%
+ \advance\pgf@yc-\pgfutil@tempdima%
+ \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname%
+ {%
+ \pgfpathcircle{%
+ \pgf@xa\halfside%
+ \pgf@x-1.16666\pgf@xa%
+ \advance\pgf@x-.5\pgflinewidth%
+ \advance\pgf@x-\invertedradius%
+ \pgf@y\pgf@yc%
+ }{+\invertedradius}%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ }%
+ \inheritanchorborder[from=and gate CDH]%
+}%
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex
new file mode 100644
index 0000000000..474a183d6f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex
@@ -0,0 +1,103 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+% Common keys for all logic gates.
+%
+\pgfkeys{/pgf/.cd,%
+ logic gate input sep/.initial=0.125cm,
+ logic gate inputs/.initial={normal,normal},%
+ logic gate inverted radius/.initial=2pt,
+}%
+
+
+% Internal macro for parsing inputs.
+%
+\expandafter\ifx\csname pgf@lib@sh@logicgate@parseinputs\endcsname\relax%
+\def\pgf@lib@sh@logicgate@parseinputs#1{%
+ \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate inputs}}%
+ \c@pgf@counta#1\relax%
+ \c@pgf@countb0\relax%
+ \expandafter\pgfutil@in@\expandafter,\expandafter{\pgf@lib@sh@temp}%
+ \ifpgfutil@in@%
+ \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@long%
+ \else%
+ \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@short%
+ \fi%
+ \pgf@lib@sh@next%
+}%
+\def\pgf@lib@sh@itext{i}%
+\def\pgf@lib@sh@invertedtext{inverted}%
+\def\pgf@lib@sh@atchar{@}%
+\def\pgf@lib@sh@gobbletilat#1@{}%
+\def\pgf@lib@sh@gobbletilatcomma#1@,{}%
+%
+% The `short' version for input specification is an extension of
+% ideas due to Juergen Werber and Christoph Bartoschek.
+%
+\def\pgf@lib@sh@logicgate@parseinputs@short{%
+ \expandafter\pgf@lib@sh@logicgate@parseinputs@@short\pgf@lib@sh@temp @%
+}%
+\def\pgf@lib@sh@logicgate@parseinputs@@short#1{%
+ \def\pgf@lib@sh@tmp{#1}%
+ \ifx\pgf@lib@sh@tmp\pgf@lib@sh@atchar%
+ \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}%
+ \let\pgf@lib@sh@next=\relax%
+ \else%
+ \ifnum\c@pgf@countb=\c@pgf@counta%
+ \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}%
+ \let\pgf@lib@sh@next=\pgf@lib@sh@gobbletilat%
+ \else%
+ \advance\c@pgf@countb by1\relax%
+ \expandafter\ifx\pgf@lib@sh@itext#1%
+ \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{%
+ \expandafter\def\csname input-\the\c@pgf@countb\endcsname{i}}%
+ \else%
+ \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{%
+ \expandafter\def\csname input-\the\c@pgf@countb\endcsname{n}}%
+ \fi%
+ \let\pgf@lib@sh@next=\pgf@lib@sh@logicgate@parseinputs@@short%
+ \fi%
+ \fi%
+ \pgf@lib@sh@next%
+}%
+
+
+\def\pgf@lib@sh@logicgate@parseinputs@long{%
+ \expandafter\pgf@lib@sh@logicgate@parseinputs@@long\pgf@lib@sh@temp,@,%
+}%
+\def\pgf@lib@sh@logicgate@parseinputs@@long#1,{%
+ \def\pgf@lib@sh@tmp{#1}%
+ \ifx\pgf@lib@sh@tmp\pgf@lib@sh@atchar%
+ \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}%
+ \let\pgf@lib@sh@next=\relax%
+ \else%
+ \ifnum\c@pgf@countb=\c@pgf@counta%
+ \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}%
+ \let\pgf@lib@sh@next=\pgf@lib@sh@gobbletilatcomma%
+ \else%
+ \advance\c@pgf@countb by1\relax%
+ \def\pgf@lib@sh@temp{#1}%
+ \ifx\pgf@lib@sh@invertedtext\pgf@lib@sh@temp%
+ \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{%
+ \expandafter\def\csname input-\the\c@pgf@countb\endcsname{i}}%
+ \else%
+ \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{%
+ \expandafter\def\csname input-\the\c@pgf@countb\endcsname{n}}%
+ \fi%
+ \let\pgf@lib@sh@next=\pgf@lib@sh@logicgate@parseinputs@@@long%
+ \fi%
+ \fi%
+ \pgf@lib@sh@next%
+}%
+\def\pgf@lib@sh@logicgate@parseinputs@@@long{%
+ \pgfutil@ifnextchar x{\pgf@lib@sh@logicgate@parseinputs@@long}%
+ {\pgf@lib@sh@logicgate@parseinputs@@long}%
+}%
+\fi%
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.arrows.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.arrows.code.tex
new file mode 100644
index 0000000000..be8cb3740c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.arrows.code.tex
@@ -0,0 +1,2361 @@
+% Copyright 2018 by Till Tantau and Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryshapes.arrows.code.tex}
+
+
+% keys for shape single arrow
+%
+% /pgf/single arrow tip angle
+% /pgf/single arrow head extend
+% /pgf/single arrow head indent
+
+\pgfkeys{/pgf/.cd,
+ single arrow tip angle/.initial=90,
+ single arrow head extend/.initial=.25cm,
+ single arrow head indent/.initial=0cm,
+}%
+
+% Shape single arrow
+%
+%
+\pgfdeclareshape{single arrow}{%
+ \savedmacro\getsinglearrowpoints{%
+ %
+ % Get the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \edef\xoutersep{\the\pgf@x}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \edef\youtersep{\the\pgf@y}%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa.5\wd\pgfnodeparttextbox%
+ \advance\pgf@xa.5\pgflinewidth%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya.5\dp\pgfnodeparttextbox%
+ \advance\pgf@ya.5\pgflinewidth%
+ \ifpgfshapeborderusesincircle%
+ \ifdim\pgf@xa<\pgf@ya%
+ \pgf@xa\pgf@ya%
+ \fi%
+ \pgf@xa1.41421\pgf@xa%
+ \pgf@ya\pgf@xa%
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \ifdim\xoutersep>\youtersep\relax%
+ \let\youtersep\xoutersep%
+ \else%
+ \let\xoutersep\youtersep%
+ \fi%
+ \else%
+ %
+ % Round the rotation.
+ %
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \pgfmathmod@{\rotate}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % Calculate the width and height of the node
+ % contents, according to any border rotation.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@x\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \pgf@ya\pgf@x%
+ \let\pgfmathresult\xoutersep%
+ \let\xoutersep\youtersep%
+ \let\youtersep\pgfmathresult%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@x\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \pgf@ya\pgf@x%
+ \let\pgfmathresult\xoutersep%
+ \let\xoutersep\youtersep%
+ \let\youtersep\pgfmathresult%
+ \fi%
+ \fi%
+ \fi%
+ \addtosavedmacro\rotate%
+ %
+ % Get some useful trig stuff.
+ %
+ \pgfmathdivide{\pgfkeysvalueof{/pgf/single arrow tip angle}}{2}%
+ \let\halftipangle\pgfmathresult%
+ \pgfmathcosec@{\halftipangle}%
+ \let\cosechalftipangle\pgfmathresult%
+ \pgfmathcos@{\halftipangle}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \pgfutil@tempdima\cosechalftipangle\pgfutil@tempdima%
+ \edef\cothalftipangle{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \let\sechalftipangle\pgfmathresult%
+ \pgfmathsin@{\halftipangle}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \pgfutil@tempdima\sechalftipangle\pgfutil@tempdima%
+ \edef\tanhalftipangle{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ %
+ % Get the single arrow head extend, and adjust for minimum width.
+ %
+ \pgf@xb\pgf@ya%
+ \pgf@xb\cothalftipangle\pgf@xb%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/single arrow head extend}}%
+ \pgf@yc\pgf@xc%
+ \advance\pgf@xc\pgf@ya%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@xc<.5\pgfutil@tempdimb%
+ \pgfutil@tempdimb.5\pgfutil@tempdimb%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgfutil@tempdimb}}{\pgfmath@tonumber{\pgf@xc}}%
+ \pgf@ya\pgfmathresult\pgf@ya%
+ \pgf@xc\pgfmathresult\pgf@xc%
+ \pgf@yc\pgfmathresult\pgf@yc%
+ \pgf@xb\pgfmathresult\pgf@xb%
+ \fi%
+ %
+ % Now calculate the height of the arrow and adjust for minimum height.
+ %
+ \advance\pgf@xc-\pgf@ya%
+ \pgf@xc\cothalftipangle\pgf@xc%
+ \pgf@xa2.0\pgf@xa%
+ \advance\pgf@xa\pgf@xb%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@xa<\pgfutil@tempdimb%
+ \pgf@xa\pgfutil@tempdimb%
+ \fi%
+ \advance\pgf@xa-\pgf@xb%
+ \pgf@xa.5\pgf@xa%
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/single arrow head indent}}%
+ %
+ % Now:
+ %
+ % xa - .5 * width of the node minus xb.
+ % ya - .5 * height of the node contents.
+ % xb - distance from the end of the node contents to the arrow tip.
+ % xc - distance from the end of the node contents to the back end of the arrow head.
+ % yc - distance from the top of the node contents to the top end of the arrow head.
+ %
+ \pgfsavepgf@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \pgfsavepgf@process\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \pgfsavepgf@process\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ %
+ % As the arrow is symmetrical it can be described by only four points:
+ %
+ \pgfsavepgf@process\arrowtip{%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x\pgf@xb%
+ \pgf@y0pt\relax%
+ }%
+ \pgfsavepgf@process\beforearrowtip{%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x-\pgf@xc%
+ \pgf@y\pgf@ya%
+ \advance\pgf@y\pgf@yc%
+ }%
+ \pgfsavepgf@process\beforearrowhead{%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x-\pgf@xc%
+ \advance\pgf@x\pgfutil@tempdima%
+ \pgf@y\pgf@ya%
+ }%
+ \pgfsavepgf@process\afterarrowtail{%
+ \pgf@x-\pgf@xa%
+ \pgf@y\pgf@ya%
+ }%
+ %
+ % Calculate the anchor point at the arrow tip...
+ %
+ \pgfsavepgf@process\arrowtipanchor{%
+ \pgfpointadd{\centerpoint}{\arrowtip}%
+ \pgf@xa\xoutersep\relax%
+ \advance\pgf@x\cosechalftipangle\pgf@xa%
+ }%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \edef\externalradius{\the\pgf@x}%
+ \addtosavedmacro\externalradius%
+ %
+ % ...and the rest of the points.
+ %
+ \pgfmathanglebetweenlines{\beforearrowtip}{\beforearrowhead}{\beforearrowtip}{\arrowtip}%
+ \pgf@xa\xoutersep\relax%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \pgfutil@tempdima.5\pgfutil@tempdima%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgf@xa\pgfmathresult\pgf@xa%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima180pt\relax%
+ \advance\pgfutil@tempdima-\halftipangle pt\relax%
+ %
+ \pgfsavepgf@process\beforearrowtipanchor{%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgf@xa}%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgf@process{\pgfpointadd{\centerpoint}{\beforearrowtip}}%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ }%
+ \pgfmathanglebetweenpoints{\beforearrowhead}{\beforearrowtip}%
+ \pgfutil@tempdima-\pgfmathresult pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdima.5\pgfutil@tempdima%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgf@xa\xoutersep\relax%
+ \pgf@xa\pgfmathresult\pgf@xa%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfsavepgf@process\beforearrowheadanchor{%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgf@xa}%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgf@process{\pgfpointadd{\centerpoint}{\beforearrowhead}}%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ }%
+ \pgfsavepgf@process\afterarrowtailanchor{%
+ \pgfpointadd{\centerpoint}{\afterarrowtail}%
+ \advance\pgf@x-\xoutersep\relax%
+ \advance\pgf@y\youtersep\relax%
+ }%
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\beforearrowtipanchor}%
+ \let\center@angle@beforearrowtip\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\beforearrowheadanchor}%
+ \let\center@angle@beforearrowhead\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\afterarrowtailanchor}%
+ \let\center@angle@afterarrowtail\pgfmathresult%
+ \addtosavedmacro\center@angle@beforearrowtip%
+ \addtosavedmacro\center@angle@beforearrowhead%
+ \addtosavedmacro\center@angle@afterarrowtail%
+ %
+ \pgfmathanglebetweenpoints{\midpoint}{\beforearrowtipanchor}%
+ \let\mid@angle@beforearrowtip\pgfmathresult%
+ \pgfmathanglebetweenpoints{\midpoint}{\beforearrowheadanchor}%
+ \let\mid@angle@beforearrowhead\pgfmathresult%
+ \pgfmathanglebetweenpoints{\midpoint}{\afterarrowtailanchor}%
+ \let\mid@angle@afterarrowtail\pgfmathresult%
+ \addtosavedmacro\mid@angle@beforearrowtip%
+ \addtosavedmacro\mid@angle@beforearrowhead%
+ \addtosavedmacro\mid@angle@afterarrowtail%
+ %
+ \pgfmathanglebetweenpoints{\basepoint}{\beforearrowtipanchor}%
+ \let\base@angle@beforearrowtip\pgfmathresult%
+ \pgfmathanglebetweenpoints{\basepoint}{\beforearrowheadanchor}%
+ \let\base@angle@beforearrowhead\pgfmathresult%
+ \pgfmathanglebetweenpoints{\basepoint}{\afterarrowtailanchor}%
+ \let\base@angle@afterarrowtail\pgfmathresult%
+ \addtosavedmacro\base@angle@beforearrowtip%
+ \addtosavedmacro\base@angle@beforearrowhead%
+ \addtosavedmacro\base@angle@afterarrowtail%
+ %
+ \addtosavedmacro\arrowtipanchor%
+ \addtosavedmacro\beforearrowtipanchor%
+ \addtosavedmacro\beforearrowheadanchor%
+ \addtosavedmacro\afterarrowtailanchor%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \getsinglearrowpoints%
+ \let\pgf@singlearrow@referencepoint\midpoint%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{mid west}{%
+ \getsinglearrowpoints%
+ \let\pgf@singlearrow@referencepoint\midpoint%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \getsinglearrowpoints%
+ \let\pgf@singlearrow@referencepoint\basepoint%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{base west}{%
+ \getsinglearrowpoints%
+ \let\pgf@singlearrow@referencepoint\basepoint%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{0pt}{\externalradius}}%
+ }%
+ \anchor{south}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}%
+ }%
+ \anchor{east}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north east}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}%
+ }%
+ \anchor{south east}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}%
+ }%
+ \anchor{south west}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}%
+ }%
+ \anchor{north west}{%
+ \getsinglearrowpoints%
+ \csname pgf@anchor@single arrow@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}%
+ }%
+ \anchor{before head}{%
+ \getsinglearrowpoints%
+ \pgfmathrotatepointaround{\beforearrowheadanchor}{\centerpoint}{\rotate}%
+ }%
+ \anchor{before tip}{%
+ \getsinglearrowpoints%
+ \pgfmathrotatepointaround{\beforearrowtipanchor}{\centerpoint}{\rotate}%
+ }%
+ \anchor{tip}{%
+ \getsinglearrowpoints%
+ \pgfmathrotatepointaround{\arrowtipanchor}{\centerpoint}{\rotate}%
+ }%
+ \anchor{after tip}{%
+ \getsinglearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{after head}{%
+ \getsinglearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{before tail}{%
+ \getsinglearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\afterarrowtailanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{after tail}{%
+ \getsinglearrowpoints%
+ \pgfmathrotatepointaround{\afterarrowtailanchor}{\centerpoint}{\rotate}%
+ }%
+ \anchor{tail}{%
+ \getsinglearrowpoints%
+ \pgfpointlineattime{0.5}{%
+ \pgfmathrotatepointaround{\afterarrowtailanchor}{\centerpoint}{\rotate}%
+ }%
+ {%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\afterarrowtailanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ }%
+ \backgroundpath{%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgftransformrotate{\rotate}%
+ \pgfpathmoveto{\arrowtip}%
+ \pgfpathlineto{\beforearrowtip}%
+ \pgfpathlineto{\beforearrowhead}%
+ \pgfpathlineto{\afterarrowtail}%
+ \pgfpathlineto{\afterarrowtail\pgf@y-\pgf@y}%
+ \pgfpathlineto{\beforearrowhead\pgf@y-\pgf@y}%
+ \pgfpathlineto{\beforearrowtip\pgf@y-\pgf@y}%
+ }%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ \pgfsavepgf@process\externalpoint{}%
+ \getsinglearrowpoints%
+ \pgfutil@ifundefined{pgf@singlearrow@referencepoint}{\let\referencepoint\centerpoint}%
+ {\let\referencepoint\pgf@singlearrow@referencepoint}%
+ \pgfsavepgf@process\externalpoint{%
+ \externalpoint%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \referencepoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya}%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\externalangle\pgfmathresult%
+ \pgf@x\externalangle pt\relax%
+ \ifx\referencepoint\midpoint%
+ \pgf@xa\mid@angle@beforearrowtip pt\relax%
+ \pgf@xb\mid@angle@beforearrowhead pt\relax%
+ \pgf@xc\mid@angle@afterarrowtail pt\relax%
+ \else%
+ \ifx\referencepoint\basepoint%
+ \pgf@xa\base@angle@beforearrowtip pt\relax%
+ \pgf@xb\base@angle@beforearrowhead pt\relax%
+ \pgf@xc\base@angle@afterarrowtail pt\relax%
+ \else%
+ \pgf@xa\center@angle@beforearrowtip pt\relax%
+ \pgf@xb\center@angle@beforearrowhead pt\relax%
+ \pgf@xc\center@angle@afterarrowtail pt\relax%
+ \fi%
+ \fi%
+ \ifdim\pgf@x<\pgf@xa%
+ \let\firstpoint\arrowtipanchor%
+ \let\secondpoint\beforearrowtipanchor%
+ \else%
+ \ifdim\pgf@x<\pgf@xb%
+ \ifdim\pgf@xb<\pgf@xa%
+ \let\firstpoint\arrowtipanchor%
+ \let\secondpoint\beforearrowtipanchor%
+ \else%
+ \let\firstpoint\beforearrowheadanchor%
+ \let\secondpoint\beforearrowtipanchor%
+ \fi%
+ \else%
+ \ifdim\pgf@x<\pgf@xc%
+ \let\firstpoint\beforearrowheadanchor%
+ \let\secondpoint\afterarrowtailanchor%
+ \else%
+ \pgf@xc-\pgf@xc%
+ \advance\pgf@xc360pt\relax%
+ \ifdim\pgf@x<\pgf@xc%
+ \let\firstpoint\afterarrowtailanchor%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\afterarrowtailanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}%
+ }%
+ \else%
+ \pgf@xa-\pgf@xa%
+ \advance\pgf@xa360pt\relax%
+ \pgf@xb-\pgf@xb%
+ \advance\pgf@xb360pt\relax%
+ \ifdim\pgf@x<\pgf@xa%
+ \ifdim\pgf@x<\pgf@xb%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\afterarrowtailanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}%
+ }%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}%
+ }%
+ \else%
+ \ifdim\pgf@xb<\pgf@xa%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}%
+ }%
+ \else%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\arrowtipanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}%
+ }%
+ \fi%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}%
+ }%
+ \fi%
+ \else%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}%
+ }%
+ \let\secondpoint\arrowtipanchor%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfmathrotatepointaround{\firstpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfmathrotatepointaround{\secondpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfpointintersectionoflines{\referencepoint}{\externalpoint}%
+ {\firstpoint}{\secondpoint}%
+ }%
+}%
+
+
+
+
+
+
+
+% keys for shape double arrow
+%
+% /pgf/double arrow tip angle
+% /pgf/double arrow head sep
+
+\pgfkeys{/pgf/.cd,
+ double arrow tip angle/.initial=90,
+ double arrow head extend/.initial=.25cm,
+ double arrow head indent/.initial=0cm,
+}%
+
+% Shape double arrow
+%
+%
+\pgfdeclareshape{double arrow}{%
+ \savedmacro\getdoublearrowpoints{%
+ %
+ % Get the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \edef\xoutersep{\the\pgf@x}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \edef\youtersep{\the\pgf@y}%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa.5\wd\pgfnodeparttextbox%
+ \advance\pgf@xa.5\pgflinewidth%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya.5\dp\pgfnodeparttextbox%
+ \advance\pgf@ya.5\pgflinewidth%
+ \ifpgfshapeborderusesincircle%
+ \ifdim\pgf@xa<\pgf@ya%
+ \pgf@xa\pgf@ya%
+ \fi%
+ \pgf@xa1.41421\pgf@xa%
+ \pgf@ya\pgf@xa%
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \ifdim\xoutersep>\youtersep\relax%
+ \let\youtersep\xoutersep%
+ \else%
+ \let\xoutersep\youtersep%
+ \fi%
+ \else%
+ %
+ % Round the rotation.
+ %
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}
+ \pgfmathmod@{\rotate}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % Calculate the width and height of the node
+ % contents, according to any border rotation.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@x\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \pgf@ya\pgf@x%
+ \let\pgfmathresult\xoutersep%
+ \let\xoutersep\youtersep%
+ \let\youtersep\pgfmathresult%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@x\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \pgf@ya\pgf@x%
+ \let\pgfmathresult\xoutersep%
+ \let\xoutersep\youtersep%
+ \let\youtersep\pgfmathresult%
+ \fi%
+ \fi%
+ \fi%
+ \addtosavedmacro\rotate%
+ %
+ % Get some useful trig stuff.
+ %
+ \pgfmathdivide{\pgfkeysvalueof{/pgf/double arrow tip angle}}{2}%
+ \let\halftipangle\pgfmathresult%
+ \pgfmathcosec@{\halftipangle}%
+ \let\cosechalftipangle\pgfmathresult%
+ \pgfmathcos@{\halftipangle}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \pgfutil@tempdima\cosechalftipangle\pgfutil@tempdima%
+ \edef\cothalftipangle{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \let\sechalftipangle\pgfmathresult%
+ \pgfmathsin@{\halftipangle}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \pgfutil@tempdima\sechalftipangle\pgfutil@tempdima%
+ \edef\tanhalftipangle{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ %
+ % Get the double arrow head extend, and adjust for minimum width.
+ %
+ \pgf@xb\pgf@ya%
+ \pgf@xb\cothalftipangle\pgf@xb%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/double arrow head extend}}%
+ \pgf@yc\pgf@xc%
+ \advance\pgf@xc\pgf@ya%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@xc<.5\pgfutil@tempdimb%
+ \pgfutil@tempdimb.5\pgfutil@tempdimb%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgfutil@tempdimb}}{\pgfmath@tonumber{\pgf@xc}}%
+ \pgf@ya\pgfmathresult\pgf@ya%
+ \pgf@xc\pgfmathresult\pgf@xc%
+ \pgf@yc\pgfmathresult\pgf@yc%
+ \pgf@xb\pgfmathresult\pgf@xb%
+ \fi%
+ %
+ % Now calculate the height of the arrow and adjust for minimum height.
+ %
+ \advance\pgf@xc-\pgf@ya%
+ \pgf@xc\cothalftipangle\pgf@xc%
+ \advance\pgf@xa\pgf@xb%
+ \pgf@xa2.0\pgf@xa%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@xa<\pgfutil@tempdimb%
+ \pgf@xa\pgfutil@tempdimb%
+ \fi%
+ \pgf@xa.5\pgf@xa%
+ \advance\pgf@xa-\pgf@xb%
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/double arrow head indent}}%
+ %
+ % Now:
+ %
+ % xa - .5 * width of the node minus xb.
+ % ya - .5 * height of the node contents.
+ % xb - distance from the end of the node contents to the arrow tip.
+ % xc - distance from the end of the node contents to the back end of the arrow head.
+ % yc - distance from the top of the node contents to the top end of the arrow head.
+ %
+ \pgfsavepgf@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \pgfsavepgf@process\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \pgfsavepgf@process\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ %
+ % As the arrow is symmetrical it can be described by only 3 points:
+ %
+ \pgfsavepgf@process\arrowtip{%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x\pgf@xb%
+ \pgf@y0pt\relax%
+ }%
+ \pgfsavepgf@process\beforearrowtip{%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x-\pgf@xc%
+ \pgf@y\pgf@ya%
+ \advance\pgf@y\pgf@yc%
+ }%
+ \pgfsavepgf@process\beforearrowhead{%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x-\pgf@xc%
+ \advance\pgf@x\pgfutil@tempdima%
+ \pgf@y\pgf@ya%
+ }%
+ %
+ % Calculate the anchor point at the arrow tip.
+ %
+ \pgfsavepgf@process\arrowtipanchor{%
+ \pgfpointadd{\centerpoint}{\arrowtip}%
+ \pgf@xa\xoutersep\relax%
+ \advance\pgf@x\cosechalftipangle\pgf@xa%
+ }%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \edef\externalradius{\the\pgf@x}%
+ \addtosavedmacro\externalradius%
+ %
+ %
+ \pgfmathanglebetweenlines{\beforearrowtip}{\beforearrowhead}{\beforearrowtip}{\arrowtip}%
+ \pgf@xa\xoutersep\relax%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \pgfutil@tempdima.5\pgfutil@tempdima%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgf@xa\pgfmathresult\pgf@xa%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima180pt\relax%
+ \advance\pgfutil@tempdima-\halftipangle pt\relax%
+ \pgfsavepgf@process\beforearrowtipanchor{%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgf@xa}%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgf@process{\pgfpointadd{\centerpoint}{\beforearrowtip}}%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ }%
+ \pgfmathanglebetweenpoints{\beforearrowhead}{\beforearrowtip}%
+ \pgfutil@tempdima-\pgfmathresult pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdima.5\pgfutil@tempdima%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgf@xa\xoutersep\relax%
+ \pgf@xa\pgfmathresult\pgf@xa%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfsavepgf@process\beforearrowheadanchor{%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgf@xa}%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgf@process{\pgfpointadd{\centerpoint}{\beforearrowhead}}%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ }%
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\beforearrowtipanchor}%
+ \let\center@angle@beforearrowtip\pgfmathresult%
+ \addtosavedmacro\center@angle@beforearrowtip%
+ %
+ \pgfmathanglebetweenpoints{\midpoint}{\beforearrowtipanchor}%
+ \let\mid@angle@beforearrowtip\pgfmathresult%
+ \addtosavedmacro\mid@angle@beforearrowtip%
+ %
+ \pgfmathanglebetweenpoints{\basepoint}{\beforearrowtipanchor}%
+ \let\base@angle@beforearrowtip\pgfmathresult%
+ \addtosavedmacro\base@angle@beforearrowtip%
+ %
+ \addtosavedmacro\arrowtipanchor%
+ \addtosavedmacro\beforearrowtipanchor%
+ \addtosavedmacro\beforearrowheadanchor%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \getdoublearrowpoints%
+ \let\pgf@singlearrow@referencepoint\midpoint%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{mid west}{%
+ \getdoublearrowpoints%
+ \let\pgf@singlearrow@referencepoint\midpoint%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \getdoublearrowpoints%
+ \let\pgf@singlearrow@referencepoint\basepoint%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{base west}{%
+ \getdoublearrowpoints%
+ \let\pgf@singlearrow@referencepoint\basepoint%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{0pt}{\externalradius}}%
+ }%
+ \anchor{south}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}%
+ }%
+ \anchor{east}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north east}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}%
+ }%
+ \anchor{south east}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}%
+ }%
+ \anchor{south west}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}%
+ }%
+ \anchor{north west}{%
+ \getdoublearrowpoints%
+ \csname pgf@anchor@double arrow@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}%
+ }%
+ \anchor{before head 1}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{\beforearrowheadanchor}{\centerpoint}{\rotate}%
+ }%
+ \anchor{before tip 1}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{\beforearrowtipanchor}{\centerpoint}{\rotate}%
+ }%
+ \anchor{tip 1}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{\arrowtipanchor}{\centerpoint}{\rotate}%
+ }%
+ \anchor{after tip 1}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{after head 1}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{before head 2}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{before tip 2}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{tip 2}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\arrowtipanchor}%
+ \pgf@x-\pgf@x%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{after tip 2}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@x-\pgf@x%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{after head 2}{%
+ \getdoublearrowpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@x-\pgf@x%
+ }{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \backgroundpath{%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgftransformrotate{\rotate}%
+ \pgfpathmoveto{\arrowtip}%
+ \pgfpathlineto{\beforearrowtip}%
+ \pgfpathlineto{\beforearrowhead}%
+ \pgfpathlineto{\beforearrowhead\pgf@x-\pgf@x}%
+ \pgfpathlineto{\beforearrowtip\pgf@x-\pgf@x}%
+ \pgfpathlineto{\arrowtip\pgf@x-\pgf@x}%
+ \pgfpathlineto{\beforearrowtip\pgf@x-\pgf@x\pgf@y-\pgf@y}%
+ \pgfpathlineto{\beforearrowhead\pgf@x-\pgf@x\pgf@y-\pgf@y}%
+ \pgfpathlineto{\beforearrowhead\pgf@y-\pgf@y}%
+ \pgfpathlineto{\beforearrowtip\pgf@y-\pgf@y}%
+ }%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ \pgfsavepgf@process\externalpoint{}%
+ \getdoublearrowpoints%
+ \pgfutil@ifundefined{pgf@singlearrow@referencepoint}{\let\referencepoint\centerpoint}%
+ {\let\referencepoint\pgf@singlearrow@referencepoint}%
+ \pgfsavepgf@process\externalpoint{%
+ \externalpoint%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \referencepoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya}%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\externalangle\pgfmathresult%
+ \pgf@x\externalangle pt\relax%
+ \ifx\referencepoint\midpoint%
+ \pgf@xa\mid@angle@beforearrowtip pt\relax%
+ \else%
+ \ifx\referencepoint\basepoint%
+ \pgf@xa\base@angle@beforearrowtip pt\relax%
+ \else%
+ \pgf@xa\center@angle@beforearrowtip pt\relax%
+ \fi%
+ \fi%
+ \ifdim\pgf@x<180pt\relax%
+ \ifdim\pgf@x<\pgf@xa%
+ \let\firstpoint\arrowtipanchor%
+ \let\secondpoint\beforearrowtipanchor%
+ \else%
+ \pgf@xa-\pgf@xa%
+ \advance\pgf@xa180pt\relax%
+ \ifdim\pgf@x<\pgf@xa%
+ \let\firstpoint\beforearrowheadanchor%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@x-\pgf@x
+ }{\centerpoint}}%
+ \else%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@x-\pgf@x
+ }{\centerpoint}}%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\arrowtipanchor}%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ \fi%
+ \fi%
+ \else%
+ \pgf@xa-\pgf@xa%
+ \advance\pgf@xa360pt\relax%
+ \ifdim\pgf@x<\pgf@xa%
+ \pgf@xa-\pgf@xa%
+ \advance\pgf@xa540pt\relax%
+ \ifdim\pgf@x<\pgf@xa%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\arrowtipanchor}%
+ \pgf@x-\pgf@x%
+ }{\centerpoint}}%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowtipanchor}%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ \else%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\centerpoint}{\beforearrowheadanchor}%
+ \pgf@y-\pgf@y%
+ }{\centerpoint}}%
+ \fi%
+ \else%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfpointadd{%
+ \pgfpointdiff{\beforearrowtipanchor}{\centerpoint}%
+ \pgf@x-\pgf@x%
+ }{\centerpoint}}%
+ \let\secondpoint\arrowtipanchor%
+ \fi%
+ \fi%
+ \pgfsavepgf@process\firstpoint{%
+ \pgfmathrotatepointaround{\firstpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfsavepgf@process\secondpoint{%
+ \pgfmathrotatepointaround{\secondpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfpointintersectionoflines{\referencepoint}{\externalpoint}%
+ {\firstpoint}{\secondpoint}%
+ }%
+}%
+
+
+
+
+%
+% Internal macros for the arrow box/shape.
+%
+\def\pgf@lib@arrowbox@parsearrowlength#1#2#3{%
+ \edef\pgf@lib@temp{#3}%
+ \edef\pgf@lib@marshal{%
+ \noexpand\pgfutil@in@{none}{\pgf@lib@temp}%
+ }%
+ \pgf@lib@marshal%
+ \ifpgfutil@in@%
+ #10pt\relax%
+ \else%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter#1\pgf@lib@temp\relax\pgfmath@%
+ %
+ \edef\pgf@lib@marshal{%
+ \noexpand\pgfutil@in@{from center}{\pgf@lib@temp}%
+ }%
+ \pgf@lib@marshal%
+ \ifpgfutil@in@%
+ \else%
+ \ifdim#1>0pt\relax%
+ \advance#1#2\relax%
+ \fi%
+ \fi%
+ \fi}%
+
+\def\pgf@lib@arrowbox@parsearrows#1{%
+ \pgfkeys{/pgf/.cd,%
+ arrow box west arrow=0pt,
+ arrow box east arrow=0pt,
+ arrow box south arrow=0pt,
+ arrow box north arrow=0pt
+ }%
+ \def\pgf@lib@arrowbox@extend{0pt}%
+ \edef\pgf@lib@temp{#1}%
+ \expandafter\pgf@lib@arrowbox@@parsearrows\pgf@lib@temp,\pgf@lib@arrowbox@parsearrows,
+}%
+
+
+\def\pgf@lib@arrowbox@@parsearrows#1,{%
+ \ifx\pgf@lib@arrowbox@parsearrows#1%
+ \let\pgflib@next\relax%
+ \else%
+ \pgfutil@in@:{#1}%
+ \ifpgfutil@in@%
+ \pgf@lib@arrowbox@getextend#1\pgf@lib%
+ \else%
+ \def\pgf@lib@arrowbox@direction{#1}%
+ \fi%
+ \edef\pgf@marshal{%
+ \noexpand\pgfkeys{/pgf/arrow box \pgf@lib@arrowbox@direction\space arrow=\pgf@lib@arrowbox@extend}%
+ }%
+ \pgf@marshal%
+ \let\pgflib@next\pgf@lib@arrowbox@@@parsearrows%
+ \fi%
+ \pgflib@next%
+}%
+\def\pgf@lib@arrowbox@@@parsearrows{%
+ \pgfutil@ifnextchar x{\relax\pgf@lib@arrowbox@@parsearrows}{\relax\pgf@lib@arrowbox@@parsearrows}%
+}%
+
+\def\pgf@lib@arrowbox@getextend#1:#2\pgf@lib{%
+ \def\pgf@lib@arrowbox@direction{#1}%
+ \def\pgf@lib@arrowbox@extend{#2}%
+}%
+
+%
+% /pgf/arrow box north arrow
+% /pgf/arrow box south arrow
+% /pgf/arrow box west arrow
+% /pgf/arrow box east arrow
+% /pgf/arrow box arrows
+% /pgf/arrow box shaft width
+% /pgf/arrow box head extend
+% /pgf/arrow box head indent
+% /pgf/arrow box tip angle
+%
+\pgfkeys{/pgf/.cd,
+ arrow box west arrow/.initial=.5cm,
+ arrow box east arrow/.initial=.5cm,
+ arrow box south arrow/.initial=.5cm,
+ arrow box north arrow/.initial=.5cm,
+ arrow box shaft width/.initial=.125cm,
+ arrow box head extend/.initial=.125cm,
+ arrow box head indent/.initial=0cm,
+ arrow box tip angle/.initial=90,
+}%
+
+%
+% arrow box/Shape.
+%
+\pgfdeclareshape{arrow box}{%
+ \saveddimen\shaftwidth{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/arrow box shaft width}}%
+ }%
+ %
+ % Calculate far the arrows extend from the center of the node.
+ %
+ \savedmacro\arrowboxpoints{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ %
+ \edef\halfboxwidth{\the\pgf@x}%
+ \edef\halfboxheight{\the\pgf@y}%
+ \pgfextract@process\arrowboxcorner{}%
+ \addtosavedmacro\arrowboxcorner%
+ %
+ \pgf@lib@arrowbox@parsearrowlength\pgf@x{\halfboxwidth}%
+ {\pgfkeysvalueof{/pgf/arrow box west arrow}}%
+ \edef\westextend{\the\pgf@x}%
+ \addtosavedmacro\westextend%
+ %
+ \pgf@lib@arrowbox@parsearrowlength\pgf@x{\halfboxwidth}%
+ {\pgfkeysvalueof{/pgf/arrow box east arrow}}%
+ \edef\eastextend{\the\pgf@x}%
+ \addtosavedmacro\eastextend%
+ %
+ \pgf@lib@arrowbox@parsearrowlength\pgf@x{\halfboxheight}%
+ {\pgfkeysvalueof{/pgf/arrow box north arrow}}%
+ \edef\northextend{\the\pgf@x}%
+ \addtosavedmacro\northextend%
+ %
+ \pgf@lib@arrowbox@parsearrowlength\pgf@x{\halfboxheight}%
+ {\pgfkeysvalueof{/pgf/arrow box south arrow}}%
+ \edef\southextend{\the\pgf@x}%
+ \addtosavedmacro\southextend%
+ }%
+ \saveddimen\arrowheadextend{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/arrow box head extend}}%
+ }%
+ \saveddimen\arrowheadindent{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/arrow box head indent}}%
+ }%
+ %
+ % Calculate the `miter' angle for the outer sep at the arrow tip.
+ %
+ \savedmacro\arrowtipmiterangle{%
+ \pgfmathparse{\pgfkeysvalueof{/pgf/arrow box tip angle}}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\arrowtipmiterangle\pgfmathresult%
+ }%
+ %
+ % Calculate the `miter' angle for the outer sep at the point just
+ % before the arrow tip.
+ %
+ \savedmacro\arrowheadangles{%
+ %
+ % Calculate the `miter' angle and its cosecant at the arrow tip...
+ %
+ \pgfmathparse{\pgfkeysvalueof{/pgf/arrow box tip angle}}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\arrowtipmiterangle\pgfmathresult%
+ \addtosavedmacro\arrowtipmiterangle%
+ \pgfmathcosec@{\arrowtipmiterangle}%
+ \let\cosecarrowtipmiterangle\pgfmathresult%
+ \addtosavedmacro\cosecarrowtipmiterangle%
+ %
+ % ...before the arrow head...
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/arrow box head extend}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/arrow box head indent}}%
+ \ifdim\pgf@y=0pt\relax%
+ \def\pgfmathresult{90}%
+ \else%
+ \ifdim\pgf@y<0pt\relax%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \pgfmathatan@{\pgfmathresult}%
+ \pgfmathadd@{\pgfmathresult}{180}%
+ \else%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \pgfmathatan@{\pgfmathresult}%
+ \fi%
+ \fi%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\beforearrowheadmiterangle\pgfmathresult%
+ \addtosavedmacro\beforearrowheadmiterangle%
+ \pgfmathcosec@{\beforearrowheadmiterangle}%
+ \let\cosecbeforearrowheadmiterangle\pgfmathresult%
+ \addtosavedmacro\cosecbeforearrowheadmiterangle%
+ %
+ % ...and before the arrow tip.
+ %
+ \pgfutil@tempdima-\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima90pt\relax%
+ \pgfutil@tempdimb\beforearrowheadmiterangle pt\relax%
+ \pgfutil@tempdimb2.0\pgfutil@tempdimb%
+ \advance\pgfutil@tempdimb-90pt\relax%
+ \advance\pgfutil@tempdima\pgfutil@tempdimb%
+ \divide\pgfutil@tempdima2\relax%
+ \edef\beforearrowtipmiterangle{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \addtosavedmacro\beforearrowtipmiterangle%
+ \pgfmathcosec@{\beforearrowtipmiterangle}%
+ \let\cosecbeforearrowtipmiterangle\pgfmathresult%
+ \addtosavedmacro\cosecbeforearrowtipmiterangle%
+ }%
+ \saveddimen\outerxsep{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ }%
+ \saveddimen\outerysep{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer ysep}}%
+ }%
+ %
+ % Calculate the (path) point immediately prior to an arrow tip.
+ %
+ \savedanchor\beforearrowtip{%
+ \pgfmathparse{\pgfkeysvalueof{/pgf/arrow box tip angle}}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \pgfmathcot@{\pgfmathresult}%
+ \let\cothalfangle\pgfmathresult%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/arrow box shaft width}}%
+ \pgf@y.5\pgf@y%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/arrow box head extend}}%
+ \pgf@y\pgf@y%
+ \pgf@x\cothalfangle\pgf@y%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \let\pgf@lib@shapes@arrowbox@referencepoint\midpoint%
+ \csname pgf@anchor@arrow box@border\endcsname{\pgfqpoint{\eastextend}{0pt}}%
+ \else%
+ \arrowboxcorner%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \advance\pgf@x\pgf@xa%
+ \fi%
+ }%
+ \anchor{mid west}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \let\pgf@lib@shapes@arrowbox@referencepoint\midpoint%
+ \csname pgf@anchor@arrow box@border\endcsname{\pgfqpoint{-\westextend}{0pt}}%
+ \else%
+ \arrowboxcorner%
+ \pgf@xa\pgf@x%
+ \midpoint%
+ \advance\pgf@x-\pgf@xa%
+ \fi%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \let\pgf@lib@shapes@arrowbox@referencepoint\basepoint%
+ \csname pgf@anchor@arrow box@border\endcsname{\pgfqpoint{\eastextend}{0pt}}%
+ \else%
+ \arrowboxcorner%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \advance\pgf@x\pgf@xa%
+ \fi%
+ }%
+ \anchor{base west}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \let\pgf@lib@shapes@arrowbox@referencepoint\basepoint%
+ \csname pgf@anchor@arrow box@border\endcsname{\pgfqpoint{-\westextend}{0pt}}%
+ \else%
+ \arrowboxcorner%
+ \pgf@xa\pgf@x%
+ \basepoint%
+ \advance\pgf@x-\pgf@xa%
+ \fi%
+ }%
+ \anchor{north}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \csname pgf@anchor@arrow box@north arrow tip\endcsname%
+ \else%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner}%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y\pgf@ya%
+ \fi%
+ }%
+ \anchor{south}{%
+ \arrowboxpoints%
+ \ifdim\southextend>0pt\relax%
+ \csname pgf@anchor@arrow box@south arrow tip\endcsname%
+ \else%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner\pgf@y-\pgf@y}%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y\pgf@ya%
+ \fi%
+ }%
+ \anchor{east}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \csname pgf@anchor@arrow box@east arrow tip\endcsname%
+ \else%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner}%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \pgf@x\pgf@xa%
+ \fi%
+ }%
+ \anchor{west}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \csname pgf@anchor@arrow box@west arrow tip\endcsname%
+ \else%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner\pgf@x-\pgf@x}%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \pgf@x\pgf@xa%
+ \fi%
+ }%
+ \anchor{north east}{%
+ \arrowboxpoints%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner}%
+ }%
+ \anchor{north west}{%
+ \arrowboxpoints%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner\pgf@x-\pgf@x}%
+ }%
+ \anchor{south west}{%
+ \arrowboxpoints%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner\pgf@x-\pgf@x\pgf@y-\pgf@y}%
+ }%
+ \anchor{south east}{%
+ \arrowboxpoints%
+ \pgfpointadd{\centerpoint}{\arrowboxcorner\pgf@y-\pgf@y}%
+ }%
+ \anchor{before east arrow}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ \advance\pgf@y\outerysep\relax%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ \anchor{before east arrow head}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ \advance\pgf@x\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ \anchor{before east arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ }%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ \anchor{east arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \centerpoint%
+ \advance\pgf@x\eastextend\relax%
+ \pgf@xa\outerxsep\relax%
+ \pgfmathcosec@{\arrowtipmiterangle}%
+ \advance\pgf@x\pgfmathresult\pgf@xa%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ \anchor{after east arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ }%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ \anchor{after east arrow head}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ \advance\pgf@x\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ \anchor{after east arrow}{%
+ \arrowboxpoints%
+ \ifdim\eastextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ \advance\pgf@y\outerysep\relax%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ %
+ \anchor{before west arrow}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@x-\pgf@x%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ \advance\pgf@y\outerysep\relax%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@west\endcsname%
+ \fi%
+ }%
+ \anchor{before west arrow head}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\westextend\relax%
+ \advance\pgf@x\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@west\endcsname%
+ \fi%
+ }%
+ \anchor{before west arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\westextend\relax%
+ }%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@west\endcsname%
+ \fi%
+ }%
+ \anchor{west arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \centerpoint%
+ \advance\pgf@x-\westextend\relax%
+ \pgf@xa\outerxsep\relax%
+ \pgfmathcosec@{\arrowtipmiterangle}%
+ \advance\pgf@x-\pgfmathresult\pgf@xa%
+ \else%
+ \csname pgf@anchor@arrow box@west\endcsname%
+ \fi%
+ }%
+ \anchor{after west arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\westextend\relax%
+ }%
+ \pgf@x-\pgf@x%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@west\endcsname%
+ \fi%
+ }%
+ \anchor{after west arrow head}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\westextend\relax%
+ \advance\pgf@x\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ \pgf@x-\pgf@x%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@west\endcsname%
+ \fi%
+ }%
+ \anchor{after west arrow}{%
+ \arrowboxpoints%
+ \ifdim\westextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ \advance\pgf@y\outerysep\relax%
+ \pgf@x-\pgf@x%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@west\endcsname%
+ \fi%
+ }%
+ %
+ \anchor{before north arrow}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@x-\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ \advance\pgf@x-\outerxsep\relax%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@north\endcsname%
+ \fi%
+ }%
+ \anchor{before north arrow head}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima270pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \advance\pgf@y\arrowheadindent\relax%
+ \pgf@x-\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ }%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@north\endcsname%
+ \fi%
+ }%
+ \anchor{before north arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-90pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y-\pgf@xa%
+ \advance\pgf@y\northextend\relax%
+ }%
+ \pgf@x-\pgf@x%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@north\endcsname%
+ \fi%
+ }%
+ \anchor{north arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \centerpoint%
+ \advance\pgf@y\northextend\relax%
+ \pgf@ya\outerysep\relax%
+ \pgfmathcosec@{\arrowtipmiterangle}%
+ \advance\pgf@y\pgfmathresult\pgf@ya%
+ \else%
+ \csname pgf@anchor@arrow box@north\endcsname%
+ \fi%
+ }%
+ \anchor{after north arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-90pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y-\pgf@xa%
+ \advance\pgf@y\northextend\relax%
+ }%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@north\endcsname%
+ \fi%
+ }%
+ \anchor{after north arrow head}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima270pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \advance\pgf@y\arrowheadindent\relax%
+ \pgf@x-\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ }%
+ \pgf@x-\pgf@x%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@north\endcsname%
+ \fi%
+ }%
+ \anchor{after north arrow}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ \advance\pgf@x\outerxsep\relax%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@north\endcsname%
+ \fi%
+ }%
+ %
+ \anchor{before south arrow}{%
+ \arrowboxpoints%
+ \ifdim\southextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ \advance\pgf@x\outerxsep\relax%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@south\endcsname%
+ \fi%
+ }%
+ \anchor{before south arrow head}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima270pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \advance\pgf@y\arrowheadindent\relax%
+ \pgf@x-\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ }%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@south\endcsname%
+ \fi%
+ }%
+ \anchor{before south arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-90pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y-\pgf@xa%
+ \advance\pgf@y\northextend\relax%
+ }%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@south\endcsname%
+ \fi%
+ }%
+ \anchor{south arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\southextend>0pt\relax%
+ \centerpoint%
+ \advance\pgf@y-\southextend\relax%
+ \pgf@ya\outerysep\relax%
+ \pgfmathcosec@{\arrowtipmiterangle}%
+ \advance\pgf@y-\pgfmathresult\pgf@ya%
+ \else%
+ \csname pgf@anchor@arrow box@east\endcsname%
+ \fi%
+ }%
+ \anchor{after south arrow tip}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima\arrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima\beforearrowtipmiterangle pt\relax%
+ \advance\pgfutil@tempdima-90pt\relax%
+ \pgfutil@tempdimb\outerxsep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowtipmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y-\pgf@xa%
+ \advance\pgf@y\northextend\relax%
+ }%
+ \pgf@x-\pgf@x%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@south\endcsname%
+ \fi%
+ }%
+ \anchor{after south arrow head}{%
+ \arrowboxpoints%
+ \ifdim\northextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointadd{%
+ \arrowheadangles%
+ \pgfutil@tempdima-\beforearrowheadmiterangle pt\relax%
+ \advance\pgfutil@tempdima270pt\relax%
+ \pgfutil@tempdimb\outerysep\relax%
+ \pgfutil@tempdimb\cosecbeforearrowheadmiterangle\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \beforearrowtip%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \advance\pgf@y\arrowheadindent\relax%
+ \pgf@x-\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ }%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@south\endcsname%
+ \fi%
+ }%
+ \anchor{after south arrow}{%
+ \arrowboxpoints%
+ \ifdim\southextend>0pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \arrowboxcorner%
+ \pgf@x-\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ \advance\pgf@x-\outerxsep\relax%
+ \pgf@y-\pgf@y%
+ }%
+ \else%
+ \csname pgf@anchor@arrow box@south\endcsname%
+ \fi%
+ }%
+ %
+ \backgroundpath{%
+ \arrowboxpoints%
+ \pgfextract@process\arrowboxcorner{%
+ \arrowboxcorner%
+ \pgfmathaddtolength\pgf@x{-\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{-\pgfkeysvalueof{/pgf/outer ysep}}%
+ }%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\arrowboxcorner}%
+ \ifdim\eastextend>0pt\relax%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ \advance\pgf@x\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ }%
+ \pgfpathlineto{%
+ \pgf@x\eastextend\relax%
+ \pgf@y0pt\relax%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ \pgf@y-\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@x-\pgf@x%
+ \advance\pgf@x\eastextend\relax%
+ \advance\pgf@x\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y-.5\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y-.5\pgf@y%
+ }%
+ \fi%
+ \pgfpathlineto{\arrowboxcorner\pgf@y-\pgf@y}%
+ \ifdim\southextend>0pt\relax%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ \pgf@y-\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@y\pgf@x%
+ \advance\pgf@y-\southextend\relax%
+ \advance\pgf@y-\arrowheadindent\relax%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@xa\pgf@y%
+ \pgf@y\pgf@x%
+ \advance\pgf@y-\southextend\relax%
+ \pgf@x\pgf@xa%
+ }%
+ \pgfpathlineto{%
+ \pgf@x0pt\relax%
+ \pgf@y-\southextend\relax%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@xa\pgf@y%
+ \pgf@y\pgf@x%
+ \advance\pgf@y-\southextend\relax%
+ \pgf@x-\pgf@xa%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@y\pgf@x%
+ \advance\pgf@y-\southextend\relax%
+ \advance\pgf@y-\arrowheadindent\relax%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x-.5\pgf@x%
+ }%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x-.5\pgf@x%
+ \pgf@y-\pgf@y%
+ }%
+ \fi%
+ \pgfpathlineto{\arrowboxcorner\pgf@x-\pgf@x\pgf@y-\pgf@y}%
+ \ifdim\westextend>0pt\relax%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@x-\pgf@x
+ \pgf@y\shaftwidth\relax%
+ \pgf@y-.5\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \advance\pgf@x-\westextend\relax%
+ \advance\pgf@x-\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y-.5\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \advance\pgf@x-\westextend\relax%
+ \pgf@y-\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \pgf@x-\westextend\relax%
+ \pgf@y0pt\relax%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \advance\pgf@x-\westextend\relax%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \advance\pgf@x-\westextend\relax%
+ \advance\pgf@x-\arrowheadindent\relax%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@x-\pgf@x%
+ \pgf@y\shaftwidth\relax%
+ \pgf@y.5\pgf@y%
+ }%
+ \fi%
+ \pgfpathlineto{\arrowboxcorner\pgf@x-\pgf@x}%
+ \ifdim\northextend>0pt\relax%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x-.5\pgf@x%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \advance\pgf@y\arrowheadindent\relax%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x-.5\pgf@x%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@xa\pgf@y%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \pgf@x-\pgf@xa%
+ }%
+ \pgfpathlineto{%
+ \pgf@x0pt\relax%
+ \pgf@y\northextend\relax%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@xa\pgf@y%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \pgf@x\pgf@xa%
+ }%
+ \pgfpathlineto{%
+ \beforearrowtip%
+ \pgf@y-\pgf@x%
+ \advance\pgf@y\northextend\relax%
+ \advance\pgf@y\arrowheadindent\relax%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ }%
+ \pgfpathlineto{%
+ \arrowboxcorner%
+ \pgf@x\shaftwidth\relax%
+ \pgf@x.5\pgf@x%
+ }%
+ \fi%
+ \pgfpathclose%
+ }%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \pgfutil@ifundefined{pgf@lib@shapes@arrowbox@referencepoint}%
+ {\let\referencepoint\centerpoint}{\let\referencepoint\pgf@lib@shapes@arrowbox@referencepoint}%
+ \pgfextract@process\externalpoint{%
+ \pgfpointadd{\referencepoint}{\externalpoint}%
+ }%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle\pgfmathresult%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@north\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@north east\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before east arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{east arrow tip}%
+ \def\secondpoint{before east arrow tip}%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before east arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{before east arrow head}%
+ \def\secondpoint{before east arrow}%
+ \else%
+ \def\firstpoint{before east arrow}%
+ \def\secondpoint{north east}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after north arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after north arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{north east}%
+ \def\secondpoint{after north arrow}%
+ \else%
+ \def\firstpoint{after north arrow}%
+ \def\secondpoint{after north arrow head}%
+ \fi%
+ \else%
+ \def\firstpoint{after north arrow tip}%
+ \def\secondpoint{north arrow tip}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@north west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before north arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{north arrow tip}%
+ \def\secondpoint{before north arrow tip}%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before north arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{before north head}%
+ \def\secondpoint{before north arrow}%
+ \else%
+ \def\firstpoint{before north arrow}%
+ \def\secondpoint{north west}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after west arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after west arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{north west}%
+ \def\secondpoint{after west arrow}%
+ \else%
+ \def\firstpoint{after west arrow}%
+ \def\secondpoint{after west arrow head}%
+ \fi%
+ \else%
+ \def\firstpoint{after west arrow tip}%
+ \def\secondpoint{west arrow tip}%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@south arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@south west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before west arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{west arrow tip}%
+ \def\secondpoint{before west arrow tip}%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before west arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{before west arrow head}%
+ \def\secondpoint{before west arrow}%
+ \else%
+ \def\firstpoint{before west arrow}%
+ \def\secondpoint{south west}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after south arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after south arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{south west}%
+ \def\secondpoint{after south arrow}%
+ \else%
+ \def\firstpoint{after south arrow}%
+ \def\secondpoint{after south arrow head}%
+ \fi%
+ \else%
+ \def\firstpoint{after south arrow tip}%
+ \def\secondpoint{south arrow tip}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@south east\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before south arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{south arrow tip}%
+ \def\secondpoint{before south arrow tip}%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@before south arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{before south arrow head}%
+ \def\secondpoint{before south arrow}%
+ \else%
+ \def\firstpoint{before south arrow}%
+ \def\secondpoint{south east}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after east arrow tip\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}%
+ {\csname pgf@anchor@arrow box@after east arrow\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \def\firstpoint{south east}%
+ \def\secondpoint{after east arrow}%
+ \else%
+ \def\firstpoint{after east arrow}%
+ \def\secondpoint{after east arrow head}%
+ \fi%
+ \else%
+ \def\firstpoint{after east arrow tip}%
+ \def\secondpoint{east arrow tip}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgfpointintersectionoflines{\referencepoint}{\externalpoint}%
+ {\csname pgf@anchor@arrow box@\firstpoint\endcsname}%
+ {\csname pgf@anchor@arrow box@\secondpoint\endcsname}%
+ }%
+}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.callouts.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.callouts.code.tex
new file mode 100644
index 0000000000..72d9761a19
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.callouts.code.tex
@@ -0,0 +1,951 @@
+% Copyright 2018 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\usepgflibrary{shapes.symbols}%
+
+% Keys for callouts
+%
+% Common to all callouts:
+% /pgf/callout absolute pointer
+% /pgf/callout relative pointer
+%
+% ellipse callout only:
+% /pgf/callout pointer arc
+%
+% rectangle callout only:
+% /pgf/callout pointer width
+%
+% cloud callout only:
+% /pgf/callout pointer start size
+% /pgf/callout pointer end size
+% /pgf/callout pointer segments
+%
+\newif\ifpgf@lib@callout@absolutepointer
+\pgfkeys{/pgf/.cd,
+ callout pointer arc/.initial=15,
+ callout pointer width/.initial=.25cm,
+ callout pointer start size/.initial=.2 of callout,
+ callout pointer end size/.initial=.1 of callout,
+ callout pointer segments/.initial=2,
+ callout absolute pointer/.code={\pgf@lib@callout@makeabsolutepointer{#1}},
+ callout relative pointer/.code={\pgf@lib@callout@makerelativepointer{#1}},
+ callout pointer shorten/.initial=0cm,
+}%
+
+
+
+\def\pgf@lib@callout@makeabsolutepointer#1{%
+ \pgf@lib@callout@absolutepointertrue%
+ {%
+ \pgftransformshift{#1}%
+ \pgfmultipartnode{coordinate}{center}{pgf@lib@callout@pointer}{}%
+ }%
+}%
+
+\def\pgf@lib@callout@makerelativepointer#1{%
+ \pgf@lib@callout@absolutepointerfalse%
+ \def\pgf@lib@callout@relativepointer{#1}%
+}%
+\pgfkeys{/pgf/callout relative pointer=\pgfpointpolar{300}{.5cm}}%
+
+
+% Shape ellipse callout
+%
+%
+\pgfdeclareshape{ellipse callout}{%
+ \savedmacro\ellipsecalloutpoints{%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x>\pgf@y%
+ \edef\outersep{\the\pgf@x}%
+ \else%
+ \edef\outersep{\the\pgf@y}%
+ \fi%
+ \addtosavedmacro\outersep%
+ %
+ % Calculate the node dimensions...
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@x1.4142136\pgf@x%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \pgf@y1.4142136\pgf@y%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ %
+ % ...without outer sep...
+ %
+ \edef\xpathradius{\the\pgf@x}%
+ \edef\ypathradius{\the\pgf@y}%
+ %
+ % ...and width outer sep.
+ %
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \edef\xradius{\the\pgf@x}%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \edef\yradius{\the\pgf@y}%
+ %
+ \addtosavedmacro\xradius%
+ \addtosavedmacro\xpathradius%
+ \addtosavedmacro\yradius%
+ \addtosavedmacro\ypathradius%
+ %
+ \pgfmathsetmacro\pointerarc{\pgfkeysvalueof{/pgf/callout pointer arc}}%
+ \addtosavedmacro\pointerarc%
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ %
+ % Get the relative pointer.
+ %
+ \ifpgf@lib@callout@absolutepointer%
+ \else%
+ \pgfextract@process\calloutpointer{%
+ \pgfextract@process\borderpoint{%
+ \expandafter\pgfpointborderellipse\expandafter{\pgf@lib@callout@relativepointer}{\pgfqpoint{\xpathradius}{\ypathradius}}%
+ }%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
+ \let\pointerangle\pgfmathresult%
+ \expandafter\pgf@process\expandafter{\pgf@lib@callout@relativepointer}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \edef\pointerradius{\pgfmathresult pt}%
+ \pgfpointadd{\borderpoint}{\pgfqpointpolar{\pointerangle}{\pointerradius}}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ \addtosavedmacro\calloutpointer%
+ \pgf@lib@callouts@shortenpointer%
+ \pgf@lib@ellipsecallout@getpoints%
+ \addtosavedmacro\calloutpointeranchor%
+ \addtosavedmacro\beforecalloutangle%
+ \addtosavedmacro\aftercalloutangle%
+ \fi%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \ellipsecalloutpoints%
+ \pgfmathpointintersectionoflineandarc{\midpoint\advance\pgf@x\xradius}{\midpoint}%
+ {\centerpoint}{270}{450}{\xradius and \yradius}%
+ }%
+ \anchor{mid west}{%
+ \ellipsecalloutpoints%
+ \pgfmathpointintersectionoflineandarc{\midpoint\advance\pgf@x-\xradius}{\midpoint}%
+ {\centerpoint}{90}{270}{\xradius and \yradius}%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \ellipsecalloutpoints%
+ \pgfmathpointintersectionoflineandarc{\basepoint\advance\pgf@x\xradius}{\basepoint}%
+ {\centerpoint}{270}{450}{\xradius and \yradius}%
+ }%
+ \anchor{base west}{%
+ \ellipsecalloutpoints%
+ \pgfmathpointintersectionoflineandarc{\basepoint\advance\pgf@x-\xradius}{\basepoint}%
+ {\centerpoint}{90}{270}{\xradius and \yradius}%
+ }%
+ \anchor{north}{%
+ \ellipsecalloutpoints%
+ \centerpoint%
+ \advance\pgf@y\yradius\relax%
+ }%
+ \anchor{south}{%
+ \ellipsecalloutpoints%
+ \centerpoint%
+ \advance\pgf@y-\yradius\relax%
+ }%
+ \anchor{east}{%
+ \ellipsecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x\xradius\relax%
+ }%
+ \anchor{west}{%
+ \ellipsecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x-\xradius\relax%
+ }%
+ \anchor{north west}{%
+ \ellipsecalloutpoints%
+ \pgf@xa\xradius\relax%
+ \pgf@ya\yradius\relax%
+ \centerpoint%
+ \advance\pgf@y0.7071067\pgf@ya%
+ \advance\pgf@x-0.7071067\pgf@xa%
+ }%
+ \anchor{north east}{%
+ \ellipsecalloutpoints%
+ \pgf@xa\xradius\relax%
+ \pgf@ya\yradius\relax%
+ \centerpoint%
+ \advance\pgf@y0.7071067\pgf@ya%
+ \advance\pgf@x0.7071067\pgf@xa%
+ }%
+ \anchor{south west}{%
+ \ellipsecalloutpoints%
+ \pgf@xa\xradius\relax%
+ \pgf@ya\yradius\relax%
+ \centerpoint%
+ \advance\pgf@y-0.7071067\pgf@ya%
+ \advance\pgf@x-0.7071067\pgf@xa%
+ }%
+ \anchor{south east}{%
+ \ellipsecalloutpoints%
+ \pgf@xa\xradius\relax%
+ \pgf@ya\yradius\relax%
+ \centerpoint%
+ \advance\pgf@y-0.7071067\pgf@ya%
+ \advance\pgf@x0.7071067\pgf@xa%
+ }%
+ \anchor{pointer}{%
+ \ellipsecalloutpoints%
+ \calloutpointeranchor%
+ }%
+ \backgroundpath{%
+ \ellipsecalloutpoints%
+ \ifpgf@lib@callout@absolutepointer%
+ \pgfextract@process\calloutpointer{%
+ \pgfpointanchor{pgf@lib@callout@pointer}{center}%
+ }%
+ \pgf@lib@callouts@shortenpointer%
+ \pgf@lib@ellipsecallout@getpoints%
+ \calloutpointeranchor%
+ \ifx\pgf@node@name\pgfutil@empty%
+ \else%
+ \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}%
+ \edef\pgf@sh@@@temp{%
+ \noexpand\def\noexpand\calloutpointeranchor{%
+ \noexpand\pgf@x\the\pgf@x%
+ \noexpand\pgf@y\the\pgf@y%
+ }%
+ }%
+ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@@@temp}
+ \fi%
+ \fi%
+ \pgfpathmoveto{\calloutpointer}%
+ \pgfpathlineto{\aftercalloutpointer}%
+ \ifdim\aftercalloutangle pt<\beforecalloutangle pt\relax%
+ \pgfpatharc{\aftercalloutangle}{\beforecalloutangle}{\xpathradius and \ypathradius}%
+ \else%
+ \pgfpatharc{\aftercalloutangle}{360}{\xpathradius and \ypathradius}%
+ \pgfpatharc{0}{\beforecalloutangle}{\xpathradius and \ypathradius}%
+ \fi%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \ellipsecalloutpoints%
+ \pgfpointadd{\pgfpointborderellipse{\externalpoint}{\pgfpoint{\xradius}{\yradius}}%
+ }{\centerpoint}%
+ }%
+}%
+
+% Internal macro for calculating the points for the
+% ellipse callout pointer.
+%
+% The following must be set up:
+%
+% \centerpoint - the center of the ellipse.
+% \calloutpointer - the location of the callout point.
+% \pointerarc - the width of the pointer.
+% \xpathradius - the x radius of the ellipse.
+% \ypathradius - the y radius of the ellipse.
+%
+\def\pgf@lib@ellipsecallout@getpoints{%
+ \pgfextract@process\borderpoint{%
+ \pgfpointborderellipse{%
+ \centerpoint%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \calloutpointer%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@y-\pgf@ya%
+ }{\pgfqpoint{\xpathradius}{\ypathradius}}%
+ }%
+ \pgfmathangleonellipse{\borderpoint}{\xpathradius and \ypathradius}%
+ \pgfutil@tempdima\pointerarc pt\relax%
+ \pgfutil@tempdimb\pgfmathresult pt\relax%
+ \advance\pgfutil@tempdimb-.5\pgfutil@tempdima%
+ \ifdim\pgfutil@tempdimb<0pt\relax%
+ \advance\pgfutil@tempdimb360pt\relax%
+ \fi%
+ \edef\beforecalloutangle{\pgfmath@tonumber{\pgfutil@tempdimb}}%
+ \advance\pgfutil@tempdimb\pgfutil@tempdima%
+ \ifdim\pgfutil@tempdimb<360pt\relax%
+ \else%
+ \advance\pgfutil@tempdimb-360pt\relax%
+ \fi%
+ \edef\aftercalloutangle{\pgfmath@tonumber{\pgfutil@tempdimb}}%
+ %
+ \pgfextract@process\beforecalloutpointer{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{\beforecalloutangle}{\xpathradius and \ypathradius}%
+ }%
+ }%
+ \pgfextract@process\aftercalloutpointer{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{\aftercalloutangle}{\xpathradius and \ypathradius}%
+ }%
+ }%
+ %
+ % Calculate the pointer anchor.
+ %
+ \pgf@lib@callouts@pointeranchor%
+}%
+
+
+% If the callout pointer is very pointed and stroked, the anchor will be
+% miles away from the end of the pointer which will (typically) be
+% bevelled.
+% Using outer sep=0pt is one solution, however, another is provided
+% using this special key:
+%
+% /pgf/callout pointer anchor aspect
+%
+% which takes a value from 0 (ignore any outer sep) to 1 (use
+% the full outer sep).
+
+\pgfkeys{/pgf/callout pointer anchor aspect/.initial=1}%
+
+% Internal macro for calculating the anchor for the callout pointer.
+%
+% Requires the following to be set up (points are anti-clockwise)
+%
+% \beforecalloutpointer - point on the border before the callout pointer
+% \calloutpointer
+% \aftercalloutpointer - point on the border after the callout pointer
+% \outersep - the largest of the outer xsep or ysep.
+%
+\def\pgf@lib@callouts@pointeranchor{%
+ \pgfutil@tempdimb\outersep\relax%
+ %
+ \pgfmathanglebetweenlines{\calloutpointer}{\aftercalloutpointer}{\calloutpointer}{\beforecalloutpointer}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
+ \pgfmathanglebetweenpoints{\calloutpointer}{\aftercalloutpointer}%
+ \advance\pgfutil@tempdima\pgfmathresult pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ %
+ \pgfextract@process\calloutpointeranchor{%
+ \pgfpointadd{%
+ \pgfmathparse{\pgfkeysvalueof{/pgf/callout pointer anchor aspect}}%
+ \pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ }{%
+ \calloutpointer%
+ }%
+ }%
+}%
+
+\def\pgf@lib@callouts@shortenpointer{%
+ \pgfextract@process\calloutpointer{%
+ \pgfmathanglebetweenpoints{\calloutpointer}{\centerpoint}%
+ \let\angle\pgfmathresult%
+ \pgfmathsin@{\angle}%
+ \let\sinpointerangle\pgfmathresult%
+ \pgfmathcos@{\angle}%
+ \let\cospointerangle\pgfmathresult%
+ \pgfpointadd{\calloutpointer}{%
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/callout pointer shorten}}%
+ \pgf@x\cospointerangle\pgfutil@tempdima%
+ \pgf@y\sinpointerangle\pgfutil@tempdima%
+ }%
+ }%
+}%
+
+
+\pgfdeclareshape{rectangle callout}{%
+ \savedmacro\rectanglecalloutpoints{%
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \edef\xtemp{\the\pgf@x}%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ \edef\ytemp{\the\pgf@y}%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ %
+ \edef\xlength{\the\pgf@x}%
+ \edef\ylength{\the\pgf@y}%
+ \addtosavedmacro\xlength%
+ \addtosavedmacro\ylength%
+ %
+ \pgfmathsetlengthmacro\pointerwidth{\pgfkeysvalueof{/pgf/callout pointer width}}%
+ \addtosavedmacro\pointerwidth%
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ %
+ % Process the relative callout pointer.
+ %
+ \ifpgf@lib@callout@absolutepointer%
+ \else%
+ \pgfextract@process\calloutpointer{%
+ \pgfextract@process\borderpoint{%
+ \expandafter\pgfpointborderrectangle\expandafter{\pgf@lib@callout@relativepointer}%
+ {\pgfqpoint{\xtemp}{\ytemp}}%
+ }%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
+ \let\pointerangle\pgfmathresult%
+ \expandafter\pgf@process\expandafter{\pgf@lib@callout@relativepointer}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \edef\pointerradius{\pgfmathresult pt}%
+ \pgfpointadd{\borderpoint}{\pgfqpointpolar{\pointerangle}{\pointerradius}}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgf@lib@callouts@shortenpointer%
+ \addtosavedmacro\calloutpointer%
+ \pgf@lib@rectanglecallout@pointer%
+ \addtosavedmacro\calloutpointeranchor%
+ \addtosavedmacro\beforecalloutpointer%
+ \addtosavedmacro\aftercalloutpointer%
+ \addtosavedmacro\firstpoint%
+ \addtosavedmacro\secondpoint%
+ \addtosavedmacro\thirdpoint%
+ \addtosavedmacro\fourthpoint%
+ \fi%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5em}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \rectanglecalloutpoints%
+ \midpoint%
+ \advance\pgf@x\xlength\relax%
+ }%
+ \anchor{mid west}{%
+ \rectanglecalloutpoints%
+ \midpoint%
+ \advance\pgf@x-\xlength\relax%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \rectanglecalloutpoints%
+ \basepoint%
+ \advance\pgf@x\xlength\relax%
+ }%
+ \anchor{base west}{%
+ \rectanglecalloutpoints%
+ \basepoint%
+ \advance\pgf@x-\xlength\relax%
+ }%
+ \anchor{north}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@y\ylength\relax%
+ }%
+ \anchor{south}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@y-\ylength\relax%
+ }%
+ \anchor{east}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x\xlength\relax%
+ }%
+ \anchor{west}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x-\xlength\relax%
+ }%
+ \anchor{north east}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x\xlength\relax%
+ \advance\pgf@y\ylength\relax%
+ }%
+ \anchor{south west}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x-\xlength\relax%
+ \advance\pgf@y-\ylength\relax%
+ }%
+ \anchor{south east}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x\xlength\relax%
+ \advance\pgf@y-\ylength\relax%
+ }%
+ \anchor{north west}{%
+ \rectanglecalloutpoints%
+ \centerpoint%
+ \advance\pgf@x-\xlength\relax%
+ \advance\pgf@y\ylength\relax%
+ }%
+ \anchor{pointer}{%
+ \rectanglecalloutpoints%
+ \calloutpointeranchor%
+ }%
+ \backgroundpath{%
+ \rectanglecalloutpoints%
+ \pgf@x\xlength\relax%
+ \pgf@y\ylength\relax%
+ \pgfmathaddtolength\pgf@x{-\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{-\pgfkeysvalueof{/pgf/outer ysep}}%
+ \edef\xtemp{\the\pgf@x}%
+ \edef\ytemp{\the\pgf@y}%
+ %
+ % The absolute pointer must be calculated here because the
+ % anchor of the shape (which is calculated after the saved
+ % macros and points) affects how the pointer joins the
+ % main rectangle.
+ %
+ \ifpgf@lib@callout@absolutepointer%
+ \pgfextract@process\calloutpointer{%
+ \pgfpointanchor{pgf@lib@callout@pointer}{center}%
+ }%
+ \pgf@lib@callouts@shortenpointer%
+ \pgfmathsetlengthmacro\pointerwidth{\pgfkeysvalueof{/pgf/callout pointer width}}%
+ \pgf@lib@rectanglecallout@pointer%
+ %
+ % \pgf@node@name = the shape name (from \pgfmultipartnode)
+ %
+ \ifx\pgf@node@name\pgfutil@empty%
+ \else%
+ %
+ % Now hack an extra saved anchor \calloutpointeranchor,
+ % with the new anchor for the callout pointer.
+ %
+ \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}%
+ \edef\pgf@sh@@@temp{%
+ \noexpand\def\noexpand\calloutpointeranchor{%
+ \noexpand\pgf@x\the\pgf@x%
+ \noexpand\pgf@y\the\pgf@y%
+ }%
+ }%
+ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@@@temp}%
+ \fi%
+ \fi%
+ {%
+ \pgfsetcornersarced{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathmoveto{\beforecalloutpointer}%
+ }%
+ \pgfpathlineto{\calloutpointer}%
+ {%
+ \pgfsetcornersarced{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathlineto{\aftercalloutpointer}%
+ }%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathlineto{\firstpoint}%
+ \pgfpathlineto{\secondpoint}%
+ \pgfpathlineto{\thirdpoint}%
+ \pgfpathlineto{\fourthpoint}%
+ {%
+ \pgfsetcornersarced{\pgfqpoint{0pt}{0pt}}%
+ \pgfpathclose%
+ }%
+ }
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \rectanglecalloutpoints%
+ \pgfpointadd{\centerpoint}%
+ {%
+ \pgfpointborderrectangle{\pgfpointadd{\centerpoint}{\externalpoint}}%
+ {\pgfqpoint{\xlength}{\ylength}}%
+ }%
+ }%
+}%
+
+
+
+% \pgf@lib@rectanglecallout@pointer
+%
+% Internal macro for calculations relating to the rectangle callout.
+%
+% Requires the following to be set up:
+%
+% \calloutpointer - the location of the callout point.
+% \xtemp - the half width of the rectangle
+% \ytemp - the half height of the rectangle
+% \pointerwidth - the width of the pointer.
+%
+\def\pgf@lib@rectanglecallout@pointer{%
+ %
+ % Ensure that the pointer never connects to the main shape
+ % too near to a corner. This is done for two reasons:
+ % 1. It can look ugly.
+ % 2. If the corners are rounded, a mess can result.
+ %
+ \pgfextract@process\borderpoint{%
+ \pgfpointborderrectangle{%
+ \centerpoint%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \calloutpointer%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@y-\pgf@ya%
+ }{\pgfqpoint{\xtemp}{\ytemp}}%
+ }%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
+ \let\borderangle\pgfmathresult%
+ %
+ \pgfutil@tempdima\pointerwidth\relax%
+ \pgf@xa\xtemp\relax%
+ \advance\pgf@xa-\pgfutil@tempdima%
+ \pgf@ya\ytemp\relax%
+ \advance\pgf@ya-\pgfutil@tempdima%
+ %
+ \pgf@process{%
+ \pgfutil@ifundefined{pgf@corner@arc}{\pgfpointorigin}{%
+ \expandafter\pgfqpoint\pgf@corner@arc}%
+ }%
+ \advance\pgf@xa-\pgf@x%
+ \advance\pgf@ya-\pgf@y%
+ %
+ \borderpoint%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ %
+ \pgf@xc0pt\relax%
+ \pgf@yc0pt\relax%
+ %
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{\xtemp}{\ytemp}}%
+ \ifdim\borderangle pt<\pgfmathresult pt\relax%
+ \pgf@yc.5\pgfutil@tempdima%
+ \ifdim\pgf@yb>\pgf@ya%
+ \pgf@yb\pgf@ya%
+ \fi%
+ %
+ % Establish the order for drawing the rectangle corners.
+ %
+ \edef\firstpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
+ \edef\secondpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
+ \edef\thirdpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
+ \edef\fourthpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
+ \else%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{-\xtemp}{\ytemp}}%
+ \ifdim\borderangle pt<\pgfmathresult pt\relax%
+ \pgf@xc-.5\pgfutil@tempdima%
+ \ifdim\pgf@xb>\pgf@xa%
+ \pgf@xb\pgf@xa%
+ \else%
+ \ifdim\pgf@xb<-\pgf@xa%
+ \pgf@xb-\pgf@xa%
+ \fi%
+ \fi%
+ \edef\firstpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
+ \edef\secondpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
+ \edef\thirdpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
+ \edef\fourthpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
+ \else%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{-\xtemp}{-\ytemp}}%
+ \ifdim\borderangle pt<\pgfmathresult pt\relax%
+ \pgf@yc-.5\pgfutil@tempdima%
+ \ifdim\pgf@yb>\pgf@ya%
+ \pgf@yb\pgf@ya%
+ \else%
+ \ifdim\pgf@yb<-\pgf@ya%
+ \pgf@yb-\pgf@ya%
+ \fi%
+ \fi%
+ \edef\firstpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
+ \edef\secondpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
+ \edef\thirdpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
+ \edef\fourthpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
+ \else%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\pgfqpoint{\xtemp}{-\ytemp}}%
+ \ifdim\borderangle pt<\pgfmathresult pt\relax%
+ \pgf@xc.5\pgfutil@tempdima%
+ \ifdim\pgf@xb>\pgf@xa%
+ \pgf@xb\pgf@xa%
+ \else%
+ \ifdim\pgf@xb<-\pgf@xa%
+ \pgf@xb-\pgf@xa%
+ \fi%
+ \fi%
+ \edef\firstpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
+ \edef\secondpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
+ \edef\thirdpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
+ \edef\fourthpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
+ \else%
+ \pgf@yc.5\pgfutil@tempdima%
+ \ifdim\pgf@yb<-\pgf@ya%
+ \pgf@yb-\pgf@ya%
+ \fi%
+ \edef\firstpoint{\noexpand\pgfqpoint{\xtemp}{\ytemp}}%
+ \edef\secondpoint{\noexpand\pgfqpoint{-\xtemp}{\ytemp}}%
+ \edef\thirdpoint{\noexpand\pgfqpoint{-\xtemp}{-\ytemp}}%
+ \edef\fourthpoint{\noexpand\pgfqpoint{\xtemp}{-\ytemp}}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgfextract@process\beforecalloutpointer{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ \advance\pgf@x-\pgf@xc%
+ \advance\pgf@y-\pgf@yc%
+ }%
+ \pgfextract@process\aftercalloutpointer{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ \advance\pgf@x\pgf@xc%
+ \advance\pgf@y\pgf@yc%
+ }%
+ %
+ % Now calculate the pointer anchor.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x>\pgf@y%
+ \edef\outersep{\the\pgf@x}%
+ \else%
+ \edef\outersep{\the\pgf@y}%
+ \fi%
+ \pgf@lib@callouts@pointeranchor%
+}%
+
+
+% Internal macro for parsing the size of
+% the cloud callout pointer.
+%
+% \pgf@x and \pgf@y should be set up as the
+% width and height of the main shape.
+%
+% \pgf@xa and \pgf@ya are returned appropriately.
+%
+\def\pgf@lib@callout@setpointersize#1{%
+ \edef\pgf@lib@callout@temp{#1}%
+ \edef\pgf@marshall{\noexpand\pgfutil@in@{of callout}{\pgf@lib@callout@temp}}%
+ \pgf@marshall%
+ \ifpgfutil@in@%
+ \expandafter\pgf@xa\expandafter\pgf@lib@callout@setpointerrelativesize%
+ \pgf@lib@callout@temp\pgf@lib@stop\pgf@x%
+ \expandafter\pgf@ya\expandafter\pgf@lib@callout@setpointerrelativesize%
+ \pgf@lib@callout@temp\pgf@lib@stop\pgf@y%
+ \else%
+ \edef\pgf@marshall{\noexpand\pgfutil@in@{and}{\pgf@lib@callout@temp}}%
+ \pgf@marshall%
+ \ifpgfutil@in@%
+ \expandafter\pgf@lib@callout@setpointerbothsizes\pgf@lib@callout@temp\pgf@lib@stop%
+ \else%
+ \pgfmathsetlength\pgf@xa{#1}%
+ \pgfmathsetlength\pgf@ya{#1}%
+ \fi%
+ \fi%
+}%
+\def\pgf@lib@callout@setpointerrelativesize#1of callout#2\pgf@lib@stop{#1}%
+\def\pgf@lib@callout@setpointerbothsizes#1and#2\pgf@lib@stop{%
+ \pgfmathsetlength\pgf@xa{#2}%
+ \pgfmathsetlength\pgf@ya{#2}%
+}%
+
+% Shape: cloud callout.
+%
+\pgfdeclareshape{cloud callout}{%
+ \savedanchor\calloutpointer{%
+ \pgfutil@ifundefined{pgf@sh@s@cloud}{%
+ \pgferror{I cannot find the cloud shape. Please load the `symbol shapes' library}}{}%
+ \pgf@sh@s@cloud%
+ \pgf@sh@savedmacros%
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \ifpgf@lib@callout@absolutepointer%
+ \else%
+ \pgfextract@process\calloutpointer{%
+ \pgfextract@process\borderpoint{%
+ \expandafter\pgfpointborderellipse\expandafter{\pgf@lib@callout@relativepointer}%
+ {\pgfqpoint{\xouterradius}{\youterradius}}%
+ }%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\borderpoint}%
+ \let\pointerangle\pgfmathresult%
+ \expandafter\pgf@process\expandafter{\pgf@lib@callout@relativepointer}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \edef\pointerradius{\pgfmathresult pt}%
+ \pgfpointadd{\borderpoint}{\pgfqpointpolar{\pointerangle}{\pointerradius}}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgf@lib@callouts@shortenpointer%
+ \fi%
+ }%
+ \anchor{pointer}{%
+ \calloutpointer%
+ }%
+ \inheritsavedanchors[from=cloud]%
+ \inheritanchor[from=cloud]{center}%
+ \inheritanchor[from=cloud]{base}%
+ \inheritanchor[from=cloud]{mid}%
+ \inheritanchor[from=cloud]{north}%
+ \inheritanchor[from=cloud]{south}%
+ \inheritanchor[from=cloud]{east}%
+ \inheritanchor[from=cloud]{west}%
+ \inheritanchor[from=cloud]{north east}%
+ \inheritanchor[from=cloud]{south west}%
+ \inheritanchor[from=cloud]{south east}%
+ \inheritanchor[from=cloud]{north west}%
+ \inheritanchorborder[from=cloud]%
+ \backgroundpath{%
+ \pgf@sh@bg@cloud%
+ \ifpgf@lib@callout@absolutepointer%
+ \pgfextract@process\calloutpointer{%
+ \pgfpointanchor{pgf@lib@callout@pointer}{center}%
+ }%
+ \ifx\pgf@node@name\pgfutil@empty%
+ \else%
+ \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}%
+ \edef\pgf@sh@@@temp{%
+ \noexpand\def\noexpand\calloutpointeranchor{%
+ \noexpand\pgf@x\the\pgf@x%
+ \noexpand\pgf@y\the\pgf@y%
+ }%
+ }%
+ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@@@temp}
+ \fi%
+ \fi%
+ %
+ \pgfextract@process\borderpoint{%
+ \pgfpointadd{%
+ \pgfpointborderellipse{\pgfpointdiff{\centerpoint}{\calloutpointer}}%
+ {\pgfqpoint{\xouterradius}{\youterradius}}%
+ }{\centerpoint}%
+ }%
+ \pgf@lib@callouts@shortenpointer%
+ \pgfmathanglebetweenpoints{\calloutpointer}{\centerpoint}%
+ \let\angle\pgfmathresult%
+ \pgfmathsin@{\angle}%
+ \let\sinpointerangle\pgfmathresult%
+ \pgfmathcos@{\angle}%
+ \let\cospointerangle\pgfmathresult%
+ %
+ \pgf@x\xouterradius\relax%
+ \pgf@x2.0\pgf@x%
+ \pgf@y\yinnerradius\relax%
+ \pgf@y2.0\pgf@y%
+ \pgf@lib@callout@setpointersize{\pgfkeysvalueof{/pgf/callout pointer start size}}%
+ \pgf@xb\pgf@xa%
+ \pgf@yb\pgf@ya%
+ \pgf@lib@callout@setpointersize{\pgfkeysvalueof{/pgf/callout pointer end size}}%
+ \advance\pgf@xb-\pgf@xa%
+ \advance\pgf@yb-\pgf@ya%
+ %
+ \pgfmathsetcount\c@pgf@counta{\pgfkeysvalueof{/pgf/callout pointer segments}}%
+ \divide\pgf@xb\c@pgf@counta%
+ \divide\pgf@yb\c@pgf@counta%
+ %
+ \pgf@process{\pgfpointdiff{\borderpoint}{\calloutpointer}}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \divide\pgfutil@tempdima\c@pgf@counta%
+ %
+ \pgfutil@tempdimb0pt\relax%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\c@pgf@counta%
+ \else%
+ {%
+ \pgf@xa.5\pgf@xa%
+ \pgf@ya.5\pgf@ya%
+ \edef\tempxradius{\the\pgf@xa}%
+ \edef\tempyradius{\the\pgf@ya}%
+ \pgfpathellipse%
+ {%
+ \calloutpointer%
+ \advance\pgf@x\cospointerangle\pgfutil@tempdimb%
+ \advance\pgf@y\sinpointerangle\pgfutil@tempdimb%
+ }%
+ {\pgfqpoint{\tempxradius}{0pt}}{\pgfqpoint{0pt}{\tempyradius}}%
+ }%
+ \advance\pgf@xa\pgf@xb%
+ \advance\pgf@ya\pgf@yb%
+ \advance\pgfutil@tempdimb\pgfutil@tempdima%
+ \repeatpgfmathloop%
+ }%
+ %
+ % Hack the puff anchors for the callout.
+ %
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@cloud callout\endcsname{%
+ \c@pgf@counta\puffs\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \pgfutil@ifundefined{pgf@anchor@cloud callout@puff\space\the\c@pgf@counta}{%
+ \expandafter\xdef\csname pgf@anchor@cloud callout@puff\space\the\c@pgf@counta\endcsname{%
+ \noexpand\pgf@sh@@cloudpuffanchor{\the\c@pgf@counta}%
+ }%
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+ }%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.code.tex
new file mode 100644
index 0000000000..dace51bf0b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.code.tex
@@ -0,0 +1,21 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryshapes.code.tex}
+
+% Only the following are loaded by default and only for historical
+% reasons.
+
+\usepgflibrary{shapes.geometric}%
+\usepgflibrary{shapes.misc}%
+\usepgflibrary{shapes.symbols}%
+
+% Further libraries should be included directly
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.geometric.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.geometric.code.tex
new file mode 100644
index 0000000000..71d03f9535
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.geometric.code.tex
@@ -0,0 +1,4417 @@
+% Copyright 2018 by Till Tantau and Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryshapes.geometric.code.tex}
+
+\pgfdeclareshape{ellipse}
+%
+% Draws a circle around the text
+%
+{%
+ \savedanchor\centerpoint{%
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgf@y=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\radius{%
+ %
+ % Calculate ``height radius''
+ %
+ \pgf@y=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by.5\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y by\pgf@yb%
+ %
+ % Calculate ``width radius''
+ %
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x by\pgf@xb%
+ %
+ % Adjust
+ %
+ \pgf@x=1.4142136\pgf@x%
+ \pgf@y=1.4142136\pgf@y%
+ %
+ % Adjust height, if necessary
+ %
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@yc%
+ \pgf@y=.5\pgf@yc%
+ \fi%
+ %
+ % Adjust width, if necessary
+ %
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<.5\pgf@xc%
+ \pgf@x=.5\pgf@xc%
+ \fi%
+ %
+ % Add outer sep
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ }%
+
+ %
+ % Anchors
+ %
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{base}{\centerpoint\pgf@y=0pt}%
+ \anchor{north}
+ {
+ \pgf@process{\radius}
+ \pgf@ya=\pgf@y%
+ \pgf@process{\centerpoint}
+ \advance\pgf@y by\pgf@ya
+ }%
+ \anchor{south}
+ {
+ \pgf@process{\radius}
+ \pgf@ya=\pgf@y%
+ \pgf@process{\centerpoint}
+ \advance\pgf@y by-\pgf@ya
+ }%
+ \anchor{west}
+ {
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by-\pgf@xa
+ }%
+ \anchor{mid west}
+ {%
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by-\pgf@xa%
+ \pgfmathsetlength\pgf@y{.5ex}
+ }%
+ \anchor{base west}
+ {%
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by-\pgf@xa%
+ \pgf@y=0pt
+ }%
+ \anchor{north west}
+ {
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by-0.707107\pgf@xa
+ \advance\pgf@y by0.707107\pgf@ya
+ }%
+ \anchor{south west}
+ {
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by-0.707107\pgf@xa
+ \advance\pgf@y by-0.707107\pgf@ya
+ }%
+ \anchor{east}
+ {%
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by\pgf@xa
+ }%
+ \anchor{mid east}
+ {%
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by\pgf@xa%
+ \pgfmathsetlength\pgf@y{.5ex}
+ }%
+ \anchor{base east}
+ {%
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by\pgf@xa%
+ \pgf@y=0pt
+ }%
+ \anchor{north east}
+ {
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by0.707107\pgf@xa
+ \advance\pgf@y by0.707107\pgf@ya
+ }%
+ \anchor{south east}
+ {
+ \pgf@process{\radius}
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\centerpoint}
+ \advance\pgf@x by0.707107\pgf@xa
+ \advance\pgf@y by-0.707107\pgf@ya
+ }%
+ \anchorborder{%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpointborderellipse
+ {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ {\noexpand\radius}%
+ }%
+ \pgf@marshal%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \centerpoint%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ }%
+
+ %
+ % Background path
+ %
+ \backgroundpath
+ {
+ \pgf@process{\radius}%
+ \pgfutil@tempdima=\pgf@x%
+ \pgfutil@tempdimb=\pgf@y%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \advance\pgfutil@tempdimb by-\pgf@yb%
+ \pgfpathellipse{\centerpoint}{\pgfqpoint{\pgfutil@tempdima}{0pt}}{\pgfqpoint{0pt}{\pgfutil@tempdimb}}%
+ }%
+}%
+
+
+
+
+% Set the recommended shape aspect ratio
+%
+% #1 = aspect ratio
+%
+% Example:
+%
+% \pgfsetshapeaspect{1.5}
+
+% Keys for shape aspect ratio.
+%
+% /pgf/aspect : recommended width/height quotient.
+%
+\pgfkeys{/pgf/.cd,
+ aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz...
+ shape aspect/.initial=1,% but this is consistent with other pgfset stuff.
+ shape aspect/.code={%
+ \pgfkeys{/pgf/aspect={#1}}%
+ \pgfkeyssetvalue{/pgf/shape aspect}{#1}
+ }%
+}%
+
+
+\def\pgfsetshapeaspect#1{%
+ \def\pgfshapeaspect{#1}%
+ % Invert
+ \pgfutil@tempdima=#1pt%
+ \pgfutil@tempdima=.125\pgfutil@tempdima%
+ \c@pgf@counta=\pgfutil@tempdima\relax% 8192*determinant
+ \pgfutil@tempdima=8192pt%
+ \divide\pgfutil@tempdima by\c@pgf@counta%
+ \edef\pgfshapeaspectinverse{\pgf@sys@tonumber{\pgfutil@tempdima}}%
+}%
+
+\pgfsetshapeaspect{1}%
+
+\pgfdeclareshape{diamond}
+{%
+ \savedanchor\outernortheast{%
+ %
+ % Calculate width and height of the inner rectangle
+ %
+ \pgf@xa=.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa by\pgf@xc%
+ \pgf@ya=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya by\pgf@yc%
+ %
+ % Calculate width and height of diamond
+ %
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by\pgfshapeaspect\pgf@ya%
+ \pgf@y=\pgfshapeaspectinverse\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ %
+ % Check against minimum height/width
+ %
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@xb=.5\pgf@xb%
+ \ifdim\pgf@x<\pgf@xb%
+ % yes, too small. Enlarge...
+ \pgf@x=\pgf@xb%
+ \fi%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@yb=.5\pgf@yb%
+ \ifdim\pgf@y<\pgf@yb%
+ % yes, too small. Enlarge...
+ \pgf@y=\pgf@yb%
+ \fi%
+ %
+ % Add outer border
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \advance\pgf@x by\pgf@xa%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \advance\pgf@y by\pgf@ya%
+ }%
+ \savedanchor\text{%
+ \pgf@x=-.5\wd\pgfnodeparttextbox%
+ \pgf@y=-.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by.5\dp\pgfnodeparttextbox%
+ }%
+
+ %
+ % Anchors
+ %
+ \anchor{text}{\text}%
+ \anchor{center}{\pgfpointorigin}%
+ \anchor{mid}{%
+ \pgf@process{\text}%
+ \pgf@x=0pt%
+ \pgfmathsetlength\pgf@ya{.5ex}%
+ \advance\pgf@y by\pgf@ya%
+ }%
+ \anchor{base}{\pgf@process{\text}\pgf@x=0pt}%
+ \anchor{north}{\pgf@process{\outernortheast}\pgf@x=0pt}%
+ \anchor{south}{\pgf@process{\outernortheast}\pgf@x=0pt\pgf@y=-\pgf@y}%
+ \anchor{west}{\pgf@process{\outernortheast}\pgf@x=-\pgf@x\pgf@y=0pt}%
+ \anchor{north west}{\pgf@process{\outernortheast}\pgf@x=-.5\pgf@x\pgf@y=.5\pgf@y}%
+ \anchor{south west}{\pgf@process{\outernortheast}\pgf@x=-.5\pgf@x\pgf@y=-.5\pgf@y}%
+ \anchor{east}{\pgf@process{\outernortheast}\pgf@y=0pt}%
+ \anchor{north east}{\pgf@process{\outernortheast}\pgf@x=.5\pgf@x\pgf@y=.5\pgf@y}%
+ \anchor{south east}{\pgf@process{\outernortheast}\pgf@x=.5\pgf@x\pgf@y=-.5\pgf@y}%
+ \anchorborder{%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\outernortheast}%
+ \ifdim\pgf@xa>0pt%
+ \else%
+ \pgf@x=-\pgf@x%
+ \fi%
+ \ifdim\pgf@ya>0pt%
+ \else%
+ \pgf@y=-\pgf@y%
+ \fi%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpointintersectionoflines
+ {\noexpand\pgfpointorigin}
+ {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}
+ {\noexpand\pgfqpoint{\the\pgf@x}{0pt}}
+ {\noexpand\pgfqpoint{0pt}{\the\pgf@y}}%
+ }%
+ \pgf@process{\pgf@marshal}%
+ }%
+
+ %
+ % Background path
+ %
+ \backgroundpath{
+ \pgf@process{\outernortheast}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \advance\pgf@xc by-1.414213\pgf@xa%
+ \advance\pgf@yc by-1.414213\pgf@ya%
+ \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}%
+ \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}%
+ \pgfpathclose%
+ }%
+}%
+
+
+
+
+
+
+\newif\ifpgf@lib@shapes@starouterradiususesratio
+\pgf@lib@shapes@starouterradiususesratiotrue
+
+% Keys for star shape
+%
+% /pgf/star points : Number of points on the star.
+% /pgf/star point height : The height of the outer star points.
+% /pgf/star point ratio : The ratio of the outer point and inner point radii.
+
+\pgfkeys{/pgf/.cd,
+ star points/.initial=5,
+ star point height/.initial=.5cm,
+ star point height/.code={%
+ \def\pgf@lib@temp{#1}%
+ \pgfkeyslet{/pgf/star point height}{\pgf@lib@temp}%
+ \pgf@lib@shapes@starouterradiususesratiofalse%
+ },
+ star point ratio/.initial=1.5,
+ star point ratio/.code={%
+ \def\pgf@lib@temp{#1}%
+ \pgfkeyslet{/pgf/star point ratio}{\pgf@lib@temp}%
+ \pgf@lib@shapes@starouterradiususesratiotrue%
+ },%
+ star rotate/.style={/pgf/shape border rotate={#1}},% For compatibility with 1.18
+}%
+
+
+% Shape star.
+%
+\pgfdeclareshape{star}{%
+ \savedmacro\totalstarpoints{%
+ \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/star points}}%
+ \multiply\c@pgf@counta2\relax%
+ \edef\totalstarpoints{\the\c@pgf@counta}%
+ }%
+ \savedmacro\anglestep{%
+ \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/star points}}%
+ \let\anglestep\pgfmathresult%
+ }%
+ \savedmacro\calculateradii{%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \ifdim\pgf@y>\pgf@x%
+ \pgf@x\pgf@y%
+ \fi%
+ %
+ % Calculate the incircle radius.
+ %
+ \pgf@x1.41421\pgf@x%
+ \edef\innerradius{\the\pgf@x}%
+ %
+ % Calculate the circumcircle radius.
+ %
+ % Use the star point height or the star point ratio?
+ %
+ \ifpgf@lib@shapes@starouterradiususesratio%
+ \pgfmathparse{\pgfkeysvalueof{/pgf/star point ratio}}%
+ \expandafter\pgf@x\pgfmathresult\pgf@x%
+ \else%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/star point height}}%
+ \fi%
+ \pgf@xc\pgf@x%
+ %
+ % Accommodate the larger of the minimum height/width.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@ya>\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \fi%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \edef\outerradius{\the\pgf@x}%
+ %
+ % If the outer radius has been enlarged, adjust the inner radius...
+ %
+ \ifdim\pgf@x>\pgf@xc%
+ %
+ % ...using the star point ratio, or...
+ %
+ \ifpgf@lib@shapes@starouterradiususesratio%
+ \pgfmathreciprocal{\pgfkeysvalueof{/pgf/star point ratio}}%
+ \pgf@xa\pgfmathresult\pgf@x\relax%
+ \edef\innerradius{\the\pgf@xa}%
+ \else%
+ %
+ % The star point height.
+ %
+ \pgf@xa\pgf@x\relax%
+ \pgfmathaddtolength\pgf@xa{-\pgfkeysvalueof{/pgf/star point height}}%
+ \edef\innerradius{\the\pgf@xa}%
+ \fi%
+ \fi%
+ \edef\outerradius{\the\pgf@x}%
+ %
+ % Now calculate the anchor radii from the outer sep.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@ya>\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \fi
+ %
+ % Take into account the miter length...
+ %
+ \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/star points}}%
+ \let\angletofirstpoint\pgfmathresult%
+ \pgfmathmultiply@{\angletofirstpoint}{2}%
+ \let\angletosecondpoint\pgfmathresult%
+ %
+ % ...for the outer radius...
+ %
+ \pgfmathanglebetweenlines%
+ {\pgfqpointpolar{\angletofirstpoint}{\outerradius}}%
+ {\pgfqpointpolar{\angletosecondpoint}{\innerradius}}%
+ {\pgfqpointpolar{\angletofirstpoint}{\outerradius}}%
+ {\pgfqpointpolar{0}{\innerradius}}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgf@x\outerradius\relax%
+ \advance\pgf@x\pgfmathresult\pgf@xa%
+ \edef\anchorouterradius{\the\pgf@x}%
+ %
+ % ...and for the inner radius.
+ %
+ \pgfmathanglebetweenlines%
+ {\pgfqpointpolar{\angletofirstpoint}{\innerradius}}%
+ {\pgfqpointpolar{0}{\outerradius}}%
+ {\pgfqpointpolar{\angletofirstpoint}{\innerradius}}%
+ {\pgfqpointpolar{\angletosecondpoint}{\outerradius}}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgf@x\innerradius\relax%
+ \advance\pgf@x\pgfmathresult\pgf@xa%
+ \edef\anchorinnerradius{\the\pgf@x}%
+ %
+ % Save all radii.
+ %
+ \addtosavedmacro{\innerradius}%
+ \addtosavedmacro{\outerradius}%
+ \addtosavedmacro{\anchorinnerradius}%
+ \addtosavedmacro{\anchorouterradius}%
+ }%
+ \savedmacro\startangle{%
+ \pgfmathadd{90}{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \let\startangle\pgfmathresult%
+ }%
+ %
+ % Saved anchors.
+ %
+ \savedanchor{\centerpoint}{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor{\midpoint}{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ %
+ %
+ % Other anchors.
+ %
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{base}{\centerpoint\pgf@y=0pt}%
+ \anchor{north}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{0pt}{\anchorouterradius}}}%
+ \anchor{south}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{0pt}{-\anchorouterradius}}}%
+ \anchor{east}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{\anchorouterradius}{0pt}}}%
+ \anchor{west}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{-\anchorouterradius}{0pt}}}%
+ \anchor{north east}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{\anchorouterradius}{\anchorouterradius}}}%
+ \anchor{north west}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{-\anchorouterradius}{\anchorouterradius}}}%
+ \anchor{south east}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{\anchorouterradius}{-\anchorouterradius}}}%
+ \anchor{south west}{%
+ \calculateradii%
+ \csname pgf@anchor@star@border\endcsname{\pgfqpoint{-\anchorouterradius}{-\anchorouterradius}}}%
+ %
+ % Background path.
+ %
+ \backgroundpath{%
+ \calculateradii%
+ \let\angle\startangle%
+ \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{\startangle}{\outerradius}}}%
+ \pgfmathloop%
+ \pgfmathadd@{\angle}{\anglestep}%
+ \let\angle\pgfmathresult%
+ \ifnum\pgfmathcounter=\totalstarpoints%
+ \pgfpathclose%
+ \else%
+ \ifodd\pgfmathcounter
+ \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{\angle}{\innerradius}}}%
+ \else%
+ \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{\angle}{\outerradius}}}%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ %
+ % Define points on the anchor border.
+ %
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % Adjust the location of the external
+ % point relative to \centerpoint.
+ %
+ \centerpoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Get the angle of the external point to the \centerpoint.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ %
+ % Locate the appropriate sides on the star border...
+ %
+ \pgfmathsubtract@{\pgfmathresult}{\startangle}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \pgfmathdivide@{\pgfmathresult}{\anglestep}%
+ \pgfmathfloor@{\pgfmathresult}%
+ \afterassignment\pgfmath@gobbletilpgfmath@
+ \c@pgf@counta\pgfmathresult\relax\pgfmath@
+ \pgfmathmultiply@{\pgfmathresult}{\anglestep}%
+ \pgfmathadd@{\pgfmathresult}{\startangle}%
+ \let\firstangle\pgfmathresult%
+ \pgfmathadd@{\pgfmathresult}{\anglestep}%
+ \let\secondangle\pgfmathresult%
+ \calculateradii%
+ %
+ % ...and thus, the point on the star border.
+ %
+ \ifodd\c@pgf@counta
+ \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}%
+ {%
+ \pgfpointadd{\centerpoint}%
+ {\pgfqpointpolar{+\firstangle}{+\anchorinnerradius}}%
+ }%
+ {%
+ \pgfpointadd{\centerpoint}%
+ {\pgfqpointpolar{+\secondangle}{+\anchorouterradius}}%
+ }%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}%
+ {%
+ \pgfpointadd{\centerpoint}%
+ {\pgfqpointpolar{+\firstangle}{+\anchorouterradius}}%
+ }%
+ {%
+ \pgfpointadd{\centerpoint}%
+ {\pgfqpointpolar{+\secondangle}{+\anchorinnerradius}}%
+ }%
+ \fi%
+ }%
+ %
+ % Some hackery. This is needed if a star is positioned using
+ % a `...point <n+1>' anchor, where n is the maximum number of
+ % points of any previously drawn star.
+ %
+ \pgfutil@g@addto@macro\pgf@sh@s@star{%
+ \c@pgf@counta\totalstarpoints\relax%
+ \divide\c@pgf@counta2\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \c@pgf@countb\c@pgf@counta\relax%
+ \advance\c@pgf@countb-1\relax%
+ \pgfutil@ifundefined{pgf@anchor@star@inner point\space\the\c@pgf@counta}{%
+ \expandafter\xdef\csname pgf@anchor@star@inner point\space\the\c@pgf@counta\endcsname{%
+ \noexpand\calculateradii%
+ \noexpand\pgfmathmultiply@{\the\c@pgf@countb}{\noexpand\anglestep}%
+ \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{2}%
+ \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\anglestep}%
+ \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}%
+ \noexpand\let\noexpand\angle\noexpand\pgfmathresult%
+ \noexpand\pgfpointadd{\noexpand\centerpoint}%
+ {\noexpand\pgfqpointpolar{\noexpand\angle}{\noexpand\anchorinnerradius}}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@star@outer point\space\the\c@pgf@counta\endcsname{%
+ \noexpand\calculateradii%
+ \noexpand\pgfmathmultiply@{\the\c@pgf@countb}{\noexpand\anglestep}%
+ \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{2}%
+ \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}%
+ \noexpand\let\noexpand\angle\noexpand\pgfmathresult%
+ \noexpand\pgfpointadd{\noexpand\centerpoint}%
+ {\noexpand\pgfqpointpolar{\noexpand\angle}{\noexpand\anchorouterradius}}%
+ }%
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+ }%
+}%
+
+
+
+
+% Keys for shape regular polygon
+%
+% /pgf/regular polygon sides
+%
+\pgfkeys{/pgf/.cd,
+ regular polygon sides/.initial=5,
+ regular polygon rotate/.style={/pgf/shape border rotate={#1}}% For compatibility with 1.18
+}%
+
+
+% Shape Regular Polygon.
+%
+\pgfdeclareshape{regular polygon}{%
+ \savedmacro\sides{%
+ \pgfmathtruncatemacro\sides{\pgfkeysvalueof{/pgf/regular polygon sides}}%
+ }%
+ \savedmacro\anglestep{%
+ \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/regular polygon sides}}%
+ \let\anglestep\pgfmathresult%
+ }%
+ \savedmacro\calculateradii{%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \ifdim\pgf@y>\pgf@x%
+ \pgf@x\pgf@y%
+ \fi%
+ %
+ % Calculate i, the incircle radius
+ %
+ \pgf@x1.41421\pgf@x%
+ %
+ % Calculate r, the polygon radius
+ %
+ % r = i / cos(360 / s / 2)
+ %
+ % (s = polygon sides)
+ %
+ \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/regular polygon sides}}%
+ \pgfmathsec@{\pgfmathresult}%
+ \pgf@x\pgfmathresult\pgf@x%
+ %
+ % Accommodate the minimum width/height.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@ya>\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \fi%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \edef\radius{\the\pgf@x}%
+ %
+ % Now calculate the anchor radius from the outer sep.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@ya>\pgf@xa%
+ \pgf@xa\pgf@ya%
+ \fi
+ %
+ % Take into account the miter length.
+ %
+ % m = o / sin (90 - (360 / s / 2))
+ %
+ % (o = outer sep, s = sides)
+ %
+ \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/regular polygon sides}}%
+ \pgfmathsubtract@{90}{\pgfmathresult}%
+ \pgfmathcosec@{\pgfmathresult}%
+ \advance\pgf@x\pgfmathresult\pgf@xa%
+ \edef\anchorradius{\the\pgf@x}%
+ %
+ % Save both radii.
+ %
+ \addtosavedmacro{\radius}%
+ \addtosavedmacro{\anchorradius}%
+ }%
+ \savedmacro\startangle{%
+ \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/regular polygon sides}}%
+ \let\anglestep\pgfmathresult%
+ \pgfmathtruncatemacro\sides{\pgfkeysvalueof{/pgf/regular polygon sides}}%
+ \expandafter\ifodd\sides\relax%
+ \edef\pgfmathresult{90}%
+ \else%
+ \pgfmathdivide@{\anglestep}{2}%
+ \pgfmathsubtract@{90}{\pgfmathresult}%
+ \fi%
+ \pgfmathadd{\pgfmathresult}{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \let\startangle\pgfmathresult%
+ }%
+ %
+ % Saved anchors.
+ %
+ \savedanchor{\centerpoint}{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor{\midpoint}{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ %
+ % Other anchors.
+ %
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{base}{\centerpoint\pgf@y=0pt}%
+ \anchor{north}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{0pt}{\anchorradius}}}%
+ \anchor{south}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{0pt}{-\anchorradius}}}%
+ \anchor{east}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{\anchorradius}{0pt}}}%
+ \anchor{west}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{-\anchorradius}{0pt}}}%
+ \anchor{north east}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{\anchorradius}{\anchorradius}}}%
+ \anchor{north west}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{-\anchorradius}{\anchorradius}}}%
+ \anchor{south east}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{\anchorradius}{-\anchorradius}}}%
+ \anchor{south west}{%
+ \calculateradii%
+ \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{-\anchorradius}{-\anchorradius}}}%
+ %
+ % Background path.
+ %
+ \backgroundpath{%
+ \calculateradii%
+ \pgfpathmoveto{%
+ \pgfpointadd{\centerpoint}{\pgfqpointpolar{\startangle}{\radius}}%
+ }%
+ \let\angle\startangle%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter=\sides\relax%
+ \pgfpathclose%
+ \else%
+ \pgfmathadd@{\angle}{\anglestep}%
+ \let\angle\pgfmathresult%
+ \pgfpathlineto{%
+ \pgfpointadd{\centerpoint}{\pgfqpointpolar{\angle}{\radius}}%
+ }%
+ \repeatpgfmathloop%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % Adjust the location of the external
+ % point relative to \centerpoint.
+ %
+ \centerpoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Get the angle of the external point to the \centerpoint.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ %
+ % Locate the appropriate sides on the polygon border...
+ %
+ \pgfmathsubtract@{\pgfmathresult}{\startangle}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \pgfmathdivide@{\pgfmathresult}{\anglestep}%
+ \pgfmathfloor@{\pgfmathresult}%
+ \pgfmathmultiply@{\pgfmathresult}{\anglestep}%
+ \pgfmathadd@{\pgfmathresult}{\startangle}%
+ \let\firstangle\pgfmathresult%
+ \pgfmathadd@{\pgfmathresult}{\anglestep}%
+ \let\secondangle\pgfmathresult%
+ \calculateradii%
+ %
+ % ...and thus, the point on the polygon border.
+ %
+ \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}%
+ {%
+ \pgfpointadd{\centerpoint}%
+ {\pgfqpointpolar{+\firstangle}{+\anchorradius}}%
+ }%
+ {%
+ \pgfpointadd{\centerpoint}%
+ {\pgfqpointpolar{+\secondangle}{+\anchorradius}}%
+ }%
+ }%
+ %
+ % More hackery for when the rectangular polygon is positioned using
+ % a `corner <n+1>' or `side <n+1>' anchor, where n is the maximum
+ % number of sides of any previously drawn regular polygon.
+ %
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@regular polygon\endcsname{%
+ \c@pgf@counta\sides\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \pgfutil@ifundefined{pgf@anchor@regular polygon@corner\space\the\c@pgf@counta}{%
+ %
+ % ...(manually \xdef as \gdef is normally used by \anchor)...
+ %
+ \expandafter\xdef\csname pgf@anchor@regular polygon@corner\space\the\c@pgf@counta\endcsname{%
+ \noexpand\calculateradii%
+ \noexpand\pgfmathsubtract@{\the\c@pgf@counta}{1}%
+ \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{\noexpand\anglestep}%
+ \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}%
+ \noexpand\let\noexpand\angle\noexpand\pgfmathresult%
+ \noexpand\pgfpointadd{\noexpand\centerpoint}%
+ {\noexpand\pgfqpointpolar{\noexpand\angle}{\noexpand\anchorradius}}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@regular polygon@side\space\the\c@pgf@counta\endcsname{%
+ \noexpand\calculateradii%
+ \noexpand\pgfmathsubtract@{\the\c@pgf@counta}{1}%
+ \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{\noexpand\anglestep}%
+ \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}%
+ \noexpand\let\noexpand\firstangle\noexpand\pgfmathresult%
+ \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\anglestep}%
+ \noexpand\let\noexpand\secondangle\noexpand\pgfmathresult%
+ \noexpand\pgfpointlineattime{0.5}%
+ {\noexpand\pgfpointadd{\noexpand\centerpoint}%
+ {\noexpand\pgfqpointpolar{\noexpand\firstangle}{\noexpand\anchorradius}}}%
+ {\noexpand\pgfpointadd{\noexpand\centerpoint}%
+ {\noexpand\pgfqpointpolar{\noexpand\secondangle}{\noexpand\anchorradius}}}%
+ }%
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+ }%
+}%
+
+
+
+% Keys for shape trapezium
+%
+% /pgf/trapezium left angle : angle of the left side.
+% /pgf/trapezium right angle : angle of the right side.
+
+\pgfkeys{/pgf/.cd,
+ trapezium left angle/.initial=60,
+ trapezium right angle/.initial=60,
+ trapezium angle/.style={
+ /pgf/trapezium left angle={#1},
+ /pgf/trapezium right angle={#1}
+ },%
+ trapezium stretches/.is if=pgf@lib@sh@trapeziumstretches,%
+ trapezium stretches body/.is if=pgf@lib@sh@trapeziumstretchesbody,%
+}%
+
+\newif\ifpgf@lib@sh@trapeziumstretchesbody
+\newif\ifpgf@lib@sh@trapeziumstretches
+
+
+% Shape trapezium.
+%
+\pgfdeclareshape{trapezium}{%
+ \savedmacro\installtrapeziumparameters{%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \ifpgfshapeborderusesincircle%
+ %
+ % Get the rotation (no rounding).
+ %
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ %
+ % Use the radius of the incircle if required...
+ %
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \pgf@x1.41421\pgf@x%
+ \pgf@y\pgf@x%
+ \else%
+ %
+ % Get the rotation (with rounding).
+ %
+ \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % Calculate the width and height of the node
+ % contents, according to any border rotation.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \fi%
+ \fi%
+ \fi%
+ \pgfmathmod{\pgfkeysvalueof{/pgf/trapezium left angle}}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\leftangle\pgfmathresult%
+ \ifdim\leftangle pt=0pt\relax%
+ \def\pgfmathresult{0}%
+ \else%
+ \pgfmathcot@{\leftangle}%
+ \fi%
+ \pgf@xa2\pgf@y%
+ \pgf@xa\pgfmathresult\pgf@xa%
+ \pgfmathmod{\pgfkeysvalueof{/pgf/trapezium right angle}}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\rightangle\pgfmathresult%
+ \ifdim\rightangle pt=0pt\relax%
+ \def\pgfmathresult{0}%
+ \else%
+ \pgfmathcot@{\rightangle}%
+ \fi%
+ \pgf@xb2\pgf@y%
+ \pgf@xb\pgfmathresult\pgf@xb%
+ %
+ % Take into account minimum height and width.
+ %
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \ifpgf@lib@sh@trapeziumstretches%
+ \pgf@y.5\pgf@ya%
+ \else%
+ \ifpgf@lib@sh@trapeziumstretchesbody%
+ \pgf@y.5\pgf@ya%
+ \else%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@y}}%
+ \pgf@yb.5\pgf@ya%
+ \pgf@yb\pgfmathresult\pgf@yb%
+ \pgf@y.5\pgf@ya%
+ \pgf@x\pgfmath@tonumber{\pgf@yb}\pgf@x%
+ \pgf@xa\pgfmath@tonumber{\pgf@yb}\pgf@xa%
+ \pgf@xb\pgfmath@tonumber{\pgf@yb}\pgf@xb%
+ \fi%
+ \fi%
+ \fi%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@xc2\pgf@x%
+ \ifdim\pgf@xa<0pt\relax%
+ \advance\pgf@xc-\pgf@xa%
+ \else%
+ \advance\pgf@xc\pgf@xa%
+ \fi%
+ \ifdim\pgf@xb<0pt\relax%
+ \advance\pgf@xc-\pgf@xb%
+ \else%
+ \advance\pgf@xc\pgf@xb%
+ \fi%
+ \ifdim\pgf@xc<\pgf@ya%
+ \ifpgf@lib@sh@trapeziumstretchesbody%
+ \pgf@xc-\pgf@xc%
+ \advance\pgf@xc\pgf@ya%
+ \advance\pgf@x.5\pgf@xc%
+ \else%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}%
+ \pgf@ya\pgfmathresult\pgf@ya%
+ \pgf@x\pgfmath@tonumber{\pgf@ya}\pgf@x%
+ \pgf@xa\pgfmath@tonumber{\pgf@ya}\pgf@xa%
+ \pgf@xb\pgfmath@tonumber{\pgf@ya}\pgf@xb%
+ \ifpgf@lib@sh@trapeziumstretches%
+ \else%
+ \pgf@y\pgfmath@tonumber{\pgf@ya}\pgf@y%
+ \fi%
+ \fi%
+ \fi%
+ \edef\halfheight{\the\pgf@y}%
+ \edef\halfwidth{\the\pgf@x}%
+ \edef\leftextension{\the\pgf@xa}%
+ \edef\rightextension{\the\pgf@xb}%
+ \pgf@xc2\pgf@x%
+ %
+ % Take the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@y>\pgf@x%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\outersep{\the\pgf@x}%
+ %
+ % The \externalradius is a length that is
+ % guarenteed to produce a point outside the trapezium.
+ %
+ \advance\pgf@xc2.0\pgf@x%
+ \pgf@yc\halfheight\relax%
+ \multiply\pgf@yc2\relax%
+ \advance\pgf@yc2.0\pgf@x%
+ \ifdim\pgf@xc<\pgf@yc%
+ \edef\externalradius{\the\pgf@yc}%
+ \else%
+ \edef\externalradius{\the\pgf@xc}%
+ \fi%
+ %
+ % Calculate the centre base and mid poins of the node.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \pgfextract@process\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \pgfextract@process\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ %
+ % Calculate each point on the trapezium (without rotation).
+ %
+ \pgfextract@process\lowerleftpoint{%
+ \centerpoint%
+ \advance\pgf@x-\halfwidth\relax%
+ \ifdim\leftextension>0pt\relax%
+ \advance\pgf@x-\leftextension\relax%
+ \fi%
+ \advance\pgf@y-\halfheight\relax%
+ }%
+ \pgfextract@process\upperleftpoint{%
+ \centerpoint%
+ \advance\pgf@x-\halfwidth\relax%
+ \ifdim\leftextension<0pt\relax%
+ \advance\pgf@x\leftextension\relax%
+ \fi%
+ \advance\pgf@y\halfheight\relax%
+ }%
+ \pgfextract@process\upperrightpoint{%
+ \centerpoint%
+ \advance\pgf@x\halfwidth\relax%
+ \ifdim\rightextension<0pt\relax%
+ \advance\pgf@x-\rightextension\relax%
+ \fi%
+ \advance\pgf@y\halfheight\relax%
+ }%
+ \pgfextract@process\lowerrightpoint{%
+ \centerpoint%
+ \advance\pgf@x\halfwidth\relax%
+ \ifdim\rightextension>0pt\relax%
+ \advance\pgf@x\rightextension\relax%
+ \fi%
+ \advance\pgf@y-\halfheight\relax%
+ }%
+ %
+ % Now calculate the adjustment for the miter length at each corner
+ % of the trapezium. This ensures more accurate anchor positioning
+ % when the line width is particularly thick.
+ %
+ \pgfextract@process\lowerleftmiter{%
+ \pgfmathanglebetweenlines{\lowerleftpoint}{\lowerrightpoint}{\lowerleftpoint}{\upperleftpoint}%
+ \pgfmathmultiply@{\pgfmathresult}{.5}%
+ \pgfmathtan@{\pgfmathresult}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@x-\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y-\outersep\relax%
+ }%
+ \pgfextract@process\upperleftmiter{%
+ \pgfmathanglebetweenlines{\upperleftpoint}{\lowerleftpoint}{\upperleftpoint}{\upperrightpoint}%
+ \pgfmathmultiply@{\pgfmathresult}{.5}%
+ \pgfmathtan@{\pgfmathresult}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@x-\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y\outersep\relax%
+ }%
+ \pgfextract@process\upperrightmiter{%
+ \pgfmathanglebetweenlines{\upperrightpoint}{\upperleftpoint}{\upperrightpoint}{\lowerrightpoint}%
+ \pgfmathmultiply@{\pgfmathresult}{.5}%
+ \pgfmathtan@{\pgfmathresult}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@x\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y\outersep\relax%
+ }%
+ \pgfextract@process\lowerrightmiter{%
+ \pgfmathanglebetweenlines{\lowerrightpoint}{\upperrightpoint}{\lowerrightpoint}{\lowerleftpoint}%
+ \pgfmathmultiply@{\pgfmathresult}{.5}%
+ \pgfmathtan@{\pgfmathresult}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@x\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y-\outersep\relax%
+ }%
+ %
+ % Now calculate the corners for determining anchor border
+ % points, by adding the adjustment for the miter length.
+ %
+ \pgfextract@process\lowerleftborderpoint{%
+ \pgfpointadd{\lowerleftpoint}{\lowerleftmiter}%
+ }%
+ \pgfextract@process\upperleftborderpoint{%
+ \pgfpointadd{\upperleftpoint}{\upperleftmiter}%
+ }%
+ \pgfextract@process\upperrightborderpoint{%
+ \pgfpointadd{\upperrightpoint}{\upperrightmiter}%
+ }%
+ \pgfextract@process\lowerrightborderpoint{%
+ \pgfpointadd{\lowerrightpoint}{\lowerrightmiter}%
+ }%
+ %
+ % Calculate the angle from the centerpoint to each corner.
+ % Rotation is not important here (see \anchorborder code).
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\lowerleftborderpoint}%
+ \let\angletolowerleft\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\upperleftborderpoint}%
+ \let\angletoupperleft\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\upperrightborderpoint}%
+ \let\angletoupperright\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\lowerrightborderpoint}%
+ \let\angletolowerright\pgfmathresult%
+ %
+ % Do the same for the *inversely rotated* base point...
+ %
+ \pgfextract@process\rotatedbasepoint{%
+ \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\lowerleftborderpoint}%
+ \let\baseangletolowerleft\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\upperleftborderpoint}%
+ \let\baseangletoupperleft\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\upperrightborderpoint}%
+ \let\baseangletoupperright\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\lowerrightborderpoint}%
+ \let\baseangletolowerright\pgfmathresult%
+ %
+ % And the *inversely rotated* mid point...
+ %
+ \pgfextract@process\rotatedmidpoint{%
+ \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\lowerleftborderpoint}%
+ \let\midangletolowerleft\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\upperleftborderpoint}%
+ \let\midangletoupperleft\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\upperrightborderpoint}%
+ \let\midangletoupperright\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\lowerrightborderpoint}%
+ \let\midangletolowerright\pgfmathresult%
+ %
+ % Now rotate the border points around the centerpoint...
+ %
+ \pgfextract@process\lowerleftborderpoint{%
+ \pgfmathrotatepointaround%
+ {\lowerleftborderpoint}%
+ {\centerpoint}%
+ {\rotate}%
+ }%
+ \pgfextract@process\upperleftborderpoint{%
+ \pgfmathrotatepointaround%
+ {\upperleftborderpoint}%
+ {\centerpoint}%
+ {\rotate}%
+ }%
+ \pgfextract@process\upperrightborderpoint{%
+ \pgfmathrotatepointaround%
+ {\upperrightborderpoint}%
+ {\centerpoint}%
+ {\rotate}%
+ }%
+ \pgfextract@process\lowerrightborderpoint{%
+ \pgfmathrotatepointaround%
+ {\lowerrightborderpoint}%
+ {\centerpoint}%
+ {\rotate}%
+ }%
+ %
+ % ...and the points for drawing the border (i.e. no outer sep).
+ %
+ \pgfextract@process\lowerleftpoint{%
+ \pgfmathrotatepointaround{\lowerleftpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\upperleftpoint{%
+ \pgfmathrotatepointaround{\upperleftpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\upperrightpoint{%
+ \pgfmathrotatepointaround{\upperrightpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\lowerrightpoint{%
+ \pgfmathrotatepointaround{\lowerrightpoint}{\centerpoint}{\rotate}%
+ }%
+ %
+ % And finally, save all the relevant stuff.
+ %
+ \addtosavedmacro{\lowerleftpoint}%
+ \addtosavedmacro{\upperleftpoint}%
+ \addtosavedmacro{\upperrightpoint}%
+ \addtosavedmacro{\lowerrightpoint}%
+ %
+ \addtosavedmacro{\lowerleftborderpoint}%
+ \addtosavedmacro{\upperleftborderpoint}%
+ \addtosavedmacro{\upperrightborderpoint}%
+ \addtosavedmacro{\lowerrightborderpoint}%
+ %
+ \addtosavedmacro{\angletolowerleft}%
+ \addtosavedmacro{\angletoupperleft}%
+ \addtosavedmacro{\angletoupperright}%
+ \addtosavedmacro{\angletolowerright}%
+ %
+ \addtosavedmacro{\baseangletolowerleft}%
+ \addtosavedmacro{\baseangletoupperleft}%
+ \addtosavedmacro{\baseangletoupperright}%
+ \addtosavedmacro{\baseangletolowerright}%
+ %
+ \addtosavedmacro{\midangletolowerleft}%
+ \addtosavedmacro{\midangletoupperleft}%
+ \addtosavedmacro{\midangletoupperright}%
+ \addtosavedmacro{\midangletolowerright}%
+ %
+ \addtosavedmacro{\rotate}%
+ \addtosavedmacro{\externalradius}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \installtrapeziumparameters%
+ \let\pgf@trapeziumanchorborderreferencepoint\basepoint%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{base west}{%
+ \installtrapeziumparameters%
+ \let\pgf@trapeziumanchorborderreferencepoint\basepoint%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \installtrapeziumparameters%
+ \let\pgf@trapeziumanchorborderreferencepoint\midpoint%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{mid west}{%
+ \installtrapeziumparameters%
+ \let\pgf@trapeziumanchorborderreferencepoint\midpoint%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{0pt}{\externalradius}}%
+ }%
+ \anchor{south}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}%
+ }%
+ \anchor{east}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north east}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}%
+ }%
+ \anchor{south west}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}%
+ }%
+ \anchor{south east}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}%
+ }%
+ \anchor{north west}{%
+ \installtrapeziumparameters%
+ \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}%
+ }%
+ \anchor{bottom left corner}{%
+ \installtrapeziumparameters%
+ \lowerleftborderpoint%
+ }%
+ \anchor{top left corner}{%
+ \installtrapeziumparameters%
+ \upperleftborderpoint%
+ }%
+ \anchor{top right corner}{%
+ \installtrapeziumparameters%
+ \upperrightborderpoint%
+ }%
+ \anchor{bottom right corner}{%
+ \installtrapeziumparameters%
+ \lowerrightborderpoint%
+ }%
+ \anchor{left side}{%
+ \installtrapeziumparameters%
+ \pgfpointlineattime{0.5}{\lowerleftborderpoint}{\upperleftborderpoint}%
+ }%
+ \anchor{right side}{%
+ \installtrapeziumparameters%
+ \pgfpointlineattime{0.5}{\lowerrightborderpoint}{\upperrightborderpoint}%
+ }%
+ \anchor{top side}{%
+ \installtrapeziumparameters%
+ \pgfpointlineattime{0.5}{\upperleftborderpoint}{\upperrightborderpoint}%
+ }%
+ \anchor{bottom side}{%
+ \installtrapeziumparameters%
+ \pgfpointlineattime{0.5}{\lowerleftborderpoint}{\lowerrightborderpoint}%
+ }%
+ \backgroundpath{%
+ \installtrapeziumparameters%
+ \pgfpathmoveto{\lowerleftpoint}%
+ \pgfpathlineto{\upperleftpoint}%
+ \pgfpathlineto{\upperrightpoint}%
+ \pgfpathlineto{\lowerrightpoint}%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % This allows anchors base east, base west, mid east and mid west,
+ % to redefine the `center' of the node to correctly calculate the
+ % border points.
+ %
+ \pgfutil@ifundefined{pgf@trapeziumanchorborderreferencepoint}%
+ {\let\referencepoint\centerpoint}%
+ {\let\referencepoint\pgf@trapeziumanchorborderreferencepoint}%
+ %
+ % Adjust the location of the external
+ % point relative to the reference point.
+ %
+ \referencepoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Install the required points and angles.
+ %
+ \installtrapeziumparameters%
+ %
+ % Get the angle of the external point to the \referencepoint.
+ %
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ %
+ % *Subtract* the rotation from the external angle. This is
+ % why the border point angles do not neeed to be rotated.
+ %
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ %
+ % Get the relevant angles for the reference point.
+ %
+ \let\externalangle\pgfmathresult%
+ \ifx\referencepoint\basepoint%
+ \let\angletoupperright\baseangletoupperright%
+ \let\angletoupperleft\baseangletoupperleft%
+ \let\angletolowerright\baseangletolowerright%
+ \let\angletolowerleft\baseangletolowerleft%
+ \else%
+ \ifx\referencepoint\midpoint%
+ \let\angletoupperright\midangletoupperright%
+ \let\angletoupperleft\midangletoupperleft%
+ \let\angletolowerright\midangletolowerright%
+ \let\angletolowerleft\midangletolowerleft%
+ \fi\fi%
+ %
+ % Find the line on the border...
+ %
+ \ifdim\externalangle pt<\angletoupperright pt\relax%
+ \let\firstpoint\upperrightborderpoint%
+ \let\secondpoint\lowerrightborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletoupperleft pt\relax%
+ \let\firstpoint\upperleftborderpoint%
+ \let\secondpoint\upperrightborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletolowerleft pt\relax%
+ \let\firstpoint\upperleftborderpoint%
+ \let\secondpoint\lowerleftborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletolowerright pt\relax%
+ \let\firstpoint\lowerleftborderpoint%
+ \let\secondpoint\lowerrightborderpoint%
+ \else%
+ \let\firstpoint\upperrightborderpoint%
+ \let\secondpoint\lowerrightborderpoint%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ %
+ % ...and thus the point on the border.
+ %
+ \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\firstpoint}{\secondpoint}%
+ }%
+}%
+
+
+
+
+% Shape semicircle.
+%
+\pgfdeclareshape{semicircle}{%
+ \savedmacro\installsemicircleparameters{%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\outersep{\the\pgf@x}%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x+.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y+.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y+.5\dp\pgfnodeparttextbox%
+ %
+ % Use the radius of the incircle if required...
+ %
+ \ifpgfshapeborderusesincircle%
+ %
+ % Get the rotation (no rounding).
+ %
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \pgf@x1.41421\pgf@x%
+ \edef\halfheight{\the\pgf@x}%
+ \advance\pgf@x\pgf@x%
+ \else%
+ %
+ % Get the rotation (with rounding).
+ %
+ \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % Calculate the width and height of the node
+ % contents, according to any border rotation.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \fi%
+ \fi%
+ \advance\pgf@y\pgf@y%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \pgf@x\pgfmathresult pt\relax%
+ \pgf@y.5\pgf@y%
+ \edef\halfheight{\the\pgf@y}%
+ \fi%
+ \edef\defaultradius{\the\pgf@x}%
+ %
+ % Take into account minimum height and width.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<\pgf@ya%
+ \pgf@x\pgf@ya%
+ \fi%
+ \edef\semicircleradius{\the\pgf@x}%
+ %
+ % Find the center/base/mid of the semi circle node.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y+-.5\dp\pgfnodeparttextbox%
+ }%
+ \pgfextract@process\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \pgfextract@process\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \pgfextract@process\semicirclecenterpoint{%
+ \centerpoint%
+ \pgf@ya\semicircleradius\relax%
+ \advance\pgf@ya-\defaultradius\relax%
+ %
+ % The point is adjusted to make the node contents
+ % appear more centered if the node is enlarged to
+ % some minimum size. The factor .4 just seems OK.
+ %
+ \pgf@ya.4\pgf@ya%
+ \advance\pgf@y-\pgf@ya%
+ \pgf@ya\halfheight\relax%
+ \advance\pgf@y-\pgf@ya%
+ }%
+ %
+ % Add the outer sep to the radius here.
+ %
+ \pgf@x\semicircleradius\relax%
+ \advance\pgf@x\outersep\relax%
+ \edef\semicircleradius{\the\pgf@x}%
+ \pgfpointdiff{\centerpoint}{\semicirclecenterpoint}%
+ \ifdim\pgf@y<0pt\pgf@y-\pgf@y\fi%
+ \edef\centerpointdiff{\the\pgf@y}%
+ %
+ % Calculate the start and end points on the border.
+ %
+ \pgfextract@process\arcstartborder{%
+ \semicirclecenterpoint%
+ \advance\pgf@x\semicircleradius\relax%
+ }%
+ \pgfextract@process\arcendborder{%
+ \semicirclecenterpoint%
+ \advance\pgf@x-\semicircleradius\relax%
+ }%
+ %
+ % Calculate the start and end *corner* points on the border.
+ % This is needed to accommodate the outer sep.
+ %
+ \pgfextract@process\arcstartcorner{%
+ \arcstartborder%
+ \advance\pgf@y-\outersep\relax%
+ }%
+ \pgfextract@process\arcendcorner{%
+ \arcendborder%
+ \advance\pgf@y-\outersep\relax%
+ }
+ %
+ % Now calculate all the relevant angles.
+ %
+ % For the center point.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcstartborder}%
+ \let\angletoarcstartborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcendborder}%
+ \let\angletoarcendborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcstartcorner}%
+ \let\angletoarcstartcorner\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcendcorner}%
+ \let\angletoarcendcorner\pgfmathresult%
+ %
+ % For the basepoint (rotated about the center point).
+ %
+ \pgfextract@process\rotatedbasepoint{%
+ \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcstartborder}%
+ \let\baseangletoarcstartborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcendborder}%
+ \let\baseangletoarcendborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcstartcorner}%
+ \let\baseangletoarcstartcorner\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcendcorner}%
+ \let\baseangletoarcendcorner\pgfmathresult%
+ %
+ % For the midpoint (rotated about the center point).
+ %
+ \pgfextract@process\rotatedmidpoint{%
+ \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcstartborder}%
+ \let\midangletoarcstartborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcendborder}%
+ \let\midangletoarcendborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcstartcorner}%
+ \let\midangletoarcstartcorner\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcendcorner}%
+ \let\midangletoarcendcorner\pgfmathresult%
+ %
+ % Now, rotate the semicircle points around the centerpoint.
+ %
+ \pgfextract@process\semicirclecenterpoint{%
+ \pgfmathrotatepointaround{\semicirclecenterpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcstartborder{%
+ \pgfmathrotatepointaround{\arcstartborder}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcendborder{%
+ \pgfmathrotatepointaround{\arcendborder}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcstartcorner{%
+ \pgfmathrotatepointaround{\arcstartcorner}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcendcorner{%
+ \pgfmathrotatepointaround{\arcendcorner}{\centerpoint}{\rotate}%
+ }%
+ %
+ % Calculate the distance between the base point and the (rotated) semicircle center.
+ %
+ \pgfpointdiff{\basepoint}{\semicirclecenterpoint}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \edef\basesemicirclecenterdiff{\pgfmathresult pt}%
+ %
+ % Calculate the distance between the base point and the (rotated) semicircle center.
+ %
+ \pgfpointdiff{\midpoint}{\semicirclecenterpoint}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \edef\midsemicirclecenterdiff{\pgfmathresult pt}%
+ %
+ % And save all the stuff.
+ %
+ \addtosavedmacro{\rotate}%
+ \addtosavedmacro{\outersep}%
+ \addtosavedmacro{\semicircleradius}%
+ %
+ \addtosavedmacro{\arcstartborder}%
+ \addtosavedmacro{\arcendborder}%
+ \addtosavedmacro{\arcstartcorner}%
+ \addtosavedmacro{\arcendcorner}%
+ \addtosavedmacro{\semicirclecenterpoint}%
+ %
+ \addtosavedmacro{\angletoarcstartborder}%
+ \addtosavedmacro{\angletoarcendborder}%
+ \addtosavedmacro{\angletoarcstartcorner}%
+ \addtosavedmacro{\angletoarcendcorner}%
+ %
+ \addtosavedmacro{\centerpointdiff}%
+ \addtosavedmacro{\basesemicirclecenterdiff}%
+ \addtosavedmacro{\midsemicirclecenterdiff}%
+ %
+ \addtosavedmacro{\baseangletoarcstartborder}%
+ \addtosavedmacro{\baseangletoarcendborder}%
+ \addtosavedmacro{\baseangletoarcstartcorner}%
+ \addtosavedmacro{\baseangletoarcendcorner}%
+ %
+ \addtosavedmacro{\midangletoarcstartborder}%
+ \addtosavedmacro{\midangletoarcendborder}%
+ \addtosavedmacro{\midangletoarcstartcorner}%
+ \addtosavedmacro{\midangletoarcendcorner}%
+ }%
+ \savedanchor{\centerpoint}{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}%
+ \pgfmathaddtolength\pgf@y{-.5\dp\pgfnodeparttextbox}%
+ }%
+ \savedanchor{\basepoint}{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor{\midpoint}{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{base west}{%
+ \installsemicircleparameters%
+ \let\pgf@semicirclereferencepoint\basepoint%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{-\semicircleradius}{0pt}}%
+ }%
+ \anchor{base east}{%
+ \installsemicircleparameters%
+ \let\pgf@semicirclereferencepoint\basepoint%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{\semicircleradius}{0pt}}%
+ }%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid west}{%
+ \installsemicircleparameters%
+ \let\pgf@semicirclereferencepoint\midpoint%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{-\semicircleradius}{0pt}}%
+ }%
+ \anchor{mid east}{%
+ \installsemicircleparameters%
+ \let\pgf@semicirclereferencepoint\midpoint%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{\semicircleradius}{0pt}}%
+ }%
+ \anchor{apex}{%
+ \installsemicircleparameters%
+ \pgfmathadd@{\rotate}{90}%
+ \let\angle\pgfmathresult%
+ \pgfpointadd{\semicirclecenterpoint}{\pgfqpointpolar{\angle}{\semicircleradius}}%
+ }%
+ \anchor{arc start}{%
+ \installsemicircleparameters%
+ \arcstartcorner%
+ }%
+ \anchor{arc end}{%
+ \installsemicircleparameters%
+ \arcendcorner%
+ }%
+ \anchor{chord center}{%
+ \installsemicircleparameters%
+ \pgfpointlineattime{0.5}{\arcstartcorner}{\arcendcorner}%
+ }%
+ \anchor{north}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{90}{\semicircleradius}}%
+ }%
+ \anchor{south}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{270}{\semicircleradius}}%
+ }%
+ \anchor{east}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{0}{\semicircleradius}}%
+ }%
+ \anchor{west}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{180}{\semicircleradius}}%
+ }%
+ \anchor{north west}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{135}{\semicircleradius}}%
+ }%
+ \anchor{south west}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{225}{\semicircleradius}}%
+ }%
+ \anchor{north east}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{45}{\semicircleradius}}%
+ }%
+ \anchor{south east}{%
+ \installsemicircleparameters%
+ \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{315}{\semicircleradius}}%
+ }%
+ \backgroundpath{%
+ \installsemicircleparameters%
+ \pgf@x\semicircleradius\relax%
+ \advance\pgf@x-\outersep\relax%
+ \edef\semicircleradius{\the\pgf@x}%
+ \pgfpathmoveto{\pgfpointadd{\semicirclecenterpoint}{\pgfqpointpolar{\rotate}{\semicircleradius}}}%
+ {%
+ \pgftransformrotate{\rotate}%
+ \pgfpatharc{0}{180}{\semicircleradius}%
+ \pgfpathclose%
+ }%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % Check if a reference point has been defined (i.e. \midpoint or \basepoint).
+ %
+ \pgfutil@ifundefined{pgf@semicirclereferencepoint}%
+ {\let\referencepoint\centerpoint}%
+ {\let\referencepoint\pgf@semicirclereferencepoint}%
+ %
+ % Adjust the location of the external point relative to the reference point.
+ %
+ \referencepoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Install the required points and angles.
+ %
+ \installsemicircleparameters%
+ %
+ % Get the angle of the external point to the \referencepoint.
+ %
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ \let\externalangle\pgfmathresult%
+ %
+ % *Subtract* the rotation from the external angle.
+ %
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\angle\pgfmathresult%
+ \ifx\referencepoint\basepoint%
+ \let\angletoarcstartborder\baseangletoarcstartborder%
+ \let\angletoarcendborder\baseangletoarcendborder%
+ \let\angletoarcstartcorner\baseangletoarcstartcorner%
+ \let\angletoarcendcorner\baseangletoarcendcorner%
+ \let\centerpointdiff\basesemicirclecenterdiff%
+ \else%
+ \ifx\referencepoint\midpoint%
+ \let\angletoarcstartborder\midangletoarcstartborder%
+ \let\angletoarcendborder\midangletoarcendborder%
+ \let\angletoarcstartcorner\midangletoarcstartcorner%
+ \let\angletoarcendcorner\midangletoarcendcorner%
+ \let\centerpointdiff\midsemicirclecenterdiff%
+ \fi\fi%
+ %
+ % Determine if the line will cross the semicircle arc, or the chord.
+ %
+ \ifdim\angle pt>\angletoarcstartborder pt\relax%
+ \let\firstpoint\pgfutil@empty%
+ \let\secondpoint\pgfutil@empty%
+ \else%
+ \ifdim\angle pt>\angletoarcstartcorner pt\relax%
+ \let\firstpoint\arcstartcorner%
+ \let\secondpoint\arcstartborder%
+ \else%
+ \ifdim\angle pt>\angletoarcendcorner pt\relax%
+ \let\firstpoint\arcendcorner%
+ \let\secondpoint\arcstartcorner%
+ \else%
+ \ifdim\angle pt>\angletoarcendborder pt\relax%
+ \let\firstpoint\arcendborder%
+ \let\secondpoint\arcendcorner%
+ \else%
+ \let\firstpoint\pgfutil@empty%
+ \let\secondpoint\pgfutil@empty%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \ifx\firstpoint\pgfutil@empty
+ %
+ % Calculate the angle from the centre of the semicircle to the
+ % point on the semicircle arc which intersects the line from
+ % the external point to the reference point...
+ %
+ \pgfmathanglebetweenlines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\semicirclecenterpoint}{\referencepoint}%
+ \pgfmathsin@{\pgfmathresult}%
+ \let\sineangle\pgfmathresult%
+ \pgf@x\semicircleradius\relax%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@x}}%
+ \let\reciprocalradius\pgfmathresult%
+ \pgf@x\centerpointdiff\relax%
+ \pgf@x\sineangle\pgf@x%
+ \pgf@x\reciprocalradius\pgf@x%
+ \pgfmathasin@{\pgfmath@tonumber{\pgf@x}}%
+ \pgf@x\pgfmathresult pt\relax%
+ \advance\pgf@x\externalangle pt\relax%
+ \edef\angle{\pgfmath@tonumber{\pgf@x}}%
+ %
+ % ...and thus the point on the border.
+ %
+ \pgfpointadd{\semicirclecenterpoint}{\pgfqpointpolar{\angle}{\semicircleradius}}%
+ \else%
+ %
+ % Calculate the the point where the semicircle chord intersects
+ % the line from the external point to the reference point.
+ %
+ \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\firstpoint}{\secondpoint}%
+ \fi%
+ }%
+}%
+
+
+% Keys for shape isosceles triangle
+%
+% /pgf/isosceles triangle apex angle : angle at the apex of the triangle.
+\pgfkeys{/pgf/.cd,
+ isosceles triangle apex angle/.initial=45,
+ isosceles triangle stretches/.is if=pgf@lib@sh@isosceslestrianglestretches
+}%
+\newif\ifpgf@lib@sh@isosceslestrianglestretches
+
+\pgfdeclareshape{isosceles triangle}{%
+ \savedmacro\trianglepoints{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/isosceles triangle apex angle}}%
+ \divide\pgf@x2\relax%
+ \edef\halfapexangle{\pgfmath@tonumber{\pgf@x}}%
+ \addtosavedmacro\halfapexangle%
+ %
+ \pgfmathtan@{\halfapexangle}%
+ \let\tanhalfapexangle\pgfmathresult%
+ %
+ \pgfmathcot@{\halfapexangle}%
+ \let\cothalfapexangle\pgfmathresult%
+ %
+ \pgfmathsin@{\halfapexangle}%
+ \let\sinhalfapexangle\pgfmathresult%
+ %
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \let\cosechalfapexangle\pgfmathresult%
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ %
+ \ifpgfshapeborderusesincircle%
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \else%
+ \pgf@y\pgf@x%
+ \fi%
+ \pgf@x1.414213\pgf@x%
+ \pgf@y1.414213\pgf@y%
+ %
+ \pgf@xa\pgf@x%
+ \advance\pgf@xa\cosechalfapexangle\pgf@x%
+ \pgf@ya\tanhalfapexangle\pgf@xa%
+ \else%
+ \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \pgfmathsetcount\c@pgf@counta{+\pgfmathresult}%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \edef\rotate{\the\c@pgf@counta}%
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xa%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xa%
+ \fi%
+ \fi%
+ %
+ \pgf@xa2.0\pgf@x%
+ \pgf@ya\tanhalfapexangle\pgf@xa%
+ \advance\pgf@xa\cothalfapexangle\pgf@y%
+ \advance\pgf@ya\pgf@y%
+ \fi%
+ \addtosavedmacro\rotate%
+ \ifdim\pgf@xa=0pt\relax%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum height}}%
+ \fi%
+ % Adjust for minimum height and width.
+ %
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@ya<.5\pgf@yb%
+ \ifpgf@lib@sh@isosceslestrianglestretches%
+ \pgf@ya.5\pgf@yb%
+ %
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@ya}}{\pgfmath@tonumber{\pgf@xa}}%
+ \pgfmathatan@{\pgfmathresult}%
+ \let\halfapexangle\pgfmathresult%
+ %
+ \else%
+ \pgf@ya.5\pgf@yb%
+ \pgf@xa\cothalfapexangle\pgf@ya%
+ \fi%
+ \fi%
+ %
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@xa<\pgf@xb%
+ \ifpgf@lib@sh@isosceslestrianglestretches%
+ \pgf@xa\pgf@xb%
+ %
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@ya}}{\pgfmath@tonumber{\pgf@xa}}%
+ \pgfmathatan@{\pgfmathresult}%
+ \let\halfapexangle\pgfmathresult%
+ %
+ \else%
+ \pgf@xa\pgf@xb%
+ \pgf@ya\tanhalfapexangle\pgf@xa%
+ \fi%
+ \fi%
+ %
+ %
+ % Now find the ``offset height'' (h'). This is the distance from the
+ % center of the node contents to the base of the triangle.
+ %
+ \ifpgfshapeborderusesincircle%
+ %
+ % h' = H*sin(a/2) / (1+sin(a/2))
+ %
+ % where:
+ % H = the height of the triangle.
+ % a = the apex angle.
+ %
+ \pgf@xc\pgf@xa%
+ \pgfmathsin@{\halfapexangle}%
+ \pgf@xc\pgfmathresult\pgf@xc%
+ \pgf@yc1pt\relax%
+ \advance\pgf@yc\pgfmathresult pt\relax%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@xc}}{\pgfmath@tonumber{\pgf@yc}}
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \else%
+ %
+ % h' = 0.5*h + (0.5*(W-w)*cos(a/2) - h*sin(a/2))/(1+sin(a/2))
+ %
+ % where:
+ % h = the height of the node contents.
+ % w = the width of the node contents.
+ % W = the width of the triangle.
+ % a = the apex angle.
+ %
+ \pgf@xc\pgf@ya%
+ \advance\pgf@xc-\pgf@y%
+ \pgfmathcos@{\halfapexangle}%
+ \pgf@xc\pgfmathresult\pgf@xc%
+ \pgfmathsin@{\halfapexangle}%
+ \advance\pgf@xc-\pgfmathresult\pgf@x%
+ \advance\pgf@xc-\pgfmathresult\pgf@x%
+ \pgf@yc\pgfmathresult pt\relax%
+ \advance\pgf@yc1pt\relax%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@xc}}{\pgfmath@tonumber{\pgf@yc}}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \advance\pgfutil@tempdima\pgf@x%
+ \fi%
+ \pgfextract@process\apex{%
+ \pgf@y0pt%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x-\pgfutil@tempdima%
+ }%
+ \addtosavedmacro\apex%
+ %
+ \pgfextract@process\lowerleft{%
+ \pgf@y\pgf@ya%
+ \pgf@x-\pgfutil@tempdima%
+ }%
+ \addtosavedmacro\lowerleft%
+ %
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \pgf@xb\pgf@yb%
+ \fi%
+ \pgfextract@process\apexanchor{%
+ \apex%
+ \advance\pgf@x\cosechalfapexangle\pgf@xb%
+ }%
+ \addtosavedmacro\apexanchor%
+ %
+ \pgf@yc-\halfapexangle pt\relax%
+ \advance\pgf@yc90pt\relax%
+ \divide\pgf@yc2\relax%
+ \pgfmathcot@{\pgfmath@tonumber{\pgf@yc}}%
+ \pgfextract@process\lowerleftanchor{%
+ \lowerleft%
+ \advance\pgf@y\pgfmathresult\pgf@xb%
+ \advance\pgf@x-\pgf@xb%
+ }%
+ \addtosavedmacro\lowerleftanchor%
+ %
+ \pgfextract@process\lowerrightanchor{%
+ \lowerleftanchor%
+ \pgf@y-\pgf@y%
+ }%
+ \addtosavedmacro\lowerrightanchor%
+ }%
+ \anchor{apex}{%
+ \trianglepoints%
+ \pgfpointadd{\centerpoint}{%
+ \pgfmathrotatepointaround{\apexanchor}{\pgfpointorigin}{\rotate}%
+ }%
+ }%
+ \anchor{left corner}{%
+ \trianglepoints%
+ \pgfpointadd{\centerpoint}{%
+ \pgfmathrotatepointaround{\lowerleftanchor}{\pgfpointorigin}{\rotate}%
+ }%
+ }%
+ \anchor{right corner}{%
+ \trianglepoints%
+ \pgfpointadd{\centerpoint}{%
+ \pgfmathrotatepointaround{\lowerrightanchor}{\pgfpointorigin}{\rotate}%
+ }%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid west}{%
+ \trianglepoints%
+ \let\pgf@isoscelestriangle@referencepoint\midpoint%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{0pt}}%
+ }%
+ \anchor{mid east}{%
+ \trianglepoints%
+ \let\pgf@isoscelestriangle@referencepoint\midpoint%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{0pt}}%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base west}{%
+ \trianglepoints%
+ \let\pgf@isoscelestriangle@referencepoint\basepoint%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{0pt}}%
+ }%
+ \anchor{base east}{%
+ \trianglepoints%
+ \let\pgf@isoscelestriangle@referencepoint\basepoint%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{0pt}}%
+ }%
+ \anchor{north}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{0pt}{1pt}}%
+ }%
+ \anchor{south}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{0pt}{-1pt}}%
+ }%
+ \anchor{east}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{0pt}}%
+ }%
+ \anchor{west}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{0pt}}%
+ }%
+ \anchor{north east}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{1pt}}%
+ }%
+ \anchor{south west}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{-1pt}}%
+ }%
+ \anchor{south east}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{-1pt}}%
+ }%
+ \anchor{north west}{%
+ \trianglepoints%
+ \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{1pt}}%
+ }%
+ \anchor{left side}{%
+ \trianglepoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{\pgfpointlineattime{0.5}{\lowerleftanchor}{\apexanchor}}{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{right side}{%
+ \trianglepoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{\pgfpointlineattime{0.5}{\lowerrightanchor}{\apexanchor}}{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{lower side}{%
+ \trianglepoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{\pgfpointlineattime{0.5}{\lowerleftanchor}{\lowerrightanchor}}{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \backgroundpath{%
+ \trianglepoints%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgftransformrotate{\rotate}%
+ \pgfpathmoveto{\apex}%
+ \pgfpathlineto{\lowerleft}%
+ \pgfpathlineto{\lowerleft\pgf@y-\pgf@y}%
+ \pgfpathclose%
+ }%
+ }%
+ \anchorborder{%
+ \pgfutil@ifundefined{pgf@isoscelestriangle@referencepoint}{\let\referencepoint\centerpoint}%
+ {\let\referencepoint\pgf@isoscelestriangle@referencepoint}%
+ \pgfextract@process\externalpoint{%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \referencepoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \trianglepoints%
+ \pgfmathanglebetweenpoints{\referencepoint}{\externalpoint}%
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \pgfmathmod@{\pgfmathresult}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\externalangle\pgfmathresult%
+ %
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\centerpoint}{\lowerrightanchor}}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\centerpoint}{\lowerleftanchor}}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\centerpoint}{\apexanchor}}%
+ \ifdim\externalangle pt>\pgfmathresult pt\relax%
+ \let\firstpoint\apexanchor%
+ \let\secondpoint\lowerleftanchor%
+ \else%
+ \let\firstpoint\apexanchor%
+ \let\secondpoint\lowerrightanchor%
+ \fi%
+ \else%
+ \let\firstpoint\lowerleftanchor%
+ \let\secondpoint\lowerrightanchor%
+ \fi%
+ \else%
+ \let\firstpoint\lowerrightanchor%
+ \let\secondpoint\apexanchor%
+ \fi%
+ \pgfpointintersectionoflines{\referencepoint}{\externalpoint}%
+ {\pgfmathrotatepointaround{\pgfpointadd{\centerpoint}{\firstpoint}}{\centerpoint}{\rotate}}%
+ {\pgfmathrotatepointaround{\pgfpointadd{\centerpoint}{\secondpoint}}{\centerpoint}{\rotate}}%
+ }%
+}%
+
+
+
+
+% Keys for shape kite
+%
+%
+\pgfkeys{/pgf/.cd,
+ kite upper vertex angle/.initial=120,
+ kite lower vertex angle/.initial=60,
+ kite vertex angles/.code={%
+ \pgfutil@in@{and}{#1}%
+ \ifpgfutil@in@%
+ \def\pgf@marshal##1and##2\@@{%
+ \pgfkeys{/pgf/kite upper vertex angle={##1}}%
+ \pgfkeys{/pgf/kite lower vertex angle={##2}}%
+ }%
+ \expandafter\pgf@marshal#1\@@%
+ \else%
+ \pgfkeys{/pgf/kite upper vertex angle={#1}}%
+ \pgfkeys{/pgf/kite lower vertex angle={#1}}%
+ \fi%
+ }%
+}%
+
+% Shape kite.
+%
+\pgfdeclareshape{kite}{%
+ \savedmacro\installkiteparameters{%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\outersep{\the\pgf@x}%
+ %
+ % Calculate the centre, base and mid points of the node.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \pgfextract@process\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \pgfextract@process\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ %
+ % Halve the vertex angles.
+ %
+ \pgfmathdivide{\pgfkeysvalueof{/pgf/kite upper vertex angle}}{2}%
+ \let\halfuppervertexangle\pgfmathresult%
+ \pgfmathdivide{\pgfkeysvalueof{/pgf/kite lower vertex angle}}{2}%
+ \let\halflowervertexangle\pgfmathresult%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \ifpgfshapeborderusesincircle%
+ %
+ % Get the rotation.
+ %
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ %
+ % Get the radius of the incircle.
+ %
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \pgf@x1.41421\pgf@x%
+ %
+ % Get the distances from the upper and lower vertices
+ % to the center of the incircle.
+ %
+ \pgfmathsin@{\halfuppervertexangle}%
+ \let\sinehalfuppervertexangle\pgfmathresult%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \let\cosechalfuppervertexangle\pgfmathresult%
+ \pgf@ya\pgfmathresult\pgf@x%
+ \pgfmathsin@{\halflowervertexangle}%
+ \let\sinehalflowervertexangle\pgfmathresult%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@yb\pgfmathresult\pgf@x%
+ %
+ % Now calculate vertical offset (yc) between the center of
+ % the incircle, and the intersection of the kite diagonals.
+ %
+ % yc = x * cosec(a/2) - x * cot(a/2) * (sin(a/2) + sin(b/2)) * cosec(a/2 + b/2)
+ %
+ % where:
+ % x = the incircle radius.
+ % a = the upper vertex angle.
+ % b = the lower vertex angle.
+ %
+ \pgf@yc\pgf@x%
+ \pgfmathadd@{\halfuppervertexangle}{\halflowervertexangle}%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgf@yc\pgfmathresult\pgf@yc%
+ \pgfmathadd@{\sinehalfuppervertexangle}{\sinehalflowervertexangle}%
+ \pgf@yc\pgfmathresult\pgf@yc%
+ \pgfmathcos@{\halfuppervertexangle}%
+ \pgf@yc\pgfmathresult\pgf@yc%
+ \pgf@yc-\cosechalfuppervertexangle\pgf@yc%
+ \advance\pgf@yc\cosechalfuppervertexangle\pgf@x%
+ \edef\deltay{\the\pgf@yc}%
+ %
+ % Now calculate the height of the kite...
+ %
+ \advance\pgf@ya-\pgf@yc%
+ %
+ % ...and the depth.
+ %
+ \advance\pgf@yb\pgf@yc%
+ %
+ % Get the half width of the widest part of the kite.
+ %
+ \pgfmathtan@{\halfuppervertexangle}%
+ \pgf@xa\pgfmathresult\pgf@ya%
+ \else%
+ \multiply\pgf@x2\relax%
+ \multiply\pgf@y2\relax%
+ %
+ % Get the rotation (with rounding).
+ %
+ \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % Calculate the width and height of the node
+ % contents, according to any border rotation.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \fi%
+ \fi%
+ %
+ % The node contents (total height y) extends a distance ya into the
+ % upper isosceles triangle of the kite and a distance yb into the
+ % lower isosceles triangle. Thus, the following relationships hold:
+ %
+ % ya/yb = tan(b/2)/tan(a/2)
+ %
+ % and y = ya + yb
+ %
+ % so ya = y * sin(a/2 + b/2) / (cos(a/2) * sin(b/2))
+ %
+ % where:
+ % a = upper vertex angle.
+ % b = lower vertex angle.
+ %
+ \pgfmathadd@{\halfuppervertexangle}{\halflowervertexangle}%
+ \pgfmathsin@{\pgfmathresult}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@ya\pgfmathresult\pgf@y%
+ \pgfmathcos@{\halfuppervertexangle}%
+ \pgf@ya\pgfmathresult\pgf@ya%
+ \pgfmathsin@{\halflowervertexangle}%
+ \pgf@ya\pgfmathresult\pgf@ya%
+ \pgf@yb\pgf@y%
+ \advance\pgf@yb-\pgf@ya%
+ %
+ % The vertical offset between the center of the node, and
+ % the intersection of the kite diagonals is given by:
+ %
+ % yc = y/2 - ya
+ %
+ \pgf@yc.5\pgf@y%
+ \advance\pgf@yc-\pgf@ya%
+ \edef\deltay{\the\pgf@yc}%
+ %
+ % Get the half width of the widest part of the kite.
+ %
+ \pgfmathtan@{\halfuppervertexangle}%
+ \pgf@xa.5\pgf@x%
+ \advance\pgf@xa\pgfmathresult\pgf@ya%
+ %
+ % Now calculate the height of the kite...
+ %
+ \pgf@xb.5\pgf@x%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \advance\pgf@ya\pgfmathresult\pgf@xb%
+ %
+ % ...and the depth.
+ %
+ \pgfmathtan@{\halflowervertexangle}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \advance\pgf@yb\pgfmathresult\pgf@xb%
+ \fi%
+ %
+ % Take into account minimum height and width.
+ %
+ % ya is the kite height.
+ % yb is the kite depth.
+ % xa is the kite (half) width.
+ %
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/minimum height}}%
+ \pgf@y\pgf@ya%
+ \advance\pgf@y\pgf@yb%
+ \ifdim\pgf@y<\pgf@yc%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@y}}%
+ \pgf@yc\pgfmathresult\pgf@yc%
+ \pgf@xa\pgfmath@tonumber{\pgf@yc}\pgf@xa%
+ \pgf@ya\pgfmath@tonumber{\pgf@yc}\pgf@ya%
+ \pgf@yb\pgfmath@tonumber{\pgf@yc}\pgf@yb%
+ \fi%
+ \pgf@x2.0\pgf@xa%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<\pgf@xc%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@x}}%
+ \pgf@xc\pgfmathresult\pgf@xc%
+ \pgf@xa\pgfmath@tonumber{\pgf@xc}\pgf@xa%
+ \pgf@ya\pgfmath@tonumber{\pgf@xc}\pgf@ya%
+ \pgf@yb\pgfmath@tonumber{\pgf@xc}\pgf@yb%
+ \fi%
+ \edef\kitehalfwidth{\the\pgf@xa}%
+ \edef\kiteheight{\the\pgf@ya}%
+ \edef\kitedepth{\the\pgf@yb}%
+ %
+ % Calculate the basic points on the kite (for the background path).
+ %
+ \pgfextract@process\toppoint{%
+ \centerpoint%
+ \advance\pgf@y\deltay\relax%
+ \advance\pgf@y\kiteheight%
+ }%
+ \pgfextract@process\bottompoint{%
+ \centerpoint%
+ \advance\pgf@y\deltay\relax%
+ \advance\pgf@y-\kitedepth%
+ }%
+ \pgfextract@process\leftpoint{%
+ \centerpoint%
+ \advance\pgf@y\deltay\relax%
+ \advance\pgf@x-\kitehalfwidth%
+ }%
+ \pgfextract@process\rightpoint{%
+ \centerpoint%
+ \advance\pgf@y\deltay\relax%
+ \advance\pgf@x\kitehalfwidth%
+ }%
+ %
+ % Now calculate the miter length. At the top...
+ %
+ \pgfmathsin@{\halfuppervertexangle}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@y\outersep\relax%
+ \pgf@y\pgfmathresult\pgf@y%
+ \edef\topmiter{\the\pgf@y}%
+ %
+ % ...at the bottom...
+ %
+ \pgfmathsin@{\halflowervertexangle}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@y\outersep\relax%
+ \pgf@y\pgfmathresult\pgf@y%
+ \edef\bottommiter{\the\pgf@y}%
+ %
+ % ...to the right...
+ %
+ \pgfmathsubtract@{180}{\halflowervertexangle}%
+ \pgfmathsubtract@{\pgfmathresult}{\halfuppervertexangle}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \pgfmathsin@{\pgfmathresult}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \pgf@xa\outersep\relax%
+ \pgf@xa\pgfmathresult\pgf@xa%
+ \pgfmathsubtract@{\halfuppervertexangle}{\halflowervertexangle}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\angle\pgfmathresult%
+ \pgfextract@process\rightmiter{%
+ \pgfqpointpolar{\angle}{\the\pgf@xa}%
+ }%
+ %
+ % ...and to the left.
+ %
+ \pgfmathsubtract@{180}{\angle}%
+ \let\angle\pgfmathresult%
+ \pgfextract@process\leftmiter{%
+ \pgfqpointpolar{\angle}{\the\pgf@xa}%
+ }%
+ %
+ % Create the border points.
+ %
+ \pgfextract@process\topborderpoint{%
+ \toppoint%
+ \advance\pgf@y\topmiter\relax%
+ }%
+ \pgfextract@process\bottomborderpoint{%
+ \bottompoint%
+ \advance\pgf@y-\bottommiter\relax%
+ }%
+ \pgfextract@process\leftborderpoint{%
+ \leftpoint%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \leftmiter%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfextract@process\rightborderpoint{%
+ \rightpoint%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \rightmiter%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ % Get the angle from the \centerpoint to the *unrotated points*.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\topborderpoint}%
+ \let\angletotoppoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\leftborderpoint}%
+ \let\angletoleftpoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\bottomborderpoint}%
+ \let\angletobottompoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\rightborderpoint}%
+ \let\angletorightpoint\pgfmathresult%
+ %
+ % ...from the *inversely rotated* \basepoint...
+ %
+ \pgfextract@process\rotatedbasepoint{%
+ \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\topborderpoint}%
+ \let\baseangletotoppoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\leftborderpoint}%
+ \let\baseangletoleftpoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\bottomborderpoint}%
+ \let\baseangletobottompoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\rightborderpoint}%
+ \let\baseangletorightpoint\pgfmathresult%
+ %
+ % ...and from the *inversely rotated* \midpoint.
+ %
+ \pgfextract@process\rotatedmidpoint{%
+ \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\topborderpoint}%
+ \let\midangletotoppoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\leftborderpoint}%
+ \let\midangletoleftpoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\bottomborderpoint}%
+ \let\midangletobottompoint\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\rightborderpoint}%
+ \let\midangletorightpoint\pgfmathresult%
+ %
+ % Calculate a radius guaranteed to be outside the kite.
+ %
+ \pgfextractx\pgf@xa{\pgfpointdiff{\leftborderpoint}{\rightborderpoint}}%
+ \ifdim\pgf@xa<0pt\relax%
+ \pgf@xa-\pgf@xa%
+ \fi%
+ \pgfextracty\pgf@ya{\pgfpointdiff{\topborderpoint}{\bottomborderpoint}}%
+ \ifdim\pgf@ya<0pt\relax%
+ \pgf@ya-\pgf@ya%
+ \fi%
+ \ifdim\pgf@ya>\pgf@xa%
+ \edef\externalradius{\the\pgf@ya}%
+ \else%
+ \edef\externalradius{\the\pgf@xa}%
+ \fi%
+ %
+ % Now rotate the points...
+ %
+ \pgfextract@process\toppoint{%
+ \pgfmathrotatepointaround{\toppoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\bottompoint{%
+ \pgfmathrotatepointaround{\bottompoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\leftpoint{%
+ \pgfmathrotatepointaround{\leftpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\rightpoint{%
+ \pgfmathrotatepointaround{\rightpoint}{\centerpoint}{\rotate}%
+ }%
+ %
+ % ...and the border points.
+ %
+ \pgfextract@process\topborderpoint{%
+ \pgfmathrotatepointaround{\topborderpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\bottomborderpoint{%
+ \pgfmathrotatepointaround{\bottomborderpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\leftborderpoint{%
+ \pgfmathrotatepointaround{\leftborderpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\rightborderpoint{%
+ \pgfmathrotatepointaround{\rightborderpoint}{\centerpoint}{\rotate}%
+ }%
+ %
+ % Now save it all.
+ %
+ \addtosavedmacro{\rotate}%
+ \addtosavedmacro{\externalradius}%
+ %
+ \addtosavedmacro\toppoint%
+ \addtosavedmacro\bottompoint%
+ \addtosavedmacro\leftpoint%
+ \addtosavedmacro\rightpoint%
+ %
+ \addtosavedmacro\topborderpoint%
+ \addtosavedmacro\bottomborderpoint%
+ \addtosavedmacro\leftborderpoint%
+ \addtosavedmacro\rightborderpoint%
+ %
+ \addtosavedmacro\angletotoppoint%
+ \addtosavedmacro\angletobottompoint%
+ \addtosavedmacro\angletoleftpoint%
+ \addtosavedmacro\angletorightpoint%
+ %
+ \addtosavedmacro\baseangletotoppoint%
+ \addtosavedmacro\baseangletobottompoint%
+ \addtosavedmacro\baseangletoleftpoint%
+ \addtosavedmacro\baseangletorightpoint%
+ %
+ \addtosavedmacro\midangletotoppoint%
+ \addtosavedmacro\midangletobottompoint%
+ \addtosavedmacro\midangletoleftpoint%
+ \addtosavedmacro\midangletorightpoint%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{base west}{%
+ \installkiteparameters%
+ \let\pgf@kiteanchorborderreferencepoint\basepoint%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{base east}{%
+ \installkiteparameters%
+ \let\pgf@kiteanchorborderreferencepoint\basepoint%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid west}{%
+ \installkiteparameters%
+ \let\pgf@kiteanchorborderreferencepoint\midpoint%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{mid east}{%
+ \installkiteparameters%
+ \let\pgf@kiteanchorborderreferencepoint\midpoint%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{north}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{0pt}{\externalradius}}%
+ }%
+ \anchor{south}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}%
+ }%
+ \anchor{east}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north east}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}%
+ }%
+ \anchor{south west}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}%
+ }%
+ \anchor{south east}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}%
+ }%
+ \anchor{north west}{%
+ \installkiteparameters%
+ \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}%
+ }%
+ \anchor{upper vertex}{%
+ \installkiteparameters%
+ \topborderpoint}%
+ \anchor{lower vertex}{%
+ \installkiteparameters%
+ \bottomborderpoint}%
+ \anchor{left vertex}{%
+ \installkiteparameters%
+ \leftborderpoint}%
+ \anchor{right vertex}{%
+ \installkiteparameters%
+ \rightborderpoint}%
+ \anchor{upper left side}{%
+ \installkiteparameters%
+ \pgfpointlineattime{0.5}{\topborderpoint}{\leftborderpoint}}%
+ \anchor{lower left side}{%
+ \installkiteparameters%
+ \pgfpointlineattime{0.5}{\bottomborderpoint}{\leftborderpoint}}%
+ \anchor{upper right side}{%
+ \installkiteparameters%
+ \pgfpointlineattime{0.5}{\topborderpoint}{\rightborderpoint}}%
+ \anchor{lower right side}{%
+ \installkiteparameters%
+ \pgfpointlineattime{0.5}{\bottomborderpoint}{\rightborderpoint}}%
+ \backgroundpath{%
+ \installkiteparameters%
+ \pgfpathmoveto{\toppoint}%
+ \pgfpathlineto{\leftpoint}%
+ \pgfpathlineto{\bottompoint}%
+ \pgfpathlineto{\rightpoint}%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % This allows anchors base east, base west, mid east and mid west,
+ % to redefine the `center' of the node to correctly calculate the
+ % border points.
+ %
+ \pgfutil@ifundefined{pgf@kiteanchorborderreferencepoint}%
+ {\let\referencepoint\centerpoint}%
+ {\let\referencepoint\pgf@kiteanchorborderreferencepoint}%
+ %
+ % Adjust the location of the external
+ % point relative to the reference point.
+ %
+ \referencepoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Install the required points and angles.
+ %
+ \installkiteparameters%
+ %
+ % Get the angle of the external point relative to \referencepoint.
+ %
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ %
+ % *Subtract* the rotation from the external angle.
+ %
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\externalangle\pgfmathresult%
+ \ifx\referencepoint\basepoint%
+ \let\angletotoppoint\baseangletotoppoint%
+ \let\angletobottompoint\baseangletobottompoint%
+ \let\angletoleftpoint\baseangletoleftpoint%
+ \let\angletorightpoint\baseangletorightpoint%
+ \else%
+ \ifx\referencepoint\midpoint%
+ \let\angletotoppoint\midangletotoppoint%
+ \let\angletobottompoint\midangletobottompoint%
+ \let\angletoleftpoint\midangletoleftpoint%
+ \let\angletorightpoint\midangletorightpoint%
+ \fi\fi%
+ %
+ % Depending on the rotation, the angle to \rightborderpoint
+ % may be smaller than the angle to \topborderpoint.
+ %
+ \ifdim\angletorightpoint pt<\angletotoppoint pt\relax%
+ \ifdim\externalangle pt<\angletorightpoint pt\relax%
+ \let\firstpoint\rightborderpoint%
+ \let\secondpoint\bottomborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletotoppoint pt\relax%
+ \let\firstpoint\rightborderpoint%
+ \let\secondpoint\topborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletoleftpoint pt\relax%
+ \let\firstpoint\topborderpoint%
+ \let\secondpoint\leftborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletobottompoint pt\relax%
+ \let\firstpoint\leftborderpoint%
+ \let\secondpoint\bottomborderpoint%
+ \else%
+ \let\firstpoint\rightborderpoint%
+ \let\secondpoint\bottomborderpoint%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\externalangle pt<\angletotoppoint pt\relax%
+ \let\firstpoint\rightborderpoint%
+ \let\secondpoint\topborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletoleftpoint pt\relax%
+ \let\firstpoint\leftborderpoint%
+ \let\secondpoint\topborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletobottompoint pt\relax%
+ \let\firstpoint\bottomborderpoint%
+ \let\secondpoint\leftborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletorightpoint pt\relax%
+ \let\firstpoint\rightborderpoint%
+ \let\secondpoint\bottomborderpoint%
+ \else%
+ \let\firstpoint\rightborderpoint%
+ \let\secondpoint\topborderpoint%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\firstpoint}{\secondpoint}%
+ }%
+}%
+
+
+
+
+% Keys for shape dart.
+%
+%
+
+\pgfkeys{/pgf/.cd,
+ dart tip angle/.initial=45,
+ dart tail angle/.initial=135,
+}%
+
+% Shape dart.
+%
+\pgfdeclareshape{dart}{%
+ \savedmacro\installdartparameters{%
+ %
+ % Get the halved angles (more useful).
+ %
+ \pgfmathdivide{\pgfkeysvalueof{/pgf/dart tip angle}}{2}%
+ \let\halftipangle\pgfmathresult%
+ \pgfmathdivide{\pgfkeysvalueof{/pgf/dart tail angle}}{2}%
+ \let\halftailangle\pgfmathresult%
+ %
+ % Calculate some common results.
+ %
+ \pgfmathcot@{\halftipangle}%
+ \let\cothalftipangle\pgfmathresult%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\outersep{\the\pgf@x}%
+ %
+ % Calculate the centre, base and mid points of the node.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \pgfextract@process\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \pgfextract@process\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ %
+ % Get the (halved) dimension of the node.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ %
+ % Get the length of the dart tip.
+ %
+ \ifpgfshapeborderusesincircle%
+ %
+ % Get the (unrounded) rotation.
+ %
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ %
+ % Get the radius of the incircle.
+ %
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \pgf@x1.41421\pgf@x%
+ %
+ % Calculate the length of the dart tip.
+ %
+ \pgf@xa\cothalftipangle\pgf@x%
+ \advance\pgf@xa\pgf@x%
+ \else%
+ %
+ % Get the rotation (with rounding).
+ %
+ \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % Flip the width and height of the node contents,
+ % according to the appropriate border rotation.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \fi%
+ \fi%
+ %
+ % Calculate the length of the dart tip.
+ %
+ \pgf@xa\cothalftipangle\pgf@y%
+ \advance\pgf@xa2.0\pgf@x%
+ \fi%
+ %
+ % Get the (half) separation of the dart tails.
+ %
+ \pgfmathsubtract@{\halftailangle}{\halftipangle}%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgf@ya\pgfmathresult\pgf@xa%
+ \pgfmathsin@{\halftipangle}%
+ \pgf@ya\pgfmathresult\pgf@ya%
+ \pgfmathcos@{\halftipangle}%
+ \pgf@ya\pgfmathresult\pgf@ya%
+ %
+ % Get the total length of the dart...
+ %
+ \pgf@xb\cothalftipangle\pgf@ya%
+ %
+ % and hence the length of the tails.
+ %
+ \pgf@xc-\pgf@xa%
+ \advance\pgf@xc\pgf@xb%
+ %
+ % Adjust for minimum height (length of the dart).
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@xb<\pgf@y%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xb}}%
+ \pgf@y\pgfmathresult\pgf@y%
+ \pgf@xa\pgfmath@tonumber{\pgf@y}\pgf@xa%
+ \pgf@xc\pgfmath@tonumber{\pgf@y}\pgf@xc%
+ \pgf@ya\pgfmath@tonumber{\pgf@y}\pgf@ya%
+ \pgf@x\pgfmath@tonumber{\pgf@y}\pgf@x%
+ \fi%
+ %
+ % Adjust for minimum width (tail separation length).
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@y.5\pgf@y%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@ya}}%
+ \pgf@ya\pgf@y%
+ \pgf@y\pgfmathresult\pgf@y%
+ \pgf@xa\pgfmath@tonumber{\pgf@y}\pgf@xa%
+ \pgf@xc\pgfmath@tonumber{\pgf@y}\pgf@xc%
+ \pgf@x\pgfmath@tonumber{\pgf@y}\pgf@x%
+ \fi%
+ \edef\dartlength{\the\pgf@xa}%
+ \edef\deltax{\the\pgf@x}%
+ \edef\taillength{\the\pgf@xc}%
+ \edef\halftailseparation{\the\pgf@ya}
+ %
+ % Create the basic points on the dart (for the background path).
+ %
+ \pgfextract@process\tippoint{%
+ \centerpoint%
+ \advance\pgf@x\dartlength\relax%
+ \advance\pgf@x-\deltax\relax%
+ }%
+ \pgfextract@process\tailcenterpoint{%
+ \centerpoint%
+ \advance\pgf@x-\deltax\relax%
+ }%
+ \pgfextract@process\lefttailpoint{%
+ \centerpoint%
+ \advance\pgf@x-\deltax\relax%
+ \advance\pgf@x-\taillength\relax%
+ \advance\pgf@y\halftailseparation\relax%
+ }%
+ \pgfextract@process\righttailpoint{%
+ \centerpoint%
+ \advance\pgf@x-\deltax\relax%
+ \advance\pgf@x-\taillength\relax%
+ \advance\pgf@y-\halftailseparation\relax%
+ }%
+ %
+ % Calculate the miter vectors. At the dart tip...
+ %
+ \pgfextract@process\tipmiter{%
+ \pgfmathcosec@{\halftipangle}%
+ \pgf@x\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y0pt\relax%
+ }%
+ %
+ % ...at the tail center...
+ %
+ \pgfextract@process\tailcentermiter{%
+ \pgfmathcosec@{\halftailangle}%
+ \pgf@x-\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y0pt\relax%
+ }%
+ %
+ % ...at the left tail...
+ %
+ \pgfmathsubtract@{\halftailangle}{\halftipangle}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\angle\pgfmathresult%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgf@x\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgfmathadd@{\angle}{90}%
+ \pgfmathsubtract{\pgfmathresult}{\halftailangle}%
+ \pgfmathsincos@{\pgfmathresult}%
+ \pgf@ya\pgfmathresultx\pgf@x%
+ \pgf@xa\pgfmathresulty\pgf@x%
+ \pgfextract@process\lefttailmiter{%
+ \pgf@x-\pgf@xa%
+ \pgf@y\pgf@ya%
+ }%
+ %
+ % ...and the right tail.
+ %
+ \pgfextract@process\righttailmiter{%
+ \pgf@x-\pgf@xa%
+ \pgf@y-\pgf@ya%
+ }%
+ %
+ % Create the border points.
+ %
+ \pgfextract@process\tipborderpoint{%
+ \pgfpointadd{\tippoint}{\tipmiter}
+ }%
+ \pgfextract@process\tailcenterborderpoint{%
+ \pgfpointadd{\tailcenterpoint}{\tailcentermiter}%
+ }%
+ \pgfextract@process\lefttailborderpoint{%
+ \pgfpointadd{\lefttailpoint}{\lefttailmiter}%
+ }%
+ \pgfextract@process\righttailborderpoint{%
+ \pgfpointadd{\righttailpoint}{\righttailmiter}%
+ }%
+ %
+ % Calculate the angles between the centerpoint
+ % and the *unrotated* borderpoints.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\tipborderpoint}%
+ \let\angletotip\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\tailcenterborderpoint}%
+ \let\angletotailcenter\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\lefttailborderpoint}%
+ \let\angletolefttail\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\righttailborderpoint}%
+ \let\angletorighttail\pgfmathresult%
+ %
+ % Calculate the angles between the *inversely rotated*
+ % basepoint and the *unrotated* borderpoints.
+ %
+ \pgfextract@process\rotatedbasepoint{%
+ \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\tipborderpoint}%
+ \let\baseangletotip\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\tailcenterborderpoint}%
+ \let\baseangletotailcenter\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\lefttailborderpoint}%
+ \let\baseangletolefttail\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedbasepoint}{\righttailborderpoint}%
+ \let\baseangletorighttail\pgfmathresult%
+ %
+ % Calculate the angles between the *inversely rotated*
+ % midpoint and the *unrotated* borderpoints.
+ %
+ \pgfextract@process\rotatedmidpoint{%
+ \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}%
+ }%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\tipborderpoint}%
+ \let\midangletotip\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\tailcenterborderpoint}%
+ \let\midangletotailcenter\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\lefttailborderpoint}%
+ \let\midangletolefttail\pgfmathresult%
+ \pgfmathanglebetweenpoints{\rotatedmidpoint}{\righttailborderpoint}%
+ \let\midangletorighttail\pgfmathresult%
+ %
+ % Rotate the background path points.
+ %
+ \pgfextract@process\tippoint{%
+ \pgfmathrotatepointaround{\tippoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\tailcenterpoint{%
+ \pgfmathrotatepointaround{\tailcenterpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\lefttailpoint{%
+ \pgfmathrotatepointaround{\lefttailpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\righttailpoint{%
+ \pgfmathrotatepointaround{\righttailpoint}{\centerpoint}{\rotate}%
+ }%
+ %
+ % Calculate a radius guaranteed to be outside the dart.
+ %
+ \pgfextractx\pgf@xa{\pgfpointdiff{\lefttailborderpoint}{\tipborderpoint}}%
+ \pgfextracty\pgf@ya{\pgfpointdiff{\lefttailborderpoint}{\righttailborderpoint}}%
+ \ifdim\pgf@xa<0pt\relax%
+ \pgf@xa-\pgf@xa%
+ \fi%
+ \ifdim\pgf@ya<0pt\relax%
+ \pgf@ya-\pgf@ya%
+ \fi%
+ \ifdim\pgf@xa>\pgf@ya%
+ \edef\externalradius{\the\pgf@xa}%
+ \else%
+ \edef\externalradius{\the\pgf@ya}%
+ \fi%
+ %
+ % Rotate the border anchor points.
+ %
+ \pgfextract@process\tipborderpoint{%
+ \pgfmathrotatepointaround{\tipborderpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\tailcenterborderpoint{%
+ \pgfmathrotatepointaround{\tailcenterborderpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\lefttailborderpoint{%
+ \pgfmathrotatepointaround{\lefttailborderpoint}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\righttailborderpoint{%
+ \pgfmathrotatepointaround{\righttailborderpoint}{\centerpoint}{\rotate}%
+ }%
+ %
+ % Save everything.
+ %
+ \addtosavedmacro{\rotate}%
+ \addtosavedmacro{\externalradius}%
+ %
+ \addtosavedmacro{\tippoint}%
+ \addtosavedmacro{\tailcenterpoint}%
+ \addtosavedmacro{\lefttailpoint}%
+ \addtosavedmacro{\righttailpoint}%
+ %
+ \addtosavedmacro{\tipborderpoint}%
+ \addtosavedmacro{\tailcenterborderpoint}%
+ \addtosavedmacro{\lefttailborderpoint}%
+ \addtosavedmacro{\righttailborderpoint}%
+ %
+ \addtosavedmacro{\angletotip}%
+ \addtosavedmacro{\angletotailcenter}%
+ \addtosavedmacro{\angletolefttail}%
+ \addtosavedmacro{\angletorighttail}%
+ %
+ \addtosavedmacro{\baseangletotip}%
+ \addtosavedmacro{\baseangletotailcenter}%
+ \addtosavedmacro{\baseangletolefttail}%
+ \addtosavedmacro{\baseangletorighttail}%
+ %
+ \addtosavedmacro{\midangletotip}%
+ \addtosavedmacro{\midangletotailcenter}%
+ \addtosavedmacro{\midangletolefttail}%
+ \addtosavedmacro{\midangletorighttail}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{base west}{%
+ \installdartparameters%
+ \let\pgf@dartanchorborderreferencepoint\basepoint%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{base east}{%
+ \installdartparameters%
+ \let\pgf@dartanchorborderreferencepoint\basepoint%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid west}{%
+ \installdartparameters%
+ \let\pgf@dartanchorborderreferencepoint\midpoint%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{mid east}{%
+ \installdartparameters%
+ \let\pgf@dartanchorborderreferencepoint\midpoint%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{north}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{0pt}{\externalradius}}%
+ }%
+ \anchor{south}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}%
+ }%
+ \anchor{east}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north east}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}%
+ }%
+ \anchor{south west}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}%
+ }%
+ \anchor{south east}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}%
+ }%
+ \anchor{north west}{%
+ \installdartparameters%
+ \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}%
+ }%
+ \anchor{tip}{%
+ \installdartparameters%
+ \tipborderpoint}%
+ \anchor{left tail}{%
+ \installdartparameters%
+ \lefttailborderpoint}%
+ \anchor{right tail}{%
+ \installdartparameters%
+ \righttailborderpoint}%
+ \anchor{tail center}{%
+ \installdartparameters%
+ \tailcenterborderpoint}%
+ \anchor{left side}{%
+ \installdartparameters%
+ \pgfpointlineattime{0.5}{\tipborderpoint}{\lefttailborderpoint}}%
+ \anchor{right side}{%
+ \installdartparameters%
+ \pgfpointlineattime{0.5}{\tipborderpoint}{\righttailborderpoint}}%
+ \backgroundpath{%
+ \installdartparameters%
+ \pgfpathmoveto{\tippoint}%
+ \pgfpathlineto{\lefttailpoint}%
+ \pgfpathlineto{\tailcenterpoint}%
+ \pgfpathlineto{\righttailpoint}%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % This allows anchors base east, base west, mid east and mid west,
+ % to redefine the `center' of the node to correctly calculate the
+ % border points.
+ %
+ \pgfutil@ifundefined{pgf@dartanchorborderreferencepoint}%
+ {\let\referencepoint\centerpoint}%
+ {\let\referencepoint\pgf@dartanchorborderreferencepoint}%
+ %
+ % Adjust the location of the external
+ % point relative to the reference point.
+ %
+ \referencepoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Install the required points and angles.
+ %
+ \installdartparameters%
+ %
+ % Get the angle of the external point relative to \referencepoint.
+ %
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ %
+ % *Subtract* the rotation from the external angle.
+ %
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\externalangle\pgfmathresult%
+ %
+ % Get the set of angles for the appropriate border point.
+ %
+ \ifx\referencepoint\basepoint%
+ \let\angletotip\baseangletotip%
+ \let\angletotailcenter\baseangletotailcenter%
+ \let\angletolefttail\baseangletolefttail%
+ \let\angletorighttail\baseangletorighttail%
+ \else%
+ \ifx\referencepoint\midpoint%
+ \let\angletotip\midangletotip%
+ \let\angletotailcenter\midangletotailcenter%
+ \let\angletolefttail\midangletolefttail%
+ \let\angletorighttail\midangletorighttail%
+ \fi\fi%
+ %
+ % Locate the appropriate line on the border...
+ %
+ \ifdim\externalangle pt<\angletotip pt\relax%
+ \let\firstpoint\tipborderpoint%
+ \let\secondpoint\righttailborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletolefttail pt\relax%
+ \let\firstpoint\lefttailborderpoint%
+ \let\secondpoint\tipborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletotailcenter pt\relax%
+ \let\firstpoint\lefttailborderpoint%
+ \let\secondpoint\tailcenterborderpoint%
+ \else%
+ \ifdim\externalangle pt<\angletorighttail pt\relax%
+ \let\firstpoint\righttailborderpoint%
+ \let\secondpoint\tailcenterborderpoint%
+ \else%
+ \let\firstpoint\tipborderpoint%
+ \let\secondpoint\righttailborderpoint%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ %
+ % ...and thus the point on the border.
+ %
+ \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\firstpoint}{\secondpoint}%
+ }%
+}%
+
+
+
+% Keys for shape circular sector:
+%
+% /pgf/circular sector angle : the angle at the center of the sector.
+%
+\pgfkeys{/pgf/circular sector angle/.initial=60}%
+
+% Shape circular sector
+%
+\pgfdeclareshape{circular sector}{%
+ \savedmacro\installcircularsectorparameters{%
+ %
+ % Define a \centerpoint, \basepoint and \midpoint.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\outersep{\the\pgf@x}%
+ %
+ % Half of the sector angle is more useful.
+ %
+ \pgfmathmod{\pgfkeysvalueof{/pgf/circular sector angle}}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\angle\pgfmathresult%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\halfangle\pgfmathresult%
+ %
+ % Get some useful trigonometric stuff.
+ %
+ \pgfmathsin@{\halfangle}%
+ \let\sinehalfangle\pgfmathresult%
+ \pgfmathreciprocal@{\pgfmathresult}%
+ \let\cosechalfangle\pgfmathresult%
+ \pgfmathabs@{\halfangle}%
+ \pgfmathcos@{\pgfmathresult}%
+ \let\coshalfangle\pgfmathresult%
+ \pgf@x\pgfmathresult pt\relax%
+ \pgf@x\cosechalfangle\pgf@x%
+ \edef\cothalfangle{\pgfmath@tonumber{\pgf@x}}%
+ %
+ % Calculate the miter length at the center,
+ % according to the outer sep.
+ %
+ \pgf@x\outersep\relax%
+ \pgf@x\cosechalfangle\pgf@x%
+ \edef\centermiter{\the\pgf@x}%
+ %
+ % Get the start and end angles of the arc.
+ %
+ \pgfmathsubtract@{180}{\halfangle}%
+ \let\startangle\pgfmathresult%
+ \pgfmathadd@{180}{\halfangle}%
+ \let\endangle\pgfmathresult%
+ %
+ % Get (half) the node dimensions.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ %
+ % Calculate the radius of the sector and the `center offset',
+ % which is the distance between the center of the node and the
+ % center of the sector.
+ %
+ \ifpgfshapeborderusesincircle%
+ %
+ % Get the rotation.
+ %
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ %
+ % Calculate the incircle radius.
+ %
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \pgf@x1.41421\pgf@x%
+ \pgf@xa\cosechalfangle\pgf@x%
+ %
+ % xa is the radius, xb the offset.
+ %
+ \pgf@xb\pgf@xa%
+ \advance\pgf@xa\pgf@x%
+ \else%
+ %
+ % Get the rotation (with rounding).
+ %
+ \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % Swap the height and width for relevant angles.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \fi%
+ \fi%
+ %
+ % xa is the radius, xb the offset.
+ %
+ \pgf@xa\cosechalfangle\pgf@y%
+ \pgf@xa\coshalfangle\pgf@xa%
+ \advance\pgf@xa\pgf@x%
+ \pgf@xb\pgf@xa%
+ \advance\pgf@xa\pgf@x%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@y}}%
+ \pgf@xa\pgfmathresult pt\relax%
+ \fi%
+ %
+ % Adjust for minimum height and width.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgf@x.5\pgf@x%
+ \pgfmathsec@{\halfangle}%
+ \pgf@xc\pgfmathresult\pgf@xb%
+ \ifdim\pgf@xc<0pt\relax%
+ \pgf@xc-\pgf@xc%
+ \fi%
+ \ifdim\pgf@xc<\pgf@x%
+ \pgfmathreciprocal{\pgfmath@tonumber{\pgf@xc}}%
+ \pgf@xc\pgfmathresult\pgf@x% Increase by ratio.
+ \pgf@xa\pgfmath@tonumber{\pgf@xc}\pgf@xa%
+ \pgf@xb\pgfmath@tonumber{\pgf@xc}\pgf@xb%
+ \fi%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@xa<\pgf@y%
+ \pgfmathreciprocal{\pgfmath@tonumber{\pgf@xa}}%
+ \pgf@xc\pgfmathresult\pgf@y% Increase by ratio.
+ \pgf@xa\pgf@y%
+ \pgf@xb\pgfmath@tonumber{\pgf@xc}\pgf@xb%
+ \fi%
+ \edef\centeroffset{\the\pgf@xb}%
+ \edef\radius{\the\pgf@xa}%
+ %
+ % Calculate the radius at sector border and the arc corners.
+ %
+ \advance\pgf@xa\outersep\relax%
+ \edef\borderradius{\the\pgf@xa}%
+ \pgf@x\outersep\relax%
+ \pgf@x\cosechalfangle\pgf@x%
+ \pgf@x\coshalfangle\pgf@x%
+ \advance\pgf@xa\pgf@x%
+ \edef\cornerradius{\the\pgf@xa}%
+ %
+ % Calculate the *unrotated* points for the background path.
+ %
+ \pgfextract@process\sectorcenter{%
+ \centerpoint%
+ \advance\pgf@x\centeroffset%
+ }%
+ \pgfextract@process\arcstart{%
+ \pgfqpointpolar{\startangle}{\radius}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \sectorcenter%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ % Calculate the *unrotated* points for the anchor border.
+ %
+ \pgfextract@process\sectorcenterborder{%
+ \sectorcenter%
+ \advance\pgf@x\centermiter\relax%
+ }%
+ \pgfextract@process\arcstartborder{%
+ \pgfqpointpolar{\startangle}{\borderradius}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \sectorcenter%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfextract@process\arcendborder{%
+ \pgfqpointpolar{\endangle}{\borderradius}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \sectorcenter%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfextract@process\arcstartcorner{%
+ \pgfqpointpolar{\startangle}{\cornerradius}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \sectorcenterborder%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfextract@process\arcendcorner{%
+ \pgfqpointpolar{\endangle}{\cornerradius}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \sectorcenterborder%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ % Calculate the *unrotated* corner angles to the \centerpoint.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\sectorcenterborder}%
+ \let\angletosectorcenterborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcstartborder}%
+ \let\angletoarcstartborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcendborder}%
+ \let\angletoarcendborder\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcstartcorner}%
+ \let\angletoarcstartcorner\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcendcorner}%
+ \let\angletoarcendcorner\pgfmathresult%
+ %
+ % Rotate the background path points around the note center.
+ %
+ \pgfextract@process\sectorcenter{%
+ \pgfmathrotatepointaround{\sectorcenter}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcstart{%
+ \pgfmathrotatepointaround{\arcstart}{\centerpoint}{\rotate}%
+ }%
+ %
+ % Rotate the border points around the note center.
+ %
+ \pgfextract@process\sectorcenterborder{%
+ \pgfmathrotatepointaround{\sectorcenterborder}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcstartborder{%
+ \pgfmathrotatepointaround{\arcstartborder}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcendborder{%
+ \pgfmathrotatepointaround{\arcendborder}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcstartcorner{%
+ \pgfmathrotatepointaround{\arcstartcorner}{\centerpoint}{\rotate}%
+ }%
+ \pgfextract@process\arcendcorner{%
+ \pgfmathrotatepointaround{\arcendcorner}{\centerpoint}{\rotate}%
+ }%
+ %
+ % Add the rotation to the start and end angles.
+ %
+ \pgfmathadd@{\startangle}{\rotate}%
+ \let\startangle\pgfmathresult%
+ \pgfmathadd@{\endangle}{\rotate}%
+ \let\endangle\pgfmathresult%
+ %
+ % Save everything.
+ %
+ % NB \addtosavedmacro is currently experimental. May get changed.
+ %
+ \addtosavedmacro{\rotate}%
+ \addtosavedmacro{\centeroffset}%
+ %
+ \addtosavedmacro{\radius}%
+ \addtosavedmacro{\borderradius}%
+ \addtosavedmacro{\cornerradius}%
+ %
+ \addtosavedmacro{\endangle}%
+ \addtosavedmacro{\startangle}%
+ %
+ \addtosavedmacro{\sectorcenter}%
+ \addtosavedmacro{\arcstart}%
+ %
+ \addtosavedmacro{\sectorcenterborder}%
+ \addtosavedmacro{\arcstartborder}%
+ \addtosavedmacro{\arcendborder}%
+ \addtosavedmacro{\arcstartcorner}%
+ \addtosavedmacro{\arcendcorner}%
+ %
+ \addtosavedmacro{\angletosectorcenterborder}%
+ \addtosavedmacro{\angletoarcstartborder}%
+ \addtosavedmacro{\angletoarcendborder}%
+ \addtosavedmacro{\angletoarcstartcorner}%
+ \addtosavedmacro{\angletoarcendcorner}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{arc start}{%
+ \installcircularsectorparameters%
+ \arcstartcorner%
+ }%
+ \anchor{arc end}{%
+ \installcircularsectorparameters%
+ \arcendcorner%
+ }%
+ \anchor{sector center}{%
+ \installcircularsectorparameters%
+ \sectorcenterborder%
+ }%
+ \anchor{arc center}{%
+ \installcircularsectorparameters%
+ \pgfmathadd@{\rotate}{180}%
+ \let\angle\pgfmathresult%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpointpolar{\angle}{\cornerradius}}%
+ }%
+ \anchor{north}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{0pt}{\cornerradius}}%
+ }%
+ \anchor{south}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{0pt}{-\cornerradius}}%
+ }%
+ \anchor{east}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{\cornerradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{-\cornerradius}{0pt}}%
+ }%
+ \anchor{north west}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{-\cornerradius}{\cornerradius}}%
+ }%
+ \anchor{south west}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{-\cornerradius}{-\cornerradius}}%
+ }%
+ \anchor{north east}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{\cornerradius}{\cornerradius}}%
+ }%
+ \anchor{south east}{%
+ \installcircularsectorparameters%
+ \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{\cornerradius}{-\cornerradius}}%
+ }%
+ \backgroundpath{%
+ \installcircularsectorparameters%
+ \pgfpathmoveto{\sectorcenter}%
+ \pgfpathlineto{\arcstart}%
+ \ifdim\endangle pt>360pt\relax%
+ \ifdim\startangle pt>360pt\relax%
+ \pgfpatharc{\startangle}{\endangle}{\radius}%
+ \else%
+ \pgfpatharc{\startangle}{360}{\radius}%
+ \pgfpatharc{0}{\endangle}{\radius}%
+ \fi%
+ \else%
+ \pgfpatharc{\startangle}{\endangle}{\radius}%
+ \fi%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % Adjust the location of the external point relative to \centerpoint.
+ %
+ \centerpoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Install the required points and angles.
+ %
+ \installcircularsectorparameters%
+ %
+ % Get the angle of the external point to the \centerpoint.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ \let\externalangle\pgfmathresult%
+ %
+ % *Subtract* the rotation from the external angle.
+ %
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\angle\pgfmathresult%
+ %
+ % Determine if the line will cross the sector arc.
+ %
+ \ifdim\angle pt>\angletoarcendcorner pt\relax%
+ \let\firstpoint\arcendcorner%
+ \let\secondpoint\sectorcenterborder%
+ \else%
+ \ifdim\angle pt>\angletoarcendborder pt\relax%
+ \let\firstpoint\arcendborder%
+ \let\secondpoint\arcendcorner%
+ \else%
+ \ifdim\angle pt>\angletoarcstartborder pt\relax%
+ \let\firstpoint\pgfutil@empty%
+ \let\secondpoint\pgfutil@empty%
+ \else%
+ \ifdim\angle pt>\angletoarcstartcorner pt\relax%
+ \let\firstpoint\arcstartborder
+ \let\secondpoint\arcstartcorner
+ \else%
+ \let\firstpoint\sectorcenterborder%
+ \let\secondpoint\arcstartcorner%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \ifx\firstpoint\pgfutil@empty
+ %
+ % Calculate the angle from the centre of the semicircle to the
+ % point on the semicircle arc which intersects the line from
+ % the external point to the reference point...
+ %
+ \pgfmathanglebetweenlines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\sectorcenter}{\centerpoint}%
+ \pgfmathsin@{\pgfmathresult}%
+ \let\sineangle\pgfmathresult%
+ \pgf@x\borderradius\relax%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@x}}%
+ \let\reciprocalradius\pgfmathresult%
+ \pgf@x\centeroffset\relax%
+ \pgf@x\sineangle\pgf@x%
+ \pgf@x\reciprocalradius\pgf@x%
+ \pgfmathasin@{\pgfmath@tonumber{\pgf@x}}%
+ \pgf@x\pgfmathresult pt\relax%
+ \advance\pgf@x\externalangle pt\relax%
+ \edef\angle{\pgfmath@tonumber{\pgf@x}}%
+ %
+ % ...and thus the point on the border.
+ %
+ \pgfpointadd{\sectorcenter}{\pgfqpointpolar{\angle}{\borderradius}}%
+ \else%
+ %
+ % Calculate the the point where the semicircle chord intersects
+ % the line from the external point to the reference point.
+ %
+ \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\firstpoint}{\secondpoint}%
+ \fi%
+ }%
+}%
+
+
+
+% Keys for shape cylinder
+%
+% /pgf/shape aspect : Ratio between the x and y radii of the cylinder end.
+% /pgf/cylinder uses custom fill : Use a custom fill for the cylinder.
+% /pgf/cylinder end fill : Custom color for the cylinder end.
+% /pgf/cylinder body fill : Custom color for the cylinder body.
+%
+
+\newif\ifpgfcylinderusescustomfill
+\pgfkeys{/pgf/.cd,
+ cylinder uses custom fill/.is if=pgfcylinderusescustomfill,
+ cylinder end fill/.initial=white,
+ cylinder body fill/.initial=white,
+}%
+
+
+\pgfdeclareshape{cylinder}{%
+ \savedmacro\getcylinderpoints{%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgf@x\pgf@xc%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \pgf@y\pgf@yc%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \ifpgfshapeborderusesincircle%
+ \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \else%
+ \pgf@y\pgf@x%
+ \fi%
+ \pgf@x1.414213\pgf@x%
+ \pgf@y1.414213\pgf@y%
+ \else%
+ \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \pgfmathsetcount\c@pgf@counta{+\pgfmathresult}%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \edef\rotate{\the\c@pgf@counta}%
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xa%
+ \pgf@yc\pgf@xc%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xa\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xa%
+ \pgf@yc\pgf@xc%
+ \fi%
+ \fi%
+ \fi%
+ \addtosavedmacro\rotate%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfutil@tempdima\pgfshapeaspect\pgf@ya%
+ \pgfutil@tempdimb\pgf@ya%
+ %
+ % Adjust for minimum height.
+ %
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgfutil@tempdimb<.5\pgf@xc\relax%
+ \pgfutil@tempdimb.5\pgf@xc%
+ \pgf@ya\pgfutil@tempdimb%
+ \fi%
+ %
+ % Calculate how far the node contents can extend into the cylinder bottom.
+ %
+ \pgf@yb\pgfutil@tempdimb%
+ \advance\pgf@yb-\pgf@yc%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yb}}{\pgfmath@tonumber{\pgfutil@tempdimb}}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ \let\angle\pgfmathresult%
+ \pgf@xb\pgfmathresult\pgfutil@tempdima%
+ %
+ % Adjust for minimum width.
+ %
+ \pgf@x.5\pgflinewidth%
+ \advance\pgf@x2.0\pgf@xa%
+ \advance\pgf@x3.0\pgfutil@tempdima%
+ \advance\pgf@x-\pgf@xb%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<\pgf@xc%
+ \advance\pgf@xc-\pgf@x%
+ \advance\pgf@xa.5\pgf@xc%
+ \fi%
+ %
+ % Add the larger of the outer sep to the radii.
+ %
+ \pgf@x\pgfutil@tempdima\relax%
+ \pgf@y\pgfutil@tempdimb\relax%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xc>\pgf@yc%
+ \advance\pgf@x\pgf@xc%
+ \advance\pgf@y\pgf@xc%
+ \edef\outersep{\the\pgf@xc}%
+ \else%
+ \advance\pgf@x\pgf@yc%
+ \advance\pgf@y\pgf@yc%
+ \edef\outersep{\the\pgf@yc}%
+ \fi%
+ \edef\xradius{\the\pgf@x}%
+ \edef\yradius{\the\pgf@y}%
+ \addtosavedmacro\xradius%
+ \addtosavedmacro\yradius%
+ \addtosavedmacro\outersep%
+ %
+ \pgfextract@process\cylindercenter{%
+ \pgf@x\pgfutil@tempdima%
+ \advance\pgf@x.5\pgflinewidth%
+ \advance\pgf@x\pgf@xb%
+ \pgf@x.5\pgf@x%
+ \pgf@y0pt%
+ }%
+ \addtosavedmacro\cylindercenter%
+ %
+ \pgfextract@process\beforetop{%
+ \pgf@x\pgf@xa%
+ \advance\pgf@x\pgfutil@tempdima%
+ \advance\pgf@x.5\pgflinewidth%
+ \pgf@y\pgf@ya%
+ }%
+ \pgfextract@process\afterbottom{%
+ \pgf@x-\pgf@xa%
+ \advance\pgf@x\pgf@xb%
+ \pgf@y\pgf@ya%
+ }%
+ \addtosavedmacro\beforetop%
+ \addtosavedmacro\afterbottom%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgfextract@process\beforetopanchor{%
+ \beforetop%
+ \advance\pgf@y\pgf@yc%
+ }%
+ \pgfextract@process\afterbottomanchor{%
+ \afterbottom%
+ \advance\pgf@y\pgf@yc%
+ }%
+ \addtosavedmacro\beforetopanchor%
+ \addtosavedmacro\afterbottomanchor%
+ %
+ \beforetopanchor%
+ \advance\pgf@x\xradius\relax%
+ \ifdim\pgf@x>\pgf@y%
+ \edef\externalradius{\the\pgf@x}%
+ \else%
+ \edef\externalradius{\the\pgf@y}%
+ \fi%
+ \addtosavedmacro\externalradius%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{shape center}{%
+ \getcylinderpoints%
+ \pgfmathrotatepointaround{\pgfpointadd{\cylindercenter}{\centerpoint}}%
+ {\centerpoint}{\rotate}%
+ }%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \getcylinderpoints%
+ \let\pgf@cylinder@referencepoint\midpoint%
+ \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{mid west}{%
+ \getcylinderpoints%
+ \let\pgf@cylinder@referencepoint\midpoint%
+ \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \getcylinderpoints%
+ \let\pgf@cylinder@referencepoint\basepoint%
+ \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{base west}{%
+ \getcylinderpoints%
+ \let\pgf@cylinder@referencepoint\basepoint%
+ \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{0pt}{\externalradius}}%
+ }%
+ \anchor{south}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{0pt}{-\externalradius}}%
+ }%
+ \anchor{east}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north east}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{\externalradius}}%
+ }%
+ \anchor{south west}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{-\externalradius}}%
+ }%
+ \anchor{south east}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{-\externalradius}}%
+ }%
+ \anchor{north west}{%
+ \getcylinderpoints%
+ \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{\externalradius}}%
+ }%
+ \anchor{before top}{%
+ \getcylinderpoints%
+ \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor}{\centerpoint}}{\centerpoint}{\rotate}%
+ }%
+ \anchor{top}{%
+ \getcylinderpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \beforetop%
+ \pgf@y0pt\relax%
+ \advance\pgf@x\xradius\relax%
+ }{\centerpoint}}{\centerpoint}{\rotate}%
+ }%
+ \anchor{after top}{%
+ \getcylinderpoints%
+ \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor\pgf@y-\pgf@y}{\centerpoint}}{\centerpoint}{\rotate}%
+ }%
+ \anchor{before bottom}{%
+ \getcylinderpoints%
+ \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor\pgf@y-\pgf@y}{\centerpoint}}{\centerpoint}{\rotate}%
+ }%
+ \anchor{bottom}{%
+ \getcylinderpoints%
+ \pgfmathrotatepointaround{%
+ \pgfpointadd{%
+ \afterbottom%
+ \pgf@y0pt\relax%
+ \advance\pgf@x-\xradius\relax%
+ }{\centerpoint}}{\centerpoint}{\rotate}%
+ }%
+ \anchor{after bottom}{%
+ \getcylinderpoints%
+ \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor}{\centerpoint}}{\centerpoint}{\rotate}%
+ }%
+ \backgroundpath{%
+ \getcylinderpoints%
+ {%
+ \pgf@x\xradius\relax%
+ \advance\pgf@x-\outersep\relax%
+ \edef\xradius{\the\pgf@x}%
+ \pgf@y\yradius\relax%
+ \advance\pgf@y-\outersep\relax%
+ \edef\yradius{\the\pgf@y}%
+ \pgftransformshift{\centerpoint}%
+ \pgftransformrotate{\rotate}%
+ \pgfpathmoveto{\afterbottom}%
+ \pgfpatharc{90}{270}{\xradius and \yradius}%
+ \pgfpathlineto{\beforetop\pgf@y-\pgf@y}%
+ \pgfpatharc{-90}{90}{\xradius and \yradius}%
+ \pgfpathclose%
+ \pgfpathmoveto{\beforetop}%
+ \pgfpatharc{90}{270}{\xradius and \yradius}%
+ }%
+ }%
+ \behindbackgroundpath{%
+ \ifpgfcylinderusescustomfill%
+ \getcylinderpoints%
+ \pgf@x\xradius\relax%
+ \advance\pgf@x-\outersep\relax%
+ \edef\xradius{\the\pgf@x}%
+ \pgf@y\yradius\relax%
+ \advance\pgf@y-\outersep\relax%
+ \edef\yradius{\the\pgf@y}%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgftransformrotate{\rotate}%
+ \pgfpathmoveto{\afterbottom}%
+ \pgfpatharc{90}{270}{\xradius and \yradius}%
+ \pgfpathlineto{\beforetop\pgf@y-\pgf@y}%
+ \pgfpatharc{270}{90}{\xradius and \yradius}%
+ \pgfpathclose%
+ \expandafter\pgfsetfillcolor\expandafter{\pgfkeysvalueof{/pgf/cylinder body fill}}%
+ \pgfusepath{fill}%
+ %
+ \pgfpathmoveto{\beforetop}%
+ \pgfpatharc{90}{-270}{\xradius and \yradius}%
+ \pgfpathclose
+ \expandafter\pgfsetfillcolor\expandafter{\pgfkeysvalueof{/pgf/cylinder end fill}}%
+ \pgfusepath{fill}%
+ }%
+ \fi%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \getcylinderpoints%
+ \pgfutil@ifundefined{pgf@cylinder@referencepoint}{\let\referencepoint\centerpoint}{%
+ \let\referencepoint\pgf@cylinder@referencepoint}%
+ \pgfextract@process\externalpoint{%
+ \externalpoint%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \referencepoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\externalangle\pgfmathresult%
+ %
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\afterbottomanchor}{\centerpoint}}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\beforetopanchor}{\centerpoint}}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathrotatepointaround{%
+ \pgfmathpointintersectionoflineandarc%
+ {\pgfmathrotatepointaround{\externalpoint}{\centerpoint}{-\rotate}}%
+ {\pgfmathrotatepointaround{\referencepoint}{\centerpoint}{-\rotate}}%
+ {%
+ \beforetop%
+ \pgf@xa\pgf@x%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ }%
+ {0}{90}{\xradius and \yradius}%
+ }{\centerpoint}{\rotate}%
+ \else%
+ \pgfpointintersectionoflines{%
+ \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor}{\centerpoint}}%
+ {\centerpoint}{\rotate}}{%
+ \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor}{\centerpoint}}%
+ {\centerpoint}{\rotate}}%
+ {\referencepoint}{\externalpoint}%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\afterbottomanchor\pgf@y-\pgf@y}{\centerpoint}}%
+ \ifdim\externalangle pt>\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\beforetopanchor\pgf@y-\pgf@y}{\centerpoint}}%
+ \ifdim\externalangle pt>\pgfmathresult pt\relax%
+ \pgfmathrotatepointaround{%
+ \pgfmathpointintersectionoflineandarc%
+ {\pgfmathrotatepointaround{\externalpoint}{\centerpoint}{-\rotate}}%
+ {\pgfmathrotatepointaround{\referencepoint}{\centerpoint}{-\rotate}}%
+ {%
+ \beforetop%
+ \pgf@xa\pgf@x%
+ \centerpoint
+ \advance\pgf@x\pgf@xa%
+ }%
+ {270}{360}{\xradius and \yradius}%
+ }{\centerpoint}{\rotate}%
+ \else%
+ \pgfpointintersectionoflines{%
+ \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor\pgf@y-\pgf@y}{\centerpoint}}%
+ {\centerpoint}{\rotate}}{%
+ \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor\pgf@y-\pgf@y}{\centerpoint}}%
+ {\centerpoint}{\rotate}}%
+ {\referencepoint}{\externalpoint}%
+ \fi%
+ \else%
+ \pgfmathrotatepointaround{%
+ \pgfmathpointintersectionoflineandarc%
+ {\pgfmathrotatepointaround{\externalpoint}{\centerpoint}{-\rotate}}%
+ {\pgfmathrotatepointaround{\referencepoint}{\centerpoint}{-\rotate}}%
+ {%
+ \afterbottom%
+ \pgf@xa\pgf@x%
+ \centerpoint
+ \advance\pgf@x\pgf@xa%
+ }%
+ {90}{270}{\xradius and \yradius}%
+ }{\centerpoint}{\rotate}%
+ \fi%
+ \fi%
+ }%
+}%
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.misc.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.misc.code.tex
new file mode 100644
index 0000000000..477a7b7caf
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.misc.code.tex
@@ -0,0 +1,1127 @@
+% Copyright 2018 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryshapes.misc.code.tex}
+
+
+\pgfdeclareshape{cross out}
+{%
+ \inheritsavedanchors[from=rectangle]% % this is nearly a rectangle
+ \inheritanchorborder[from=rectangle]%
+ \inheritanchor[from=rectangle]{north}%
+ \inheritanchor[from=rectangle]{north west}%
+ \inheritanchor[from=rectangle]{north east}%
+ \inheritanchor[from=rectangle]{center}%
+ \inheritanchor[from=rectangle]{west}%
+ \inheritanchor[from=rectangle]{east}%
+ \inheritanchor[from=rectangle]{mid}%
+ \inheritanchor[from=rectangle]{mid west}%
+ \inheritanchor[from=rectangle]{mid east}%
+ \inheritanchor[from=rectangle]{base}%
+ \inheritanchor[from=rectangle]{base west}%
+ \inheritanchor[from=rectangle]{base east}%
+ \inheritanchor[from=rectangle]{south}%
+ \inheritanchor[from=rectangle]{south west}%
+ \inheritanchor[from=rectangle]{south east}%
+ \foregroundpath{
+ % store lower right in xa/ya and upper right in xb/yb
+ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ \pgfsetarrowsstart{}
+ \pgfsetarrowsend{}
+ }%
+}%
+
+
+\pgfdeclareshape{strike out}
+{%
+ \inheritsavedanchors[from=rectangle]% % this is nearly a rectangle
+ \inheritanchorborder[from=rectangle]%
+ \inheritanchor[from=rectangle]{north}%
+ \inheritanchor[from=rectangle]{north west}%
+ \inheritanchor[from=rectangle]{north east}%
+ \inheritanchor[from=rectangle]{center}%
+ \inheritanchor[from=rectangle]{west}%
+ \inheritanchor[from=rectangle]{east}%
+ \inheritanchor[from=rectangle]{mid}%
+ \inheritanchor[from=rectangle]{mid west}%
+ \inheritanchor[from=rectangle]{mid east}%
+ \inheritanchor[from=rectangle]{base}%
+ \inheritanchor[from=rectangle]{base west}%
+ \inheritanchor[from=rectangle]{base east}%
+ \inheritanchor[from=rectangle]{south}%
+ \inheritanchor[from=rectangle]{south west}%
+ \inheritanchor[from=rectangle]{south east}%
+ \foregroundpath{
+ \pgfpathmoveto{\southwest}
+ \pgfpathlineto{\northeast}
+ \pgfsetarrowsstart{}
+ \pgfsetarrowsend{}
+ }%
+}%
+
+
+% Rounded rectangle
+
+
+\pgfkeys{/pgf/.cd,
+ rounded rectangle west arc/.initial=convex,
+ rounded rectangle east arc/.initial=convex,
+ rounded rectangle left arc/.style={/pgf/rounded rectangle west arc={#1}},%
+ rounded rectangle right arc/.style={/pgf/rounded rectangle east arc={#1}},%
+ rounded rectangle arc length/.initial=180%
+}%
+
+\def\pgf@lib@sh@misc@rr@text@concave{concave}%
+\def\pgf@lib@sh@misc@rr@text@convex{convex}%
+
+\pgfdeclareshape{rounded rectangle}{%
+ \savedmacro\westarc{%
+ \edef\westarc{\pgfkeysvalueof{/pgf/rounded rectangle west arc}}%
+ }%
+ \savedmacro\eastarc{%
+ \edef\eastarc{\pgfkeysvalueof{/pgf/rounded rectangle east arc}}%
+ }%
+ \savedmacro\roundedrectanglepoints{%
+ %
+ % Get half the arc angle, a.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/rounded rectangle arc length}}%
+ \pgf@x=.5\pgf@x%
+ \edef\halfarcangle{\pgfmath@tonumber{\pgf@x}}%
+ \addtosavedmacro\halfarcangle%
+ %
+ % Get the (half) node dimensions x & y.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \edef\innerxsep{\the\pgf@x}%
+ \pgf@xa=0.5\wd\pgfnodeparttextbox%
+ \edef\halftextwidth{\the\pgf@xa}%
+ \addtosavedmacro\halftextwidth%
+ \advance\pgf@x by\pgf@xa%
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \edef\innerysep{\the\pgf@y}%
+ \pgf@ya=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
+ \edef\halftextheight{\the\pgf@ya}%
+ \addtosavedmacro\halftextheight%
+ \advance\pgf@y by\pgf@ya%
+ %
+ % Adjust for minimum height
+ %
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@yb%
+ \pgf@y=.5\pgf@yb%
+ \fi%
+ \edef\halfheight{\the\pgf@y}%
+ \addtosavedmacro\halfheight%
+ %
+ % Calculate the radius of the arc ends.
+ %
+ \pgfmathcosec@{\halfarcangle}%
+ \pgf@ya=\pgfmathresult\pgf@y%
+ \edef\radius{\the\pgf@ya}%
+ \addtosavedmacro\radius%
+ %
+ % Arc width = r - r*cos(a/2).
+ %
+ \pgfmathcos@{\halfarcangle}%
+ \pgf@xa=\pgf@ya%
+ \advance\pgf@xa by-\pgfmathresult\pgf@ya%
+ %
+ % When the node contents are pushed inside a convex arc,
+ % the resulting chord has a height r - r*cos(asin(0.5*h/r)).
+ %
+ \pgfmathdivide{\halftextheight}{\radius}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathcos@{\pgfmathresult}%
+ \pgf@xb=\pgf@ya%
+ \advance\pgf@xb by-\pgfmathresult\pgf@ya%
+ %
+ % Adjust for minimum width.
+ %
+ \edef\westarc{\pgfkeysvalueof{/pgf/rounded rectangle west arc}}%
+ \edef\eastarc{\pgfkeysvalueof{/pgf/rounded rectangle east arc}}%
+ %
+ \pgfutil@tempdima=2.0\pgf@x% x still holds the half width.
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@concave%
+ \advance\pgfutil@tempdima by\pgf@xa%
+ \else%
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@convex%
+ \advance\pgfutil@tempdima by\pgf@xb%
+ \fi%
+ \fi%
+ %
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@concave%
+ \advance\pgfutil@tempdima by\pgf@xa%
+ \else%
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@convex%
+ \advance\pgfutil@tempdima by\pgf@xb%
+ \fi%
+ \fi%
+ %
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgfutil@tempdima<\pgfutil@tempdimb%
+ \advance\pgfutil@tempdimb by-\pgfutil@tempdima%
+ \divide\pgfutil@tempdimb by2\relax%
+ \edef\xoffset{\the\pgfutil@tempdimb}%
+ \else%
+ \let\xoffset=\innerxsep%
+ \fi%
+ %
+ % The node is made wider if convex arcs overlap.
+ %
+ \pgf@x=\halftextwidth\relax%
+ \advance\pgf@x by\xoffset\relax%
+ \pgf@xc=\pgf@ya%
+ \advance\pgf@xc by-\pgf@xb%
+ \ifdim\pgf@xc>\pgf@x\relax%
+ \advance\pgf@xc by-\pgf@x%
+ \advance\pgf@xc by\xoffset\relax%
+ \edef\xoffset{\the\pgf@xc}%
+ \fi%
+ \addtosavedmacro\xoffset%
+ %
+ \pgf@x=\halftextwidth\relax%
+ \advance\pgf@x by\xoffset\relax%
+ \edef\halfwidth{\the\pgf@x}%
+ \addtosavedmacro\halfwidth%
+ %
+ \edef\arcwidth{\the\pgf@xa}%
+ \addtosavedmacro\arcwidth%
+ %
+ \edef\chordwidth{\the\pgf@xb}%
+ \addtosavedmacro\chordwidth%
+ %
+ \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \addtosavedmacro\outerxsep%
+ \addtosavedmacro\outerysep%
+ %
+ % calculate some horizontal adjustments made for the default miter
+ % drawn when an arc meets the north or south side of the node path.
+ %
+ \ifdim\halfarcangle pt=90pt\relax% Avoid division by zero.
+ \def\concavexshift{0pt}%
+ \else%
+ % For a concave arc: outer xsep * cosec((90-a/2)/2)*cos((90-a/2)/2).
+ \pgfmathsubtract@{90}{\halfarcangle}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\angletemp=\pgfmathresult%
+ \pgf@x=\outerxsep\relax%
+ \pgfmathcosec@{\angletemp}%
+ \pgf@x=\pgfmathresult\pgf@x%
+ \pgfmathcos@{\angletemp}%
+ \pgf@x=\pgfmathresult\pgf@x%
+ \edef\concavexshift{\the\pgf@x}%
+ \fi%
+ \addtosavedmacro\concavexshift%
+ %
+ \ifdim\halfarcangle pt=90pt\relax% Avoid division by zero.
+ \def\convexxshift{0pt}%
+ \else%
+ % For a convex arc: outer xsep * cosec((90+a/2)/2)*cos((90+a/2)/2).
+ \pgfmathadd@{90}{\halfarcangle}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\angletemp=\pgfmathresult%
+ \pgf@x=\outerxsep\relax%
+ \pgfmathcosec@{\angletemp}%
+ \pgf@x=\pgfmathresult\pgf@x%
+ \pgfmathcos@{\angletemp}%
+ \pgf@x=\pgfmathresult\pgf@x%
+ \edef\convexxshift{\the\pgf@x}%
+ \fi%
+ \addtosavedmacro\convexxshift%
+ }%
+ \saveddimen\halflinewidth{\pgf@x.5\pgflinewidth}%
+ \savedanchor\centerpoint{%
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgf@y=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgf@y=0pt\relax%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid west}{%
+ \csname pgf@anchor@rounded rectangle@west\endcsname%
+ \pgf@xc=\pgf@x%
+ \midpoint%
+ \pgf@x=\pgf@xc%
+ }%
+ \anchor{mid east}{%
+ \csname pgf@anchor@rounded rectangle@east\endcsname%
+ \pgf@xc=\pgf@x%
+ \midpoint%
+ \pgf@x=\pgf@xc%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base west}{%
+ \csname pgf@anchor@rounded rectangle@west\endcsname%
+ \pgf@xc=\pgf@x%
+ \basepoint%
+ \pgf@x=\pgf@xc%
+ }%
+ \anchor{base east}{%
+ \csname pgf@anchor@rounded rectangle@east\endcsname%
+ \pgf@xc=\pgf@x%
+ \basepoint%
+ \pgf@x=\pgf@xc%
+ }%
+ \anchor{north}{%
+ \roundedrectanglepoints%
+ \pgfpointadd{\centerpoint}{\pgfpoint{+0pt}{\halfheight+\outerysep}}%
+ }%
+ \anchor{south}{%
+ \roundedrectanglepoints%
+ \pgfpointadd{\centerpoint}{\pgfpoint{+0pt}{-\halfheight-\outerysep}}%
+ }%
+ \anchor{west}{%
+ \roundedrectanglepoints%
+ \pgfpointadd{\centerpoint}{%
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@concave%
+ \pgfpoint{-\halfwidth-\arcwidth-\concavexshift}{+0pt}%
+ \else%
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpoint{-\halfwidth-\chordwidth-\outerxsep}{+0pt}%
+ \else%
+ \pgfpoint{-\halfwidth-\outerxsep}{+0pt}%
+ \fi%
+ \fi%
+ }%
+ }%
+ \anchor{north west}{%
+ \roundedrectanglepoints%
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpointadd{\centerpoint}{\pgfpoint{-\halfwidth-\chordwidth+\arcwidth-\convexxshift}{+0pt}}%
+ \else%
+ \csname pgf@anchor@rounded rectangle@west\endcsname%
+ \fi%
+ \pgf@xc=\pgf@x%
+ \csname pgf@anchor@rounded rectangle@north\endcsname%
+ \pgf@x=\pgf@xc%
+ }%
+ \anchor{south west}{%
+ \roundedrectanglepoints%
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpointadd{\centerpoint}{\pgfpoint{-\halfwidth-\chordwidth+\arcwidth-\convexxshift}{+0pt}}%
+ \else%
+ \csname pgf@anchor@rounded rectangle@west\endcsname%
+ \fi%
+ \pgf@xc=\pgf@x%
+ \csname pgf@anchor@rounded rectangle@south\endcsname%
+ \pgf@x=\pgf@xc%
+ }%
+ \anchor{east}{%
+ \roundedrectanglepoints%
+ \pgfpointadd{\centerpoint}{%
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@concave%
+ \pgfpoint{\halfwidth+\arcwidth+\concavexshift}{+0pt}%
+ \else%
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpoint{\halfwidth+\chordwidth+\outerxsep}{+0pt}%
+ \else%
+ \pgfpoint{\halfwidth+\outerxsep}{+0pt}%
+ \fi%
+ \fi%
+ }%
+ }%
+ \anchor{north east}{%
+ \roundedrectanglepoints%
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpointadd{\centerpoint}{\pgfpoint{\halfwidth+\chordwidth-\arcwidth+\convexxshift}{+0pt}}%
+ \else%
+ \csname pgf@anchor@rounded rectangle@east\endcsname%
+ \fi%
+ \pgf@xc=\pgf@x%
+ \csname pgf@anchor@rounded rectangle@north\endcsname%
+ \pgf@x=\pgf@xc%
+ }%
+ \anchor{south east}{%
+ \roundedrectanglepoints%
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpointadd{\centerpoint}{\pgfpoint{\halfwidth+\chordwidth-\arcwidth+\convexxshift}{+0pt}}%
+ \else%
+ \csname pgf@anchor@rounded rectangle@east\endcsname%
+ \fi%
+ \pgf@xc=\pgf@x%
+ \csname pgf@anchor@rounded rectangle@south\endcsname%
+ \pgf@x=\pgf@xc%
+ }%
+ \backgroundpath{%
+ {%
+ \roundedrectanglepoints%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfpoint{0pt}{\halfheight}}%
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@concave%
+ \pgfpathlineto{\pgfpoint{\halfwidth+\arcwidth}{+\halfheight}}%
+ \pgfpatharc{180-\halfarcangle}{180+\halfarcangle}{+\radius}%
+ \else%
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpathlineto{\pgfpoint{\halfwidth+\chordwidth-\arcwidth}{+\halfheight}}%
+ \pgfpatharc{+\halfarcangle}{+-\halfarcangle}{+\radius}%
+ \else%
+ \pgfpathlineto{\pgfqpoint{\halfwidth}{\halfheight}}%
+ \pgfpathlineto{\pgfqpoint{\halfwidth}{-\halfheight}}%
+ \fi%
+ \fi%
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@concave%
+ \pgfpathlineto{\pgfpoint{-\halfwidth-\arcwidth}{+-\halfheight}}%
+ \pgfpatharc{+-\halfarcangle}{+\halfarcangle}{+\radius}%
+ \else%
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfpathlineto{\pgfpoint{-\halfwidth-\chordwidth+\arcwidth}{+-\halfheight}}%
+ \pgfpatharc{180+\halfarcangle}{180-\halfarcangle}{+\radius}%
+ \else%
+ \pgfpathlineto{\pgfqpoint{-\halfwidth}{-\halfheight}}%
+ \pgfpathlineto{\pgfqpoint{-\halfwidth}{\halfheight}}%
+ \fi%
+ \fi%
+ \pgfpathclose%
+ }%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{%
+ \pgfextract@process\externalpoint{}%
+ \pgfpointadd{\centerpoint}{\externalpoint}%
+ }%
+ \roundedrectanglepoints%
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle=\pgfmathresult%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@rounded rectangle@north west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@rounded rectangle@north east\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ % Between north east and east.
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfextract@process\arccenter{%
+ \pgfpointadd{\centerpoint}{\pgfpoint{\halfwidth+\chordwidth-\radius}{+0pt}}%
+ }%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {\arccenter}{0}{\halfarcangle}{\radius+\outerxsep and \radius+\outerysep}%
+ \else%
+ \pgfpointintersectionoflines%
+ {\csname pgf@anchor@rounded rectangle@north east\endcsname}%
+ {\csname pgf@anchor@rounded rectangle@south east\endcsname}%
+ {\externalpoint}{\centerpoint}%
+ \fi%
+ \else%
+ % Between north west and north east.
+ \pgfpointintersectionoflines%
+ {\csname pgf@anchor@rounded rectangle@north east\endcsname}%
+ {\csname pgf@anchor@rounded rectangle@north west\endcsname}%
+ {\externalpoint}{\centerpoint}%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@rounded rectangle@south west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ % Between south west and north west.
+ \ifx\westarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfextract@process\arccenter{%
+ \pgfpointadd{\centerpoint}{\pgfpoint{-\halfwidth-\chordwidth+\radius}{+0pt}}%
+ }%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {\arccenter}{180-\halfarcangle}{180+\halfarcangle}{\radius+\outerxsep and \radius+\outerysep}%
+ \else%
+ \pgfpointintersectionoflines%
+ {\csname pgf@anchor@rounded rectangle@north west\endcsname}%
+ {\csname pgf@anchor@rounded rectangle@south west\endcsname}%
+ {\externalpoint}{\centerpoint}%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@rounded rectangle@south east\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ % Between south east and south west.
+ \pgfpointintersectionoflines%
+ {\csname pgf@anchor@rounded rectangle@south east\endcsname}%
+ {\csname pgf@anchor@rounded rectangle@south west\endcsname}%
+ {\externalpoint}{\centerpoint}%
+ \else%
+ % Between east and south east.
+ \ifx\eastarc\pgf@lib@sh@misc@rr@text@convex%
+ \pgfextract@process\arccenter{%
+ \pgfpointadd{\centerpoint}{\pgfpoint{\halfwidth+\chordwidth-\radius}{+0pt}}%
+ }%
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {\arccenter}{360-\halfarcangle}{360}{\radius+\outerxsep and \radius+\outerysep}%
+ \else%
+ \pgfpointintersectionoflines%
+ {\csname pgf@anchor@rounded rectangle@north east\endcsname}%
+ {\csname pgf@anchor@rounded rectangle@south east\endcsname}%
+ {\externalpoint}{\centerpoint}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+
+% Keys for chamfered rectangle
+%
+% /pgf/chamfered rectangle corners : specify the corners to chamfer.
+% /pgf/chamfered rectangle angle : set the angle of the chamfer.
+% /pgf/chamfered rectangle xsep : set the extent of the x chamferling.
+% /pgf/chamfered rectangle ysep : set the extent of the y chamferling.
+
+\pgfkeys{/pgf/chamfered rectangle corners/.store in=\pgf@lib@sh@misc@cr@corners}%
+\pgfkeys{/tikz/chamfered rectangle corners/.store in=\pgf@lib@sh@misc@cr@corners}%
+
+\def\pgf@lib@sh@misc@cr@chamferall{chamfer all}%
+\def\pgf@lib@sh@misc@cr@chamfer{chamfer}%
+\let\pgf@lib@sh@misc@cr@corners\pgf@lib@sh@misc@cr@chamferall
+
+
+\def\pgf@lib@sh@misc@cr@getcorners{%
+ \let\northeastcorner\pgfutil@empty%
+ \let\southeastcorner\pgfutil@empty%
+ \let\southwestcorner\pgfutil@empty%
+ \let\northwestcorner\pgfutil@empty%
+ \expandafter\pgfutil@in@\expandafter{\pgf@lib@sh@misc@cr@corners}{chamfer all}%
+ \ifpgfutil@in@%
+ \let\northeastcorner\pgf@lib@sh@misc@cr@round%
+ \let\southeastcorner\pgf@lib@sh@misc@cr@round%
+ \let\southwestcorner\pgf@lib@sh@misc@cr@round%
+ \let\northwestcorner\pgf@lib@sh@misc@cr@round%
+ \let\pgf@next\relax%
+ \else%
+ \let\pgf@next\pgf@lib@sh@misc@cr@parsecorners%
+ \fi%
+ \pgf@next}%
+
+\def\pgf@lib@sh@misc@cr@parsecorners{%
+ \expandafter\pgf@@chamferedrectangle@parsecorners\pgf@lib@sh@misc@cr@corners,\pgf@stop,%
+}%
+
+\def\pgf@@chamferedrectangle@parsecorners#1,{%
+ \ifx#1\pgf@stop%
+ \let\pgf@next\relax%
+ \else%
+ \pgfutil@in@{@#1@}{@north east@@top left@}%
+ \ifpgfutil@in@%
+ \let\northeastcorner\pgf@lib@sh@misc@cr@chamfer%
+ \else%
+ \pgfutil@in@{@#1@}{@south east@@bottom right@}%
+ \ifpgfutil@in@%
+ \let\southeastcorner\pgf@lib@sh@misc@cr@chamfer%
+ \else%
+ \pgfutil@in@{@#1@}{@south west@@bottom left@}%
+ \ifpgfutil@in@%
+ \let\southwestcorner\pgf@lib@sh@misc@cr@chamfer%
+ \else%
+ \pgfutil@in@{@#1@}{@north west@@top right@}%
+ \ifpgfutil@in@%
+ \let\northwestcorner\pgf@lib@sh@misc@cr@round%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \let\pgf@next\pgf@@@chamferedrectangle@parsecorners%
+ \fi%
+ \pgf@next%
+}%
+\def\pgf@@@chamferedrectangle@parsecorners{%
+ \pgfutil@ifnextchar x{\pgf@@chamferedrectangle@parsecorners}{\pgf@@chamferedrectangle@parsecorners}%
+}%
+
+\pgfkeys{/pgf/.cd,
+ chamfered rectangle angle/.initial=45,%
+ chamfered rectangle xsep/.initial=.666ex,%
+ chamfered rectangle ysep/.initial=.666ex%
+}%
+ \pgfkeys{/pgf/chamfered rectangle sep/.style={%
+ /pgf/chamfered rectangle xsep={#1},/pgf/chamfered rectangle ysep={#1}}%
+}%
+
+
+
+
+% Shape chamfered rectangle.
+%
+%
+\pgfdeclareshape{chamfered rectangle}{%
+ \savedmacro\getchamferedrectanglepoints{%
+ \pgf@lib@sh@misc@cr@getcorners%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya.5\dp\pgfnodeparttextbox%
+ %
+ % Get chamfer stuff.
+ %
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/chamfered rectangle angle}}%
+ \ifdim\pgfutil@tempdima<89pt\relax%
+ \ifdim\pgfutil@tempdima<1pt\relax%
+ \pgfutil@tempdima1pt\relax%
+ \fi%
+ \else%
+ \pgfutil@tempdima89pt\relax%
+ \fi%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima90pt\relax%
+ \pgfmathtan@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \let\tanangle\pgfmathresult%
+ \pgfmathcot@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \let\cotangle\pgfmathresult%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/chamfered rectangle xsep}}%
+ \pgf@yc\tanangle\pgf@xb%
+ \ifdim\pgf@yc>\pgf@ya%
+ \pgf@yc\pgf@ya%
+ \pgf@xb\cotangle\pgf@yc%
+ \fi%
+ \pgfmathcot@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/chamfered rectangle ysep}}%
+ \pgf@xc\cotangle\pgf@yb%
+ \ifdim\pgf@xc>\pgf@xa%
+ \pgf@xc\pgf@xa%
+ \pgf@yb\tanangle\pgf@xc%
+ \fi%
+ %
+ % Check for minimum width and height%
+ %
+ \pgfutil@tempdima\pgf@xa%
+ \advance\pgfutil@tempdima\pgf@xb%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgfutil@tempdima<.5\pgfutil@tempdimb%
+ \pgf@xa.5\pgfutil@tempdimb%
+ \advance\pgf@xa-\pgf@xb%
+ \fi%
+ \pgfutil@tempdima\pgf@ya%
+ \advance\pgfutil@tempdima\pgf@yb%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgfutil@tempdima<.5\pgfutil@tempdimb%
+ \pgf@ya.5\pgfutil@tempdimb%
+ \advance\pgf@ya-\pgf@yb%
+ \fi%
+ %
+ % Define the background path points.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}%
+ \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}%
+ }%
+ \pgfextract@process\beforenortheast{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@ya%
+ \advance\pgf@y-\pgf@yc%
+ }%
+ \pgfextract@process\northeast{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ \ifx\northeastcorner\pgfutil@empty%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ \fi%
+ }%
+ \pgfextract@process\afternortheast{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@x-\pgf@xc%
+ \advance\pgf@y\pgf@ya%
+ \advance\pgf@y\pgf@yb%
+ }%
+ \pgfextract@process\northwest{%
+ \centerpoint%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ \ifx\northwestcorner\pgfutil@empty%
+ \advance\pgf@x-\pgf@xb%
+ \advance\pgf@y\pgf@yb%
+ \fi%
+ }%
+ \pgfextract@process\beforesouthwest{%
+ \centerpoint%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@x-\pgf@xb%
+ \advance\pgf@y-\pgf@ya%
+ \advance\pgf@y\pgf@yc%
+ }%
+ \pgfextract@process\southwest{%
+ \centerpoint%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@y-\pgf@ya%
+ \ifx\southwestcorner\pgfutil@empty%
+ \advance\pgf@x-\pgf@xb%
+ \advance\pgf@y-\pgf@yb%
+ \fi%
+ }%
+ \pgfextract@process\aftersouthwest{%
+ \centerpoint%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@x\pgf@xc%
+ \advance\pgf@y-\pgf@ya%
+ \advance\pgf@y-\pgf@yb%
+ }%
+ \pgfextract@process\southeast{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y-\pgf@ya%
+ \ifx\southeastcorner\pgfutil@empty%
+ \advance\pgf@x\pgf@xb%
+ \advance\pgf@y-\pgf@yb%
+ \fi%
+ }%
+ %
+ % Calculate the `miter' vectors.
+ %
+ \pgfmathanglebetweenlines{\beforenortheast}{\afternortheast}{\beforenortheast}%
+ {\beforesouthwest\pgf@ya\pgf@y\beforenortheast\pgf@y\pgf@ya}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \ifdim\pgfutil@tempdima>180pt\relax%
+ \advance\pgfutil@tempdima-180pt\relax%
+ \fi%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \ifdim\pgfutil@tempdima<90pt\relax%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
+ \pgfutil@tempdima0pt\relax%
+ \else%
+ \pgfutil@tempdima.5\pgfutil@tempdima%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima90pt\relax%
+ \fi%
+ \pgfextract@process\before@ne@anchor{%
+ \beforenortheast%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfextract@process\before@sw@anchor{%
+ \beforesouthwest%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfqpointpolar{-\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ \pgfmathanglebetweenlines{\afternortheast}{\aftersouthwest\pgf@xa\pgf@x\afternortheast\pgf@x\pgf@xa}%
+ {\afternortheast}{\beforenortheast}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \ifdim\pgfutil@tempdima>270pt\relax%
+ \advance\pgfutil@tempdima-270pt\relax%
+ \fi%
+ \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgfutil@tempdima<90pt\relax%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
+ \pgfutil@tempdima90pt\relax%
+ \else%
+ \pgfutil@tempdima.5\pgfutil@tempdima%
+ \pgfmathcosec@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfutil@tempdimb\pgfmathresult\pgfutil@tempdimb%
+ \fi%
+ %
+ \pgfextract@process\after@ne@anchor{%
+ \afternortheast%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfqpointpolar{\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfutil@tempdima-\pgfutil@tempdima%
+ \advance\pgfutil@tempdima180pt\relax%
+ \pgfextract@process\after@sw@anchor{%
+ \aftersouthwest
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfqpointpolar{-\pgfmath@tonumber{\pgfutil@tempdima}}{\the\pgfutil@tempdimb}%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \addtosavedmacro\before@ne@anchor%
+ \addtosavedmacro\after@ne@anchor%
+ \addtosavedmacro\before@sw@anchor%
+ \addtosavedmacro\after@sw@anchor%
+ \pgfextract@process\ne@anchor{%
+ \ifx\northeastcorner\pgfutil@empty%
+ \northeast%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \else%
+ \pgfpointlineattime{0.5}{\before@ne@anchor}{\after@ne@anchor}%
+ \fi%
+ }%
+ \pgfextract@process\nw@anchor{%
+ \ifx\northwestcorner\pgfutil@empty%
+ \northwest%
+ \pgfmathaddtolength\pgf@x{-\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \else%
+ \pgfpointlineattime{0.5}{%
+ \before@ne@anchor%
+ \pgf@ya\pgf@y
+ \before@sw@anchor%
+ \pgf@y\pgf@ya%
+ }{%
+ \after@ne@anchor%
+ \pgf@ya\pgf@y
+ \after@sw@anchor%
+ \pgf@y\pgf@ya%
+ }%
+ \fi%
+ }%
+ \pgfextract@process\sw@anchor{%
+ \ifx\southwestcorner\pgfutil@empty%
+ \southwest%
+ \pgfmathaddtolength\pgf@x{-\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{-\pgfkeysvalueof{/pgf/outer ysep}}%
+ \else%
+ \pgfpointlineattime{0.5}{\before@sw@anchor}{\after@sw@anchor}%
+ \fi%
+ }%
+ \pgfextract@process\se@anchor{%
+ \ifx\southeastcorner\pgfutil@empty%
+ \southeast%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{-\pgfkeysvalueof{/pgf/outer ysep}}%
+ \else%
+ \pgfpointlineattime{0.5}{%
+ \before@ne@anchor%
+ \pgf@xa\pgf@x
+ \before@sw@anchor%
+ \pgf@x\pgf@xa%
+ }{%
+ \after@ne@anchor%
+ \pgf@xa\pgf@x
+ \after@sw@anchor%
+ \pgf@x\pgf@xa%
+ }%
+ \fi%
+ }%
+ \addtosavedmacro\ne@anchor%
+ \addtosavedmacro\nw@anchor%
+ \addtosavedmacro\sw@anchor%
+ \addtosavedmacro\se@anchor%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \getchamferedrectanglepoints%
+ \midpoint%
+ \pgf@ya\pgf@y%
+ \pgf@process{%
+ \before@sw@anchor%
+ \pgf@ya\pgf@y%
+ \before@ne@anchor%
+ \pgf@y\pgf@ya%
+ }%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\midpoint}{\midpoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\after@sw@anchor\pgf@ya\pgf@y\after@ne@anchor\pgf@y\pgf@ya}%
+ \else%
+ \pgf@process{\before@ne@anchor}%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\midpoint}{\midpoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\midpoint}{\midpoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor}%
+ {\after@ne@anchor}%
+ \fi%
+ \fi%
+ }%
+ \anchor{mid west}{%
+ \getchamferedrectanglepoints%
+ \midpoint%
+ \pgf@ya\pgf@y%
+ \pgf@process{\before@sw@anchor}%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\midpoint}{\midpoint\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor}{\after@sw@anchor}%
+ \else%
+ \pgf@process{\before@ne@anchor\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\midpoint}{\midpoint\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\midpoint}{\midpoint\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\after@ne@anchor\pgf@ya\pgf@y\after@sw@anchor\pgf@y\pgf@ya}%
+ \fi%
+ \fi%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \getchamferedrectanglepoints%
+ \basepoint%
+ \pgf@ya\pgf@y%
+ \pgf@process{%
+ \before@sw@anchor%
+ \pgf@ya\pgf@y%
+ \before@ne@anchor%
+ \pgf@y\pgf@ya%
+ }%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\basepoint}{\basepoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\after@sw@anchor\pgf@ya\pgf@y\after@ne@anchor\pgf@y\pgf@ya}%
+ \else%
+ \pgf@process{\before@ne@anchor}%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\basepoint}{\basepoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\basepoint}{\basepoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor}%
+ {\after@ne@anchor}%
+ \fi%
+ \fi%
+ }%
+ \anchor{base west}{%
+ \getchamferedrectanglepoints%
+ \basepoint%
+ \pgf@ya\pgf@y%
+ \pgf@process{\before@sw@anchor}%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\basepoint}{\basepoint\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor}{\after@sw@anchor}%
+ \else%
+ \pgf@process{\before@ne@anchor\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ \ifdim\pgf@ya<\pgf@y%
+ \pgfpointintersectionoflines{\basepoint}{\basepoint\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@sw@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\basepoint}{\basepoint\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\before@ne@anchor\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ {\after@ne@anchor\pgf@ya\pgf@y\after@sw@anchor\pgf@y\pgf@ya}%
+ \fi%
+ \fi%
+ }%
+ \anchor{before north east}{\getchamferedrectanglepoints\before@ne@anchor}%
+ \anchor{north east}{\getchamferedrectanglepoints\ne@anchor}%
+ \anchor{after north east}{\getchamferedrectanglepoints\after@ne@anchor}%
+ \anchor{north}{%
+ \getchamferedrectanglepoints%
+ \centerpoint%
+ \pgf@xa\pgf@x%
+ \after@ne@anchor%
+ \pgf@x\pgf@xa}%
+ \anchor{before north west}{%
+ \getchamferedrectanglepoints%
+ \after@sw@anchor%
+ \pgf@xa\pgf@x%
+ \after@ne@anchor%
+ \pgf@x\pgf@xa}%
+ \anchor{north west}{\getchamferedrectanglepoints\nw@anchor}%
+ \anchor{after north west}{%
+ \getchamferedrectanglepoints%
+ \before@sw@anchor%
+ \pgf@xa\pgf@x%
+ \before@ne@anchor%
+ \pgf@x\pgf@xa}%
+ \anchor{west}{%
+ \getchamferedrectanglepoints%
+ \centerpoint%
+ \pgf@ya\pgf@y%
+ \before@sw@anchor%
+ \pgf@y\pgf@ya}%
+ \anchor{before south west}{\getchamferedrectanglepoints\before@sw@anchor}%
+ \anchor{south west}{\getchamferedrectanglepoints\sw@anchor}%
+ \anchor{after south west}{\getchamferedrectanglepoints\after@sw@anchor}%
+ \anchor{south}{%
+ \getchamferedrectanglepoints%
+ \centerpoint%
+ \pgf@xa\pgf@x%
+ \after@sw@anchor%
+ \pgf@x\pgf@xa}%
+ \anchor{before south east}{%
+ \getchamferedrectanglepoints%
+ \after@sw@anchor%
+ \pgf@ya\pgf@y%
+ \after@ne@anchor%
+ \pgf@y\pgf@ya}%
+ \anchor{south east}{\getchamferedrectanglepoints\se@anchor}%
+ \anchor{after south east}{%
+ \getchamferedrectanglepoints%
+ \before@sw@anchor%
+ \pgf@ya\pgf@y%
+ \before@ne@anchor%
+ \pgf@y\pgf@ya}%
+ \anchor{east}{%
+ \getchamferedrectanglepoints%
+ \centerpoint%
+ \pgf@ya\pgf@y%
+ \before@ne@anchor%
+ \pgf@y\pgf@ya}%
+ \backgroundpath{%
+ \pgfpathmoveto{\beforenortheast}%
+ \pgfpathlineto{\northeast}%
+ \pgfpathlineto{\afternortheast}%
+ \pgfpathlineto{\aftersouthwest\pgf@xa\pgf@x\afternortheast\pgf@x\pgf@xa}%
+ \pgfpathlineto{\northwest}%
+ \pgfpathlineto{\beforesouthwest\pgf@xa\pgf@x\beforenortheast\pgf@x\pgf@xa}%
+ \pgfpathlineto{\beforesouthwest}%
+ \pgfpathlineto{\southwest}%
+ \pgfpathlineto{\aftersouthwest}%
+ \pgfpathlineto{\aftersouthwest\pgf@ya\pgf@y\afternortheast\pgf@y\pgf@ya}%
+ \pgfpathlineto{\southeast}%
+ \pgfpathlineto{\beforesouthwest\pgf@ya\pgf@y\beforenortheast\pgf@y\pgf@ya}%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle\pgfmathresult%
+ \getchamferedrectanglepoints%
+ \pgfmathanglebetweenpoints{\centerpoint}{\centerpoint\pgf@ya\pgf@y\before@sw@anchor\pgf@y\pgf@ya}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% west.
+ \pgfmathanglebetweenpoints{\centerpoint}{\centerpoint\pgf@xa\pgf@x\after@ne@anchor\pgf@x\pgf@xa}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% north.
+ \pgfmathanglebetweenpoints{\centerpoint}{\ne@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% north east.
+ \pgfmathanglebetweenpoints{\centerpoint}{\before@ne@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% before north east.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\centerpoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}{\before@ne@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\before@ne@anchor}{\ne@anchor}%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\after@ne@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% after north east.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\ne@anchor}{\after@ne@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\after@ne@anchor}{\centerpoint\pgf@xa\pgf@x\after@ne@anchor\pgf@x\pgf@xa}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\nw@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% north west.
+ \pgfmathanglebetweenpoints{\centerpoint}{\after@sw@anchor\pgf@xa\pgf@x\after@ne@anchor\pgf@x\pgf@xa}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% before north west.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\centerpoint\pgf@xa\pgf@x\after@ne@anchor\pgf@x\pgf@xa}%
+ {\after@sw@anchor\pgf@xa\pgf@x\after@ne@anchor\pgf@x\pgf@xa}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\after@sw@anchor\pgf@xa\pgf@x\after@ne@anchor\pgf@x\pgf@xa}%
+ {\nw@anchor}%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\before@sw@anchor\pgf@xa\pgf@x\before@ne@anchor\pgf@x\pgf@xa}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% after north west.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\nw@anchor}{\before@sw@anchor\pgf@xa\pgf@x\before@ne@anchor\pgf@x\pgf@xa}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\before@sw@anchor\pgf@xa\pgf@x\before@ne@anchor\pgf@x\pgf@xa}%
+ {\before@sw@anchor\pgf@xa\pgf@x\centerpoint\pgf@x\pgf@xa}%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\centerpoint\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% south.
+ \pgfmathanglebetweenpoints{\centerpoint}{\sw@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% south west.
+ \pgfmathanglebetweenpoints{\centerpoint}{\before@sw@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% before south west.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\before@sw@anchor\pgf@xa\pgf@x\centerpoint\pgf@x\pgf@xa}%
+ {\before@sw@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\before@sw@anchor}{\sw@anchor}%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\after@sw@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% after south west.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\sw@anchor}{\after@sw@anchor}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\after@sw@anchor}{\centerpoint\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\se@anchor}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% south east.
+ \pgfmathanglebetweenpoints{\centerpoint}{\after@ne@anchor\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% before south east.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\after@ne@anchor\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}%
+ {\centerpoint\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\after@ne@anchor\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}{\se@anchor}
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\before@ne@anchor\pgf@xa\pgf@x\before@sw@anchor\pgf@x\pgf@xa}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax% after south east.
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\se@anchor}{\before@ne@anchor\pgf@xa\pgf@x\before@sw@anchor\pgf@x\pgf@xa}%
+ \else%
+ \pgfpointintersectionoflines{\centerpoint}{\externalpoint}%
+ {\before@ne@anchor\pgf@xa\pgf@x\before@sw@anchor\pgf@x\pgf@xa}%
+ {\centerpoint\pgf@ya\pgf@y\before@ne@anchor\pgf@y\pgf@ya}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.multipart.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.multipart.code.tex
new file mode 100644
index 0000000000..481e65094f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.multipart.code.tex
@@ -0,0 +1,1356 @@
+% Copyright 2018 by Till Tantau and Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryshapes.multipart.code.tex}
+
+\newbox\pgfnodepartlowerbox
+
+%
+% A circle that is split in the middle into an upper and a lower part.
+%
+% This node consists of two parts: The upper (main) part is shown in
+% the upper half of the circle. The second part is the (optional)
+% lower part.
+%
+% Parts: text, lower
+
+\pgfdeclareshape{circle split}
+{%
+ %
+ % Node parts
+ %
+ \nodeparts{text,lower}%
+
+ %
+ % Anchors
+ %
+ \savedanchor\centerpoint{%
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \pgf@y=-\pgf@y%
+ \advance\pgf@y by-\dp\pgfnodeparttextbox%
+ \advance\pgf@y by-.5\pgflinewidth%
+ }%
+ \savedanchor\loweranchor{%
+ \pgf@x=-.5\wd\pgfnodepartlowerbox%
+ \advance\pgf@x by.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \pgf@y=-2\pgf@y%
+ \advance\pgf@y by-\ht\pgfnodepartlowerbox%
+ \advance\pgf@y by-.5\pgflinewidth%
+ \advance\pgf@y by-\dp\pgfnodeparttextbox%
+ \advance\pgf@y by-.5\pgflinewidth%
+ }%
+
+ \saveddimen\radius{%
+ %
+ % Calculate ``height radius''
+ %
+ %\pgf@ya=.5\ht\pgfnodeparttextbox%
+% \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
+% \advance\pgf@ya by.5\ht\pgfnodepartlowerbox%
+% \advance\pgf@ya by.5\dp\pgfnodepartlowerbox%
+% \advance\pgf@ya by.5\pgflinewidth%
+ %
+ % MW: Suggested correction for above calculation: Use the tallest box * 2.
+ %
+ \pgf@ya=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
+ \pgf@yb=.5\ht\pgfnodepartlowerbox%
+ \advance\pgf@yb by.5\dp\pgfnodepartlowerbox%
+ \ifdim\pgf@ya>\pgf@yb\relax%
+ \pgf@ya2.0\pgf@ya\relax%
+ \else%
+ \pgf@ya2.0\pgf@yb\relax%
+ \fi%
+ \advance\pgf@ya by.5\pgflinewidth%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya by2\pgf@yb%
+ %
+ % Calculate ``width radius''
+ %
+ \pgf@xa=.5\wd\pgfnodeparttextbox%
+ \ifdim\pgf@xa<.5\wd\pgfnodepartlowerbox%
+ \pgf@xa=.5\wd\pgfnodepartlowerbox%
+ \fi%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa by\pgf@xb%
+ %
+ % Calculate length of radius vector:
+ %
+ \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
+ \ifdim\pgf@x>\pgf@y%
+ \c@pgf@counta=\pgf@x%
+ \ifnum\c@pgf@counta=0\relax%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@xa=16\pgf@xa\relax%
+ \divide\pgf@xa by\c@pgf@counta%
+ \pgf@xa=16\pgf@xa\relax%
+ \fi%
+ \else%
+ \c@pgf@counta=\pgf@y%
+ \ifnum\c@pgf@counta=0\relax%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@ya=16\pgf@ya\relax%
+ \divide\pgf@ya by\c@pgf@counta%
+ \pgf@xa=16\pgf@ya\relax%
+ \fi%
+ \fi%
+ \pgf@x=\pgf@xa%
+ %
+ % If necessary, adjust radius so that the size requirements are
+ % met:
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<.5\pgf@xb%
+ \pgf@x=.5\pgf@xb%
+ \fi%
+ \ifdim\pgf@x<.5\pgf@yb%
+ \pgf@x=.5\pgf@yb%
+ \fi%
+ %
+ % Now, add larger of outer separations.
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgf@x by\pgf@yb%
+ \else%
+ \advance\pgf@x by\pgf@xb%
+ \fi%
+ }%
+
+ %
+ % Anchors
+ %
+ \inheritanchorborder[from=circle]%
+ \inheritanchor[from=circle]{north}%
+ \inheritanchor[from=circle]{north west}%
+ \inheritanchor[from=circle]{north east}%
+ \inheritanchor[from=circle]{center}%
+ \inheritanchor[from=circle]{west}%
+ \inheritanchor[from=circle]{east}%
+ \inheritanchor[from=circle]{mid}%
+ \inheritanchor[from=circle]{mid west}%
+ \inheritanchor[from=circle]{mid east}%
+ \inheritanchor[from=circle]{base}%
+ \inheritanchor[from=circle]{base west}%
+ \inheritanchor[from=circle]{base east}%
+ \inheritanchor[from=circle]{south}%
+ \inheritanchor[from=circle]{south west}%
+ \inheritanchor[from=circle]{south east}%
+ \anchor{lower}{\loweranchor}%
+
+ %
+ % Background path
+ %
+ \inheritbackgroundpath[from=circle]%
+ \beforebackgroundpath{
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \advance\pgfutil@tempdima by-.5\pgflinewidth%
+ \pgfsetshortenstart{0pt}%
+ \pgfsetshortenend{0pt}%
+ \pgfsetarrows{-}%
+ \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpoint{-1\pgfutil@tempdima}{0pt}}}%
+ \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpoint{\pgfutil@tempdima}{0pt}}}%
+ \pgfusepath{stroke}%
+ }%
+}%
+
+
+%
+% A circle that is split diagonally into an upper and a lower part.
+%
+% Parts: text, lower
+
+\pgfdeclareshape{circle solidus}{%
+ % Node parts
+ \nodeparts{text,lower}%
+ % Anchors
+ % solidus slants at 45 degrees
+ % text placement minimizes the required radius,
+ % this is achieved placing the "outer" corner
+ % of each box in the line orthogonal to the
+ % solidus which passes through circle center
+ \savedanchor\centerpoint{%
+ \pgf@x=0.5\wd\pgfnodeparttextbox%
+ \advance\pgf@x by0.5\dp\pgfnodeparttextbox%
+ \advance\pgf@x by0.5\ht\pgfnodeparttextbox%
+ \pgf@y=-\pgf@x%
+ \advance\pgf@y by\ht\pgfnodeparttextbox%
+ \advance\pgf@x by0.3536\pgflinewidth%
+ \advance\pgf@y by-0.3536\pgflinewidth%
+ \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x by\pgf@xa%
+ \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y by-\pgf@ya%
+ }%
+ \savedanchor\loweranchor{%
+ \pgf@x=0.5\wd\pgfnodeparttextbox%
+ \advance\pgf@x by0.5\dp\pgfnodeparttextbox%
+ \advance\pgf@x by0.5\ht\pgfnodeparttextbox%
+ \pgf@y=-\pgf@x%
+ \advance\pgf@y by\ht\pgfnodeparttextbox%
+ \advance\pgf@x by0.5\ht\pgfnodepartlowerbox%
+ \advance\pgf@x by0.5\dp\pgfnodepartlowerbox%
+ \advance\pgf@x by-0.5\wd\pgfnodepartlowerbox%
+ \advance\pgf@y by-0.5\ht\pgfnodepartlowerbox%
+ \advance\pgf@y by0.5\dp\pgfnodepartlowerbox%
+ \advance\pgf@y by-0.5\wd\pgfnodepartlowerbox%
+ \advance\pgf@x by0.7071\pgflinewidth%
+ \advance\pgf@y by-0.7071\pgflinewidth%
+ \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x by2\pgf@xa%
+ \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y by-2\pgf@ya%
+ }%
+ \saveddimen\radius{%
+ % "top" radius
+ \pgf@x=\ht\pgfnodeparttextbox%
+ \advance\pgf@x by\dp\pgfnodeparttextbox%
+ \advance\pgf@x by\wd\pgfnodeparttextbox%
+ % "bottom" radius
+ \pgf@y=\ht\pgfnodepartlowerbox%
+ \advance\pgf@y by\dp\pgfnodepartlowerbox%
+ \advance\pgf@y by\wd\pgfnodepartlowerbox%
+ % use the larger
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x=\pgf@y%
+ \fi%
+ \pgf@x=0.7071\pgf@x%
+ % add spacings
+ \advance\pgf@x by0.5\pgflinewidth%
+ \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \pgfmathaddtolength{\pgf@x}{veclen(2\pgf@xa,2\pgf@ya)}%
+ % If necessary, adjust radius so that the size requirements are
+ % met:
+ \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x=.5\pgf@xa%
+ \fi%
+ \ifdim\pgf@x<.5\pgf@ya%
+ \pgf@x=.5\pgf@ya%
+ \fi%
+ % Now, add larger of outer separations.
+ \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xa<\pgf@ya%
+ \advance\pgf@x by\pgf@ya%
+ \else%
+ \advance\pgf@x by\pgf@xa%
+ \fi%
+ }%
+ % Anchors
+ \inheritanchorborder[from=circle]%
+ \inheritanchor[from=circle]{north}%
+ \inheritanchor[from=circle]{north west}%
+ \inheritanchor[from=circle]{north east}%
+ \inheritanchor[from=circle]{center}%
+ \inheritanchor[from=circle]{west}%
+ \inheritanchor[from=circle]{east}%
+ \inheritanchor[from=circle]{mid}%
+ \inheritanchor[from=circle]{mid west}%
+ \inheritanchor[from=circle]{mid east}%
+ \inheritanchor[from=circle]{base}%
+ \inheritanchor[from=circle]{base west}%
+ \inheritanchor[from=circle]{base east}%
+ \inheritanchor[from=circle]{south}%
+ \inheritanchor[from=circle]{south west}%
+ \inheritanchor[from=circle]{south east}%
+ \anchor{lower}{\loweranchor}%
+ % Background path
+ \inheritbackgroundpath[from=circle]%
+ \beforebackgroundpath{%
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xa<\pgf@ya%
+ \advance\pgfutil@tempdima by-\pgf@ya%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xa%
+ \fi%
+ \advance\pgfutil@tempdima by-.5\pgflinewidth%
+ \pgfsetshortenstart{0pt}%
+ \pgfsetshortenend{0pt}%
+ \pgfsetarrows{-}%
+ % solidus slants at 45 degrees and its length is
+ % the golden section of the diameter
+ \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpoint{-0.437\pgfutil@tempdima}{-0.437\pgfutil@tempdima}}}%
+ \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpoint{0.437\pgfutil@tempdima}{0.437\pgfutil@tempdima}}}%
+ \pgfusepath{stroke}%
+ }%
+}%
+
+
+\def\pgf@lib@sh@newbox{\csname newbox\endcsname}% Get round outer.
+
+\def\pgf@lib@sh@toalpha#1{%
+ \ifcase#1\relax%
+ \or one\or two\or three\or four\or five\or six\or seven\or eight\or nine\or ten%
+ \or eleven\or twelve\or thirteen\or fourteen\or fifteen%
+ \or sixteen\or seventeen\or eighteen\or nineteen\or twenty%
+ \else%
+ twenty%
+ \fi%
+}%
+
+
+\def\pgf@lib@sh@getalpha#1#2{\expandafter\edef\expandafter#1\expandafter{\pgf@lib@sh@toalpha{#2}}}%
+
+\newbox\pgfnodeparttwobox
+\newbox\pgfnodepartthreebox
+\newbox\pgfnodepartfourbox
+
+\let\pgfnodepartonebox=\pgfnodeparttextbox
+\let\pgfnodepartsecondbox=\pgfnodeparttwobox
+\let\pgfnodepartthirdbox=\pgfnodepartthreebox
+\let\pgfnodepartfourthbox=\pgfnodepartfourbox
+
+\def\pgf@lib@sh@allocateboxes#1{%
+ \c@pgf@counta=#1\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>4\relax%
+ \pgfutil@ifundefined{pgfnodepart\pgf@lib@sh@toalpha{\c@pgf@counta}box}%
+ {%
+ \expandafter\pgf@lib@sh@newbox\csname pgfnodepart\pgf@lib@sh@toalpha{\c@pgf@counta}box\endcsname%
+ }%
+ {}%
+ \advance\c@pgf@counta by-1\relax%
+ \repeatpgfmathloop%
+}%
+
+\def\pgf@lib@sh@rs@lefttext{left}%
+\def\pgf@lib@sh@rs@righttext{right}%
+\def\pgf@lib@sh@rs@centertext{center}%
+\def\pgf@lib@sh@rs@bottomtext{bottom}%
+\def\pgf@lib@sh@rs@toptext{top}%
+\def\pgf@lib@sh@rs@basetext{base}%
+\def\pgf@lib@sh@rs@nonetext{none}%
+
+
+\newif\ifpgfrectanglesplithorizontal
+\newif\ifpgfrectanglesplitdrawsplits\pgfrectanglesplitdrawsplitstrue
+\newif\ifpgfrectanglesplitignoreemptyparts
+\newif\ifpgfrectanglesplitusecustomfill
+
+\let\pgf@lib@sh@rs@every@emptypart=\pgfutil@empty
+\let\pgf@lib@sh@rs@every@part=\pgfutil@empty
+\def\pgf@lib@sh@rs@list@fill{none}%
+
+\pgfkeys{/pgf/.cd,
+ rectangle split parts/.initial=4,
+ rectangle split part align/.initial=center,
+ rectangle split horizontal/.is if=pgfrectanglesplithorizontal,
+ rectangle split ignore empty parts/.is if=pgfrectanglesplitignoreemptyparts,
+ rectangle split empty part width/.code={%
+ \pgfmathsetlength\pgf@x{#1}
+ \edef\pgf@lib@sh@rs@temp{\noexpand\vrule width\the\pgf@x height0ptdepth0pt\relax}%
+ \def\pgf@lib@sh@rs@@temp{\def\pgf@lib@sh@rs@every@emptypart}%
+ \expandafter\expandafter\expandafter\pgf@lib@sh@rs@@temp\expandafter\expandafter\expandafter{%
+ \expandafter\pgf@lib@sh@rs@every@emptypart\pgf@lib@sh@rs@temp}%
+ },%
+ rectangle split empty part width=1ex,
+ rectangle split empty part height/.code={%
+ \pgfmathsetlength\pgf@x{#1}
+ \edef\pgf@lib@sh@rs@temp{\noexpand\vrule width0ptheight\the\pgf@x depth0pt\relax}%
+ \def\pgf@lib@sh@rs@@temp{\def\pgf@lib@sh@rs@every@emptypart}%
+ \expandafter\expandafter\expandafter\pgf@lib@sh@rs@@temp\expandafter\expandafter\expandafter{%
+ \expandafter\pgf@lib@sh@rs@every@emptypart\pgf@lib@sh@rs@temp}%
+ },%
+ rectangle split empty part height=1ex,
+ rectangle split empty part depth/.code={%
+ \pgfmathsetlength\pgf@x{#1}
+ \edef\pgf@lib@sh@rs@temp{\noexpand\vrule width0ptheight0ptdepth\the\pgf@x\relax}%
+ \def\pgf@lib@sh@rs@@temp{\def\pgf@lib@sh@rs@every@emptypart}%
+ \expandafter\expandafter\expandafter\pgf@lib@sh@rs@@temp\expandafter\expandafter\expandafter{%
+ \expandafter\pgf@lib@sh@rs@every@emptypart\pgf@lib@sh@rs@temp}%
+ },%
+ rectangle split empty part depth=0ex,
+ rectangle split every empty part/.store in=\pgf@lib@sh@rs@every@emptypart,
+ rectangle split part fill/.code=\def\pgf@lib@sh@rs@list@fill{#1}\pgfrectanglesplitusecustomfilltrue,
+ rectangle split uses custom fill/.is if=pgfrectanglesplitusecustomfill,
+ rectangle split draw splits/.is if=pgfrectanglesplitdrawsplits,
+ rectangle split allocate boxes/.code=\pgf@lib@sh@allocateboxes{#1},
+}%
+
+
+\def\pgf@lib@sh@rs@process@list#1#2{%
+ \c@pgf@counta=1\relax%
+ \c@pgf@countb=#2\relax%
+ \edef\pgf@lib@sh@rs@temp{#1}%
+ \expandafter\pgf@lib@sh@rs@@process@list\pgf@lib@sh@rs@temp,\pgf@stop,
+}%
+
+\def\pgf@lib@sh@rs@@process@list{%
+ \pgfutil@ifnextchar x{\pgf@lib@sh@rs@@@process@list}%
+ {\pgf@lib@sh@rs@@@process@list}
+}%
+
+\def\pgf@lib@sh@rs@@@process@list#1,{%
+ \ifx#1\pgf@stop%
+ \let\pgf@next\pgf@lib@sh@rs@@@@process@list%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\c@pgf@counta}%
+ \def\pgf@lib@sh@rs@lastalign{#1}%
+ \pgfutil@namedef{pgf@lib@sh@rs@\pgf@lib@sh@toalpha{\c@pgf@counta}@item}{#1}%
+ \let\pgf@next\pgf@lib@sh@rs@@process@list%
+ \advance\c@pgf@counta by1\relax%
+ \fi%
+ \pgf@next}%
+
+\def\pgf@lib@sh@rs@@@@process@list{%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>\c@pgf@countb%
+ \else%
+ \expandafter\edef\csname pgf@lib@sh@rs@\pgf@lib@sh@toalpha{\c@pgf@counta}@item\endcsname%
+ {\pgf@lib@sh@rs@lastalign}%
+ \advance\c@pgf@counta by1\relax%
+ \repeatpgfmathloop%
+}%
+
+\pgf@lib@sh@allocateboxes{20}%
+
+\pgfdeclareshape{rectangle split}{%
+ \savedmacro\rectanglesplitparameters{%
+ \pgfmathsetcount\c@pgf@counta{\pgfkeysvalueof{/pgf/rectangle split parts}}%
+ \edef\parts{\the\c@pgf@counta}%
+ \addtosavedmacro\parts%
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \edef\innerxsep{\the\pgf@x}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \edef\innerysep{\the\pgf@y}%
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \edef\outerxsep{\the\pgf@x}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \edef\outerysep{\the\pgf@y}%
+ \addtosavedmacro\outerxsep%
+ \addtosavedmacro\outerysep%
+ %
+ \pgf@x=0pt\relax% Widest box.
+ \pgf@y=0pt\relax% Tallest box.
+ %
+ \pgfutil@tempdima=0pt\relax% Maximum box height.
+ \pgfutil@tempdimb=0pt\relax% Maximum box depth.
+ %
+ % Get the dimensions of the boxes...
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ %
+ \expandafter\let\expandafter\pgf@lib@sh@box\expandafter=%
+ \csname pgfnodepart\pgf@lib@sh@rs@number box\endcsname%
+ \pgf@xa=\wd\pgf@lib@sh@box%
+ \pgf@ya=\ht\pgf@lib@sh@box%
+ \pgf@yb=\dp\pgf@lib@sh@box%
+ %
+ % Test to see if the box is empty...
+ %
+ \expandafter\def\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname{\relax}%
+ \ifdim\pgf@xa=0pt\relax%
+ \ifdim\pgf@ya=0pt\relax%
+ \ifdim\pgf@yb=0pt\relax%
+ %
+ % ...It is. So...
+ %
+ \ifpgfrectanglesplitignoreemptyparts%
+ %
+ % ...flag this if we are ignoring parts...
+ %
+ \expandafter\let\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname=\pgfutil@empty%
+ \else%
+ %
+ % ...otherwise insert the code for every empty part.
+ %
+ \setbox\pgf@lib@sh@box=\hbox{{\pgf@lib@sh@rs@every@emptypart}}%
+ \pgf@xa=\wd\pgf@lib@sh@box%
+ \pgf@ya=\ht\pgf@lib@sh@box%
+ \pgf@yb=\dp\pgf@lib@sh@box%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \expandafter\edef\csname pgf@lib@sh@rs@width@\pgf@lib@sh@rs@number\endcsname{\the\pgf@xa}%
+ \expandafter\edef\csname pgf@lib@sh@rs@height@\pgf@lib@sh@rs@number\endcsname{\the\pgf@ya}%
+ \expandafter\edef\csname pgf@lib@sh@rs@depth@\pgf@lib@sh@rs@number\endcsname{\the\pgf@yb}%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname%
+ %
+ % ...saving the widest box...
+ %
+ \ifdim\pgf@xa>\pgf@x%
+ \pgf@x=\pgf@xa%
+ \fi%
+ %
+ % ...the maximum height and depth...
+ %
+ \ifdim\pgf@ya>\pgfutil@tempdima%
+ \pgfutil@tempdima=\pgf@ya%
+ \fi%
+ \ifdim\pgf@yb>\pgfutil@tempdimb%
+ \pgfutil@tempdimb=\pgf@yb%
+ \fi%
+ %
+ % ...and the tallest box.
+ %
+ \pgf@yc=\pgfutil@tempdima%
+ \advance\pgf@yc by\pgfutil@tempdimb%
+ \ifdim\pgf@yc>\pgf@y%
+ \pgf@y=\pgf@yc%
+ \fi%
+ \repeatpgfmathloop%
+ %
+ \edef\pgf@lib@sh@rs@max@width{\the\pgf@x}%
+ \edef\pgf@lib@sh@rs@max@totalheight{\the\pgf@y}%
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}%
+ \advance\pgf@x by-\innerxsep\relax%
+ \advance\pgf@x by-\innerxsep\relax%
+ \pgf@xa=\pgf@x%
+ \advance\pgf@xa by-\pgf@lib@sh@rs@max@width\relax%
+ \ifdim\pgf@xa>0pt\relax%
+ \edef\pgf@lib@sh@rs@max@width{\the\pgf@x}%
+ \fi%
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}%
+ \advance\pgf@y by-\innerysep\relax%
+ \advance\pgf@y by-\innerysep\relax%
+ \pgf@ya=\pgf@y%
+ \advance\pgf@ya by-\pgf@lib@sh@rs@max@totalheight\relax%
+ \ifdim\pgf@ya>0pt\relax%
+ \edef\pgf@lib@sh@rs@max@totalheight{\the\pgf@y}%
+ \fi%
+ %
+ % Get the alignment of each node part box.
+ %
+ \pgf@lib@sh@rs@process@list{\pgfkeysvalueof{/pgf/rectangle split part align}}{\parts}%
+ %
+ % Are we splitting horizontally or vertically?
+ %
+ \ifpgfrectanglesplithorizontal%
+ %
+ % Calculate the origins of each node part box.
+ %
+ \pgf@x=0pt\relax%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ %
+ \expandafter\let\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname=\pgfutil@empty%
+ \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \ifpgfrectanglesplitignoreemptyparts%
+ \expandafter\let\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname=%
+ \pgf@lib@sh@rs@lastanchor%
+ \fi%
+ \fi%
+ %
+ % Adjust for alignment.
+ %
+ \expandafter\ifx\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname%
+ \pgf@lib@sh@rs@bottomtext%
+ \pgf@y=\csname pgf@lib@sh@rs@depth@\pgf@lib@sh@rs@number\endcsname\relax%
+ \else%
+ \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname%
+ \pgf@lib@sh@rs@toptext%
+ \pgf@y=-\csname pgf@lib@sh@rs@height@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@y by\pgf@lib@sh@rs@max@totalheight\relax%
+ \else%
+ \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname%
+ \pgf@lib@sh@rs@basetext%
+ \pgf@y=\pgf@lib@sh@rs@max@totalheight\relax%
+ \advance\pgf@y by-\pgfutil@tempdima%
+ \advance\pgf@y by\pgfutil@tempdimb%
+ \divide\pgf@y by2\relax%
+ \else%
+ \pgf@y=\pgf@lib@sh@rs@max@totalheight\relax%
+ \advance\pgf@y by-\csname pgf@lib@sh@rs@height@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@y by\csname pgf@lib@sh@rs@depth@\pgf@lib@sh@rs@number\endcsname\relax%
+ \divide\pgf@y by2\relax%
+ \fi%
+ \fi%
+ \fi%
+ %
+ % Re-adjust as the first box is at the origin.
+ %
+ \ifnum\pgfmathcounter=1\relax%
+ \edef\pgf@lib@sh@rs@yoffset{\the\pgf@y}%
+ \pgf@y=0pt\relax%
+ \pgfextract@process\pgf@lib@sh@rs@anchor@one{}%
+ \addtosavedmacro\pgf@lib@sh@rs@anchor@one%
+ \let\pgf@lib@sh@rs@lastanchor=\pgf@lib@sh@rs@anchor@one%
+ \let\pgf@lib@sh@rs@lastnumber=\pgf@lib@sh@rs@number%
+ \else
+ \advance\pgf@y by-\pgf@lib@sh@rs@yoffset\relax%
+ \advance\pgf@x by\csname pgf@lib@sh@rs@width@\pgf@lib@sh@rs@lastnumber\endcsname\relax%
+ \advance\pgf@x by\innerxsep\relax%
+ \advance\pgf@x by\pgflinewidth%
+ \advance\pgf@x by\innerxsep\relax%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname{}%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@lastanchor\expandafter=%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname%
+ \let\pgf@lib@sh@rs@lastnumber=\pgf@lib@sh@rs@number%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname%
+ \fi%
+ \fi%
+ \repeatpgfmathloop%
+ %
+ % Calculate some anchors.
+ %
+ \pgfextract@process\northeast{%
+ \pgf@lib@sh@rs@lastanchor%
+ \advance\pgf@x by\csname pgf@lib@sh@rs@width@\pgf@lib@sh@rs@lastnumber\endcsname\relax%
+ \advance\pgf@x by\innerxsep\relax%
+ \advance\pgf@x by\outerxsep\relax%
+ \pgf@y=\pgf@lib@sh@rs@max@totalheight\relax%
+ \advance\pgf@y by-\pgf@lib@sh@rs@yoffset\relax%
+ \advance\pgf@y by\innerysep\relax%
+ \advance\pgf@y by\outerysep\relax%
+ }%
+ \addtosavedmacro\northeast%
+ \pgfextract@process\southwest{%
+ \pgf@lib@sh@rs@anchor@one%
+ \advance\pgf@x by-\innerxsep\relax%
+ \advance\pgf@x by-\outerxsep\relax%
+ \pgf@y=-\pgf@lib@sh@rs@yoffset\relax%
+ \advance\pgf@y by-\innerysep\relax%
+ \advance\pgf@y by-\outerysep\relax%
+ }%
+ \addtosavedmacro\southwest%
+ %
+ \pgfextract@process\centerpoint{%
+ \pgfpointadd{\southwest}{\northeast}%
+ \divide\pgf@x by2\relax%
+ \divide\pgf@y by2\relax%
+ }%
+ \addtosavedmacro\centerpoint%
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ %
+ \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \else%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname%
+ \pgf@xa=\pgf@x%
+ \pgf@xb=\csname pgf@lib@sh@rs@width@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@xa by0.5\pgf@xb%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @south\endcsname{%
+ \southwest%
+ \pgf@x=\pgf@xa%
+ }%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @north\endcsname{%
+ \northeast%
+ \pgf@x=\pgf@xa%
+ }%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @north\endcsname%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @south\endcsname%
+ \ifnum\pgfmathcounter=\parts%
+ \else%
+ \advance\pgf@xa by0.5\pgf@xb%
+ \advance\pgf@xa by\innerxsep\relax%
+ \advance\pgf@xa by.5\pgflinewidth%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@south\endcsname{%
+ \southwest%
+ \pgf@x=\pgf@xa%
+ }%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@north\endcsname{%
+ \northeast%
+ \pgf@x=\pgf@xa%
+ }%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split\endcsname{%
+ \centerpoint%
+ \pgf@x=\pgf@xa%
+ }%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@north\endcsname%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@south\endcsname%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split\endcsname%
+ \fi%
+ \fi%
+ \repeatpgfmathloop%
+ \else%
+ %
+ % Calculate the origins of each node part box.
+ %
+ \pgf@y=0pt\relax%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ %
+ \expandafter\let\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname=\pgfutil@empty%
+ \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \ifpgfrectanglesplitignoreemptyparts%
+ \expandafter\let\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname=%
+ \pgf@lib@sh@rs@lastanchor%
+ \fi%
+ \fi%
+ %
+ % Adjust for alignment.
+ %
+ \expandafter\ifx\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname%
+ \pgf@lib@sh@rs@lefttext%
+ \pgf@x=0pt\relax%
+ \else%
+ \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname%
+ \pgf@lib@sh@rs@righttext%
+ \pgf@x=-\csname pgf@lib@sh@rs@width@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@x by\pgf@lib@sh@rs@max@width\relax%
+ \else%
+ \pgf@x=-\csname pgf@lib@sh@rs@width@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@x by\pgf@lib@sh@rs@max@width\relax%
+ \divide\pgf@x by2\relax%
+ \fi%
+ \fi%
+ %
+ % Re-adjust as the first box is at the origin.
+ %
+ \ifnum\pgfmathcounter=1\relax%
+ \edef\pgf@lib@sh@rs@xoffset{\the\pgf@x}%
+ \pgf@x=0pt\relax%
+ \pgfextract@process\pgf@lib@sh@rs@anchor@one{}%
+ \addtosavedmacro\pgf@lib@sh@rs@anchor@one%
+ \let\pgf@lib@sh@rs@lastanchor=\pgf@lib@sh@rs@anchor@one%
+ \let\pgf@lib@sh@rs@lastnumber=\pgf@lib@sh@rs@number%
+ \else
+ \advance\pgf@x by-\pgf@lib@sh@rs@xoffset\relax%
+ \advance\pgf@y by-\csname pgf@lib@sh@rs@depth@\pgf@lib@sh@rs@lastnumber\endcsname\relax%
+ \advance\pgf@y by-\innerysep\relax%
+ \advance\pgf@y by-\pgflinewidth%
+ \advance\pgf@y by-\innerysep\relax%
+ \advance\pgf@y by-\csname pgf@lib@sh@rs@height@\pgf@lib@sh@rs@number\endcsname\relax%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname{}%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@lastanchor\expandafter=%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname%
+ \let\pgf@lib@sh@rs@lastnumber=\pgf@lib@sh@rs@number%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname%
+ \fi%
+ \fi%
+ \repeatpgfmathloop%
+ %
+ % Calculate some anchors.
+ %
+ \pgfextract@process\northeast{%
+ \pgf@x=\pgf@lib@sh@rs@max@width\relax%
+ \advance\pgf@x by-\pgf@lib@sh@rs@xoffset\relax%
+ \advance\pgf@x by\innerxsep\relax%
+ \advance\pgf@x by\outerxsep\relax%
+ \pgf@y=\pgf@lib@sh@rs@height@one\relax%
+ \advance\pgf@y by\innerysep\relax%
+ \advance\pgf@y by\outerysep\relax%
+ \advance\pgf@y by.5\pgflinewidth%
+ }%
+ \addtosavedmacro\northeast%
+ \pgfextract@process\southwest{%
+ \pgf@lib@sh@rs@lastanchor%
+ \pgf@x=-\pgf@lib@sh@rs@xoffset\relax%
+ \advance\pgf@x by-\innerxsep\relax%
+ \advance\pgf@x by-\outerxsep\relax%
+ \advance\pgf@y by-\csname pgf@lib@sh@rs@depth@\pgf@lib@sh@rs@lastnumber\endcsname\relax%
+ \advance\pgf@y by-\innerysep\relax%
+ \advance\pgf@y by-\outerysep\relax%
+ \advance\pgf@y by-.5\pgflinewidth%
+ }%
+ \addtosavedmacro\southwest%
+ %
+ \pgfextract@process\centerpoint{%
+ \pgfpointadd{\southwest}{\northeast}%
+ \divide\pgf@x by2\relax%
+ \divide\pgf@y by2\relax%
+ }%
+ \addtosavedmacro\centerpoint%
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ %
+ \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \else%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname%
+ \pgf@ya=\csname pgf@lib@sh@rs@height@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@y by0.5\pgf@ya%
+ \pgf@ya=\csname pgf@lib@sh@rs@depth@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@y by-0.5\pgf@ya%
+ \pgf@ya=\pgf@y%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @west\endcsname{%
+ \southwest%
+ \pgf@y=\pgf@ya%
+ }%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @east\endcsname{%
+ \northeast%
+ \pgf@y=\pgf@ya%
+ }%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @east\endcsname%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @west\endcsname%
+ \ifnum\pgfmathcounter=\parts%
+ \else%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number\endcsname%
+ \pgf@ya=\pgf@y%
+ \advance\pgf@ya by-\csname pgf@lib@sh@rs@depth@\pgf@lib@sh@rs@number\endcsname\relax%
+ \advance\pgf@ya by-\innerysep\relax%
+ \advance\pgf@ya by-.5\pgflinewidth%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@west\endcsname{%
+ \southwest%
+ \pgf@y=\pgf@ya%
+ }%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@east\endcsname{%
+ \northeast%
+ \pgf@y=\pgf@ya%
+ }%
+ \expandafter\pgfextract@process\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split\endcsname{%
+ \centerpoint%
+ \pgf@y=\pgf@ya%
+ }%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@east\endcsname%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@west\endcsname%
+ \expandafter\addtosavedmacro\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split\endcsname%
+ \fi%
+ \fi%
+ \repeatpgfmathloop%
+ \fi%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x=0.5\wd\pgfnodeparttextbox%
+ \pgf@y=0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x=0.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \anchor{center}{%
+ \rectanglesplitparameters%
+ \centerpoint%
+ }%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \rectanglesplitparameters%
+ \northeast%
+ \pgf@y=0pt\relax%
+ }%
+ \anchor{base west}{%
+ \rectanglesplitparameters%
+ \southwest%
+ \pgf@y=0pt\relax%
+ }%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \rectanglesplitparameters%
+ \northeast%
+ \pgf@xa=\pgf@x%
+ \midpoint%
+ \pgf@x=\pgf@xa%
+ }%
+ \anchor{mid west}{%
+ \rectanglesplitparameters%
+ \southwest%
+ \pgf@xa=\pgf@x%
+ \midpoint%
+ \pgf@x=\pgf@xa%
+ }%
+ \anchor{north}{%
+ \rectanglesplitparameters%
+ \centerpoint%
+ \pgf@xa=\pgf@x%
+ \northeast%
+ \pgf@x=\pgf@xa%
+ }%
+ \anchor{south}{%
+ \rectanglesplitparameters%
+ \centerpoint%
+ \pgf@xa=\pgf@x%
+ \southwest%
+ \pgf@x=\pgf@xa%
+ }%
+ \anchor{east}{%
+ \rectanglesplitparameters%
+ \centerpoint%
+ \pgf@ya=\pgf@y%
+ \northeast%
+ \pgf@y=\pgf@ya%
+ }%
+ \anchor{west}{%
+ \rectanglesplitparameters%
+ \centerpoint%
+ \pgf@ya=\pgf@y%
+ \southwest%
+ \pgf@y=\pgf@ya%
+ }%
+ \anchor{north east}{%
+ \rectanglesplitparameters%
+ \northeast%
+ }%
+ \anchor{north west}{%
+ \rectanglesplitparameters%
+ \northeast%
+ \pgf@ya=\pgf@y%
+ \southwest%
+ \pgf@y=\pgf@ya%
+ }%
+ \anchor{south west}{%
+ \rectanglesplitparameters%
+ \southwest%
+ }%
+ \anchor{south east}{%
+ \rectanglesplitparameters%
+ \southwest%
+ \pgf@ya=\pgf@y%
+ \northeast%
+ \pgf@y=\pgf@ya%
+ }%
+ \behindbackgroundpath{%
+ \ifpgfrectanglesplitusecustomfill%
+ \pgf@lib@sh@rs@process@list{\pgf@lib@sh@rs@list@fill}{\parts}%
+ {%
+ \ifpgfrectanglesplithorizontal%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@fill@bottomleft\expandafter=%
+ \csname pgf@anchor@rectangle split@south west\endcsname%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ \ifnum\pgfmathcounter=\parts%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@fill@topright\expandafter=%
+ \csname pgf@anchor@rectangle split@north east\endcsname%
+ \else%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@fill@topright\expandafter=%
+ \csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space split north\endcsname%
+ \fi%
+ \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \else%
+ \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname\pgf@lib@sh@rs@nonetext%
+ \else%
+ \pgfextract@process\pgf@lib@sh@rs@fill@bottomleft{%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \advance\pgf@y by\outerysep\relax%
+ \ifnum\pgfmathcounter=1\relax%
+ \advance\pgf@x by\outerxsep\relax%
+ \fi%
+ }%
+ \pgfextract@process\pgf@lib@sh@rs@fill@topright{%
+ \pgf@lib@sh@rs@fill@topright%
+ \advance\pgf@y by-\outerysep\relax%
+ \ifnum\pgfmathcounter=\parts\relax%
+ \advance\pgf@x by-\outerxsep\relax%
+ \fi%
+ }%
+ \ifnum\pgfmathcounter>1\relax%
+ \begingroup\pgfsetcornersarced{\pgfpointorigin}%
+ \fi%
+ \pgfpathmoveto{%
+ \pgf@lib@sh@rs@fill@topright%
+ \pgf@xa=\pgf@x%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \pgf@x=\pgf@xa%
+ }%
+ \pgfpathlineto{\pgf@lib@sh@rs@fill@bottomleft}%
+ \pgfpathlineto{%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \pgf@xa=\pgf@x%
+ \pgf@lib@sh@rs@fill@topright%
+ \pgf@x=\pgf@xa%
+ }%
+ \ifnum\pgfmathcounter>1\relax%
+ \endgroup%
+ \fi%
+ \ifnum\pgfmathcounter<\parts%
+ \begingroup\pgfsetcornersarced{\pgfpointorigin}%
+ \fi%
+ \pgfpathlineto{\pgf@lib@sh@rs@fill@topright}%
+ \pgfpathclose%
+ \ifnum\pgfmathcounter<\parts%
+ \endgroup%
+ \fi%
+ \pgfsetfillcolor{\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname}%
+ \pgfusepath{fill}%
+ \fi%
+ \fi%
+ \pgfextract@process\pgf@lib@sh@rs@fill@bottomleft{%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \pgf@ya=\pgf@y%
+ \pgf@lib@sh@rs@fill@topright%
+ \pgf@y=\pgf@ya%
+ \advance\pgf@y by-\outerysep%
+ }%
+ \repeatpgfmathloop%
+ \else%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@fill@topright\expandafter=%
+ \csname pgf@anchor@rectangle split@north east\endcsname%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ \ifnum\pgfmathcounter=\parts%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@fill@bottomleft\expandafter=%
+ \csname pgf@anchor@rectangle split@south west\endcsname%
+ \else%
+ \expandafter\let\expandafter\pgf@lib@sh@rs@fill@bottomleft\expandafter=%
+ \csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space split west\endcsname%
+ \fi%
+ \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \else%
+ \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname\pgf@lib@sh@rs@nonetext%
+ \else%
+ \pgfextract@process\pgf@lib@sh@rs@fill@bottomleft{%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \advance\pgf@x by\outerxsep\relax%
+ \ifnum\parts=1\relax%
+ \advance\pgf@y by\outerysep\relax%
+ \else%
+ \ifnum\pgfmathcounter=\parts
+ \advance\pgf@y by\outerysep\relax%
+ \fi%
+ \fi%
+ }%
+ \pgfextract@process\pgf@lib@sh@rs@fill@topright{%
+ \pgf@lib@sh@rs@fill@topright%
+ \advance\pgf@x by-\outerxsep\relax%
+ \ifnum\parts=1\relax%
+ \advance\pgf@y by-\outerysep\relax%
+ \else%
+ \ifnum\pgfmathcounter=1\relax%
+ \advance\pgf@y by-\outerysep\relax%
+ \fi%
+ \fi%
+ }%
+ \pgfpathmoveto{\pgf@lib@sh@rs@fill@bottomleft}%
+ \ifnum\pgfmathcounter>1\relax%
+ \begingroup\pgfsetcornersarced{\pgfpointorigin}%
+ \fi%
+ \pgfpathlineto{%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \pgf@xa=\pgf@x%
+ \pgf@lib@sh@rs@fill@topright%
+ \pgf@x=\pgf@xa%
+ }%
+ \pgfpathlineto{\pgf@lib@sh@rs@fill@topright}%
+ \ifnum\pgfmathcounter>1\relax%
+ \endgroup%%
+ \fi%
+ \ifnum\pgfmathcounter<\parts%
+ \begingroup\pgfsetcornersarced{\pgfpointorigin}%
+ \fi%
+ \pgfpathlineto{%
+ \pgf@lib@sh@rs@fill@topright%
+ \pgf@xa=\pgf@x%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \pgf@x=\pgf@xa%
+ }%
+ \pgfpathclose%
+ \ifnum\pgfmathcounter<\parts%
+ \endgroup%
+ \fi%
+ \pgfsetfillcolor{\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname}%
+ \pgfusepath{fill}%
+ \fi%
+ \fi%
+ \pgfextract@process\pgf@lib@sh@rs@fill@topright{%
+ \pgf@lib@sh@rs@fill@topright%
+ \pgf@xa=\pgf@x%
+ \pgf@lib@sh@rs@fill@bottomleft%
+ \pgf@x=\pgf@xa%
+ \advance\pgf@x by\outerxsep\relax%
+ }%
+ \repeatpgfmathloop%
+ \fi%
+ }%
+ \fi%
+ }%
+ \backgroundpath{%
+ \begingroup%
+ \pgfextract@process\southwest{%
+ \southwest%
+ \advance\pgf@x by\outerxsep\relax%
+ \advance\pgf@y by\outerysep\relax%
+ }%
+ \pgfextract@process\northeast{%
+ \northeast%
+ \advance\pgf@x by-\outerxsep\relax%
+ \advance\pgf@y by-\outerysep\relax%
+ }%
+ \pgfpathrectangle{\southwest}{\pgfpointdiff{\southwest}{\northeast}}%
+ \endgroup%
+ \ifpgfrectanglesplitdrawsplits%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter=\parts%
+ \else%
+ \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
+ %
+ \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
+ \else%
+ \pgfpathmoveto{%
+ \ifpgfrectanglesplithorizontal%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@north\endcsname%
+ \advance\pgf@y by-\outerysep\relax%
+ \else%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@east\endcsname%
+ \advance\pgf@x by-\outerxsep\relax%
+ \fi%
+ }%
+ \pgfpathlineto{%
+ \ifpgfrectanglesplithorizontal%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@south\endcsname%
+ \advance\pgf@y by\outerysep\relax%
+ \else%
+ \csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@number @split@west\endcsname%
+ \advance\pgf@x by\outerxsep\relax%
+ \fi%
+ }%
+ \fi%
+ \repeatpgfmathloop%
+ \fi%
+ }%
+ \anchorborder{%
+ \pgfutil@tempdima\pgf@x%
+ \pgfutil@tempdimb\pgf@y%
+ \rectanglesplitparameters%
+ \pgfpointdiff{\southwest}{\northeast}%
+ \pgf@x.5\pgf@x%
+ \pgf@y.5\pgf@y%
+ \edef\pgf@marshall{%
+ \noexpand\pgfpointborderrectangle{%
+ \noexpand\pgfqpoint{\the\pgfutil@tempdima}{\the\pgfutil@tempdimb}%
+ }%
+ {%
+ \noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}%
+ }%
+ }%
+ \pgf@marshall%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ % Hackery to install the correct number of node parts.
+ %
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@rectangle split\endcsname{%
+ \let\pgf@lib@sh@rs@temp=\pgfutil@empty%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter=\parts%
+ \expandafter\edef\csname pgf@sh@boxes@rectangle split\endcsname%
+ {\pgf@lib@sh@rs@temp\pgf@lib@sh@toalpha{\pgfmathcounter}}%
+ \else%
+ \edef\pgf@lib@sh@rs@temp{\pgf@lib@sh@rs@temp\pgf@lib@sh@toalpha{\pgfmathcounter},}%
+ \repeatpgfmathloop%
+ }%
+}%
+
+\pgfutil@for\pgf@lib@sh@rs@temp:={one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty}\do{%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp}{\noexpand\pgf@lib@sh@rs@anchor@one}%
+ {\noexpand\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space split\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split}%
+ {\noexpand\centerpoint}%
+ {\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space split north\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@north}%
+ {\noexpand\csname pgf@anchor@rectangle split@north\noexpand\endcsname}%
+ {\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@north\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space split south\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@south}%
+ {\noexpand\csname pgf@anchor@rectangle split@south\noexpand\endcsname}%
+ {\noexpand\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@south\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space north\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @north}%
+ {\noexpand\csname pgf@anchor@rectangle split@north\noexpand\endcsname}%
+ {\noexpand\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @north\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space south\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @south}%
+ {\noexpand\csname pgf@anchor@rectangle split@south\noexpand\endcsname}%
+ {\noexpand\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @south\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space split east\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@east}%
+ {\noexpand\csname pgf@anchor@rectangle split@east\noexpand\endcsname}%
+ {\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@east\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space split west\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@west}%
+ {\noexpand\csname pgf@anchor@rectangle split@west\noexpand\endcsname}%
+ {\noexpand\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @split@west\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space east\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @east}%
+ {\noexpand\csname pgf@anchor@rectangle split@east\noexpand\endcsname}%
+ {\noexpand\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @east\noexpand\endcsname}%
+ }%
+ \expandafter\xdef\csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@temp\space west\endcsname{%
+ \noexpand\rectanglesplitparameters%
+ \noexpand\pgfutil@ifundefined{pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @west}%
+ {\noexpand\csname pgf@anchor@rectangle split@west\noexpand\endcsname}%
+ {\noexpand\csname pgf@lib@sh@rs@anchor@\pgf@lib@sh@rs@temp @west\noexpand\endcsname}%
+ }%
+}%
+
+
+\pgfutil@namelet{pgf@anchor@rectangle split@text east}{pgf@anchor@rectangle split@one east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@text west}{pgf@anchor@rectangle split@one west}%
+\pgfutil@namelet{pgf@anchor@rectangle split@text split}{pgf@anchor@rectangle split@one split}%
+\pgfutil@namelet{pgf@anchor@rectangle split@text split east}{pgf@anchor@rectangle split@one split east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@text split west}{pgf@anchor@rectangle split@one split west}%
+
+\pgfutil@namelet{pgf@anchor@rectangle split@second}{pgf@anchor@rectangle split@two}%
+\pgfutil@namelet{pgf@anchor@rectangle split@second east}{pgf@anchor@rectangle split@two east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@second west}{pgf@anchor@rectangle split@two west}%
+\pgfutil@namelet{pgf@anchor@rectangle split@second split}{pgf@anchor@rectangle split@two split}%
+\pgfutil@namelet{pgf@anchor@rectangle split@second split east}{pgf@anchor@rectangle split@two split east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@second split west}{pgf@anchor@rectangle split@two split west}%
+
+\pgfutil@namelet{pgf@anchor@rectangle split@third}{pgf@anchor@rectangle split@three}%
+\pgfutil@namelet{pgf@anchor@rectangle split@third east}{pgf@anchor@rectangle split@three east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@third west}{pgf@anchor@rectangle split@three west}%
+\pgfutil@namelet{pgf@anchor@rectangle split@third split}{pgf@anchor@rectangle split@three split}%
+\pgfutil@namelet{pgf@anchor@rectangle split@third split east}{pgf@anchor@rectangle split@three split east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@third split west}{pgf@anchor@rectangle split@three split west}%
+
+\pgfutil@namelet{pgf@anchor@rectangle split@fourth}{pgf@anchor@rectangle split@four}%
+\pgfutil@namelet{pgf@anchor@rectangle split@fourth east}{pgf@anchor@rectangle split@four east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@fourth west}{pgf@anchor@rectangle split@four west}%
+\pgfutil@namelet{pgf@anchor@rectangle split@fourth split}{pgf@anchor@rectangle split@four split}%
+\pgfutil@namelet{pgf@anchor@rectangle split@fourth split east}{pgf@anchor@rectangle split@four split east}%
+\pgfutil@namelet{pgf@anchor@rectangle split@fourth split west}{pgf@anchor@rectangle split@four split west}%
+
+
+
+
+% Shape: ellipse split.
+%
+\pgfdeclareshape{ellipse split}{%
+ \nodeparts{text,lower}%
+ \savedanchor\radii{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \pgf@y2.0\pgf@y%
+ \advance\pgf@y.5\pgflinewidth%
+ \pgf@xa.5\wd\pgfnodeparttextbox%
+ \pgf@xb.5\wd\pgfnodepartlowerbox%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@xb\pgf@x%
+ \pgf@ya\ht\pgfnodeparttextbox%
+ \advance\pgf@ya\dp\pgfnodeparttextbox%
+ \pgf@yb\ht\pgfnodepartlowerbox%
+ \advance\pgf@yb\dp\pgfnodepartlowerbox%
+ \advance\pgf@ya\pgf@y%
+ \advance\pgf@yb\pgf@y%
+ \ifdim\pgf@xa>\pgf@xb%
+ \pgf@x1.414213\pgf@xa%
+ \else%
+ \pgf@x1.414213\pgf@xb%
+ \fi%
+ \ifdim\pgf@ya>\pgf@yb%
+ \pgf@y1.414213\pgf@ya%
+ \else%
+ \pgf@y1.414213\pgf@yb%
+ \fi%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ }%
+ \savedanchor\lower{%
+ \pgf@x-.5\wd\pgfnodepartlowerbox%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \pgf@y-2.0\pgf@y%
+ \advance\pgf@y-\pgflinewidth%
+ \advance\pgf@y-\dp\pgfnodeparttextbox%
+ \advance\pgf@y-\ht\pgfnodepartlowerbox%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{-\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y-\dp\pgfnodeparttextbox%
+ \advance\pgf@y-.5\pgflinewidth%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt\relax%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{lower}{\lower}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{\radii\pgf@xa\pgf@x\midpoint\advance\pgf@x\pgf@xa}%
+ \anchor{mid west}{\radii\pgf@xa\pgf@x\midpoint\advance\pgf@x-\pgf@xa}%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{\radii\pgf@xa\pgf@x\basepoint\advance\pgf@x\pgf@xa}%
+ \anchor{base west}{\radii\pgf@xa\pgf@x\basepoint\advance\pgf@x-\pgf@xa}%
+ \anchor{north}{\pgfpointadd{\centerpoint}{\radii\pgf@x0pt}}%
+ \anchor{south}{\pgfpointadd{\centerpoint}{\radii\pgf@x0pt\pgf@y-\pgf@y}}%
+ \anchor{east}{\pgfpointadd{\centerpoint}{\radii\pgf@y0pt}}%
+ \anchor{west}{\pgfpointadd{\centerpoint}{\radii\pgf@x-\pgf@x\pgf@y0pt}}%
+ \anchor{north west}{\pgfpointadd{\centerpoint}{\radii\pgf@x-0.707106\pgf@x\pgf@y0.707106\pgf@y}}%
+ \anchor{south west}{\pgfpointadd{\centerpoint}{\radii\pgf@x-0.707106\pgf@x\pgf@y-0.707106\pgf@y}}%
+ \anchor{north east}{\pgfpointadd{\centerpoint}{\radii\pgf@x0.707106\pgf@x\pgf@y0.707106\pgf@y}}%
+ \anchor{south east}{\pgfpointadd{\centerpoint}{\radii\pgf@x0.707106\pgf@x\pgf@y-0.707106\pgf@y}}%
+ \backgroundpath{%
+ \radii%
+ \pgfmathaddtolength\pgf@x{-\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathaddtolength\pgf@y{-\pgfkeysvalueof{/pgf/outer ysep}}%
+ \pgfutil@tempdima\pgf@x%
+ \pgfutil@tempdimb\pgf@y%
+ \pgfpathellipse{\centerpoint}{\pgfqpoint{\the\pgfutil@tempdima}{0pt}}{\pgfqpoint{0pt}{\the\pgfutil@tempdimb}}%
+ \pgfpathmoveto{\centerpoint\advance\pgf@x-\pgfutil@tempdima}%
+ \pgfpathlineto{\centerpoint\advance\pgf@x\pgfutil@tempdima}%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \radii%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpointadd{\noexpand\pgfpointborderellipse{\noexpand\externalpoint}%
+ {\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}}{\noexpand\centerpoint}%
+ }%
+ \pgf@marshal%
+ }%
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.symbols.code.tex b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.symbols.code.tex
new file mode 100644
index 0000000000..b876db6fd1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/libraries/shapes/pgflibraryshapes.symbols.code.tex
@@ -0,0 +1,2775 @@
+% Copyright 2018 by Till Tantau and Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgflibraryshapes.symbols.code.tex}
+
+\pgfdeclareshape{forbidden sign}
+{%
+ \inheritsavedanchors[from=circle]% this is nearly a circle
+ \inheritanchorborder[from=circle]%
+ \inheritanchor[from=circle]{north}%
+ \inheritanchor[from=circle]{north west}%
+ \inheritanchor[from=circle]{north east}%
+ \inheritanchor[from=circle]{center}%
+ \inheritanchor[from=circle]{west}%
+ \inheritanchor[from=circle]{east}%
+ \inheritanchor[from=circle]{mid}%
+ \inheritanchor[from=circle]{mid west}%
+ \inheritanchor[from=circle]{mid east}%
+ \inheritanchor[from=circle]{base}%
+ \inheritanchor[from=circle]{base west}%
+ \inheritanchor[from=circle]{base east}%
+ \inheritanchor[from=circle]{south}%
+ \inheritanchor[from=circle]{south west}%
+ \inheritanchor[from=circle]{south east}%
+ \inheritbackgroundpath[from=circle]%
+ \foregroundpath{
+ \centerpoint%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}}
+ \pgfsetarrowsstart{}
+ \pgfsetarrowsend{}
+ }%
+}%
+
+
+\pgfdeclareshape{correct forbidden sign}
+{%
+ \inheritsavedanchors[from=circle]% this is nearly a circle
+ \inheritanchorborder[from=circle]%
+ \inheritanchor[from=circle]{north}%
+ \inheritanchor[from=circle]{north west}%
+ \inheritanchor[from=circle]{north east}%
+ \inheritanchor[from=circle]{center}%
+ \inheritanchor[from=circle]{west}%
+ \inheritanchor[from=circle]{east}%
+ \inheritanchor[from=circle]{mid}%
+ \inheritanchor[from=circle]{mid west}%
+ \inheritanchor[from=circle]{mid east}%
+ \inheritanchor[from=circle]{base}%
+ \inheritanchor[from=circle]{base west}%
+ \inheritanchor[from=circle]{base east}%
+ \inheritanchor[from=circle]{south}%
+ \inheritanchor[from=circle]{south west}%
+ \inheritanchor[from=circle]{south east}%
+ \inheritbackgroundpath[from=circle]%
+ \foregroundpath{
+ \centerpoint%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}}
+ \pgfsetarrowsstart{}
+ \pgfsetarrowsend{}
+ }%
+}%
+
+
+
+
+
+% Keys for starburst shape
+%
+% /pgf/starburst point height : The maximum height of the outer points.
+% /pgf/starburst points : The number of points.
+% /pgf/random starburst : The seed for the random number generator.
+%
+\pgfkeys{/pgf/random starburst/%
+ .code={%
+ \ifx\pgfkeysnovalue#1%
+ \pgfmathgeneratepseudorandomnumber%
+ \else%
+ \pgfmathtruncatemacro\pgfmathresult{#1}%
+ \fi%
+ \pgfkeyslet{/pgf/random starburst}{\pgfmathresult}%
+ }%
+}%
+\pgfkeys{/pgf/random starburst=100}%
+
+\pgfkeys{/pgf/starburst point height/.value required}%
+\pgfkeys{/pgf/starburst point height/.code={%
+ \pgfmathparse{#1}%
+ \edef\pgfmathresult{\pgfmathresult pt}%
+ \pgfkeyslet{/pgf/starburst point height}{\pgfmathresult}%
+ }%
+}%
+\pgfkeys{/pgf/starburst point height=.5cm}%
+
+\pgfkeys{/pgf/starburst points/.value required}%
+\pgfkeys{/pgf/starburst points/.code={%
+ \pgfmathtruncatemacro\pgfmathresult{#1}%
+ \pgfkeyslet{/pgf/starburst points}{\pgfmathresult}%
+ }%
+}%
+\pgfkeys{/pgf/starburst points=17}%
+
+\pgfdeclareshape{starburst}{%
+ \savedmacro\anglestep{%
+ \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}%
+ \let\anglestep\pgfmathresult%
+ }%
+ \savedmacro\calculatestarburstpoints{%
+ %
+ % Get the angle step.
+ %
+ \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}%
+ \let\anglestep\pgfmathresult%
+ %
+ % Get the total number of points.
+ %
+ \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/starburst points}}%
+ \multiply\c@pgf@counta2\relax%
+ \edef\totalpoints{\the\c@pgf@counta}%
+ \addtosavedmacro{\totalpoints}%
+ %
+ % Calculate the centerpoint.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}%
+ \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}%
+ }%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\outersep{\the\pgf@x}%
+ %
+ % Get the node dimensions.
+ %
+ \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgfmathaddtolength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/inner ysep}}%
+ \pgfmathaddtolength\pgf@y{+.5\ht\pgfnodeparttextbox}%
+ \pgfmathaddtolength\pgf@y{+.5\dp\pgfnodeparttextbox}%
+ %
+ % Calculate the inner radii.
+ %
+ \ifpgfshapeborderusesincircle%
+ \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}%
+ %
+ % Use the incircle...
+ %
+ \ifdim\pgf@y>\pgf@x%
+ \pgf@x\pgf@y%
+ \fi%
+ \pgf@x1.41421\pgf@x%
+ \pgf@y\pgf@x%
+ \else%
+ %
+ % Get the rotation (with rounding).
+ %
+ \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}%
+ \pgfmathmod@{\rotate}{360}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@%
+ \advance\c@pgf@counta45\relax%
+ \divide\c@pgf@counta90\relax%
+ \multiply\c@pgf@counta90\relax%
+ \ifnum\c@pgf@counta<0\relax%
+ \advance\c@pgf@counta360\relax%
+ \fi%
+ %
+ % Calculate the width and height of the node
+ % contents, according to any border rotation.
+ %
+ \ifnum\c@pgf@counta=90\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \else%
+ \ifnum\c@pgf@counta=270\relax%
+ \pgf@xc\pgf@x%
+ \pgf@x\pgf@y%
+ \pgf@y\pgf@xc%
+ \fi%
+ \fi%
+ \edef\rotate{\the\c@pgf@counta}%
+ %
+ % ...or not.
+ %
+ \pgf@x=1.41421\pgf@x%
+ \pgf@y=1.41421\pgf@y%
+ \fi%
+ \addtosavedmacro{\rotate}%
+ %
+ % Adjust innerradius for minimum width and height.
+ %
+ \pgf@xa\pgf@x%
+ \pgfmathsetlength\pgf@xb{+\pgfkeysvalueof{/pgf/starburst point height}}%
+ \advance\pgf@xa\pgf@xb%
+ \pgfmathsetlength\pgf@xc{+\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@xa<.5\pgf@xc%
+ \pgf@x.5\pgf@xc%
+ \advance\pgf@x-\pgf@xb%
+ \fi%
+ \pgf@ya\pgf@y%
+ \pgfmathsetlength\pgf@yb{+\pgfkeysvalueof{/pgf/starburst point height}}%
+ \advance\pgf@ya\pgf@yb%
+ \pgfmathsetlength\pgf@yc{+\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@ya<.5\pgf@yc%
+ \pgf@y.5\pgf@yc%
+ \advance\pgf@y-\pgf@yb%
+ \fi%
+ \edef\xinnerradius{\the\pgf@x}%
+ \edef\yinnerradius{\the\pgf@y}%
+ \addtosavedmacro{\xinnerradius}%
+ \addtosavedmacro{\yinnerradius}%
+ %
+ % Calculate a radius outside the starburst.
+ %
+ \ifdim\pgf@y>\pgf@x%
+ \pgf@x\pgf@y%
+ \fi%
+ \pgfmathaddtolength\pgf@x{+\pgfkeysvalueof{/pgf/starburst point height}}%
+ \edef\externalradius{\the\pgf@x}%
+ \addtosavedmacro{\externalradius}%
+ %
+ % Set the seed for the random number generator.
+ %
+ \pgfmathsetseed{\pgfkeysvalueof{/pgf/random starburst}}%
+ %
+ % Now create the points on the shape and also
+ % the miter length and angle for each point.
+ %
+ \def\angle{90}% Start at the top.
+ %
+ % At point a, the miter length and angle are calculated for point b = a - 1.
+ %
+ \c@pgf@counta1\relax%
+ \c@pgf@countb0\relax%
+ %
+ % As 3 consecutive points are required to be defined for miter
+ % calculations, it is necessary to go over the first two points
+ % again.
+ %
+ \c@pgf@countc\totalpoints\relax%
+ \advance\c@pgf@countc2\relax%
+ \edef\looppoints{\the\c@pgf@countc}%
+ \let\secondpoint\pgfutil@empty%
+ \let\thirdpoint\pgfutil@empty%
+ \pgfmathloop%
+ %
+ % Cycle the point definitions.
+ %
+ \let\firstpoint\secondpoint%
+ \let\secondpoint\thirdpoint%
+ \ifnum\pgfmathcounter>\looppoints%
+ \else%
+ \ifnum\pgfmathcounter>\totalpoints%
+ \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname%
+ \else%
+ \ifodd\pgfmathcounter%
+ %
+ % An outer point.
+ %
+ \ifnum\pgfkeysvalueof{/pgf/random starburst}=0\relax%
+ \pgf@xa\pgfkeysvalueof{/pgf/starburst point height}\relax%
+ \else%
+ \pgf@x\pgfkeysvalueof{/pgf/starburst point height}\relax%
+ \pgf@xa.75\pgf@x%
+ \pgf@xb.25\pgf@x%
+ \pgfmathrnd%
+ \pgf@xa\pgfmathresult\pgf@xa%
+ \advance\pgf@xa\pgf@xb%
+ \fi%
+ \pgf@x\xinnerradius\relax%
+ \advance\pgf@x\pgf@xa%
+ \pgf@y\yinnerradius\relax%
+ \advance\pgf@y\pgf@xa%
+ \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{%
+ \pgfpointpolar{\angle}{\the\pgf@x and \the\pgf@y}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \else%
+ %
+ % An inner point.
+ %
+ \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{%
+ \pgfpointpolar{\angle}{\xinnerradius and \yinnerradius}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \fi%
+ %
+ % Add the points to the saved macro.
+ %
+ \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname%
+ \expandafter\addtosavedmacro\expandafter{\csname point@\the\c@pgf@counta @\endcsname}%
+ \fi%
+ %
+ % It is only possible to do the miter calculations if three points are defined.
+ %
+ \ifx\firstpoint\pgfutil@empty%
+ \else%
+ %
+ % Calculate the miter length...
+ %
+ \pgfmathanglebetweenlines{\secondpoint}{\thirdpoint}{\secondpoint}{\firstpoint}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\defaultmiterangle\pgfmathresult%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgf@x\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \edef\miterlength{\the\pgf@x}%
+ %
+ % ...the miter angle...
+ %
+ \pgfmathanglebetweenlines{\firstpoint}{\secondpoint}{\firstpoint}{\thirdpoint}%
+ \pgfmathadd@{\pgfmathresult}{\defaultmiterangle}%
+ \pgfmathsubtract@{180}{\pgfmathresult}%
+ \let\angletemp\pgfmathresult%
+ \pgfmathanglebetweenpoints{\firstpoint}{\thirdpoint}%
+ \pgfmathsubtract@{180}{\pgfmathresult}%
+ \pgfmathsubtract@{\angletemp}{\pgfmathresult}%
+ \edef\miterangle{\pgfmathresult}%
+ %
+ % ...and thus the border point.
+ %
+ \pgfextract@process\borderpoint{%
+ \secondpoint%
+ \pgf@xa\pgf@x
+ \pgf@ya\pgf@y%
+ \pgfpointpolar{\miterangle}{\miterlength}%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ % Get the angle from the centerpoint to the *unrotated* border points.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\borderpoint}%
+ \expandafter\edef\csname angletoborderpoint@\the\c@pgf@countb @\endcsname{\pgfmathresult}%
+ \expandafter\addtosavedmacro\expandafter{\csname angletoborderpoint@\the\c@pgf@countb @\endcsname}%
+ %
+ % Rotate the border points and save.
+ %
+ \expandafter\pgfextract@process\csname borderpoint@\the\c@pgf@countb @\endcsname{%
+ \pgfmathrotatepointaround{\borderpoint}{\centerpoint}{\rotate}%
+ }%
+ \expandafter\addtosavedmacro\expandafter{\csname borderpoint@\the\c@pgf@countb @\endcsname}%
+ %
+ % Now create the anchors.
+ %
+ \c@pgf@countc\c@pgf@countb%
+ \advance\c@pgf@countc1\relax%
+ \divide\c@pgf@countc2\relax%
+ \ifodd\c@pgf@countb\relax%
+ \pgfutil@ifundefined{pgf@anchor@starburst@outer point\space\the\c@pgf@countc}{%
+ \expandafter\xdef\csname pgf@anchor@starburst@outer point\space\the\c@pgf@countc\endcsname{%
+ \noexpand\calculatestarburstpoints%
+ \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname%
+ }%
+ }{}%
+ \else%
+ \pgfutil@ifundefined{pgf@anchor@starburst@inner point\space\the\c@pgf@countc}{%
+ \expandafter\xdef\csname pgf@anchor@starburst@inner point\space\the\c@pgf@countc\endcsname{%
+ \noexpand\calculatestarburstpoints%
+ \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname%
+ }%
+ }{}%
+ \fi%
+ \fi%
+ \pgfmathadd@{\angle}{\anglestep}%
+ \pgfmathmod@{\pgfmathresult}{360}%
+ \let\angle\pgfmathresult%
+ \advance\c@pgf@counta1\relax%
+ \ifnum\c@pgf@counta>\totalpoints%
+ \c@pgf@counta1\relax%
+ \fi%
+ \advance\c@pgf@countb1\relax%
+ \ifnum\c@pgf@countb>\totalpoints%
+ \c@pgf@countb1\relax%
+ \fi%
+ \repeatpgfmathloop%
+ }%
+ \savedanchor\centerpoint{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}%
+ \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}%
+ }%
+ \savedanchor\midpoint{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}%
+ \pgf@y0pt\relax%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{north}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{\externalradius}}%
+ }%
+ \anchor{south}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}%
+ }%
+ \anchor{east}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}%
+ }%
+ \anchor{north west}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}%
+ }%
+ \anchor{south west}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}%
+ }%
+ \anchor{north east}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}%
+ }%
+ \anchor{south east}{%
+ \calculatestarburstpoints%
+ \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}%
+ }%
+ \backgroundpath{%
+ \calculatestarburstpoints%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\totalpoints%
+ \else%
+ \ifnum\pgfmathcounter=1\relax%
+ \let\starburstaction\pgfpathmoveto%
+ \else%
+ \let\starburstaction\pgfpathlineto%
+ \fi%
+ \starburstaction{%
+ %\pgfmathrotatepointaround{\csname point@\pgfmathcounter @\endcsname}{\centerpoint}{\rotate}}%
+ \csname point@\pgfmathcounter @\endcsname}
+ \repeatpgfmathloop%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % Adjust the location of the external
+ % point relative to \centerpoint.
+ %
+ \centerpoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Get the starburst points.
+ %
+ \calculatestarburstpoints%
+ %
+ % Get the angle of the external point to the \centerpoint.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ \pgfmathsubtract@{\pgfmathresult}{\rotate}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\externalangle\pgfmathresult%
+ %
+ % Locate the appropriate sides on the starburst border...
+ %
+ \ifdim\externalangle pt<90pt\relax%
+ \c@pgf@counta0\relax%
+ \c@pgf@countb\totalpoints\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \else%
+ \ifdim\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt>90pt\relax%
+ \c@pgf@counta\c@pgf@countb%
+ \else%
+ \ifdim\externalangle pt>\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt\relax%
+ \c@pgf@counta\c@pgf@countb%
+ \fi%
+ \fi%
+ \advance\c@pgf@countb-1\relax%
+ \repeatpgfmathloop%
+ \edef\first{\the\c@pgf@counta}%
+ \advance\c@pgf@counta1\relax%
+ \ifnum\c@pgf@counta>\totalpoints\relax%
+ \c@pgf@counta1\relax%
+ \fi%
+ \edef\second{\the\c@pgf@counta}%
+ \else%
+ \c@pgf@counta0\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \else%
+ \ifdim\csname angletoborderpoint@\pgfmathcounter @\endcsname pt<90pt\relax%
+ \c@pgf@counta\pgfmathcounter%
+ \else%
+ \ifdim\externalangle pt<\csname angletoborderpoint@\pgfmathcounter @\endcsname pt\relax%
+ \c@pgf@counta\pgfmathcounter%
+ \fi%
+ \fi%
+ \repeatpgfmathloop%
+ \edef\first{\the\c@pgf@counta}%
+ \advance\c@pgf@counta-1\relax%
+ \ifnum\c@pgf@counta=0\relax%
+ \c@pgf@counta\totalpoints\relax%
+ \fi%
+ \edef\second{\the\c@pgf@counta}%
+ \fi%
+ %
+ % ...and thus, the point on the star border.
+ %
+ \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\csname borderpoint@\first @\endcsname}{\csname borderpoint@\second @\endcsname}%
+ }%
+}%
+
+
+
+
+% Keys for shape cloud.
+%
+% /pgf/cloud puffs : the number of cloud puffs.
+% /pgf/cloud puff arc : the length of the cloud puff arc.
+
+\newif\ifpgfcloudanchorsuseellipse%
+\newif\ifpgfcloudignoresaspect%
+\pgfcloudignoresaspectfalse%
+\pgfkeys{/pgf/.cd,
+ cloud puffs/.initial=10,
+ cloud puff arc/.initial=150,
+ cloud ignores aspect/.is if=pgfcloudignoresaspect,
+ cloud anchors use ellipse/.is if=pgfcloudanchorsuseellipse,
+}%
+
+
+% If symbol library is loaded separately these need to be defined.
+%
+\pgfkeys{/pgf/.cd,
+ aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz...
+ shape aspect/.initial=1,% but this is consistent with other pgfset stuff.
+ shape aspect/.code={%
+ \pgfkeys{/pgf/aspect={#1}}%
+ \pgfkeyssetvalue{/pgf/shape aspect}{#1}
+ }%
+}%
+
+\def\pgfsetshapeaspect#1{%
+ \def\pgfshapeaspect{#1}%
+ % Invert
+ \pgfutil@tempdima=#1pt%
+ \pgfutil@tempdima=.125\pgfutil@tempdima%
+ \c@pgf@counta=\pgfutil@tempdima\relax% 8192*determinant
+ \pgfutil@tempdima=8192pt%
+ \divide\pgfutil@tempdima by\c@pgf@counta%
+ \edef\pgfshapeaspectinverse{\pgf@sys@tonumber{\pgfutil@tempdima}}%
+}%
+
+\pgfsetshapeaspect{1}%
+
+
+% Shape cloud.
+%
+\pgfdeclareshape{cloud}{%
+ \savedmacro\getradii{%
+ \pgfmathtruncatemacro\puffs{\pgfkeysvalueof{/pgf/cloud puffs}}%
+ \addtosavedmacro\puffs%
+ \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/cloud puffs}}%
+ \let\anglestep\pgfmathresult%
+ \addtosavedmacro\anglestep%
+ \pgfmathsetmacro\arc{\pgfkeysvalueof{/pgf/cloud puff arc}}%
+ \addtosavedmacro\arc%
+ %
+ % x radius.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@x1.4142135\pgf@x%
+ %
+ % y radius.
+ %
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ \pgf@y1.4142135\pgf@y%
+ %
+ % Adjust for shape aspect.
+ %
+ \ifpgfcloudignoresaspect%
+ \pgf@xc\pgf@x%
+ \pgf@yc\pgf@y%
+ \else%
+ \pgf@xc\pgfshapeaspect\pgf@y%
+ \ifdim\pgf@xc<\pgf@x%
+ \pgf@xc\pgf@x%
+ \fi%
+ \pgf@yc\pgfshapeaspectinverse\pgf@xc%
+ \ifdim\pgf@yc<\pgf@y%
+ \pgf@yc\pgf@y%
+ \pgf@xc\pgfshapeaspect\pgf@y%
+ \fi%
+ \fi%
+ %
+ \edef\xinnerradius{\the\pgf@xc}%
+ \edef\yinnerradius{\the\pgf@yc}%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x<\pgf@y%
+ \pgf@x\pgf@y%
+ \fi%
+ \edef\outersep{\the\pgf@x}%
+ \addtosavedmacro\outersep%
+ %
+ % For a given cloud, with puff arc length a, the quotient of the
+ % distance between the start and end point of a puffs circular arc
+ % and the radius of that arc, is constant:
+ %
+ % g = .5 * sec((180-a)/2)
+ %
+ \pgfmathsubtract{180}{\arc}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\tempangle\pgfmathresult%
+ \pgfmathsec@{\pgfmathresult}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\arcradiusquotient\pgfmathresult%
+ \addtosavedmacro\arcradiusquotient%
+ %
+ % In addition, the quotient of the distance between the start and
+ % end point of a puffs circular arc and the height of that arc
+ % (ignoring rotation), is also constant:
+ %
+ % h = .5 * (1-sin((180-a)/2))/cos((180-a)/2)
+ % = g * (1 - sin((180-a)/2))
+ \pgfmathsin@{\tempangle}%
+ \pgfmathsubtract@{1}{\pgfmathresult}%
+ \pgfmathmultiply@{\pgfmathresult}{\arcradiusquotient}%
+ \let\archeightquotient\pgfmathresult%
+ \addtosavedmacro\archeightquotient%
+ %
+ % Minimum size is applied to the circum-ellipse (i.e. the ellipse
+ % that passes through the extremities of each puff). Thus, the
+ % relationship between the radii of the elliptical incircle ("inellipse"?)
+ % of the cloud (x and y) and the radii of the circum-ellipse (X and Y),
+ % is given by
+ %
+ % X = 2(x*cos(p/2) + ky)
+ % Y = 2(y*cos(p/2) + kx)
+ %
+ % where:
+ % k = sin(p/2)*((1-cos(a/2))/sin(a/2))
+ % p = the angle between each puff (i.e. 360/<puffs>)
+ % a = the length of arc of the puff.
+ %
+ \pgfmathdivide{\arc}{2}%
+ \let\halfarcangle\pgfmathresult%
+ \pgfmathcos@{\pgfmathresult}%
+ \pgfmathsubtract@{1}{\pgfmathresult}%
+ \let\pgf@temp\pgfmathresult%
+ \pgfmathsin@{\halfarcangle}%
+ \pgfmathdivide@{\pgf@temp}{\pgfmathresult}%
+ \let\pgf@temp\pgfmathresult%
+ \pgfmathdivide@{\anglestep}{2}%
+ \pgfmathsin@{\pgfmathresult}%
+ \pgfmathmultiply@{\pgfmathresult}{\pgf@temp}%
+ \let\k\pgfmathresult%
+ %
+ \pgfmathdivide@{\anglestep}{2}%
+ \pgfmathcos@{\pgfmathresult}%
+ \let\coshalfanglestep\pgfmathresult%
+ %
+ % Calculate the actual radii of the circum-ellipse.
+ %
+ \pgf@x\xinnerradius\relax%
+ \pgf@y\yinnerradius\relax%
+ \pgf@xa\coshalfanglestep\pgf@x%
+ \advance\pgf@xa\k\pgf@y%
+ \pgf@ya\coshalfanglestep\pgf@y%
+ \advance\pgf@ya\k\pgf@x%
+ %
+ % Adjust for minimum height (Y').
+ %
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@ya<.5\pgf@yb%
+ \pgf@ya.5\pgf@yb%
+ \fi%
+ %
+ % Adjust for minimum width (X').
+ %
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@xa<.5\pgf@xb%
+ \pgf@xa.5\pgf@xb%
+ \fi%
+ %
+ \edef\xouterradius{\the\pgf@xa}%
+ \addtosavedmacro\xouterradius%
+ \edef\youterradius{\the\pgf@ya}%
+ \addtosavedmacro\youterradius%
+ %
+ % Now recalculate `in-ellipse' radii:
+ %
+ % x = (X'cos(p/2)-kY')/cos^2(p/2)-k^2,
+ % y = (Y'cos(p/2)-kX')/cos^2(p/2)-k^2,
+ %
+ \pgf@xc\k pt\relax%
+ \pgf@xc-\k\pgf@xc%
+ \pgf@yc\coshalfanglestep pt\relax%
+ \pgf@yc\coshalfanglestep\pgf@yc%
+ \advance\pgf@xc\pgf@yc\relax%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}% cos^2(p/2)-k^2
+ %
+ \pgf@x\coshalfanglestep\pgf@xa%
+ \advance\pgf@x-\k\pgf@ya%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y\coshalfanglestep\pgf@ya%
+ \advance\pgf@y-\k\pgf@xa%
+ \pgf@y\pgfmathresult\pgf@y%
+ %
+ \edef\xinnerradius{\the\pgf@x}%
+ \edef\yinnerradius{\the\pgf@y}%
+ \addtosavedmacro\xinnerradius%
+ \addtosavedmacro\yinnerradius%
+ %
+ % Get some useful trig. constants.
+ %
+ \pgfmathdivide@{\arc}{4}%
+ \let\quarterarc\pgfmathresult%
+ \pgfmathsubtract@{180}{\arc}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\halfcomplementarc\pgfmathresult%
+ %
+ \addtosavedmacro\arc%
+ \addtosavedmacro\quarterarc%
+ \addtosavedmacro\halfcomplementarc%
+ %
+ \pgfmathsec@{\halfcomplementarc}% 1/cos((180-a)/2)
+ \let\sechalfcomplementarc\pgfmathresult%
+ \pgfmathsin@{\halfcomplementarc}% sin((180-a)/2)
+ \let\sinhalfcomplementarc\pgfmathresult%
+ %
+ \addtosavedmacro\sechalfcomplementarc%
+ \addtosavedmacro\sinhalfcomplementarc%
+ %
+ \pgfmathsin@{\quarterarc}% sin(a/4)
+ \let\sinquarterarc\pgfmathresult%
+ \pgfmathcos@{\quarterarc}% cos(a/4)
+ \let\cosquarterarc\pgfmathresult%
+ \pgfmathreciprocal@{\cosquarterarc}%
+ \pgfmathmultiply@{\pgfmathresult}{\sinquarterarc}% tan(a/4)
+ \let\tanquarterarc\pgfmathresult%
+ %
+ \addtosavedmacro\sinquarterarc%
+ \addtosavedmacro\cosquarterarc%
+ \addtosavedmacro\tanquarterarc%
+ %
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{north}{%
+ \getradii%
+ \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{\youterradius}}%
+ }%
+ \anchor{south}{%
+ \getradii%
+ \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{-\youterradius}}%
+ }%
+ \anchor{east}{%
+ \getradii%
+ \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{\xouterradius}{0pt}}%
+ }%
+ \anchor{west}{%
+ \getradii%
+ \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{-\xouterradius}{0pt}}%
+ }%
+ \anchor{north west}{%
+ \getradii%
+ \pgfextract@process\pgf@sh{%
+ \pgf@x\xouterradius\relax%
+ \pgf@x-0.707106\pgf@x%
+ \pgf@y\youterradius\relax%
+ \pgf@y0.707106\pgf@y%
+ }%
+ \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
+ }%
+ \anchor{north east}{%
+ \getradii%
+ \pgfextract@process\pgf@sh{%
+ \pgf@x\xouterradius\relax%
+ \pgf@x0.707106\pgf@x%
+ \pgf@y\youterradius\relax%
+ \pgf@y0.707106\pgf@y%
+ }%
+ \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
+ }%
+ \anchor{south west}{%
+ \getradii%
+ \pgfextract@process\pgf@sh{%
+ \pgf@x\xouterradius\relax%
+ \pgf@x-0.707106\pgf@x%
+ \pgf@y\youterradius\relax%
+ \pgf@y-0.707106\pgf@y%
+ }%
+ \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
+ }%
+ \anchor{south east}{%
+ \getradii%
+ \pgfextract@process\pgf@sh{%
+ \pgf@x\xouterradius\relax%
+ \pgf@x0.707106\pgf@x%
+ \pgf@y\youterradius\relax%
+ \pgf@y-0.707106\pgf@y%
+ }%
+ \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}%
+ }%
+ %
+ % Each `puff' is a circular arc of length a, drawn using two a/2
+ % arcs (a < 180), approximated by Bezier curves.
+ % Due to TeX rounding errors, it is sometimes necessary to `force'
+ % the arc to end at a specific point. So...
+ %
+ % @article{riskus2006,
+ % author = {Aleskus Ri\v{s}kus},
+ % title = {Approximation of a cubic Bezier curve by circular arcs and vice versa},
+ % journal = {Information Technology and Control},
+ % year = {2006},
+ % volume = {35},
+ % number = {4}
+ % }
+ %
+ \backgroundpath{%
+ {%
+ \getradii%
+ %
+ % Get the start angle.
+ %
+ \pgfmathdivide@{\anglestep}{2}%
+ \pgfmathsubtract@{90}{\pgfmathresult}%
+ \let\angle\pgfmathresult%
+ %
+ % Calculate the first arc point.
+ %
+ \pgfextract@process\arcfirstpoint{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
+ }%
+ }%
+ \pgfpathmoveto{\arcfirstpoint}%
+ \let\arcendpoint\arcfirstpoint%
+ %
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>\puffs\relax%
+ \else
+ \let\arcstartpoint\arcendpoint%
+ %
+ % Make sure beginning and end of path are exactly the same.
+ %
+ \ifnum\pgfmathcounter=\puffs\relax%
+ \let\arcendpoint\arcfirstpoint%
+ \else%
+ \pgfmathadd@{\angle}{\anglestep}%
+ \let\angle\pgfmathresult%
+ \pgfextract@process\arcendpoint{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
+ }%
+ }%
+ \fi%
+ %
+ % Get some useful cloud parameters from \arcstartpoint and \arcendpoint.
+ %
+ \pgf@sh@getcloudpuffparameters%
+ %
+ % Get the rotation for the Bezier curve.
+ %
+ \pgfmathsubtract@{90}{\quarterarc}%
+ \pgfmathadd@{\pgfmathresult}{\arcslope}%
+ \let\arcrotate\pgfmathresult%
+ \pgfmathsin@{\arcrotate}%
+ \let\sinarcrotate\pgfmathresult%
+ \pgfmathcos@{\arcrotate}%
+ \let\cosarcrotate\pgfmathresult%
+ %
+ % Calculate the amount by which to scale the control
+ % points, in order to approximate an a/2 arc with radius x.
+ %
+ \pgf@x\arcradius\relax%
+ \pgf@x\tanquarterarc\pgf@x% tan(a/4)
+ \edef\controlscale{\pgfmath@tonumber{\pgf@x}}%
+ %
+ % Get the first control point for the first arc (length a/2)...
+ %
+ \pgfextract@process\controlone{%
+ %
+ % k = 0.552284745 (a `magic' number)...
+ %
+ \pgf@x0.55228475pt\relax%
+ \pgf@x\sinquarterarc\pgf@x% k * sin(a/2)
+ \pgf@y0.55228475pt\relax%
+ \pgf@y\cosquarterarc\pgf@y% k * cos(a/2)
+ %
+ % ...scale the control points up...
+ %
+ \pgf@x\controlscale\pgf@x%
+ \pgf@y\controlscale\pgf@y%
+ %
+ % ...rotate...
+ %
+ \pgf@xa\cosarcrotate\pgf@x%
+ \advance\pgf@xa-\sinarcrotate\pgf@y%
+ \pgf@ya\cosarcrotate\pgf@y%
+ \advance\pgf@ya\sinarcrotate\pgf@x%
+ %
+ % ...and shift.
+ %
+ \arcstartpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ % Get the midpoint of the 150� arc.
+ %
+ \pgfextract@process\arcmidpoint{%
+ \pgfextract@process\arcmidpoint{%
+ \pgf@x-\halfchordlength\relax%
+ \pgf@y\segmentheight\relax%
+ }%
+ \pgfpointadd{\arcstartpoint}{%
+ \pgfmathrotatepointaround{\arcmidpoint}{\pgfpointorigin}{\arcslope}%
+ }%
+ }%
+ %
+ % Get the second control point for the first arc (length a/2)...
+ %
+ \pgfextract@process\controltwo{%
+ \pgf@x0.55228475pt\relax%
+ \pgf@x\sinquarterarc\pgf@x% k * sin(a/2)
+ \pgf@y-0.55228475pt\relax%
+ \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2)
+ %
+ % ...scale, rotate and shift.
+ %
+ \pgf@x\controlscale\pgf@x%
+ \pgf@y\controlscale\pgf@y%
+ %
+ \pgf@xa\cosarcrotate\pgf@x%
+ \advance\pgf@xa-\sinarcrotate\pgf@y%
+ \pgf@ya\cosarcrotate\pgf@y%
+ \advance\pgf@ya\sinarcrotate\pgf@x%
+ %
+ \arcmidpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ {%
+ \pgfsetcornersarced{\pgfpointorigin}%
+ \pgfpathcurveto{\controlone}{\controltwo}{\arcmidpoint}%
+ }%
+ %
+ % Do the same for the second arc...
+ %
+ \pgfmathadd@{\quarterarc}{90}%
+ \pgfmathadd@{\pgfmathresult}{\arcslope}%
+ \let\arcrotate\pgfmathresult%
+ \pgfmathsin@{\arcrotate}%
+ \let\sinarcrotate\pgfmathresult%
+ \pgfmathcos@{\arcrotate}%
+ \let\cosarcrotate\pgfmathresult%
+ %
+ % First control point for the second arc...
+ %
+ \pgfextract@process\controlone{%
+ \pgf@x0.55228475pt\relax%
+ \pgf@x\sinquarterarc\pgf@x% k * sin(a/2)
+ \pgf@y0.55228475pt\relax%
+ \pgf@y\cosquarterarc\pgf@y% k * cos(a/2)
+ %
+ % ...scale, rotate and shift.
+ %
+ \pgf@x\controlscale\pgf@x%
+ \pgf@y\controlscale\pgf@y%
+ %
+ \pgf@xa\cosarcrotate\pgf@x%
+ \advance\pgf@xa-\sinarcrotate\pgf@y%
+ \pgf@ya\cosarcrotate\pgf@y%
+ \advance\pgf@ya\sinarcrotate\pgf@x%
+ %
+ \arcmidpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ %
+ % Second control point for the second arc.
+ %
+ \pgfextract@process\controltwo{%
+ \pgf@x0.55228475pt\relax%
+ \pgf@x\sinquarterarc\pgf@x% k * sin(a/2)
+ \pgf@y-0.55228475pt\relax%
+ \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2)
+ %
+ % ...scale, rotate and shift.
+ %
+ \pgf@x\controlscale\pgf@x%
+ \pgf@y\controlscale\pgf@y%
+ %
+ \pgf@xa\cosarcrotate\pgf@x%
+ \advance\pgf@xa-\sinarcrotate\pgf@y%
+ \pgf@ya\cosarcrotate\pgf@y%
+ \advance\pgf@ya\sinarcrotate\pgf@x%
+ %
+ \arcendpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfpathcurveto{\controlone}{\controltwo}{\arcendpoint}%
+ \repeatpgfmathloop%
+ \pgfpathclose% Phew!
+ }%
+ }%
+ %
+ % Calculate a point on the border of the cloud. This is a two-stage process:
+ %
+ % 1. Locate the correct puff.
+ % 2. Locate the angle on the circular arc which forms the puff.
+ %
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % Get the inner radii and trig. constants.
+ %
+ \getradii%
+ %
+ %
+ %
+ \ifpgfcloudanchorsuseellipse%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointborderellipse{%
+ \pgfpoint{\externalx}{\externaly}
+ }{%
+ \pgfpoint{\xouterradius}{\youterradius}
+ }%
+ }%
+ \else%
+ \pgfextract@process\externalpoint{%
+ \centerpoint%
+ \advance\pgf@x\externalx\relax%
+ \advance\pgf@y\externaly\relax%
+ }%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle\pgfmathresult%
+ %
+ % 1. Locate the correct puff:
+ %
+ % Get end angle of the relevant puff arc.
+ %
+ \pgfmathdivide@{\anglestep}{2}%
+ \let\halfanglestep\pgfmathresult%
+ \pgfmathsubtract@{90}{\halfanglestep}%
+ \let\endangle\pgfmathresult%
+ \pgfmathloop%
+ \pgfmathsubtract@{\endangle}{\anglestep}%
+ \ifdim\pgfmathresult pt<-\anglestep pt\relax%
+ \else%
+ \let\endangle\pgfmathresult%
+ \repeatpgfmathloop%
+ \def\angle{0}%
+ \let\lastangle\angle%
+ \pgfmathloop%
+ \pgfmathadd@{\endangle}{\anglestep}%
+ \let\endangle\pgfmathresult%
+ %
+ % Calculate the `miter point'. This is the point between
+ % each puff, and takes into account the outer sep.
+ %
+ \pgfextract@process\miterpoint{%
+ %
+ \pgfextract@process\secondpoint{%
+ \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}%
+ }%
+ %
+ \pgfmathadd@{\endangle}{\anglestep}%
+ \let\angletemp\pgfmathresult%
+ \pgfextract@process\thirdpoint{%
+ \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}%
+ }%
+ %
+ \pgfmathsubtract@{\endangle}{\anglestep}%
+ \let\angletemp\pgfmathresult%
+ \pgfextract@process\firstpoint{%
+ \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}%
+ }%
+ %
+ \pgfmathanglebetweenpoints{\firstpoint}{\secondpoint}%
+ \let\anglealpha\pgfmathresult%
+ \pgfmathanglebetweenpoints{\secondpoint}{\thirdpoint}%
+ \let\anglebeta\pgfmathresult%
+ %
+ \pgfmathsubtract@{\anglebeta}{\anglealpha}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \pgfmathadd@{\pgfmathresult}{\halfcomplementarc}%
+ \pgfmathcosec@{\pgfmathresult}%
+ \pgf@x\outersep\relax%
+ \pgf@x\pgfmathresult\pgf@x%
+ \edef\miterradius{\the\pgf@x}%
+ %
+ \pgfmathadd@{\anglealpha}{\anglebeta}%
+ \pgfmathsubtract@{\pgfmathresult}{180}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\miterangle\pgfmathresult%
+ \pgfpointadd{\secondpoint}{%
+ \pgfqpointpolar{\miterangle}{\miterradius}%
+ }%
+ }%
+ %
+ % Get the angle of the miter point...
+ %
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\miterpoint}%
+ \let\angle\pgfmathresult%
+ \ifdim\angle pt<\lastangle pt\relax% Guard against 360� = 0�
+ \pgfmathadd@{\angle}{360}%
+ \let\angle\pgfmathresult%
+ \fi%
+ \let\lastangle\angle%
+ %
+ % ...and see if it is greater than the external point.
+ %
+ \ifdim\externalangle pt>\angle pt\relax%
+ \repeatpgfmathloop%
+ %
+ % Get the start angle of the relevant arc and ensure angles are in the range.
+ %
+ \pgfmathmod@{\endangle}{360}%
+ \let\endangle\pgfmathresult%
+ \pgfmathsubtract@{\endangle}{\anglestep}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\startangle\pgfmathresult%
+ %
+ % Now, get the start and end points of the arc.
+ %
+ \pgfextract@process\arcstartpoint{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{+\startangle}{+\xinnerradius and +\yinnerradius}%
+ }%
+ }%
+ \pgfextract@process\arcendpoint{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}%
+ }%
+ }%
+ %
+ % Get some useful cloud parameters from \arcstartpoint and \arcendpoint.
+ %
+ \pgf@sh@getcloudpuffparameters%
+ %
+ % Hackery, for when an arc straddles 0�.
+ %
+ \ifdim\endangle pt<\startangle pt\relax%
+ \pgfmathadd@{\externalangle}{180}%
+ \pgfmathmod@{\pgfmathresult}{360}%
+ \let\x\pgfmathresult%
+ \else%
+ \let\x\externalangle%
+ \fi%
+ %
+ % 2. Locate the angle on the circular arc which forms the puff.
+ %
+ % Essentially a binary search to find the angle on the circular
+ % arc, which provides the nearest estimate to the border point.
+ %
+ \let\s\halfcomplementarc% The start of the arc.
+ \pgfmathadd@{\s}{\arc}%
+ \let\e\pgfmathresult% The end of the arc.
+ \pgfmathadd@{\e}{\s}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\n\pgfmathresult% The nearest estimate (default to middle of arc).
+ \def\m{360}% Measure of `nearness'.
+ \pgfmathloop%
+ \pgfmathadd@{\e}{\s}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\p\pgfmathresult% The point halfway between \s and \e.
+ \ifdim\p pt=\s pt\relax%
+ \else%
+ %
+ % Get the point on the circular arc.
+ %
+ \pgfmathadd@{\p}{\arcslope}%
+ \let\a\pgfmathresult%
+ \pgfextract@process\arcpoint{%
+ \pgfpointadd{\circlecenterpoint}{%
+ \pgfqpointpolar{\a}{\outerarcradius}%
+ }%
+ }%
+ %
+ % Find the angle between the node centre and the point on the arc.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\arcpoint}%
+ %
+ % Hackery, for when an arc straddles 0�.
+ %
+ \ifdim\endangle pt<\startangle pt\relax%
+ \pgfmathadd@{\pgfmathresult}{180}%
+ \pgfmathmod@{\pgfmathresult}{360}%
+ \fi%
+ \let\q\pgfmathresult%
+ \ifdim\x pt=\q pt% Found it!
+ \pgfmathbreakloop% Breaks after current iteration is complete.
+ \else
+ \ifdim\x pt<\q pt\relax%
+ \let\e\p%
+ \else%
+ \let\s\p%
+ \fi%
+ \fi%
+ \pgfmathsubtract@{\x}{\q}%
+ \pgfmathabs@{\pgfmathresult}%
+ %
+ % Save the estimate if it is better than any previous estimate.
+ %
+ \ifdim\pgfmathresult pt<\m pt\relax%
+ \let\m\pgfmathresult%
+ \let\n\p%
+ \fi%
+ \repeatpgfmathloop%
+ %
+ % Use the nearest estimate as the anchor angle.
+ %
+ \pgfmathadd@{\n}{\arcslope}%
+ \let\anchorangle\pgfmathresult%
+ %
+ % Finally, the required point.
+ %
+ \pgfpointadd{\circlecenterpoint}{%
+ \pgfqpointpolar{\anchorangle}{\outerarcradius}%
+ }%
+ \fi%
+ }% Again, Phew!
+ %
+ % Now, a sneaky hack. This means an arbitrary `puff' anchors
+ % can be used for positioning the cloud shape. This is needed
+ % if a cloud is positioned using the `puff <n+1>' anchor, where
+ % n is the number of puffs of any previously drawn cloud.
+ %
+ \pgfutil@g@addto@macro\pgf@sh@s@cloud{%
+ \c@pgf@counta\puffs\relax%
+ \pgfmathloop%
+ \ifnum\c@pgf@counta>0\relax%
+ \pgfutil@ifundefined{pgf@anchor@cloud@puff\space\the\c@pgf@counta}{%
+ \expandafter\xdef\csname pgf@anchor@cloud@puff\space\the\c@pgf@counta\endcsname{%
+ \noexpand\pgf@sh@@cloudpuffanchor{\the\c@pgf@counta}%
+ }%
+ }{\c@pgf@counta0\relax}%
+ \advance\c@pgf@counta-1\relax%
+ \repeatpgfmathloop%
+ }%
+}%
+
+% \pgf@sh@@cloudpuffanchor
+%
+% Internal macro for calculating the anchors puff 1, puff 2, ... etc.
+%
+\def\pgf@sh@@cloudpuffanchor#1{%
+ \getradii%
+ \pgfmathdivide@{\anglestep}{2}%
+ \let\halfanglestep\pgfmathresult%
+ \c@pgf@counta#1\relax%
+ \advance\c@pgf@counta-1\relax%
+ \pgfmathmultiply@{\anglestep}{\the\c@pgf@counta}%
+ \pgfmathadd@{\pgfmathresult}{90}%
+ \pgfmathsubtract@{\pgfmathresult}{\halfanglestep}%
+ \let\angle\pgfmathresult%
+ %
+ % Calculate the first arc point.
+ %
+ \pgfextract@process\arcstartpoint{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
+ }%
+ }%
+ %
+ \pgfmathadd@{\angle}{\anglestep}%
+ \let\angle\pgfmathresult%
+ \pgfextract@process\arcendpoint{%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}%
+ }%
+ }%
+ %
+ % Get some useful cloud parameters from \arcstartpoint and \arcendpoint.
+ %
+ \pgf@sh@getcloudpuffparameters%
+ %
+ % Calculate the point.
+ %
+ \pgfmathadd@{\arcslope}{90}%
+ \let\anchorangle\pgfmathresult%
+ \pgfpointadd{\circlecenterpoint}{%
+ \pgfqpointpolar{\anchorangle}{\outerarcradius}%
+ }%
+}%
+
+% \pgf@sh@cloudpuffparameters
+%
+% Internal macro to calculate some common arc parameters which
+% are required when calculating radii, drawing the background
+% path and calculating border anchors.
+%
+\def\pgf@sh@getcloudpuffparameters{%
+ %
+ % Calculate the angle to which the entire arc is sloped.
+ %
+ \pgfmathanglebetweenpoints{\arcendpoint}{\arcstartpoint}%
+ \let\arcslope\pgfmathresult%
+ %
+ % Calculate the chord length and arc radius.
+ %
+ \pgfpointdiff{\arcendpoint}{\arcstartpoint}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}
+ \pgf@x\pgfmathresult pt\relax%
+ \pgf@xa.5\pgf@x%
+ \edef\halfchordlength{\the\pgf@xa}%
+ \pgf@x\arcradiusquotient\pgf@x%
+ \edef\arcradius{\the\pgf@x}%
+ \pgf@xa\outersep\relax%
+ \advance\pgf@xa\pgf@x%
+ \edef\outerarcradius{\the\pgf@xa}%
+ %
+ % Calculate the height of the resulting segment.
+ %
+ \pgf@y-\sinhalfcomplementarc\pgf@x% sin((180-a)/2)
+ \advance\pgf@y\pgf@x%
+ \edef\segmentheight{\the\pgf@y}%
+ %
+ % Calculate the center of the circle of which the arc is a part.
+ %
+ \pgfextract@process\circlecenterpoint{%
+ \pgfextract@process\circlecenterpoint{%
+ \pgf@x-\halfchordlength\relax%
+ \pgf@y\segmentheight\relax%
+ \advance\pgf@y-\arcradius
+ }%
+ \pgfpointadd{\arcstartpoint}{%
+ \pgfmathrotatepointaround{\circlecenterpoint}{\pgfpointorigin}{\arcslope}%
+ }%
+ }%
+}%
+
+
+
+
+
+% Internal macros for signal shape.
+%
+\def\pgf@lib@sh@signal@nowhere{nowhere}%
+\def\pgf@lib@sh@signal@from{from}%
+\def\pgf@lib@sh@signal@to{to}%
+
+\def\pgf@lib@sh@signal@parsedirection#1#2{%
+ %
+ \let\pgf@lib@sh@signal@direction=#2%
+ \edef\pgf@lib@sh@temp{#1}%
+ \expandafter\pgf@lib@sh@signal@@parsedirection\pgf@lib@sh@temp\pgf@stop}%
+
+\def\pgf@lib@sh@signal@@parsedirection#1\pgf@stop{%
+ \pgfutil@in@{and}{#1}%
+ \ifpgfutil@in@%
+ \pgf@lib@sh@signal@@@parsedirection#1\pgf@lib%
+ \else%
+ \pgf@lib@sh@signal@@@parsedirection#1 and #1\pgf@lib%
+ \fi
+}%
+\def\pgf@lib@sh@signal@@@parsedirection#1 and #2\pgf@lib{%
+ \pgfutil@in@{nowhere}{#1}%
+ \ifpgfutil@in@
+ \else%
+ \pgf@lib@sh@signal@@@@parsedirection{#1}%
+ \pgf@lib@sh@signal@@@@parsedirection{#2}%
+ \fi%
+}%
+\def\pgf@lib@sh@signal@@@@parsedirection#1{%
+ \pgfutil@in@{ #1 }{ east right }%
+ \ifpgfutil@in@%
+ \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@direction%
+ \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere%
+ \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere%
+ \fi%
+ \pgfutil@in@{ #1 }{ left west }%
+ \ifpgfutil@in@%
+ \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@direction%
+ \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere%
+ \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere%
+ \fi%
+ \pgfutil@in@{ #1 }{ above up north }%
+ \ifpgfutil@in@%
+ \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@direction%
+ \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere%
+ \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere%
+ \fi%
+ \pgfutil@in@{ #1 }{ below down south }%
+ \ifpgfutil@in@%
+ \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@direction%
+ \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere%
+ \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere%
+ \fi%
+}%
+
+
+% Keys for signal shape:
+%
+\pgfkeys{/pgf/.cd,
+ signal pointer angle/.initial=90,
+ signal to/.initial=east,
+ signal from/.initial=nowhere,
+}%
+
+\pgfdeclareshape{signal}{%
+ \savedmacro\installsignalparameters{%
+ %
+ \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere%
+ \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere%
+ \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere%
+ \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere%
+ %
+ \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal from}}{\pgf@lib@sh@signal@from}%
+ \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal to}}{\pgf@lib@sh@signal@to}%
+ %
+ % Define a centerpoint.
+ %
+ \pgfextract@process\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ %
+ % Get some useful trig. stuff
+ %
+ \pgfmathsetmacro\pointerangle{\pgfkeysvalueof{/pgf/signal pointer angle}}%
+ %
+ \pgfmathdivide@{\pointerangle}{2}%
+ \let\halfpointerangle=\pgfmathresult%
+ %
+ \pgfmathcosec@{\halfpointerangle}%
+ \let\cosechalfpointerangle=\pgfmathresult%
+ %
+ \pgfmathdivide@{\halfpointerangle}{2}%
+ \let\quarterpointerangle=\pgfmathresult%
+ %
+ \pgfmathcosec@{\quarterpointerangle}%
+ \let\cosecquarterpointerangle=\pgfmathresult%
+ %
+ \pgfmathsec@{\quarterpointerangle}%
+ \let\secquarterpointerangle=\pgfmathresult%
+ %
+ \pgfmathsubtract@{90}{\quarterpointerangle}%
+ \let\complementquarterpointerangle\pgfmathresult%
+ %
+ % Get the larger of the outer sep.
+ %
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@x>\pgf@y%
+ \pgf@y\pgf@x%
+ \fi%
+ \pgf@yc=\pgf@y%
+ %
+ % Calculate the miter due to the line width, at the pointer apex...
+ %
+ \pgf@x=\cosechalfpointerangle\pgf@y%
+ \edef\pointerapexmiter{\the\pgf@x}%
+ %
+ % ...at a corner by a `to' pointer (i.e. sticks out)...
+ %
+ \pgf@x=\secquarterpointerangle\pgf@y%
+ \edef\tocornermiter{\the\pgf@x}%
+ %
+ % ...at a corner by a `from' pointer (i.e. sticks in).
+ %
+ \pgf@x=\cosecquarterpointerangle\pgf@y
+ \edef\fromcornermiter{\the\pgf@x}%
+ %
+ % Get the (half) dimensions of the node.
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya.5\dp\pgfnodeparttextbox%
+ %
+ % Get the distance a pointer sticks out to the side...
+ %
+ \pgfmathsubtract@{90}{\halfpointerangle}%
+ \pgfmathtan@{\pgfmathresult}%
+ \pgf@xb=\pgfmathresult\pgf@ya%
+ %
+ % ...and up.
+ %
+ \pgf@yb=\pgfmathresult\pgf@xa%
+ %
+ % Adjust for minimum height.
+ %
+ \pgfutil@tempdima=2.0\pgf@ya%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by\pgf@yb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by\pgf@yb%
+ \fi%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgfutil@tempdima<\pgf@y%
+ \pgfutil@tempdima=\pgf@y%
+ %
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \fi%
+ \pgf@ya=0.5\pgfutil@tempdima%
+ \pgfmathsubtract@{90}{\halfpointerangle}%
+ \pgfmathtan@{\pgfmathresult}%
+ \pgf@xb=\pgfmathresult\pgf@ya%
+ \fi%
+ %
+ % Adjust for minimum width.
+ %
+ \pgfutil@tempdima=2.0\pgf@xa%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by\pgf@xb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by\pgf@xb%
+ \fi%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgfutil@tempdima<\pgf@x%
+ \pgfutil@tempdima=\pgf@x%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \pgf@xa=0.5\pgfutil@tempdima%
+ \pgfmathsubtract@{90}{\halfpointerangle}%
+ \pgfmathtan@{\pgfmathresult}%
+ \pgf@yb=\pgfmathresult\pgf@xa%
+ \fi%
+ %
+ % So, define the points for the background path.
+ %
+ \pgfextract@process\north{%
+ \centerpoint%
+ \advance\pgf@y\pgf@ya%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to%
+ \advance\pgf@y\pgf@yb%
+ \fi%
+ }%
+ \pgfextract@process\south{%
+ \centerpoint%
+ \advance\pgf@y-\pgf@ya%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to%
+ \advance\pgf@y-\pgf@yb%
+ \fi%
+ }%
+ \pgfextract@process\east{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to%
+ \advance\pgf@x\pgf@xb%
+ \fi%
+ }%
+ \pgfextract@process\west{%
+ \centerpoint%
+ \advance\pgf@x-\pgf@xa%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
+ \advance\pgf@x-\pgf@xb%
+ \fi%
+ }%
+ \pgfextract@process\northeast{%
+ \centerpoint%
+ \advance\pgf@y\pgf@ya%
+ \advance\pgf@x\pgf@xa%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
+ \advance\pgf@y\pgf@yb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
+ \advance\pgf@x\pgf@xb%
+ \fi%
+ }%
+ \pgfextract@process\southeast{%
+ \centerpoint%
+ \advance\pgf@y-\pgf@ya%
+ \advance\pgf@x\pgf@xa%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
+ \advance\pgf@y-\pgf@yb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
+ \advance\pgf@x\pgf@xb%
+ \fi%
+ }%
+ \pgfextract@process\southwest{%
+ \centerpoint%
+ \advance\pgf@y-\pgf@ya%
+ \advance\pgf@x-\pgf@xa%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
+ \advance\pgf@y-\pgf@yb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
+ \advance\pgf@x-\pgf@xb%
+ \fi%
+ }%
+ \pgfextract@process\northwest{%
+ \centerpoint%
+ \advance\pgf@y\pgf@ya%
+ \advance\pgf@x-\pgf@xa%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
+ \advance\pgf@y\pgf@yb%
+ \fi%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
+ \advance\pgf@x-\pgf@xb%
+ \fi%
+ }%
+ \addtosavedmacro{\north}%
+ \addtosavedmacro{\south}%
+ \addtosavedmacro{\east}%
+ \addtosavedmacro{\west}%
+ \addtosavedmacro{\northeast}%
+ \addtosavedmacro{\southwest}%
+ \addtosavedmacro{\southeast}%
+ \addtosavedmacro{\northwest}%
+ %
+ % Calculate the `miter vectors' (i.e. +outer sep).
+ %
+ \pgfextract@process\northmiter{%
+ \pgf@x0pt%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere%
+ \pgf@y\pgf@yc%
+ \else%
+ \pgf@y\pointerapexmiter\relax%
+ \fi%
+ }%
+ \pgfextract@process\southmiter{%
+ \pgf@x0pt%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere%
+ \pgf@y-\pgf@yc%
+ \else%
+ \pgf@y-\pointerapexmiter\relax%
+ \fi%
+ }%
+ \pgfextract@process\eastmiter{%
+ \pgf@y0pt%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
+ \pgf@x\pgf@yc%
+ \else%
+ \pgf@x\pointerapexmiter\relax%
+ \fi%
+ }%
+ \pgfextract@process\westmiter{%
+ \pgf@y0pt%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
+ \pgf@x-\pgf@yc%
+ \else%
+ \pgf@x-\pointerapexmiter\relax%
+ \fi%
+ }%
+ \pgfextract@process\northeastmiter{%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
+ \pgf@x\pgf@yc
+ \pgf@y\pgf@yc%
+ \else
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
+ \pgfqpointpolar{\quarterpointerangle}{\fromcornermiter}
+ \else%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to%
+ \pgfqpointpolar{\complementquarterpointerangle}{\tocornermiter}%
+ \fi%
+ \fi%
+ \fi%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
+ \pgfqpointpolar{\complementquarterpointerangle}{\fromcornermiter}%
+ \else%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to%
+ \pgfqpointpolar{\quarterpointerangle}{\tocornermiter}%
+ \fi%
+ \fi%
+ }%
+ \pgfextract@process\southeastmiter{%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere%
+ \pgf@x\pgf@yc%
+ \pgf@y\pgf@yc%
+ \else
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from%
+ \pgfqpointpolar{-\quarterpointerangle}{\fromcornermiter}
+ \else%
+ \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to%
+ \pgfqpointpolar{-\complementquarterpointerangle}{\tocornermiter}%
+ \fi%
+ \fi%
+ \fi%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
+ \pgfqpointpolar{-\complementquarterpointerangle}{\fromcornermiter}
+ \else%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to%
+ \pgfqpointpolar{-\quarterpointerangle}{\tocornermiter}%
+ \fi%
+ \fi%
+ }%
+ \pgfextract@process\southwestmiter{%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
+ \pgf@x-\pgf@yc
+ \pgf@y-\pgf@yc%
+ \else
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
+ \pgfmathadd@{\quarterpointerangle}{180}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}
+ \else%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
+ \pgfmathadd@{\complementquarterpointerangle}{180}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
+ \fi%
+ \fi%
+ \fi%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from%
+ \pgfmathadd@{\complementquarterpointerangle}{180}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}%
+ \else%
+ \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to%
+ \pgfmathadd@{\quarterpointerangle}{180}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
+ \fi%
+ \fi%
+ }%
+ \pgfextract@process\northwestmiter{%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere%
+ \pgf@x-\pgf@yc%
+ \pgf@y\pgf@yc%
+ \else
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from%
+ \pgfmathsubtract@{180}{\quarterpointerangle}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}
+ \else%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
+ \pgfmathsubtract@{180}{\complementquarterpointerangle}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
+ \fi%
+ \fi%
+ \fi%
+ \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from%
+ \pgfmathsubtract@{180}{\complementquarterpointerangle}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}%
+ \else%
+ \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to%
+ \pgfmathsubtract@{180}{\quarterpointerangle}%
+ \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}%
+ \fi%
+ \fi%
+ }%
+ \addtosavedmacro{\northmiter}%
+ \addtosavedmacro{\southmiter}%
+ \addtosavedmacro{\eastmiter}%
+ \addtosavedmacro{\westmiter}%
+ \addtosavedmacro{\northeastmiter}%
+ \addtosavedmacro{\southeastmiter}%
+ \addtosavedmacro{\southwestmiter}%
+ \addtosavedmacro{\northwestmiter}%
+ %
+ % Now calculate the anchor points
+ %
+ \pgfextract@process\anchornorth{%
+ \pgfpointadd{\north}{\northmiter}%
+ }%
+ \pgfextract@process\anchorsouth{%
+ \pgfpointadd{\south}{\southmiter}%
+ }%
+ \pgfextract@process\anchoreast{%
+ \pgfpointadd{\east}{\eastmiter}%
+ }%
+ \pgfextract@process\anchorwest{%
+ \pgfpointadd{\west}{\westmiter}%
+ }%
+ \pgfextract@process\anchornortheast{%
+ \pgfpointadd{\northeast}{\northeastmiter}%
+ }%
+ \pgfextract@process\anchorsoutheast{%
+ \pgfpointadd{\southeast}{\southeastmiter}%
+ }%
+ \pgfextract@process\anchorsouthwest{%
+ \pgfpointadd{\southwest}{\southwestmiter}%
+ }%
+ \pgfextract@process\anchornorthwest{%
+ \pgfpointadd{\northwest}{\northwestmiter}%
+ }%
+ \addtosavedmacro{\anchornorth}%
+ \addtosavedmacro{\anchorsouth}%
+ \addtosavedmacro{\anchoreast}%
+ \addtosavedmacro{\anchorwest}%
+ \addtosavedmacro{\anchornortheast}%
+ \addtosavedmacro{\anchorsouthwest}%
+ \addtosavedmacro{\anchorsoutheast}%
+ \addtosavedmacro{\anchornorthwest}%
+ }%
+ \savedanchor\centerpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor\basepoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \savedanchor\midpoint{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+.5ex}%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{%
+ \installsignalparameters%
+ \anchoreast%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \anchorsoutheast%
+ \ifdim\pgf@xa>\pgf@x%
+ \pgfutil@tempdima\pgf@xa%
+ \else%
+ \pgfutil@tempdima\pgf@x%
+ \fi%
+ \pgfextract@process\externalpoint{%
+ \basepoint%
+ \pgf@x\pgfutil@tempdima%
+ }
+ \basepoint%
+ \let\firstpoint\anchoreast%
+ \ifdim\pgf@y<\pgf@ya%
+ \let\secondpoint\anchorsoutheast%
+ \else%
+ \let\secondpoint\anchornortheast%
+ \fi%
+ \pgfpointintersectionoflines{\basepoint}{\externalpoint}%
+ {\firstpoint}{\secondpoint}%
+ }%
+ \anchor{base west}{%
+ \installsignalparameters%
+ \anchorwest%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \anchorsouthwest%
+ \ifdim\pgf@xa<\pgf@x%
+ \pgfutil@tempdima\pgf@xa%
+ \else%
+ \pgfutil@tempdima\pgf@x%
+ \fi%
+ \pgfextract@process\externalpoint{%
+ \basepoint%
+ \pgf@x\pgfutil@tempdima%
+ }
+ \basepoint%
+ \let\firstpoint\anchorwest%
+ \ifdim\pgf@y<\pgf@ya%
+ \let\secondpoint\anchorsouthwest%
+ \else%
+ \let\secondpoint\anchornorthwest%
+ \fi%
+ \pgfpointintersectionoflines{\basepoint}{\externalpoint}%
+ {\firstpoint}{\secondpoint}%
+ }%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{%
+ \installsignalparameters%
+ \anchoreast%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \anchorsoutheast%
+ \ifdim\pgf@xa>\pgf@x%
+ \pgfutil@tempdima\pgf@xa%
+ \else%
+ \pgfutil@tempdima\pgf@x%
+ \fi%
+ \pgfextract@process\externalpoint{%
+ \midpoint%
+ \pgf@x\pgfutil@tempdima%
+ }
+ \midpoint%
+ \let\firstpoint\anchoreast%
+ \ifdim\pgf@y<\pgf@ya%
+ \let\secondpoint\anchorsoutheast%
+ \else%
+ \let\secondpoint\anchornortheast%
+ \fi%
+ \pgfpointintersectionoflines{\midpoint}{\externalpoint}%
+ {\firstpoint}{\secondpoint}%
+ }%
+ \anchor{mid west}{%
+ \installsignalparameters%
+ \anchorwest%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \anchorsouthwest%
+ \ifdim\pgf@xa<\pgf@x%
+ \pgfutil@tempdima\pgf@xa%
+ \else%
+ \pgfutil@tempdima\pgf@x%
+ \fi%
+ \pgfextract@process\externalpoint{%
+ \midpoint%
+ \pgf@x\pgfutil@tempdima%
+ }
+ \midpoint%
+ \let\firstpoint\anchorwest%
+ \ifdim\pgf@y<\pgf@ya%
+ \let\secondpoint\anchorsouthwest%
+ \else%
+ \let\secondpoint\anchornorthwest%
+ \fi%
+ \pgfpointintersectionoflines{\midpoint}{\externalpoint}%
+ {\firstpoint}{\secondpoint}%
+ }%
+ \anchor{north}{\installsignalparameters\anchornorth}%
+ \anchor{south}{\installsignalparameters\anchorsouth}%
+ \anchor{east}{\installsignalparameters\anchoreast}%
+ \anchor{west}{\installsignalparameters\anchorwest}%
+ \anchor{north east}{\installsignalparameters\anchornortheast}%
+ \anchor{south east}{\installsignalparameters\anchorsoutheast}%
+ \anchor{south west}{\installsignalparameters\anchorsouthwest}%
+ \anchor{north west}{\installsignalparameters\anchornorthwest}%
+ \backgroundpath{%
+ \installsignalparameters%
+ \pgfpathmoveto{\north}%
+ \pgfpathlineto{\northeast}%
+ \pgfpathlineto{\east}%
+ \pgfpathlineto{\southeast}%
+ \pgfpathlineto{\south}%
+ \pgfpathlineto{\southwest}%
+ \pgfpathlineto{\west}%
+ \pgfpathlineto{\northwest}%
+ \pgfpathclose%
+ }%
+ \anchorborder{%
+ %
+ % Save x and y.
+ %
+ \edef\externalx{\the\pgf@x}%
+ \edef\externaly{\the\pgf@y}%
+ %
+ % Adjust the location of the external
+ % point relative to \centerpoint.
+ %
+ \centerpoint%
+ \pgf@xa\externalx\relax%
+ \pgf@ya\externaly\relax%
+ \advance\pgf@xa\pgf@x%
+ \advance\pgf@ya\pgf@y%
+ \edef\externalx{\the\pgf@xa}%
+ \edef\externaly{\the\pgf@ya}%
+ %
+ % Get the shape parameters.
+ %
+ \installsignalparameters%
+ %
+ % Get the angle of the external point to the \centerpoint.
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ \let\externalangle\pgfmathresult%
+ %
+ %
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\anchorwest}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\centerpoint}{\anchornorth}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\centerpoint}{\anchornortheast}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \let\firstpoint\anchoreast%
+ \let\secondpoint\anchornortheast%
+ \else%
+ \let\secondpoint\anchornortheast%
+ \let\firstpoint\anchornorth%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\anchornorthwest}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \let\firstpoint\anchornorth%
+ \let\secondpoint\anchornorthwest%
+ \else%
+ \let\secondpoint\anchornorthwest%
+ \let\firstpoint\anchorwest%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouth}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouthwest}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \let\firstpoint\anchorwest%
+ \let\secondpoint\anchorsouthwest%
+ \else%
+ \let\secondpoint\anchorsouthwest%
+ \let\firstpoint\anchorsouth%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\anchorsoutheast}%
+ \ifdim\externalangle pt<\pgfmathresult pt\relax%
+ \let\firstpoint\anchorsouth%
+ \let\secondpoint\anchorsoutheast%
+ \else%
+ \let\secondpoint\anchorsoutheast%
+ \let\firstpoint\anchoreast%
+ \fi%
+ \fi%
+ \fi%
+ %
+ % Now locate the point.
+ %
+ \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}%
+ {\firstpoint}{\secondpoint}%
+ }%
+}%
+
+
+
+
+
+
+% Keys for shape tape
+%
+% /pgf/tape bend top : Type of bend for north side.
+% /pgf/tape bend bottom : Type of bend for south side.
+% /pgf/tape bend height : The height of the bends.
+\pgfkeys{/pgf/.cd,
+ tape bend top/.initial=in and out,
+ tape bend bottom/.initial=in and out,
+ tape bend/.style={/pgf/tape bend top={#1}, /pgf/tape bend bottom={#1}},
+ tape bend height/.initial=5pt,
+}%
+
+\def\pgf@lib@sh@inandouttext{in and out}%
+\def\pgf@lib@sh@outandintext{out and in}%
+\def\pgf@lib@sh@nonetext{none}%
+
+\pgfdeclareshape{tape}{%
+ \savedmacro\tapedimensions{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y.5\dp\pgfnodeparttextbox%
+ %
+ \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \addtosavedmacro\outerxsep%
+ \addtosavedmacro\outerysep%
+ %
+ \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/tape bend height}}%
+ \pgfutil@tempdima.5\pgfutil@tempdima%
+ \edef\halfbendheight{\the\pgfutil@tempdima}%
+ \addtosavedmacro\halfbendheight%
+ %
+ \pgfkeysgetvalue{/pgf/tape bend top}{\topbendstyle}%
+ \pgfkeysgetvalue{/pgf/tape bend bottom}{\bottombendstyle}%
+ \addtosavedmacro\topbendstyle%
+ \addtosavedmacro\bottombendstyle%
+ %
+ \ifx\topbendstyle\pgf@lib@sh@nonetext%
+ \else%
+ \advance\pgf@y\pgfutil@tempdima%
+ \fi%
+ \ifx\bottombendstyle\pgf@lib@sh@none%
+ \else%
+ \advance\pgf@y\pgfutil@tempdima%
+ \fi%
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<.5\pgf@xa%
+ \pgf@x.5\pgf@xa%
+ \fi%
+ \ifdim\pgf@y<.5\pgf@ya%
+ \pgf@y.5\pgf@ya%
+ \fi%
+ \ifx\topbendstyle\pgf@lib@sh@nonetext%
+ \else%
+ \advance\pgf@y-\pgfutil@tempdima%
+ \fi%
+ \ifx\bottombendstyle\pgf@lib@sh@nonetext%
+ \else%
+ \advance\pgf@y-\pgfutil@tempdima%
+ \fi%
+ %
+ \pgfutil@tempdima3.414213\pgfutil@tempdima% 1 / (1-sin(45))
+ \edef\bendyradius{\the\pgfutil@tempdima}%
+ \addtosavedmacro\bendyradius%
+ \advance\pgfutil@tempdima\outerysep%
+ \edef\outerbendyradius{\the\pgfutil@tempdima}%
+ \addtosavedmacro\outerbendyradius%
+ \advance\pgfutil@tempdima-\outerysep%
+ \advance\pgfutil@tempdima-\outerysep%
+ \edef\innerbendyradius{\the\pgfutil@tempdima}%
+ \addtosavedmacro\innerbendyradius%
+ %
+ \pgfutil@tempdima0.707106\pgf@x% cos(45)
+ \edef\bendxradius{\the\pgfutil@tempdima}%
+ \addtosavedmacro\bendxradius%
+ \advance\pgfutil@tempdima\outerxsep%
+ \edef\outerbendxradius{\the\pgfutil@tempdima}%
+ \addtosavedmacro\outerbendxradius%
+ \advance\pgfutil@tempdima-\outerxsep%
+ \advance\pgfutil@tempdima-\outerxsep%
+ \edef\innerbendxradius{\the\pgfutil@tempdima}%
+ \addtosavedmacro\innerbendxradius%
+ %
+ \edef\halfwidth{\the\pgf@x}%
+ \edef\halfheight{\the\pgf@y}%
+ \addtosavedmacro\halfwidth%
+ \addtosavedmacro\halfheight%
+ %
+ \advance\pgf@x\outerxsep%
+ \edef\outerhalfwidth{\the\pgf@x}%
+ \addtosavedmacro\outerhalfwidth%
+ %
+ \pgf@xc\bendxradius%
+ \pgf@yc\bendyradius%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@xc}}%
+ \pgfmathatan{\pgfmathresult}%
+ \pgf@xc\pgfmathresult pt\relax%
+ \pgf@xc.5\pgf@xc%
+ \edef\halfangle{\pgfmath@tonumber{\pgf@xc}}%
+ \addtosavedmacro\halfangle%
+ %
+ \pgf@xc45pt\relax%
+ \advance\pgf@xc-\halfangle pt%
+ \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}%
+ \let\cothalfanglein\pgfmathresult%
+ \addtosavedmacro\cothalfanglein%
+ %
+ \pgf@xc90pt\relax%
+ \advance\pgf@xc-\halfangle pt%
+ \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}%
+ \let\cothalfangleout\pgfmathresult%
+ \addtosavedmacro\cothalfangleout%
+ %
+ }%
+ \savedanchor{\centerpoint}{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y-.5\dp\pgfnodeparttextbox%
+ }%
+ \savedanchor{\midpoint}{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@y{+0.5ex}%
+ }%
+ \savedanchor{\basepoint}{%
+ \pgf@x.5\wd\pgfnodeparttextbox%
+ \pgf@y0pt%
+ }%
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\midpoint}%
+ \anchor{mid east}{\tapedimensions\midpoint\advance\pgf@x\outerhalfwidth}%
+ \anchor{mid west}{\tapedimensions\midpoint\advance\pgf@x-\outerhalfwidth}%
+ \anchor{base}{\basepoint}%
+ \anchor{base east}{\tapedimensions\basepoint\advance\pgf@x\outerhalfwidth}%
+ \anchor{base west}{\tapedimensions\basepoint\advance\pgf@x-\outerhalfwidth}%
+ \anchor{north}{%
+ \csname pgf@anchor@tape@north east\endcsname%
+ \pgf@ya\pgf@y%
+ \csname pgf@anchor@tape@north west\endcsname%
+ \advance\pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y.5\pgf@ya%
+ }%
+ \anchor{south}{%
+ \csname pgf@anchor@tape@south east\endcsname%
+ \pgf@ya\pgf@y%
+ \csname pgf@anchor@tape@south west\endcsname%
+ \advance\pgf@ya\pgf@y%
+ \centerpoint%
+ \pgf@y.5\pgf@ya%
+ }%
+ \anchor{east}{%
+ \tapedimensions%
+ \centerpoint%
+ \advance\pgf@x\outerhalfwidth%
+ }%
+ \anchor{west}{%
+ \tapedimensions%
+ \centerpoint%
+ \advance\pgf@x-\outerhalfwidth%
+ }%
+ \anchor{north east}{%
+ \tapedimensions%
+ \centerpoint%
+ \advance\pgf@x\outerhalfwidth%
+ \advance\pgf@y\halfheight%
+ \pgf@yc\outerysep%
+ \ifx\topbendstyle\pgf@lib@sh@inandouttext%
+ \advance\pgf@y\halfbendheight%
+ \advance\pgf@y\cothalfangleout\pgf@yc%
+ \else%
+ \ifx\topbendstyle\pgf@lib@sh@outandintext%
+ \advance\pgf@y\halfbendheight%
+ \advance\pgf@y\cothalfanglein\pgf@yc%
+ \else%
+ \advance\pgf@y\pgf@yc%
+ \fi%
+ \fi%
+ }%
+ \anchor{north west}{%
+ \tapedimensions%
+ \centerpoint%
+ \advance\pgf@x-\outerhalfwidth%
+ \advance\pgf@y\halfheight%
+ \pgf@yc\outerysep%
+ \ifx\topbendstyle\pgf@lib@sh@inandouttext%
+ \advance\pgf@y\halfbendheight%
+ \advance\pgf@y\cothalfanglein\pgf@yc%
+ \else%
+ \ifx\topbendstyle\pgf@lib@sh@outandintext%
+ \advance\pgf@y\halfbendheight%
+ \advance\pgf@y\cothalfangleout\pgf@yc%
+ \else%
+ \advance\pgf@y\pgf@yc%
+ \fi%
+ \fi%
+ }%
+ \anchor{south east}{%
+ \tapedimensions%
+ \centerpoint%
+ \advance\pgf@x\outerhalfwidth%
+ \advance\pgf@y-\halfheight%
+ \pgf@yc\outerysep%
+ \ifx\topbendstyle\pgf@lib@sh@outandintext%
+ \advance\pgf@y-\halfbendheight%
+ \advance\pgf@y-\cothalfangleout\pgf@yc%
+ \else%
+ \ifx\topbendstyle\pgf@lib@sh@inandouttext%
+ \advance\pgf@y-\halfbendheight%
+ \advance\pgf@y-\cothalfanglein\pgf@yc%
+ \else%
+ \advance\pgf@y-\pgf@yc%
+ \fi%
+ \fi%
+ }%
+ \anchor{south west}{%
+ \tapedimensions%
+ \centerpoint%
+ \advance\pgf@x-\outerhalfwidth%
+ \advance\pgf@y-\halfheight%
+ \pgf@yc\outerysep%
+ \ifx\topbendstyle\pgf@lib@sh@outandintext%
+ \advance\pgf@y-\halfbendheight%
+ \advance\pgf@y-\cothalfanglein\pgf@yc%
+ \else%
+ \ifx\topbendstyle\pgf@lib@sh@inandouttext%
+ \advance\pgf@y-\halfbendheight%
+ \advance\pgf@y-\cothalfangleout\pgf@yc%
+ \else%
+ \advance\pgf@y-\pgf@yc%
+ \fi%
+ \fi%
+ }%
+ \backgroundpath{%
+ \tapedimensions%
+ %
+ \pgf@xc\halfwidth%
+ \pgf@yc\halfheight%
+ %
+ \pgf@xc\bendxradius%
+ \pgf@yc\bendyradius%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfqpoint{-\halfwidth}{0pt}}%
+ \pgfpathlineto{\pgfqpoint{-\halfwidth}{\halfheight}}%
+ \ifx\topbendstyle\pgf@lib@sh@inandouttext%
+ \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}%
+ \pgfpatharc{225}{315}{\bendxradius and \bendyradius}%
+ \pgfpatharc{135}{45}{\bendxradius and \bendyradius}%
+ \else%
+ \ifx\topbendstyle\pgf@lib@sh@outandintext%
+ \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}%
+ \pgfpatharc{135}{45}{\bendxradius and \bendyradius}%
+ \pgfpatharc{225}{315}{\bendxradius and \bendyradius}%
+ \else%
+ \pgfpathlineto{\pgfqpoint{\halfwidth}{\halfheight}}%
+ \fi%
+ \fi%
+ \pgfpathlineto{\pgfqpoint{\halfwidth}{-\halfheight}}%
+ \ifx\bottombendstyle\pgf@lib@sh@inandouttext%
+ \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}%
+ \pgfpatharc{45}{135}{\bendxradius and \bendyradius}%
+ \pgfpatharc{315}{225}{\bendxradius and \bendyradius}%
+ \else%
+ \ifx\bottombendstyle\pgf@lib@sh@outandintext%
+ \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}%
+ \pgfpatharc{315}{225}{\bendxradius and \bendyradius}%
+ \pgfpatharc{45}{135}{\bendxradius and \bendyradius}%
+ \else%
+ \pgfpathlineto{\pgfqpoint{-\halfwidth}{-\halfheight}}%
+ \fi%
+ \fi%
+ \pgfpathclose%
+ }%
+ }%
+ \anchorborder{%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfextract@process\externalpoint{%
+ \centerpoint%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+ \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}%
+ \let\externalangle\pgfmathresult%
+ \tapedimensions%
+ %
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north west\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt%
+ \ifdim\externalangle pt<90pt%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north east\endcsname}%
+ \ifdim\externalangle pt<\pgfmathresult pt%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@tape@north east\endcsname}%
+ {\csname pgf@anchor@tape@south east\endcsname}%
+ \else%
+ % Between north and north east.
+ \ifx\topbendstyle\pgf@lib@sh@inandouttext%
+ % in and out.
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x.5\pgf@xc%
+ \advance\pgf@y\halfheight%
+ \advance\pgf@y\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y-.707106\pgf@yc%
+ }%
+ {5}{175}{\outerbendxradius and \outerbendyradius}%
+ \else%
+ \ifx\topbendstyle\pgf@lib@sh@outandintext%
+ % out and in.
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x.5\pgf@xc%
+ \advance\pgf@y\halfheight%
+ \advance\pgf@y\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y.707106\pgf@yc%
+ }%
+ {185}{355}{\innerbendxradius and \innerbendyradius}%
+ \else%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@tape@north east\endcsname}%
+ {\csname pgf@anchor@tape@north west\endcsname}%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ % Between north and north west.
+ \ifx\topbendstyle\pgf@lib@sh@inandouttext%
+ % in and out.
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x-.5\pgf@xc%
+ \advance\pgf@y\halfheight%
+ \advance\pgf@y\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y.707106\pgf@yc%
+ }%
+ {185}{355}{\innerbendxradius and \innerbendyradius}%
+ \else%
+ \ifx\topbendstyle\pgf@lib@sh@outandintext%
+ % out and in.
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x-.5\pgf@xc%
+ \advance\pgf@y\halfheight%
+ \advance\pgf@y\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y-.707106\pgf@yc%
+ }%
+ {5}{175}{\outerbendxradius and \outerbendyradius}%
+ \else%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@tape@north east\endcsname}%
+ {\csname pgf@anchor@tape@north west\endcsname}%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south west\endcsname}%
+ \ifdim\externalangle pt>\pgfmathresult pt%
+ \ifdim\externalangle pt>270pt%
+ \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south east\endcsname}%
+ \ifdim\externalangle pt>\pgfmathresult pt%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@tape@north east\endcsname}%
+ {\csname pgf@anchor@tape@south east\endcsname}%
+ \else%
+ % Between south and south east.
+ \ifx\bottombendstyle\pgf@lib@sh@inandouttext%
+ % in and out.
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x.5\pgf@xc%
+ \advance\pgf@y-\halfheight%
+ \advance\pgf@y-\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y-.707106\pgf@yc%
+ }%
+ {5}{175}{\innerbendxradius and \innerbendyradius}%
+ \else%
+ \ifx\bottombendstyle\pgf@lib@sh@outandintext%
+ % out and in.
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x.5\pgf@xc%
+ \advance\pgf@y-\halfheight%
+ \advance\pgf@y-\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y.707106\pgf@yc%
+ }%
+ {185}{355}{\outerbendxradius and \outerbendyradius}%
+ \else%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@tape@south east\endcsname}%
+ {\csname pgf@anchor@tape@south west\endcsname}%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ % Between south and south west.
+ \ifx\bottombendstyle\pgf@lib@sh@inandouttext%
+ % in and out.
+ \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x-.5\pgf@xc%
+ \advance\pgf@y-\halfheight%
+ \advance\pgf@y-\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y.707106\pgf@yc%
+ }%
+ {185}{355}{\outerbendxradius and \outerbendyradius}%
+ \else%
+ \ifx\bottombendstyle\pgf@lib@sh@outandintext%
+ % out and in.
+ \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}%
+ {%
+ \centerpoint%
+ \pgf@xc\halfwidth%
+ \advance\pgf@x-.5\pgf@xc%
+ \advance\pgf@y-\halfheight%
+ \advance\pgf@y-\halfbendheight%
+ \pgf@yc\bendyradius%
+ \advance\pgf@y-.707106\pgf@yc%
+ }%
+ {5}{175}{\innerbendxradius and \innerbendyradius}%
+ \else%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@tape@south east\endcsname}%
+ {\csname pgf@anchor@tape@south west\endcsname}%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \pgfpointintersectionoflines{\externalpoint}{\centerpoint}%
+ {\csname pgf@anchor@tape@north west\endcsname}%
+ {\csname pgf@anchor@tape@south west\endcsname}%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+
+
+% Keys for magnifying glass shape
+%
+% /pgf/magnifying glass handle angle : The angle of handle
+% /pgf/magnifying glass handle aspect : The length of the handle as a multiple
+% of the radius of the circle
+%
+
+\pgfkeys{/pgf/.cd,
+ magnifying glass handle angle/.initial=-45,
+ magnifying glass handle aspect/.initial=1.5,
+}%
+
+\pgfdeclareshape{magnifying glass}
+{%
+ \inheritsavedanchors[from=circle]% this is nearly a circle
+ \inheritanchorborder[from=circle]%
+ \inheritanchor[from=circle]{north}%
+ \inheritanchor[from=circle]{north west}%
+ \inheritanchor[from=circle]{north east}%
+ \inheritanchor[from=circle]{center}%
+ \inheritanchor[from=circle]{west}%
+ \inheritanchor[from=circle]{east}%
+ \inheritanchor[from=circle]{mid}%
+ \inheritanchor[from=circle]{mid west}%
+ \inheritanchor[from=circle]{mid east}%
+ \inheritanchor[from=circle]{base}%
+ \inheritanchor[from=circle]{base west}%
+ \inheritanchor[from=circle]{base east}%
+ \inheritanchor[from=circle]{south}%
+ \inheritanchor[from=circle]{south west}%
+ \inheritanchor[from=circle]{south east}%
+ \inheritbackgroundpath[from=circle]%
+ \foregroundpath{
+ \centerpoint%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}
+ {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima}}}
+ \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}
+ {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima+\pgfutil@tempdima*(\pgfkeysvalueof{/pgf/magnifying glass handle aspect})}}}
+ \pgfsetarrowsstart{}
+ \pgfsetarrowsend{}
+ }%
+}%
+
+
+\pgfkeys{%
+ /pgf/magnetic tape tail/.initial=0.15,
+ /pgf/magnetic tape tail extend/.initial=0cm,
+}%
+\pgfdeclareshape{magnetic tape}{%
+ \nodeparts{text}%
+ \savedmacro\installparameters{%
+ %
+ \pgf@x=0.5\wd\pgfnodeparttextbox%
+ \pgf@y=0.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by-0.5\dp\pgfnodeparttextbox%
+ \edef\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ %
+ \pgf@x=\wd\pgfnodeparttextbox%
+ \pgf@y=\ht\pgfnodeparttextbox%
+ \advance\pgf@y by\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@x by2.0\pgf@xa%
+ \advance\pgf@y by2.0\pgf@ya%
+ \ifdim\pgf@y>\pgf@x%
+ \pgf@x=\pgf@y%
+ \fi%
+ \pgf@x=1.414213\pgf@x%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<\pgf@xa%
+ \pgf@x=\pgf@xa%
+ \fi%
+ \ifdim\pgf@x<\pgf@ya%
+ \pgf@x=\pgf@ya%
+ \fi%
+ \pgf@x=0.5\pgf@x%
+ \edef\radius{\the\pgf@x}%
+ %
+ \pgfmathparse{max(\pgfkeysvalueof{/pgf/magnetic tape tail extend},0)}%
+ \edef\tailextend{\pgfmathresult pt}%
+ %
+ \pgfmathparse{min(max(\pgfkeysvalueof{/pgf/magnetic tape tail},0),1)}%
+ \pgf@xa=\pgfmathresult\pgf@x%
+ \edef\tailheight{\the\pgf@xa}%
+ %
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xa<\pgf@ya%
+ \pgf@xa=\pgf@ya%
+ \fi%
+ \edef\outersep{\the\pgf@xa}%
+ %
+ \pgfmathparse{\outersep+\radius}%
+ \edef\outerradius{\pgfmathresult pt}%
+ %
+ \pgfmathparse{(\radius-\tailheight)/\radius}%
+ \pgfmathasin@{\pgfmathresult}%
+ \pgfmathadd@{-\pgfmathresult}{360}%
+ \let\tailangle=\pgfmathresult%
+ %
+ \pgfmathparse{\outerradius/(\outerradius+\tailextend)}%
+ \pgfmathatan@{\pgfmathresult}%
+ \pgfmathadd@{-\pgfmathresult}{360}%
+ \let\tailbottomangle=\pgfmathresult%
+ %
+ \pgfmathparse{(\outerradius-\outersep-\tailheight-\outersep)/(\outerradius+\tailextend)}%
+ \pgfmathatan@{\pgfmathresult}%
+ \pgfmathadd@{-\pgfmathresult}{360}%
+ \let\tailtopangle=\pgfmathresult%
+ %
+ \addtosavedmacro\radius%
+ \addtosavedmacro\outerradius%
+ \addtosavedmacro\outersep%
+ \addtosavedmacro\tailheight%
+ \addtosavedmacro\tailextend
+ \addtosavedmacro\tailangle%
+ \addtosavedmacro\tailtopangle%
+ \addtosavedmacro\tailbottomangle%
+ \addtosavedmacro\centerpoint%
+ }%
+ \savedanchor{\base}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}}%
+ \savedanchor{\mid}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{center}{\installparameters\centerpoint}% \addtosavedmacro\outerradius%
+ \anchor{base}{\base}%
+ \anchor{mid}{\mid}%
+ \anchor{base west}{\installparameters\pgfpointadd{\base}{\pgfqpoint{-\outerradius}{0pt}}}%
+ \anchor{base east}{\installparameters\pgfpointadd{\base}{\pgfqpoint{\outerradius}{0pt}}}%
+ \anchor{mid west}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{-\outerradius}{0pt}}}%
+ \anchor{mid east}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{\outerradius}{0pt}}}%
+ \anchor{north}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{\outerradius}}}%
+ \anchor{north east}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpointpolar{45}{\outerradius}}}%
+ \anchor{south}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{-\outerradius}}}%
+ \anchor{south east}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{-\outerradius}}}%
+ \anchor{east}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{0pt}}}%
+ \anchor{south west}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpointpolar{225}{\outerradius}}}%
+ \anchor{west}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpoint{-\outerradius}{0pt}}}%
+ \anchor{north west}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfqpointpolar{135}{\outerradius}}}%
+ \anchor{tail east}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight/2}}}%
+ \anchor{tail south east}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius}}}%
+ \anchor{tail north east}{\installparameters%
+ \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight+\outersep}}}%
+ \backgroundpath{
+ %
+ \installparameters%
+ {%
+ \pgftransformshift{\centerpoint}%
+ \pgfpathmoveto{\pgfpointpolar{\tailangle}{\radius}}%
+ \pgfpatharc{\tailangle}{360}{\radius}%
+ \pgfpatharc{0}{270}{\radius}%
+ \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius}}%
+ \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius+\tailheight}}%
+ \pgfpathclose%
+ }%
+ }%
+ \anchorborder{%
+ \pgfextract@process\externalpoint{}%
+ \installparameters%
+ \pgfmathanglebetweenpoints{\pgfpointorigin}{\externalpoint}
+ \ifdim\pgfmathresult pt<270pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointborderellipse%
+ {\externalpoint}%
+ {\pgfqpoint{\outerradius}{\outerradius}}%
+ }%
+ \else%
+ \ifdim\pgfmathresult pt<\tailbottomangle pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointintersectionoflines%
+ {\externalpoint}{\pgfpointorigin}%
+ {\pgfqpoint{0pt}{-\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}%
+ }%
+ \else%
+ \ifdim\pgfmathresult pt<\tailtopangle pt\relax%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointintersectionoflines%
+ {\externalpoint}{\pgfpointorigin}%
+ {\pgfqpoint{\outerradius}{\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}%
+ }%
+ \else%
+ \pgfpointadd{\centerpoint}{%
+ \pgfpointborderellipse%
+ {\externalpoint}%
+ {\pgfqpoint{\outerradius}{\outerradius}}%
+ }%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+% Local Variables:
+% tab-width: 2
+% End:
diff --git a/graphics/pgf/base/tex/generic/lua/pgf/manual.lua b/graphics/pgf/base/tex/generic/lua/pgf/manual.lua
new file mode 100644
index 0000000000..7142eea3ec
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/lua/pgf/manual.lua
@@ -0,0 +1,18 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+local manual = {}
+
+require 'pgf'.manual = manual
+
+return manual
diff --git a/graphics/pgf/base/tex/generic/lua/pgf/manual/DocumentParser.lua b/graphics/pgf/base/tex/generic/lua/pgf/manual/DocumentParser.lua
new file mode 100644
index 0000000000..bd2a7026a4
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/lua/pgf/manual/DocumentParser.lua
@@ -0,0 +1,613 @@
+-- Copyright 2013 by Till Tantau
+--
+-- This file may be distributed an/or modified
+--
+-- 1. under the LaTeX Project Public License and/or
+-- 2. under the GNU Public License
+--
+-- See the file doc/generic/pgf/licenses/LICENSE for more information
+
+-- @release $Header$
+
+
+
+---
+-- This class offers functions for converting the documentation of Lua
+-- and other code into \TeX.
+--
+-- @field renderers This array must consist of tables having two
+-- fields: |test| and |renderer|. The first must be set to a function
+-- that is called with an information table as parameter and must
+-- return |true| if the function stored in the |renderer| should be
+-- called. (Typically, the |test| will test whether the ``head line''
+-- following a documentation block has a special form.)
+
+local DocumentParser = {
+ renderers = {}
+}
+
+-- Namespace:
+require 'pgf.manual'.DocumentParser = DocumentParser
+
+-- Imports
+local keys = require 'pgf.gd.interface.InterfaceCore'.keys
+
+-- Forwards:
+
+local collect_infos, render_infos
+
+
+---
+-- Includes the documentation stored in some file in the manual.
+--
+-- @param filename The file from which the documentation is to be read
+-- @param type The type of the file.
+
+function DocumentParser.include(filename, typ)
+
+ local fullname = assert(kpse.find_file(filename:gsub("%.", "/"), typ or "lua")
+ or kpse.find_file(filename:gsub("%.", "\\"), typ or "lua"),
+ "file " .. filename .. " not found")
+
+ local file, error = io.open(fullname)
+
+ -- First, let us read the file into a table to make handling easier:
+ local lines = {}
+
+ for line in file:lines() do
+ lines [#lines + 1] = line
+ end
+
+ -- A table storing the current output. The array part contains TeX
+ -- lines, the table part contains information about special table.s
+ local output = {}
+
+ -- Now, start the main parser loop.
+ local i = 1
+ while i <= #lines do
+
+ if lines[i]:match("^%-%-%-") then
+ local infos = collect_infos (lines, i)
+
+ infos.filename = filename
+
+ render_infos(infos, output)
+
+ i = infos.last_line
+ end
+
+ i = i + 1
+ end
+
+ -- Render output:
+ for _,l in ipairs(output) do
+ if type(l) == "string" then
+ tex.print(l)
+ else
+ l()
+ end
+ end
+
+end
+
+
+
+---
+-- Add a test and a renderer to the array of renderers.
+--
+-- @param test A test function (see |DocumentParser.renderers|).
+-- @param renderer A rendering function.
+
+function DocumentParser.addRenderer (test, renderer)
+ DocumentParser.renderers [#DocumentParser.renderers + 1] =
+ { test = test, renderer = renderer }
+end
+
+
+-- Forwards:
+local print_on_output, print_on_output_escape, print_docline_on_output, open_mode, close_mode, print_lines_on_output
+
+
+
+local function strip_quotes(s)
+ if s then return string.gsub(s, '^"(.*)"$', "%1") end
+end
+
+local function split(s)
+ local t = {}
+ for line in string.gmatch(s, ".-\n") do
+ t[#t+1] = line
+ end
+ for i=#t,1,-1 do
+ if t[i]:match("^%s*$") then
+ t[i] = nil
+ else
+ return t
+ end
+ end
+ return t
+end
+
+
+local function process_string(s)
+ if s then
+ local t = split(s.."\n")
+ -- Compute min spaces
+ local min = math.huge
+ for _,l in ipairs(t) do
+ min = math.min(min, string.find(l, "%S") or math.huge)
+ end
+ if min < math.huge then
+ -- Now, trim 'em all!
+ for i=1,#t do
+ t[i] = string.sub(t[i],min,-2)
+ end
+ end
+ return t
+ end
+end
+
+
+local function process_examples(t)
+ if not t then
+ return nil
+ end
+
+ if type(t) == "string" then
+ t = {t}
+ end
+
+ local n = {}
+ for i=1,#t do
+ local code, options
+ if type(t[i]) == "table" then
+ code = assert(t[i].code)
+ options = t[i].options
+ else
+ code = t[i]
+ end
+ n[i] = {
+ options = process_string(strip_quotes(options)),
+ code = process_string(strip_quotes(code))
+ }
+ end
+ return n
+end
+
+
+
+-- The standard renderers:
+
+
+-- The function renderer
+DocumentParser.addRenderer (
+ function (infos)
+ -- The test
+ return
+ infos.keywords["function"] or
+ infos.head_line:match("^%s*function%s+") or
+ infos.head_line:match("^%s*local%s+function%s+")
+ end,
+ function (infos, output)
+ -- The renderer
+
+ if infos.keywords["function"] then
+ local k = infos.keywords["function"][1]
+ infos.head_line = k:match("^%s*@(.*)")
+ end
+
+ local rest = infos.head_line:match("function%s+(.*)")
+ local tab = rest:match("([^(]*[%.%:]).*")
+ local fun = rest:match("[^(]*[%.%:](.-)%s*%(") or rest:match("(.-)%s*%(")
+ local pars = rest:match(".-%((.*)%)")
+
+ -- Render the head
+ print_on_output_escape(output, [[\begin{luacommand}]])
+ output[#output+1] = "{" .. (tab or "") .. fun .. "}"
+ print_on_output_escape(output,
+ "{", tab or "", "}",
+ "{", fun, "}",
+ "{", pars, "}")
+
+ if tab then
+ local table_name = tab:sub(1,-2)
+ local t = output[table_name] or {}
+ t[#t+1] = {
+ link = "pgf/lua/" .. tab .. fun,
+ text = "function " .. tab .. "\\declare{" .. fun .. "} (" .. pars .. ")"
+ }
+ output[table_name] = t
+ end
+
+ local mode = "text"
+ for _,l in ipairs(infos.doc_lines) do
+ if mode ~= "done" then
+ mode = print_docline_on_output(output, l, mode)
+ end
+ end
+ close_mode(output, mode)
+
+ print_on_output(output, [[\end{luacommand}]])
+
+ end
+)
+
+
+-- The table renderer
+DocumentParser.addRenderer (
+ function (infos)
+ -- The test
+ return
+ infos.keywords["table"] or
+ infos.head_line:match("=%s*{")
+ end,
+ function (infos, output)
+ -- The renderer
+
+ if infos.keywords["table"] then
+ local k = infos.keywords["table"][1]
+ infos.head_line = k:match("^%s*@table(.*)") .. "="
+ end
+
+ local name =
+ infos.head_line:match("^%s*local%s+(.-)%s*=") or
+ infos.head_line:match("^%s*(.*)%s*=")
+
+ -- Render the head
+ print_on_output_escape(output,
+ [[\begin{luatable}]],
+ "{", name:match("(.*[%.%:]).*") or "", "}",
+ "{", name:match(".*[%.%:](*-)") or name,"}",
+ "{", infos.filename, "}")
+
+ local mode = "text"
+ for _,l in ipairs(infos.doc_lines) do
+ mode = print_docline_on_output(output, l, mode)
+ end
+ close_mode(output, mode)
+
+ output[#output+1] =
+ function ()
+ if output[name] then
+ tex.print("\\par\\emph{Alphabetical method summary:}\\par{\\small")
+ table.sort(output[name], function (a,b) return a.text < b.text end)
+ for _,l in ipairs(output[name]) do
+ tex.print("\\texttt{\\hyperlink{" .. l.link .. "}{" .. l.text:gsub("_", "\\_") .. "}}\\par")
+ end
+ tex.print("}")
+ end
+ end
+
+ print_on_output(output, [[\end{luatable}]])
+
+ end
+)
+
+
+
+-- The library renderer
+DocumentParser.addRenderer (
+ function (infos)
+ -- The test
+ return infos.keywords["library"]
+ end,
+ function (infos, output)
+ -- The renderer
+
+ local name = infos.filename:gsub("%.library$",""):gsub("^pgf%.gd%.","")
+
+ -- Render the head
+ print_on_output_escape(output, "\\begin{lualibrary}{", name, "}")
+
+ local mode = "text"
+ for _,l in ipairs(infos.doc_lines) do
+ mode = print_docline_on_output(output, l, mode)
+ end
+ close_mode(output, mode)
+
+ print_on_output(output, "\\end{lualibrary}")
+
+ end
+)
+
+
+-- The section renderer
+DocumentParser.addRenderer (
+ function (infos)
+ -- The test
+ return infos.keywords["section"]
+ end,
+ function (infos, output)
+ -- The renderer
+ local mode = "text"
+ for _,l in ipairs(infos.doc_lines) do
+ mode = print_docline_on_output(output, l, mode)
+ end
+ close_mode(output, mode)
+ end
+)
+
+
+-- The documentation (plain text) renderer
+DocumentParser.addRenderer (
+ function (infos)
+ -- The test
+ return infos.keywords["documentation"]
+ end,
+ function (infos, output)
+ -- The renderer
+ local mode = "text"
+ for _,l in ipairs(infos.doc_lines) do
+ mode = print_docline_on_output(output, l, mode)
+ end
+ close_mode(output, mode)
+ end
+)
+
+
+-- The declare renderer
+DocumentParser.addRenderer (
+ function (infos)
+ -- The test
+ return
+ infos.keywords["declare"] or
+ infos.head_line:match("declare%s*{") or
+ infos.head_line:match("^%s*key%s*")
+ end,
+ function (infos, output)
+ -- The renderer
+
+ local key_name
+
+ if infos.keywords["declare"] then
+ local k = infos.keywords["declare"][1]
+ key_name = k:match("^%s*@declare%s*(.*)")
+ elseif infos.head_line:match("^%s*key%s*") then
+ key_name = infos.head_line:match('^%s*key%s*"(.*)"') or
+ infos.head_line:match("^%s*key%s*'(.*)'")
+ else
+ local l = infos.lines [infos.last_line + 1]
+ key_name = l:match('key%s*=%s*"(.*)"') or l:match("key%s*=%s*'(.*)'")
+ end
+
+ assert (key_name, "could not determine key")
+ local key = assert (keys[key_name], "unknown key '" .. key_name .. "'")
+
+ -- Render the head
+ if key.type then
+ print_on_output_escape(output,
+ "\\begin{luadeclare}",
+ "{", key.key, "}",
+ "{\\meta{", key.type, "}}",
+ "{", key.default or "", "}",
+ "{", key.initial or "", "}")
+ else
+ print_on_output_escape(output,
+ "\\begin{luadeclarestyle}",
+ "{", key.key, "}",
+ "{}",
+ "{", key.default or "", "}",
+ "{", key.initial or "", "}")
+ end
+
+
+ local mode = "text"
+
+ print_lines_on_output(output, process_string(strip_quotes(key.summary)))
+ print_lines_on_output(output, process_string(strip_quotes(key.documentation)))
+
+ if key.examples then
+ local e = process_examples(key.examples)
+ print_on_output(output,
+ "\\par\\smallskip\\emph{Example" .. (((#e>1) and "s") or "") .. "}\\par")
+ for _,example in ipairs(e) do
+ local opts = table.concat(example.options or {}, "")
+ print_on_output(output, "\\begin{codeexample}[" .. opts .. "]")
+ print_lines_on_output(output, example.code)
+ print_on_output(output, "\\end{codeexample}")
+ end
+ end
+
+ print_on_output(output, key.type and "\\end{luadeclare}" or "\\end{luadeclarestyle}")
+ end
+)
+
+
+
+-- The empty line
+DocumentParser.addRenderer (
+ function (infos)
+ -- The test
+ return
+ #infos.doc_lines == 1 and
+ infos.doc_lines[1]:match("^%-*%s*$")
+ end,
+ function (infos, output)
+ end
+)
+
+
+function print_lines_on_output(output, lines)
+ for n,l in ipairs(lines or {}) do
+ if (n == 1 or n == #lines) and l == "" then
+ -- skip leading and trailing blank lines
+ else
+ output[#output+1] = l
+ end
+ end
+end
+
+function print_on_output(output, ...)
+ local args = {...}
+ if #args > 0 then
+ for i = 1, #args do
+ args[i] = tostring(args[i])
+ end
+ output[#output+1] = table.concat(args)
+ end
+end
+
+function print_on_output_escape(output, ...)
+ local args = {...}
+ if #args > 0 then
+ for i = 1, #args do
+ args[i] = tostring(args[i]):gsub("_", "\\_")
+ end
+ output[#output+1] = table.concat(args)
+ end
+end
+
+
+function print_docline_on_output(output, l, mode)
+
+ if l:match("^%s*@section") then
+ print_on_output(output, "\\", l:match("%s*@section%s*(.*)"))
+ elseif l:match("^%s*@param%s+") then
+ if mode ~= "param" then
+ close_mode (output, mode)
+ mode = open_mode (output, "param")
+ end
+ print_on_output(output, "\\item[\\texttt{",
+ l:match("%s@param%s+(.-)%s"):gsub("_", "\\_"),
+ "}] ",
+ l:match("%s@param%s+.-%s+(.*)"))
+ elseif l:match("^%s*@return%s+") then
+ if mode ~= "return" then
+ close_mode (output, mode)
+ mode = open_mode (output, "returns")
+ end
+ print_on_output(output, "\\item[]", l:match("%s@return%s+(.*)"))
+ elseif l:match("^%s*@see%s+") then
+ if mode ~= "text" then
+ close_mode (output, mode)
+ mode = open_mode (output, "text")
+ end
+ print_on_output(output, "\\par\\emph{See also:} \\texttt{",
+ l:match("%s@see%s+(.*)"):gsub("_", "\\_"),
+ "}")
+ elseif l:match("^%s*@usage%s+") then
+ if mode ~= "text" then
+ close_mode (output, mode)
+ mode = open_mode (output, "text")
+ end
+ print_on_output(output, "\\par\\emph{Usage:} ",
+ l:match("%s@usage%s+(.*)"))
+ elseif l:match("^%s*@field+") then
+ close_mode (output, mode)
+ mode = open_mode (output, "field")
+ print_on_output(output, "{",
+ (l:match("%s@field%s+(.-)%s") or l:match("%s@field%s+(.*)")):gsub("_", "\\_"),
+ "}",
+ l:match("%s@field%s+.-%s+(.*)"))
+ elseif l:match("^%s*@done") or l:match("^%s*@text") then
+ close_mode(output, mode)
+ print_on_output(output, l)
+
+ mode = "text"
+ elseif l:match("^%s*@library") then
+ -- do nothing
+ elseif l:match("^%s*@function") then
+ -- do nothing
+ elseif l:match("^%s*@end") then
+ close_mode(output, mode)
+ mode = "done"
+ elseif l:match("^%s*@") then
+ error("Unknown mark " .. l)
+ else
+ print_on_output(output, l)
+ end
+
+ return mode
+end
+
+function open_mode (output, mode)
+ if mode == "param" then
+ print_on_output(output, "\\begin{luaparameters}")
+ elseif mode == "field" then
+ print_on_output(output, "\\begin{luafield}")
+ elseif mode == "returns" then
+ print_on_output(output, "\\begin{luareturns}")
+ end
+ return mode
+end
+
+function close_mode (output, mode)
+ if mode == "param" then
+ print_on_output(output, "\\end{luaparameters}")
+ elseif mode == "field" then
+ print_on_output(output, "\\end{luafield}")
+ elseif mode == "returns" then
+ print_on_output(output, "\\end{luareturns}")
+ end
+ return mode
+end
+
+
+function collect_infos (lines, i, state)
+
+ local doc_lines = {}
+
+ local keywords = {}
+
+ local function find_keywords(line)
+ local keyword = line:match("^%s*@([^%s]*)")
+ if keyword then
+ local t = keywords[keyword] or {}
+ t[#t+1] = line
+ keywords[keyword] = t
+ end
+ return line
+ end
+
+ -- Copy triple matches:
+ while lines[i] and lines[i]:match("^%-%-%-") do
+ doc_lines [#doc_lines + 1] = find_keywords(lines[i]:sub(4))
+ i = i + 1
+ end
+
+ -- Continue with double matches:
+ while lines[i] and lines[i]:match("^%-%-") do
+ doc_lines [#doc_lines + 1] = find_keywords(lines[i]:sub(3))
+ i = i + 1
+ end
+
+ local head_line = ""
+
+ if not keywords["end"] then
+ -- Skip empty lines
+ while lines[i] and lines[i]:match("^%s*$") do
+ i = i + 1
+ end
+ head_line = lines[i] or ""
+ if lines[i] and lines[i]:match("^%-%-%-") then
+ i = i - 1
+ end
+ end
+
+ return {
+ lines = lines,
+ last_line = i,
+ doc_lines = doc_lines,
+ keywords = keywords,
+ head_line = head_line
+ }
+
+end
+
+
+
+function render_infos(infos, state)
+
+ for _,renderer in ipairs(DocumentParser.renderers) do
+ if renderer.test (infos, state) then
+ renderer.renderer (infos, state)
+ return
+ end
+ end
+
+ pgf.debug(infos)
+ error("Unknown documentation type")
+end
+
+
+return DocumentParser
diff --git a/graphics/pgf/base/tex/generic/math/pgfint.code.tex b/graphics/pgf/base/tex/generic/math/pgfint.code.tex
new file mode 100644
index 0000000000..8921ee5fbd
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfint.code.tex
@@ -0,0 +1,126 @@
+% Copyright 2019 by Henri Menke
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+% Guard against reading twice
+\ifx\pgfintloaded\pgfutil@undefined
+ \let\pgfintloaded=\relax
+\else
+ \expandafter\endinput
+\fi
+
+% This module is pretty much a rip-off of the LaTeX3 l3int module for integer
+% calculations. Since PGF supports e-TeX now, we can make use of those
+% extended facilities.
+
+% In contrast to l3int we will just admit that integers are regular TeX \count
+% register and will not implement an extra "integer datatype".
+
+% Evaluate an integer expression using \numexpr
+\def\pgfinteval#1{\number\numexpr#1\relax}
+
+% Get the absolute value of an integer by stripping off a leading minus sign
+\def\pgfintabs#1{\number\expandafter\pgfint@abs\number\numexpr#1\relax}
+\def\pgfint@abs#1{\ifx-#1\else\expandafter#1\fi}
+
+% Minimum and maximum
+\def\pgfintmax#1#2{%
+ \number\expandafter\pgfint@minmax
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ >
+}
+\def\pgfintmin#1#2{%
+ \number\expandafter\pgfint@minmax
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ <
+}
+\def\pgfint@minmax#1;#2;#3{%
+ \ifnum#1#3#2
+ #1%
+ \else
+ #2%
+ \fi
+}
+
+% \numexpr has the annoying property to round divisions rather than truncating
+% (as you would expect for integer arithmetic). Therefore we need a truncating
+% division function.
+\def\pgfintdivtruncate#1#2{%
+ \number\numexpr\expandafter\pgfint@divtruncate
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ \relax
+}
+\def\pgfint@divtruncate#1#2;#3#4;{%
+ \ifx0#1
+ 0%
+ \else
+ (#1#2%
+ \ifx-#1 +\else-\fi
+ (\ifx-#3 -\fi#3#4-1)/2%
+ )%
+ \fi
+ /#3#4%
+}
+
+% \pgfintdivtruncate always truncates the result which leads to a rounding
+% towards zero. Donald Knuth defines in TAoCP, Vol 1, 3rd Ed, Section 1.2.4
+% that the modulo operation is
+%
+% x mod y = x - y * floor(x/y)
+%
+% In contrast to truncated division, floored division always rounds towards
+% -inf, i.e. floor(1/2) = 0 and floor(-1/2) = -1. This is also how integer
+% division is done in Lua.
+\def\pgfintdivfloor#1#2{%
+ \number\numexpr\expandafter\pgfint@divfloor
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ \relax
+}
+\def\pgfint@divfloor#1#2;#3#4;{%
+ \ifx0#1
+ 0%
+ \else
+ \ifnum
+ 0\ifx-#1\ifx#3-\else1\fi\fi
+ 0\ifx-#3\ifx#1-\else1\fi\fi
+ >0
+ \pgfint@@divfloor#1#2;#3#4;-+%
+ \else
+ \pgfint@@divfloor#1#2;#3#4;+-%
+ \fi
+ \fi
+ /#3#4%
+}
+\def\pgfint@@divfloor#1#2;#3#4;#5#6{%
+ (#1#2%
+ \ifx-#1 #5\else#6\fi
+ (\ifx-#3 -\fi#3#4#61)/2%
+ )%
+}
+
+% Round
+\def\pgfintdivround#1#2{\number\numexpr(#1)/(#2)\relax}
+
+% Modulo
+\def\pgfintmod#1#2{%
+ \number\numexpr\expandafter\pgfint@mod%
+ \number\numexpr#1\expandafter;%
+ \number\numexpr#2;%
+ \relax
+}
+\def\pgfint@mod#1;#2;{#1-(\pgfint@divfloor#1;#2;)*#2}
+
+% Setter function so we don't always have to write \pgfinteval
+\def\pgfintset#1#2{#1 \numexpr#2\relax}
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/math/pgfmath.code.tex b/graphics/pgf/base/tex/generic/math/pgfmath.code.tex
new file mode 100644
index 0000000000..fd40a36d59
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmath.code.tex
@@ -0,0 +1,37 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+% Guard against reading twice
+\ifx\pgfmathloaded\pgfutil@undefined
+ \let\pgfmathloaded=\relax
+\else
+ \expandafter\endinput
+\fi
+
+% We need keys:
+\ifx\pgfkeysloaded\pgfutil@undefined
+ \input pgfkeys.code.tex
+\fi
+
+\input pgfmathutil.code.tex
+\input pgfmathparser.code.tex
+\input pgfmathfunctions.code.tex
+\input pgfmathfunctions.basic.code.tex
+\input pgfmathfunctions.trigonometric.code.tex
+\input pgfmathfunctions.random.code.tex
+\input pgfmathfunctions.comparison.code.tex
+\input pgfmathfunctions.base.code.tex
+\input pgfmathfunctions.round.code.tex
+\input pgfmathfunctions.misc.code.tex
+\input pgfmathfunctions.integerarithmetics.code.tex
+\input pgfmathcalc.code.tex
+\input pgfmathfloat.code.tex
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex
new file mode 100644
index 0000000000..1e854864d8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathcalc.code.tex
@@ -0,0 +1,537 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file loads all the parsing, functions and operator stuff
+%
+% Version 1.414213 29/9/2007
+
+% \pgfmathsetlength, \pgfmathaddtolength
+%
+% #1 = dimension register
+% #2 = expression
+%
+% Description:
+%
+% These functions work similar to \setlength and \addtolength. Only,
+% they allow #2 to contain an expression, which is evaluated before
+% assignment. Furthermore, the font is setup before the assignment is
+% done, so that dimensions like 1em are evaluated correctly.
+%
+% If #2 starts with "+", then a simple assignment is done (but the
+% font is still setup). This is orders of magnitude faster than a
+% parsed assignment.
+
+\def\pgfmathsetlength#1#2{%
+ \expandafter\pgfmath@onquick#2\pgfmath@%
+ {%
+ % Ok, quick version:
+ \begingroup%
+ \pgfmath@selectfont%
+ #1#2\unskip%
+ \expandafter\endgroup%
+ \expandafter#1\the#1\relax%
+ }%
+ {%
+ \pgfmathparse{#2}%
+ \ifpgfmathmathunitsdeclared%
+ #1\pgfmathresult mu\relax%
+ \else%
+ #1\pgfmathresult pt\relax%
+ \fi%
+ }%
+ \ignorespaces%
+}
+
+% \pgfmathaddtolength
+%
+% Add to #1 the result of evaluating #2.
+%
+% #1 - a dimension register
+% #2 - an expression
+%
+\def\pgfmathaddtolength#1#2{%
+ \expandafter\pgfmath@onquick#2\pgfmath@%
+ {%
+ \begingroup%
+ \pgfmath@selectfont%
+ \advance#1#2\unskip%
+ \expandafter%
+ \endgroup%
+ \expandafter#1\the#1\relax%
+ }%
+ {%
+ \pgfmathparse{#2}%
+ \ifpgfmathmathunitsdeclared%
+ \advance#1\pgfmathresult mu\relax%
+ \else%
+ \advance#1\pgfmathresult pt\relax%
+ \fi%
+ }%
+ \ignorespaces%
+}
+
+% \pgfmathsetcount
+%
+% Assign #1 the truncated evaluation of #2.
+%
+% #1 - a count register
+% #2 - an expression
+%
+\def\pgfmathsetcount#1#2{%
+ \expandafter\pgfmath@onquick#2\pgfmath@%
+ {%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ #1#2\relax\pgfmath@%
+ }%
+ {%
+ \pgfmathparse{#2}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ #1\pgfmathresult\relax\pgfmath@%
+ }%
+ \ignorespaces%
+}
+
+% \pgfmathaddtocount
+%
+% Add to #1 the truncated evaluation of #2.
+%
+% #1 - a count register
+% #2 - an expression
+%
+\def\pgfmathaddtocount#1#2{%
+ \expandafter\pgfmath@onquick#2\pgfmath@%
+ {%
+ \edef\pgfmath@addtocounttemp{\the#1}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ #1#2\relax\pgfmath@%
+ \advance#1\pgfmath@addtocounttemp\relax%
+ }%
+ {%
+ \edef\pgfmath@addtocounttemp{\the#1}%
+ \pgfmathparse{#2}%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ #1\pgfmathresult\relax\pgfmath@%
+ \advance#1\pgfmath@addtocounttemp\relax%
+ }%
+ \ignorespaces%
+}
+
+% \pgfmathnewcounter
+%
+% LaTeX style counter which also works in plain TeX. Defines
+% \c@<name> as a count register and also defines \the<name>.
+%
+% #1 the name of the counter.
+%
+% Example:
+%
+% \pgfmathnewcounter{counter}
+% \pgfmathsetcounter{counter}{12}
+% \thecounter (same as \the\c@counter)
+%
+\def\pgfmathnewcounter#1{%
+ \expandafter\ifx\csname c@#1\endcsname\relax%
+ \def\pgfmath@marshal{\csname newcount\endcsname}% Ha! Who cares about \outer?
+ \expandafter\pgfmath@marshal\csname c@#1\endcsname%
+ \expandafter\def\csname the#1\endcsname{\expandafter\the\csname c@#1\endcsname}%
+ \fi%
+}
+
+% \pgfmathsetcounter
+%
+% Set the counter #1 to the evaluation of #2.
+%
+% #1 - a counter name
+% #2 - an expression
+%
+\def\pgfmathsetcounter#1#2{%
+ \expandafter\pgfmathsetcount\csname c@#1\endcsname{#2}%
+}
+
+% \pgfmathaddtocounter
+%
+% Add the counter #1 to the evaluation of #2.
+%
+% #1 - a counter name
+% #2 - an expression
+%
+\def\pgfmathaddtocounter#1#2{%
+ \expandafter\pgfmathaddtocount\csname c@#1\endcsname{#2}%
+}
+
+% \pgfmathmakecounterglobal
+%
+% Make the current value of a counter globally defined.
+%
+% #1 - a (valid) counter name.
+%
+\def\pgfmath@pgftext{pgf}
+\def\pgfmath@tikztext{tikz}
+\def\pgfmathmakecounterglobal#1{%
+ \pgfmath@ifundefined{c@#1}{}{%
+ \expandafter\pgfmath@in@\expandafter{\pgfmath@pgftext}{#1}%
+ \ifpgfmath@in@%
+ \else%
+ \expandafter\pgfmath@in@\expandafter{\pgfmath@tikztext}{#1}%
+ \ifpgfmath@in@%
+ \else%
+ \expandafter\global\csname c@#1\endcsname\csname c@#1\endcsname\relax%
+ \fi%
+ \fi%
+ }%
+}
+
+% \pgfmathsetmacro
+%
+% \edef#1 as the result of evaluating #2.
+%
+% #1 - a macro
+% #2 - an expression
+%
+\def\pgfmathsetmacro#1#2{%
+ \begingroup%
+ \pgfmathparse{#2}%
+ \let#1=\pgfmathresult
+ \pgfmath@smuggleone{#1}%
+ \endgroup%
+}
+
+% \pgfmathsetlengthmacro
+%
+% \edef#1 as the result of evaluating #2 with pt.
+%
+% #1 - a macro
+% #2 - an expression
+%
+\def\pgfmathsetlengthmacro#1#2{%
+ \begingroup%
+ \pgfmathsetlength\pgfmath@x{#2}%
+ \edef#1{\the\pgfmath@x}%
+ \pgfmath@smuggleone{#1}%
+ \endgroup%
+}
+
+% \pgfmathtruncatemacro
+%
+% \edef#1 as the truncated result of evaluating #2.
+%
+% #1 - a macro
+% #2 - an expression
+%
+\def\pgfmathtruncatemacro#1#2{%
+ \begingroup%
+ \pgfmathsetcount\c@pgfmath@counta{#2}%
+ \edef#1{\the\c@pgfmath@counta}%
+ \pgfmath@smuggleone{#1}%
+ \endgroup%
+}
+
+% Check whether a given parameter starts with quick.
+%
+% The command should be followed by nonempty text, ending with
+% \pgfmath@ as a stop-token. Then should follow
+%
+% #1 - code to execute if text starts with +
+% #2 - code to execute if text does not
+%
+% Example:
+%
+% \pgfmath@onquick+0pt\pgfmath@{is quick}{is slow}
+
+\def\pgfmath@onquick{%
+ \futurelet\pgfmath@next%
+ \pgfmath@@onquick}
+\def\pgfmath@@onquick#1\pgfmath@{%
+ \ifx\pgfmath@next+%
+ \let\pgfmath@next=\pgfmath@firstoftwo%
+ \else%
+ \let\pgfmath@next=\pgfmath@secondoftwo%
+ \fi%
+ \pgfmath@next%
+}
+
+% *** The following commands DO NOT WORK without the rest of PGF ***
+%
+% (a dumping ground for stuff that doesn't really belong anywhere else)
+
+% \pgfmathanglebetweenpoints
+%
+% Define \pgfmathresult as the angle between points #1 and #2
+% Should get the quadrants right as well.
+%
+\def\pgfmathanglebetweenpoints#1#2{%
+ \begingroup%
+ \pgf@process{\pgfpointdiff{#1}{#2}}%
+ \edef\pgf@marshall{\expandafter\noexpand\csname pgfmathatan2@\endcsname{\expandafter\Pgf@geT\the\pgf@y}{\expandafter\Pgf@geT\the\pgf@x}}%
+ \pgf@marshall%
+ \ifdim\pgfmathresult pt<0pt%
+ \pgfmathparse{\pgfmathresult+360}%
+ \fi%
+ \expandafter%
+ \endgroup\expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult}%
+}
+
+%
+% \pgfmathrotatepointaround
+%
+% Rotate point #1 about point #2 by #3 degrees.
+%
+\def\pgfmathrotatepointaround#1#2#3{%
+ \pgf@process{%
+ \pgf@process{#1}%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgf@process{#2}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgf@xb\pgf@x%
+ \pgf@yb\pgf@y%
+ \pgf@x=\pgf@xc%
+ \pgf@y=\pgf@yc%
+ \advance\pgf@x-\pgf@xa%
+ \advance\pgf@y-\pgf@ya%
+ \pgfmathsetmacro\angle{#3}%
+ \pgfmathsin@{\angle}%
+ \let\sineangle\pgfmathresult%
+ \pgfmathcos@{\angle}%
+ \let\cosineangle\pgfmathresult%
+ \pgf@xa\cosineangle\pgf@x%
+ \advance\pgf@xa-\sineangle\pgf@y%
+ \pgf@ya\sineangle\pgf@x%
+ \advance\pgf@ya\cosineangle\pgf@y%
+ \pgf@x\pgf@xb%
+ \pgf@y\pgf@yb%
+ \advance\pgf@x\pgf@xa%
+ \advance\pgf@y\pgf@ya%
+ }%
+}
+
+% \pgfmathanglebetweenlines
+%
+% Calculate the clockwise angle between a line from point #1
+% to point #2 and a line from #3 to point #4.
+%
+\def\pgfmathanglebetweenlines#1#2#3#4{%
+ \begingroup%
+ \pgfmathanglebetweenpoints{#1}{#2}%
+ \let\firstangle\pgfmathresult%
+ \pgfmathanglebetweenpoints{#3}{#4}%
+ \let\secondangle\pgfmathresult%
+ \ifdim\firstangle pt>\secondangle pt\relax%
+ \pgfmathadd@{\secondangle}{360}%
+ \let\secondangle\pgfmathresult%
+ \fi%
+ \pgfmathsubtract@{\secondangle}{\firstangle}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% \pgfmathpointreflectalongaxis
+%
+% Reflects point #1 around an axis centered on #2 at an angle #3.
+%
+\def\pgfmathreflectpointalongaxis#1#2#3{%
+ \pgf@process{%
+ \pgfmathanglebetweenpoints{#2}{#1}%
+ \pgfmath@tempdima\pgfmathresult pt\relax%
+ \pgfmathparse{#3}%
+ \advance\pgfmath@tempdima-\pgfmathresult pt\relax%
+ \pgfmath@tempdima-2.0\pgfmath@tempdima%
+ \pgfmathrotatepointaround{#1}{#2}{\pgfmath@tonumber{\pgfmath@tempdima}}%
+ }%
+}
+
+
+
+% \pgfmathpointintersectionoflineandarc
+%
+% A bit experimental at the moment:
+%
+% Locates the point where a line crosses an eliptical arc. If the line
+% does not cross the arc, a meaningless point will result.
+%
+% #1 the point of the line on the "convex" side of the arc.
+% #2 the point of the line on the "concave" side of the arc.
+% #3 the center of the eliptical arc.
+% #4 start angle of the arc.
+% #5 end angle of the arc.
+% #6 radii of the arc.
+%
+\def\pgfmathpointintersectionoflineandarc#1#2#3#4#5#6{%
+ \pgf@process{%
+ %
+ % Get the required angle.
+ %
+ \pgfmathanglebetweenpoints{#2}{#1}%
+ \let\x\pgfmathresult%
+ %
+ % Get the radii of the arc.
+ %
+ \pgfmath@in@{and }{#6}%
+ \ifpgfmath@in@%
+ \pgf@polar@#6\@@%
+ \else%
+ \pgf@polar@#6 and #6\@@%
+ \fi%
+ \edef\xarcradius{\the\pgf@x}%
+ \edef\yarcradius{\the\pgf@y}%
+ %
+ % Get the start and end angles of the arc...
+ %
+ \pgfmathsetmacro\s{#4}%
+ \pgfmathsetmacro\e{#5}%
+ %
+ % ...and also with rounding.
+ %
+ \pgfmathmod@{\s}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\ss\pgfmathresult%
+ \pgfmathmod@{\e}{360}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathadd@{\pgfmathresult}{360}%
+ \fi%
+ \let\ee\pgfmathresult%
+ %
+ % Hackery for when arc straddles zero.
+ %
+ \ifdim\ee pt<\ss pt\relax%
+ \pgfmathadd@{\x}{180}%
+ \pgfmathmod@{\pgfmathresult}{360}%
+ \let\x\pgfmathresult%
+ \fi%
+ \def\m{360}% Measure of nearness.
+ \pgfmathadd@{\s}{\e}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\n\pgfmathresult% The best estimate (default to middle of arc).
+ \pgfmathloop%
+ \pgfmathadd@{\s}{\e}%
+ \pgfmathdivide@{\pgfmathresult}{2}%
+ \let\p\pgfmathresult%
+ \ifdim\p pt=\s pt\relax%
+ \else%
+ \pgfmathanglebetweenpoints{#2}{%
+ \pgfpointadd{#3}{%
+ \pgf@x\xarcradius\relax%
+ \pgfmathcos@{\p}%
+ \pgf@x\pgfmathresult\pgf@x%
+ \pgf@y\yarcradius\relax%
+ \pgfmathsin@{\p}%
+ \pgf@y\pgfmathresult\pgf@y%
+ }%
+ }%
+ %
+ % Hackery for when arc straddles zero.
+ %
+ \ifdim\ee pt<\ss pt\relax%
+ \pgfmathadd@{\pgfmathresult}{180}%
+ \pgfmathmod@{\pgfmathresult}{360}%
+ \fi%
+ \let\q\pgfmathresult%
+ %
+ % More hackery...
+ %
+ \ifdim\x pt>335pt\relax%
+ \ifdim\q pt<45pt\relax%
+ \pgfmathadd@{\q}{360}%
+ \let\q\pgfmathresult%
+ \fi%
+ \fi%
+ \ifdim\x pt=\q pt% Found it!
+ \pgfmathbreakloop% Breaks after current iteration is complete.
+ \else
+ \ifdim\x pt<\q pt\relax%
+ \let\e\p%
+ \else%
+ \let\s\p%
+ \fi%
+ \fi%
+ \pgfmathsubtract@{\x}{\q}%
+ \pgfmathabs@{\pgfmathresult}%
+ %
+ % Save the estimate if it is better than any previous estimate.
+ %
+ \ifdim\pgfmathresult pt<\m pt\relax%
+ \let\m\pgfmathresult%
+ \let\n\p%
+ \fi%
+ \repeatpgfmathloop%
+ \pgfpointadd{#3}{\pgfpointpolar{\n}{\xarcradius and \yarcradius}}%
+ }%
+}
+
+% \pgfmathangleonellipse
+%
+% Find the angle corresponding to a point on the border of an ellispe.
+%
+% #1 - the point on the border.
+% #2 - the radii of the ellipse.
+%
+\def\pgfmathangleonellipse#1#2{%
+ \begingroup%
+ \pgfmath@in@{and }{#2}%
+ \ifpgfmath@in@%
+ \pgf@polar@#2\@@%
+ \else%
+ \pgf@polar@#2 and #2\@@%
+ \fi%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgf@process{#1}%
+ \ifdim\pgf@x=0pt\relax%
+ \pgfutil@tempdima1pt\relax%
+ \else%
+ \pgfutil@tempdima\pgf@x%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \fi%
+ \ifdim\pgf@y=0pt\relax%
+ \pgfutil@tempdima1pt\relax%
+ \else%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgf@y}}{\pgfmath@tonumber{\pgf@ya}}%
+ \pgfutil@tempdima\pgfmathresult\pgfutil@tempdima%
+ \pgfmathatan@{\pgfmath@tonumber{\pgfutil@tempdima}}%
+ \fi%
+ %
+ \pgfutil@tempdima\pgfmathresult pt\relax%
+ \ifdim\pgfutil@tempdima<0pt\relax%
+ \advance\pgfutil@tempdima360pt\relax%
+ \fi%
+ \ifdim\pgf@x<0pt\relax%
+ \ifdim\pgf@y=0pt\relax%
+ \pgfutil@tempdima180pt\relax%
+ \else%
+ \ifdim\pgf@y<0pt\relax%
+ \advance\pgfutil@tempdima180pt\relax%
+ \else%
+ \advance\pgfutil@tempdima-180pt\relax%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgf@x=0pt\relax%
+ \ifdim\pgf@y<0pt\relax%
+ \pgfutil@tempdima270pt\relax%
+ \else%
+ \pgfutil@tempdima90pt\relax%
+ \fi%
+ \else%
+ \ifdim\pgf@y=0pt\relax%
+ \pgfutil@tempdima0pt\relax%
+ \fi%
+ \fi%
+ \fi%
+ \pgfmath@returnone\pgfutil@tempdima%
+ \endgroup%
+}
+
+
+% Local Variables:
+% tab-width: 2
+% End:
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfloat.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfloat.code.tex
new file mode 100644
index 0000000000..f133c6d495
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfloat.code.tex
@@ -0,0 +1,2669 @@
+% Copyright 2019 by Christian Feuersaenger
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% This file contains methods for basic floating point arithmetics, rounding
+% to arbitrary precision and number pretty printing.
+%
+
+
+\pgfkeys{
+ % The bug 3430171 (wrong minus sign spacing in pgfmathprintnumber)
+ % has been fixed in 2.10 CVS. Since it changes the spacing, its
+ % effects can be undone with this compatibility switch.
+ /pgf/compat/number printer/.is choice,
+ /pgf/compat/number printer/2.10/.code={%
+ \def\pgfmathprintnumber@begingroup{\bgroup}%
+ \def\pgfmathprintnumber@endgroup{\egroup}%
+ },
+ % I do not know the version number of the next release at this
+ % time. Please be so kind and KEEP THIS NAME INTACT. Add an alias
+ % if needed.
+ /pgf/compat/number printer/next after 2.10/.code={%
+ \def\pgfmathprintnumber@begingroup{\begingroup}%
+ \def\pgfmathprintnumber@endgroup{\endgroup}%
+ },
+ % activate the fix by default.
+ /pgf/compat/number printer/next after 2.10,%
+}
+
+
+\newif\ifpgfmathfloatcomparison
+\newif\ifpgfmathfloatroundhasperiod
+\newif\ifpgfmathprintnumberskipzeroperiod
+
+
+% used internally in grouped macros:
+\toksdef\pgfmathfloat@tmptoks=1
+\newif\ifpgfmathfloat@fixed@digits@after@period
+\newif\ifpgfmathfloatroundmayneedrenormalize
+\toksdef\pgfmathfloat@a@Mtok=0
+
+%% WARNING: avoid conflicting register names!
+\let\pgfmathfloat@a@S=\c@pgf@counta
+\let\pgfmathfloat@a@M=\pgf@xa
+\let\pgfmathfloat@a@E=\c@pgf@countb
+\let\pgfmathfloat@b@S=\c@pgf@countc
+\let\pgfmathfloat@b@M=\pgf@xb
+\let\pgfmathfloat@b@E=\c@pgf@countd
+
+% can be changed with options.
+\def\pgfmathfloat@round@precision{2}
+
+% I introduced this to access the "original" precision in case a
+% formatted changes it locally... in this case, the formatter may
+% overwrite \pgfmathfloat@round@precision@orig to provide the original
+% one.
+% The default implementation here does nothing:
+\def\pgfmathfloat@round@precision@orig{\pgfmathfloat@round@precision}%
+
+\gdef\pgfmathfloat@glob@TMP{}
+
+
+% Computes a normalised floating point representation for #1 of the
+% form
+% [FLAGS] MANTISSE EXPONENT
+% meaning
+% [+-]X.XXXXXXX*10^C
+% where
+% X.XXXXXX is a mantissa with first number != 0, C is an integer and
+% FLAGS contains the sign and some other special cases.
+%
+% This method does NOT use TeX Registers to represent the numbers! The
+% computation is COMPLETELY STRING BASED.
+% This allows numbers such at 10000000 or 5.23e-10 to be represented
+% properly, although TeX-registers would produce overflow/underflow
+% errors in these cases.
+%
+% It is to be used to compute logs, because log(X*10^Y) = log(X) + log(10)*Y
+%
+% Arguments:
+% #1: an arbitrary number which shall be parsed. Maybe a macro.
+% Examples:
+% [+-]XXXXX.XXXXXX
+% [+-]XXXXX.XXXXXXeXXXX
+% [+-]0.0000XXXXXX
+% [+-]0.0000XXXXXXeXXXX
+% [+-]inf
+% nan
+% Maybe a macro containing such a number.
+%
+% Return value:
+% \pgfmathresult will be \def'ed to
+% FLAGS MANTISSE 'e' EXPONENT
+% where
+% FLAGS is a number in [0-5] where
+% 0 == '0' (the number is +- 0.0),
+% 1 == '+',
+% 2 == '-',
+% 3 == 'not a number'
+% 4 == '+ infinity'
+% 5 == '- infinity'
+%
+% MANTISSE is a normalised number 1 <= M < 10. It always contains a
+% period and at least one digit after the period.
+%
+% EXPONENT is an integer value.
+%
+% Example:
+% \pgfmathfloatparsenumber{1}
+% -> \pgfmathresult = 11.0e0
+% \pgfmathfloatparsenumber{141.212}
+% -> \pgfmathresult = 11.41212e2
+\def\pgfmathfloatparsenumber#1{%
+ \begingroup
+ \edef\pgfmathresult{#1}%
+ \expandafter\pgfflt@impl\pgfmathresult\pgfflt@EOI
+ \ifpgfmathfloatparsenumberpendingperiod
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.0}%
+ \fi
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+% The same as \pgfmathfloatparsenumber, but does not perform sanity checking.
+% FIXME: there is no longer any difference here.
+\let\pgfmathfloatqparsenumber=\pgfmathfloatparsenumber
+
+% Takes a floating point number #1 as input and writes flags to count
+% register #2, mantissa to dimen register #3 and exponent to count
+% register #4.
+\def\pgfmathfloattoregisters#1#2#3#4{%
+ \expandafter\pgfmathfloat@decompose#1\relax{#2}{#3}{#4}%
+}
+
+% the same, but writes the mantissa into a token register.
+\def\pgfmathfloattoregisterstok#1#2#3#4{%
+ \expandafter\pgfmathfloat@decompose@tok#1\relax{#2}{#3}{#4}%
+}
+
+% Extracts the flags of #1 into the count register #2.
+\def\pgfmathfloatgetflags#1#2{%
+ \expandafter\pgfmathfloat@decompose@F#1\relax{#2}%
+}
+% Extracts the flags of #1 into the macro #2.
+\def\pgfmathfloatgetflagstomacro#1#2{%
+ \expandafter\pgfmathfloat@decompose@Fmacro#1\relax{#2}%
+}%
+
+% Extracts the mantissa of #1 into the dimen register #2.
+\def\pgfmathfloatgetmantissa#1#2{%
+ \expandafter\pgfmathfloat@decompose@M#1\relax{#2}%
+}
+\let\pgfmathfloatgetmantisse=\pgfmathfloatgetmantissa
+% Extracts the mantissa of #1 into the token register #2.
+\def\pgfmathfloatgetmantissatok#1#2{%
+ \expandafter\pgfmathfloat@decompose@Mtok#1\relax{#2}%
+}
+\let\pgfmathfloatgetmantissetok=\pgfmathfloatgetmantissatok
+% Extracts the exponent of #1 into the count register #2.
+\def\pgfmathfloatgetexponent#1#2{%
+ \expandafter\pgfmathfloat@decompose@E#1\relax{#2}%
+}
+
+
+% Assigns \pgfmathresult to be a float encoded as
+% <FLAGS><MANTISSE>e<EXPONENT>
+%
+% example:
+% \pgfmathfloatcreate{1}{2.0}{10}
+% \pgfmathfloat@to@FMeE@style\pgfmathresult
+% ->
+% \pgfmathresult is now '12.0e10' regardless of the internal float
+% format.
+\def\pgfmathfloat@to@FMeE@style#1{\expandafter\pgfmathfloat@to@FMeE@style@#1\relax\relax}%
+\def\pgfmathfloat@to@FMeE@style@#1#2{%
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@to@FMeE@style@@%
+ \else
+ \expandafter\pgfmathfloat@to@FMeE@style@error%
+ \fi
+ #1#2%
+}%
+\def\pgfmathfloat@to@FMeE@style@@#1Y#2e#3]\relax\relax{\def\pgfmathresult{#1#2e#3}}%
+\def\pgfmathfloat@to@FMeE@style@error#1\relax\relax{%
+ \begingroup
+ \pgfmathfloatparsenumber@handleerror{wrong lowlevel format}{#1}{#1}%
+ \xdef\pgfmathfloat@decompose@TMP{%
+ \noexpand\pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ }%
+ \endgroup
+ \pgfmathfloat@decompose@TMP
+}%
+
+
+% decomposes a lowlevel floating point representation into flags,
+% mantissa and exponent.
+%
+% #4: integer register for the flags.
+% #5: dimen registers for the mantissa.
+% #6: integer register for the exponent.
+%
+% \expandafter\pgfmathfloat@decompose\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@M\pgfmathfloat@a@E
+% -> the three temp registers contain flags, mantissa and exponent
+\def\pgfmathfloat@decompose#1#2{% sanitize!
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@decompose@%
+ \else
+ \expandafter\pgfmathfloat@decompose@error%
+ \fi
+ #1#2%
+}
+\def\pgfmathfloat@decompose@#1Y#2e#3]\relax#4#5#6{%
+ #4=#1\relax
+ #5=#2pt % keep space here.
+ #6=#3\relax%
+}
+
+% overloaded, #5 needs to be a token register for the mantissa.
+% @see also \pgfmathfloatvalueof which does also employ the load
+% level repr.
+% \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+% -> the three temp registers contain flags, mantissa and exponent
+\def\pgfmathfloat@decompose@tok#1#2{%
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@decompose@tok@%
+ \else
+ \expandafter\pgfmathfloat@decompose@tok@error%
+ \fi
+ #1#2%
+}%
+\def\pgfmathfloat@decompose@tok@#1Y#2e#3]\relax#4#5#6{%
+ #4=#1\relax
+ #5={#2}%
+ #6=#3\relax%
+}
+% overloaded, returns only ONE of the three components into #4:
+% \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S
+% -> \pgfmathfloat@a@S contains the flags field.
+\def\pgfmathfloat@decompose@F#1#2{%
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@decompose@F@%
+ \else
+ \expandafter\pgfmathfloat@decompose@F@error%
+ \fi
+ #1#2%
+}%
+\def\pgfmathfloat@decompose@Fmacro#1#2{%
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@decompose@Fmacro@%
+ \else
+ \expandafter\pgfmathfloat@decompose@F@error%
+ \fi
+ #1#2%
+}%
+\def\pgfmathfloat@decompose@M#1#2{%
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@decompose@M@%
+ \else
+ \expandafter\pgfmathfloat@decompose@M@error%
+ \fi
+ #1#2%
+}%
+\def\pgfmathfloat@decompose@E#1#2{%
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@decompose@E@%
+ \else
+ \expandafter\pgfmathfloat@decompose@E@error%
+ \fi
+ #1#2%
+}%
+\def\pgfmathfloat@decompose@Mtok#1#2{%
+ \ifx#2Y%
+ \expandafter\pgfmathfloat@decompose@Mtok@%
+ \else
+ \expandafter\pgfmathfloat@decompose@Mtok@error%
+ \fi
+ #1#2%
+}%
+\def\pgfmathfloat@decompose@F@#1Y#2e#3]\relax#4{#4=#1\relax}%
+\def\pgfmathfloat@decompose@Fmacro@#1Y#2e#3]\relax#4{\def#4{#1}}%
+\def\pgfmathfloat@decompose@M@#1Y#2e#3]\relax#4{#4=#2pt}%
+\def\pgfmathfloat@decompose@Mtok@#1Y#2e#3]\relax#4{#4={#2}}%
+\def\pgfmathfloat@decompose@E@#1Y#2e#3]\relax#4{#4=#3\relax}%
+
+\def\pgfmathfloat@decompose@error#1\relax#2#3#4{%
+ \begingroup
+ \pgfmathfloatparsenumber@handleerror{wrong lowlevel format}{#1}{#1}%
+ \xdef\pgfmathfloat@decompose@TMP{%
+ \noexpand#2=\the\pgfmathfloat@a@S\space
+ \noexpand#3=\the\pgfmathfloat@a@Mtok pt
+ \noexpand#4=\the\pgfmathfloat@a@E\space
+ }%
+ \endgroup
+ \pgfmathfloat@decompose@TMP
+}%
+\def\pgfmathfloat@decompose@tok@error#1\relax#2#3#4{%
+ \begingroup
+ \pgfmathfloatparsenumber@handleerror{wrong lowlevel format}{#1}{#1}%
+ \xdef\pgfmathfloat@decompose@TMP{%
+ \noexpand#2=\the\pgfmathfloat@a@S\space
+ \noexpand#3={\the\pgfmathfloat@a@Mtok}%
+ \noexpand#4=\the\pgfmathfloat@a@E\space
+ }%
+ \endgroup
+ \pgfmathfloat@decompose@TMP
+}%
+\def\pgfmathfloat@decompose@F@error#1\relax#2{%
+ \begingroup
+ \pgfmathfloatparsenumber@handleerror{wrong lowlevel format}{#1}{#1}%
+ \xdef\pgfmathfloat@decompose@TMP{\noexpand#2=\the\pgfmathfloat@a@S\space}%
+ \endgroup
+ \pgfmathfloat@decompose@TMP
+}%
+\def\pgfmathfloat@decompose@M@error#1\relax#2{%
+ \begingroup
+ \pgfmathfloatparsenumber@handleerror{wrong lowlevel format}{#1}{#1}%
+ \xdef\pgfmathfloat@decompose@TMP{\noexpand#2=\the\pgfmathfloat@a@Mtok pt }%
+ \endgroup
+ \pgfmathfloat@decompose@TMP
+}%
+\def\pgfmathfloat@decompose@Mtok@error#1\relax#2{%
+ \begingroup
+ \pgfmathfloatparsenumber@handleerror{wrong lowlevel format}{#1}{#1}%
+ \xdef\pgfmathfloat@decompose@TMP{\noexpand#2={\the\pgfmathfloat@a@Mtok}}%
+ \endgroup
+ \pgfmathfloat@decompose@TMP
+}%
+\def\pgfmathfloat@decompose@E@error#1\relax#2{%
+ \begingroup
+ \pgfmathfloatparsenumber@handleerror{wrong lowlevel format}{#1}{#1}%
+ \xdef\pgfmathfloat@decompose@TMP{\noexpand#2=\the\pgfmathfloat@a@E\space}%
+ \endgroup
+ \pgfmathfloat@decompose@TMP
+}%
+% Takes a floating point number #1 as input and writes flags to macro
+% #2, mantissa to macro #3 and exponent to macro #4.
+\def\pgfmathfloattomacro#1#2#3#4{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \xdef\pgfmathfloat@glob@TMP{%
+ \noexpand\def\noexpand#2{\the\pgfmathfloat@a@S}%
+ \noexpand\def\noexpand#3{\the\pgfmathfloat@a@Mtok}%
+ \noexpand\def\noexpand#4{\the\pgfmathfloat@a@E}%
+ }%
+ \endgroup
+ \pgfmathfloat@glob@TMP
+}
+
+
+% Defines \pgfmathresult as the floating point number encoded by
+% the flags #1, mantissa #2 and exponent #3.
+%
+% All arguments are characters and will be expanded using '\edef'.
+\def\pgfmathfloatcreate#1#2#3{%
+ \edef\pgfmathresult{#1Y#2e#3]}%
+}%
+% This is the character present in any low-level floating point
+% number. It is assumed to be the SECOND character of a float (after
+% the flags integer).
+\def\pgfmathfloat@POSTFLAGSCHAR{Y}
+
+
+
+% Converts a composed floating point representation to fixed point.
+%
+% Example:
+% \pgfmathfloattofixed{142e1}
+% -> \pgfmathresult = 42.0
+\def\pgfmathfloattofixed@#1{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifcase\pgfmathfloat@a@S
+ \def\pgfmathresult{0.0}%
+ \or
+ \expandafter\pgfmathfloattofixed@impl\the\pgfmathfloat@a@Mtok\relax
+ \or
+ \expandafter\pgfmathfloattofixed@impl\the\pgfmathfloat@a@Mtok\relax
+ \pgfmathfloat@a@Mtok=\expandafter{\pgfmathresult}%
+ \edef\pgfmathresult{-\the\pgfmathfloat@a@Mtok}%
+ \or\def\pgfmathresult{nan}%
+ \or\def\pgfmathresult{inf}%
+ \or\def\pgfmathresult{-inf}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+\let\pgfmathfloattofixed=\pgfmathfloattofixed@
+
+% Converts a float to an integer (in integer format).
+%
+% @see \pgfmathfloatint
+\def\pgfmathfloattoint#1{%
+ \pgfmathfloattofixed{#1}%
+ \expandafter\pgfmathfloattoint@@\pgfmathresult\relax
+}%
+\def\pgfmathfloattoint@@#1.#2\relax{%
+ \def\pgfmathresult{#1}%
+}%
+
+% Converts a floating point number to scientific format 1.234e5.
+%
+% This operation is very fast.
+\def\pgfmathfloattosci@#1{%
+ \begingroup
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifcase\pgfmathfloat@a@S
+ \def\pgfmathresult{0.0e0}%
+ \or
+ \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok e\the\pgfmathfloat@a@E}%
+ \or
+ \edef\pgfmathresult{-\the\pgfmathfloat@a@Mtok e\the\pgfmathfloat@a@E}%
+ \or\def\pgfmathresult{nan}%
+ \or\def\pgfmathresult{inf}%
+ \or\def\pgfmathresult{-inf}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\let\pgfmathfloattosci=\pgfmathfloattosci@
+
+% Expands a floating point number to scientific format 1.234e5.
+%
+% This operation is very fast.
+\def\pgfmathfloatvalueof#1{\expandafter\pgfmathfloatvalueof@@#1@@}%
+
+% Make it fool proof such that the following arguments work:
+% \pgfmathfloatvalueof{1Y1.0e1} -> 1.0e1
+% \pgfmathfloatvalueof{2Y1.0e1} -> -1.0e1
+% and wrong arguments as well:
+% \pgfmathfloatvalueof{1} -> 1
+% \pgfmathfloatvalueof{1e2} -> 1e2
+\def\pgfmathfloatvalueof@@#1#2{%
+ \if#2Y%
+ % keep in mind that \pgfmathfloatvalueof should be expandable!
+ % We must not use \let here. Let's hope that #1 and #2 are
+ % single tokens (not something which was enclosed by curly
+ % braces...)
+ \expandafter\pgfmathfloatvalueof@@@\expandafter#1\expandafter#2%
+ \else
+ % Oh - no float!? Ok, we cannot report errors in this context.
+ % So: make it a feature and return the input argument as-is.
+ % Might be useful, in fact...
+ \expandafter\pgfmathfloatvalueof@abort\expandafter#1\expandafter#2%
+ \fi
+}
+\def\pgfmathfloatvalueof@@@#1Y#2e#3]@@{%
+ \ifcase#1 %
+ 0.0e0%
+ \or
+ #2e#3%
+ \or
+ -#2e#3%
+ \or nan%
+ \or inf%
+ \or -inf%
+ \fi
+}%
+\def\pgfmathfloatvalueof@abort#1@@{#1}%
+
+
+
+% Rounds a fixed point number #1 to \pgfmathfloat@round@precision digits precision and returns
+% the result into \pgfmathresult.
+%
+% Any trailing zeros after the period are discarded.
+% See \pgfmathroundtozerofill if you want trailing zeros and fixed
+% width.
+%
+% This method is PURELY text based and can work with arbitrary
+% precision (well, limited to TeX's stack size and integer size).
+%
+% Examples:
+% \pgfmathroundto{1}
+% -> \pgfmathresult = '1'
+%
+% \pgfmathroundto{19999.9996}
+% -> \pgfmathresult = '20000'
+%
+% Arguments:
+% #1 may be either a number or a macro (\pgfmathresult is allowed) expanding to a number.
+%
+% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set.
+\def\pgfmathroundto#1{%
+ \pgfmathfloatroundhasperiodtrue
+ \begingroup
+ \pgfmathfloat@fixed@digits@after@periodfalse
+ \pgfmathroundto@impl{#1}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+
+% Overloaded method.
+%
+% This variant always uses a FIXED number behind the period and fills
+% in zeros if necessary.
+% Examples:
+% \pgfmathroundtozerofill{1}
+% -> \pgfmathresult = '1.00'
+%
+% \pgfmathroundtozerofill{19999.9996}
+% -> \pgfmathresult = '20000.00'
+%
+% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set.
+\def\pgfmathroundtozerofill#1{%
+ \pgfmathfloatroundhasperiodtrue
+ \begingroup
+ \pgfmathfloat@fixed@digits@after@periodtrue
+ \pgfmathroundto@impl{#1}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+% see \pgfmathprintnumber@fixed@style for docs
+\def\pgfmathprintnumber@fixed@styleDEFAULT#1#2#3e#4\relax{%
+ \begingroup
+ \pgfkeysgetvalue{/pgf/number format/set decimal separator}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP
+ \pgfkeysgetvalue{/pgf/number format/@dec sep mark}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK
+ \pgfkeysgetvalue{/pgf/number format/set thousands separator}\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP
+ \c@pgf@counta=#4\relax % it is the exponent here.
+ \ifnum#2=0
+ \c@pgf@counta=0
+ \fi
+ \def\pgfmathresult{}%
+ \ifpgfmathfloatroundhasperiod
+ \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@period#1\pgfmathfloat@EOI
+ \else
+ \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI%
+ \begingroup
+ \toks0=\expandafter{\pgfmathresult}%
+ \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }%
+ \endgroup
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@period#1.#2\pgfmathfloat@EOI{%
+ \ifpgfmathprintnumberskipzeroperiod
+ \def\pgfmathfloat@loc@TMPb{#1}%
+ \ifx\pgfmathfloatparsenumber@tok@ZERO\pgfmathfloat@loc@TMPb
+ \else
+ \def\pgfmathfloat@loc@TMPc{-0}%
+ \ifx\pgfmathfloat@loc@TMPc\pgfmathfloat@loc@TMPb
+ \def\pgfmathresult{-}%
+ \else
+ \def\pgfmathfloat@loc@TMPc{+0}%
+ \ifx\pgfmathfloat@loc@TMPc\pgfmathfloat@loc@TMPb
+ \def\pgfmathresult{+}%
+ \else
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI
+ \fi
+ \fi
+ \fi
+ \else
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI
+ \fi
+ \ifpgfmathprintnumber@thousand@sep@in@fractional
+ \let\pgfmathresultfractional\pgfutil@empty%
+ \pgfmathprintnumber@thousand@sep@in@fractional#2MMMM\@@
+ \else
+ \def\pgfmathresultfractional{#2}%
+ \fi
+ \begingroup
+ \toks0=\expandafter{\pgfmathresult}%
+ \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}%
+ \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP}%
+ \toks3=\expandafter{\pgfmathresultfractional}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 \the\toks3 }%
+ \endgroup
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+}%
+
+% assigns \pgfmathresult such that it contains the formatted result.
+% It assumes that none of the following tokens contains a period.
+\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod{%
+ \ifx\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP\pgfutil@empty
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}%
+ \else
+ \ifnum\c@pgf@counta<0\relax % exponent of the number in this context
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}%
+ \else
+ \ifnum\c@pgf@counta<\pgfkeysvalueof{/pgf/number format/min exponent for 1000 sep}\relax
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}%
+ \else
+ \advance\c@pgf@counta by1 % counta:= total number of digits, N.
+ \c@pgf@countb=\c@pgf@counta
+ \divide\c@pgf@countb by3 % countb := N DIV 3
+ \c@pgf@countc=\c@pgf@countb
+ \multiply\c@pgf@countc by3
+ \advance\c@pgf@counta by-\c@pgf@countc% now counta := N MOD 3
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printsign
+ }%
+ \fi
+ \fi
+ \fi
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT
+}
+\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printsign#1{%
+ \def\pgfmathfloat@loc@TMPb{#1}%
+ \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@MINUS
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}%
+ \let\pgfmathfloat@loc@TMPb=\pgfutil@empty
+ \else
+ \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@PLUS
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}%
+ \let\pgfmathfloat@loc@TMPb=\pgfutil@empty
+ \else
+ \ifpgfmathprintnumber@showpositive
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult +}%
+ \fi
+ \fi
+ \fi
+ \ifnum\c@pgf@counta>0 % \c@pgf@counta = N MOD 3 in this context
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits\pgfmathfloat@loc@TMPb
+ }%
+ \else
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird\pgfmathfloat@loc@TMPb
+ }%
+ \fi
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT
+}
+\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits#1#2{%
+ \ifcase\c@pgf@counta % = N MOD 3 in this context
+ % does not happen per construction
+ \or
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}%
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird#2%
+ }%
+ \or
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1#2}%
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird%
+ }%
+ \fi
+ \ifnum\c@pgf@countb>0\relax % \c@pgf@countb = N DIV 3 in this context
+ \begingroup
+ \toks0=\expandafter{\pgfmathresult}%
+ \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }%
+ \endgroup
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+ \fi
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT
+}
+\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird#1#2#3{%
+ \ifnum\c@pgf@countb>0\relax
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1#2#3}%
+ \advance\c@pgf@countb by-1
+ \ifnum\c@pgf@countb>0\relax
+ \begingroup
+ \toks0=\expandafter{\pgfmathresult}%
+ \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }%
+ \endgroup
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+ \fi
+ \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{%
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird%
+ }%
+ \else
+ % in this case, #1#2#3 are expected to be
+ % \pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI
+ %--------------------------------------------------
+ % \def\pgfmathfloat@loc@TMPb{\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI}%
+ % \def\pgfmathfloat@loc@TMPc{#1#2#3}%
+ % \ifx\pgfmathfloat@loc@TMPc\pgfmathfloat@loc@TMPb
+ % \else
+ % \pgfmath@error{INTERNAL ERROR in fixed style - The input sequence did not terminate as expected; which indicates a wrong exponent argument provided to \string\pgfmathprintnumber@fixed@style}{}%
+ % \fi
+ %--------------------------------------------------
+ \let\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT=\relax
+ \fi
+ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT
+}
+
+% \pgfmathprintnumber@thousand@sep@in@fractional 01234525MMMM\@@
+% ->
+% 012<sep>345<sep>25
+\def\pgfmathprintnumber@thousand@sep@in@fractional#1#2#3#4{%
+ \if#4M%
+ % Ok, no further separator
+ \def\pgfmathprint@next{\pgfmathprintnumber@thousand@sep@in@fractional@finish#1#2#3#4}%
+ \else
+ \begingroup
+ \toks0=\expandafter{\pgfmathresultfractional}%
+ \toks1={#1#2#3}%
+ \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }%
+ \endgroup
+ \let\pgfmathresultfractional=\pgfmathfloat@glob@TMP
+ \def\pgfmathprint@next{\pgfmathprintnumber@thousand@sep@in@fractional#4}%
+ \fi
+ \pgfmathprint@next
+}%
+\def\pgfmathprintnumber@thousand@sep@in@fractional@finish#1M{%
+ \expandafter\def\expandafter\pgfmathresultfractional\expandafter{\pgfmathresultfractional #1}%
+ \pgfmathprintnumber@thousand@sep@in@fractional@finish@
+}%
+\def\pgfmathprintnumber@thousand@sep@in@fractional@finish@#1\@@{}%
+
+\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall#1{%
+ \def\pgfmathfloat@loc@TMPb{#1}%
+ \let\pgfmathfloat@loc@TMPc=\pgfutil@empty
+ \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@MINUS
+ \else
+ \ifx\pgfmathfloat@loc@TMPb\pgfmathfloatparsenumber@tok@PLUS
+ \else
+ \ifpgfmathprintnumber@showpositive
+ \def\pgfmathfloat@loc@TMPc{+}%
+ \fi
+ \fi
+ \fi
+ \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall@\pgfmathfloat@loc@TMPc#1%
+}
+\def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall@#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI{%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}%
+}%
+
+% @deprecated. It has been replaced by \pgfmathprintnumber@fixed@styleDEFAULT
+% #1 maybe a macro
+\def\pgfmathprintnumber@fixed@stylePERIOD#1#2#3e#4\relax{%
+ \def\pgfmathresult{#1}%
+}
+
+% @deprecated. It has been replaced by \pgfmathprintnumber@fixed@styleDEFAULT
+% #1 maybe a macro
+\def\pgfmathprintnumber@fixed@styleCOMMA#1#2#3e#4\relax{%
+ \ifpgfmathfloatroundhasperiod
+ \expandafter\pgfmathprintnumber@fixed@styleCOMMA@impl#1\pgfmathfloat@EOI
+ \else
+ \def\pgfmathresult{#1}%
+ \fi
+}
+\def\pgfmathprintnumber@fixed@styleCOMMA@impl#1.#2\pgfmathfloat@EOI{\def\pgfmathresult{#1{,}#2}}
+
+% The default style to display fixed point numbers.
+%
+% It does not apply numerics, but it is responsible for typesetting the
+% rounded number.
+% It can access the \ifpgfmathfloatroundhasperiod boolean.
+%
+% Arguments:
+% #1#2#3e#4\relax
+
+% Input:
+% #1 the fixed point number to be displayed (maybe a macro).
+% #2#3e#4: the (possibly unformatted) floating point representation
+% which belongs to #1. This format is returned (only!) by
+% \pgfmathfloat@to@FMeE@style.
+% It is used to determine sign and exponent.
+\let\pgfmathprintnumber@fixed@style=\pgfmathprintnumber@fixed@styleDEFAULT
+
+
+% Rounds a normalized floating point number to \pgfmathfloat@round@precision
+% digits precision and writes the result to \pgfmathresult.
+%
+% This method uses \pgfmathroundto for the mantissa.
+%
+% @see pgfmathfloatroundzerofill
+%
+% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set to
+% whether the final mantissa #5 has a period or not.
+\def\pgfmathfloatround#1{%
+ \pgfmathfloatroundhasperiodtrue
+ \begingroup
+ \pgfmathfloat@fixed@digits@after@periodfalse
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \pgfmathfloatround@impl
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+% Overload.
+%
+% This method uses a fixed width for the mantissa and fills in zeros
+% if necessary.
+%
+% This method uses \pgfmathroundtozerofill for the mantissa.
+%
+% SIDE EFFECT: the global variable \ifpgfmathfloatroundhasperiod will be set to
+% whether the final mantissa #5 has a period or not.
+\def\pgfmathfloatroundzerofill#1{%
+ \pgfmathfloatroundhasperiodtrue
+ \begingroup
+ \pgfmathfloat@fixed@digits@after@periodtrue
+ \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \pgfmathfloatround@impl
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+\newif\ifpgfmathfloatround@allow@empty@mantissa
+\def\pgfmathfloatround@mantissa@ONE{1pt }%
+
+% #1: sign
+% #2: mantissa
+% #3: exponent
+% #4: CODE to display if the mantissa is drawn.
+% This code will be shown just before the exponent.
+% Example: #4=\cdot
+% #5: CODE to display if the mantissa is NOT draw. (unused currently)
+% Might be used to display '10^1' instead of '1*10^1'.
+% #6: CODE to display the exponent.
+\def\pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax#4#5#6{%
+ \pgfkeysgetvalue{/pgf/number format/@sci exponent mark}\pgfmathfloatrounddisplaystyle@e@mark
+ \ifcase#1\relax
+ \pgfmathprintnumber@fixed@style{#2}#1#2e0\relax%
+ \expandafter\pgfmathfloatrounddisplaystyle@shared@impl@\expandafter{\pgfmathresult}{#4#6}%
+ \or
+ \def\pgfmathfloat@loc@TMPa{1}% "should draw mantissa=1"
+ \ifpgfmathfloatround@allow@empty@mantissa
+ \else
+ \ifdim#2pt=\pgfmathfloatround@mantissa@ONE
+ \def\pgfmathfloat@loc@TMPa{0}% do not draw it.
+ \fi
+ \fi
+ %
+ \if1\pgfmathfloat@loc@TMPa
+ \pgfmathprintnumber@fixed@style{#2}#1#2e0\relax%
+ \expandafter\pgfmathfloatrounddisplaystyle@shared@impl@\expandafter{\pgfmathresult}{#4#6}%
+ \else
+ \def\pgfmathfloat@loc@TMPa{0}%
+ \pgfmathfloatrounddisplaystyle@shared@impl@{#5}{#6}%
+ \fi
+ \or
+ \def\pgfmathfloat@loc@TMPa{1}% "should draw mantissa=1"
+ \ifpgfmathfloatround@allow@empty@mantissa
+ \else
+ \ifdim#2pt=\pgfmathfloatround@mantissa@ONE
+ \def\pgfmathfloat@loc@TMPa{0}% do not draw it.
+ \fi
+ \fi
+ %
+ \if1\pgfmathfloat@loc@TMPa
+ \pgfmathprintnumber@fixed@style{-#2}#1#2e0\relax%
+ \expandafter\pgfmathfloatrounddisplaystyle@shared@impl@\expandafter{\pgfmathresult}{#4#6}%
+ \else
+ \def\pgfmathfloat@loc@TMPa{0}%
+ \pgfmathfloatrounddisplaystyle@shared@impl@{-#5}{#6}%
+ \fi
+ \or
+ \pgfmathfloatrounddisplaystyle@shared@impl@@{\hbox{NaN}}{}%
+ \or
+ \ifpgfmathprintnumber@showpositive
+ \pgfmathfloatrounddisplaystyle@shared@impl@@{+\infty}{}%
+ \else
+ \pgfmathfloatrounddisplaystyle@shared@impl@@{\infty}{}%
+ \fi
+ \or
+ \pgfmathfloatrounddisplaystyle@shared@impl@@{-\infty}{}%
+ \fi
+}
+
+% #1: the part before the exponent code
+% #2: the part for the exponent code.
+\def\pgfmathfloatrounddisplaystyle@shared@impl@#1#2{%
+ \pgfmathprintnumber@begingroup
+ \toks0={#1}%
+ \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }%
+ \pgfmathprintnumber@endgroup
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+}%
+% Same as \pgfmathfloatrounddisplaystyle@shared@impl@, but it also
+% inserts the '@dec sep mark' at the end.
+\def\pgfmathfloatrounddisplaystyle@shared@impl@@#1#2{%
+ \pgfmathprintnumber@begingroup
+ \toks0={#1}%
+ \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}%
+ \pgfkeysgetvalue{/pgf/number format/@dec sep mark}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK
+ \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}%
+ \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }%
+ \pgfmathprintnumber@endgroup
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+}
+
+\def\pgfmathfloatrounddisplaystyle@std#1#2e#3\relax{%
+ \pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{\cdot}{}{10^{#3}}%
+}
+\def\pgfmathfloatrounddisplaystyle@subscript#1#2e#3\relax{%
+ \pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{}{1}{_{#3}}%
+}
+\def\pgfmathfloatrounddisplaystyle@superscript#1#2e#3\relax{%
+ \pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{}{1}{^{#3}}%
+}
+\def\pgfmathfloatrounddisplaystyle@e#1#2e#3\relax{%
+ \ifnum#3<0\relax
+ \pgfmathprintnumber@begingroup
+ \count0=#3\relax
+ \multiply\count0 by-1
+ \xdef\pgfmathfloat@glob@TMP{e{-}\the\count0}%
+ \pgfmathprintnumber@endgroup%
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+ \else
+ \def\pgfmathresult{e{+}#3}%
+ \fi
+ \def\pgfmathfloat@loc@TMPb{\pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{}{1}}%
+ \expandafter\pgfmathfloat@loc@TMPb\expandafter{\pgfmathresult}%
+}
+\def\pgfmathfloatrounddisplaystyle@E#1#2e#3\relax{%
+ \ifnum#3<0\relax
+ \pgfmathprintnumber@begingroup
+ \count0=#3\relax
+ \multiply\count0 by-1
+ \xdef\pgfmathfloat@glob@TMP{E{-}\the\count0}%
+ \pgfmathprintnumber@endgroup%
+ \let\pgfmathresult=\pgfmathfloat@glob@TMP
+ \else
+ \def\pgfmathresult{E{+}#3}%
+ \fi
+ \def\pgfmathfloat@loc@TMPb{\pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\relax{}{1}}%
+ \expandafter\pgfmathfloat@loc@TMPb\expandafter{\pgfmathresult}%
+}
+
+\def\pgfmathfloatrounddisplaystyle@generic#1#2e#3\relax{%
+ \begingroup
+ \pgfkeysvalueof {/pgf/number format/sci generic/@/.@cmd}{#3}{#1}{#2}\pgfeov
+ \pgfkeysgetvalue{/pgf/number format/sci generic/mantissa sep}\pgfmathdisplay@aftermantissa
+ \pgfkeysgetvalue{/pgf/number format/sci generic/empty mantissa sep}\pgfmathdisplay@nomantissa
+ \pgfkeysgetvalue{/pgf/number format/sci generic/exponent}\pgfmathdisplay@e
+ \toks0=\expandafter{\pgfmathdisplay@aftermantissa}%
+ \toks1=\expandafter{\pgfmathdisplay@nomantissa}%
+ \toks2=\expandafter{\pgfmathdisplay@e}%
+ \xdef\pgfmathfloat@glob@TMP{\noexpand\pgfmathfloatrounddisplaystyle@shared@impl#1#2e#3\noexpand\relax{\the\toks0}{\the\toks1}{\the\toks2}}%
+ \endgroup
+ \pgfmathfloat@glob@TMP
+}
+
+% A macro which takes the argument '<SIGN><MANTISSE>e<EXPONENT>' and
+% expands to the final TeX-representation for that floating point
+% number.
+%
+% PRECONDITION:
+% the floating point number has already been rounded properly and
+% the mantissa has been rounded correctly.
+%
+% The argument needs to be in the format returned by
+% \pgfmathfloat@to@FMeE@style and terminated by '\relax'.
+\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@std
+\newif\ifpgfmathfloat@usezerofill@sci
+\newif\ifpgfmathfloat@usezerofill@fixed
+\newif\ifpgfmathprintnumber@assumemathmode
+\newif\ifpgfmathprintnumber@showpositive
+\newif\ifpgfmathprintnumber@frac@warn
+\newif\ifpgfmathprintnumber@frac@whole
+\newif\ifpgfmathparsenumber@comma@as@period
+
+\long\def\pgfmathfloatfrac@verbatim#1#2{#1/#2}%
+
+\let\pgfmathround@@orig=\pgfmathround@
+
+% 2 = compatible
+% 0 = no
+% 1 = yes
+\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{2}%
+
+\newif\ifpgfmathprintnumber@thousand@sep@in@fractional
+\pgfkeys{%
+ /pgf/number format/.is family,
+ /pgf/number format,
+ fixed/.code= \pgfmath@set@number@printer{pgfmathprintnumber@FIXED},
+ sci/.code= \pgfmath@set@number@printer{pgfmathprintnumber@SCI},
+ std/.code= {\pgfmath@set@number@printer{pgfmathprintnumber@STD}\pgfmathprintnumber@STD@setparam{#1}},
+ std/.default=,%
+ relative round mode/.is choice,
+ relative round mode/fixed/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{1}},
+ relative round mode/mantissa/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{0}},
+ relative round mode/compatible/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{2}},
+ % relative={<exponent base 10>}
+ relative/.code={%
+ \pgfmath@set@number@printer{pgfmathprintnumber@RELATIVE}%
+ \pgfmathround@@orig{#1}%
+ \expandafter\pgfmathfloattoint@@\pgfmathresult\relax
+ \let\pgfmathprintnumber@RELATIVE@param=\pgfmathresult
+ },%
+ relative/.value required,
+ relative*/.style={/pgf/number format/relative={#1},/pgf/number format/relative round mode=fixed},
+ every relative/.style=std,
+ relative style/.style={/pgf/number format/every relative/.append style={#1}},
+ fixed relative/.code= \pgfmath@set@number@printer{pgfmathprintnumber@FIXED@RELATIVE},
+ int detect/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@DETECT},
+ int trunc/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@TRUNC},
+ frac/.code= \pgfmath@set@number@printer{pgfmathprintnumber@frac},%
+ frac TeX/.initial=\frac,
+ frac whole format/.code={\def\pgfmathresult{#1}},
+ frac denom/.initial=,
+ frac whole/.is if=pgfmathprintnumber@frac@whole,
+ frac whole=true,
+ frac shift/.initial=4,
+ frac warning/.is if=pgfmathprintnumber@frac@warn,
+ frac warning=true,
+ assume math mode/.is if=pgfmathprintnumber@assumemathmode,
+ assume math mode/.default=true,
+ fixed zerofill/.is if= pgfmathfloat@usezerofill@fixed,
+ fixed zerofill/.default=true,
+ sci zerofill/.is if= pgfmathfloat@usezerofill@sci,
+ sci zerofill/.default=true,
+ zerofill/.style= {/pgf/number format/fixed zerofill={#1},/pgf/number format/sci zerofill={#1}},
+ zerofill/.default= true,
+ precision/.store in= \pgfmathfloat@round@precision,
+ sci precision/.code={%
+ \edef\pgfmathfloat@loc@TMPa{#1}%
+ \ifx\pgfmathfloat@loc@TMPa\pgfutil@empty
+ \def\pgfmathprintnumber@sci@precision{\pgfmathfloat@round@precision}%
+ \else
+ \let\pgfmathprintnumber@sci@precision=\pgfmathfloat@loc@TMPa
+ \fi
+ },%
+ sci precision/.default=,
+ sci precision=,
+ fixed default/.code= {\let\pgfmathprintnumber@fixed@style=\pgfmathprintnumber@fixed@styleDEFAULT},
+ set decimal separator/.initial=,
+ dec sep/.style={/pgf/number format/set decimal separator={#1}},
+ @dec sep mark/.initial=,
+ @sci exponent mark/.initial=,
+ set thousands separator/.initial=,
+ 1000 sep in fractionals/.is if=pgfmathprintnumber@thousand@sep@in@fractional,
+ 1000 sep in fractionals/.default=true,
+ 1000 sep/.style={/pgf/number format/set thousands separator={#1}},
+ min exponent for 1000 sep/.initial=0,
+ use period/.style= {/pgf/number format/set decimal separator={.},/pgf/number format/set thousands separator={{{,}}}},
+ use comma/.style= {/pgf/number format/set decimal separator={{{,}}},/pgf/number format/set thousands separator={.}},
+ showpos/.is if=pgfmathprintnumber@showpositive,
+ showpos/.default=true,
+ print sign/.is if=pgfmathprintnumber@showpositive,
+ print sign/.default=true,
+ read comma as period/.is if=pgfmathparsenumber@comma@as@period,
+ read comma as period/.default=true,
+ skip 0./.is if=pgfmathprintnumberskipzeroperiod,
+ skip 0./.default=true,
+ skip 0.= false,
+ use period,
+ sci 10^e/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@std},
+ sci 10e/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@std},
+ sci e/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@e},
+ sci E/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@E},
+ sci subscript/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@subscript},
+ sci superscript/.code= {\let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@superscript},
+ sci generic/.code= {%
+ \let\pgfmathfloatrounddisplaystyle=\pgfmathfloatrounddisplaystyle@generic
+ \pgfkeysdefargs{/pgf/number format/sci generic/@}%
+ {##1##2##3}%
+ {\pgfqkeys{/pgf/number format/sci generic}{#1}}%
+ },
+ sci generic/mantissa sep/.initial=,%
+ sci generic/empty mantissa sep/.initial=,%
+ sci generic/mantisse sep/.style={/pgf/number format/sci generic/mantissa sep={#1}},%
+ sci generic/empty mantisse sep/.style={/pgf/number format/sci generic/empty mantissa sep={#1}},%
+ sci generic/exponent/.initial=,%
+ sci generic/.value required,
+ verbatim/.code={%
+ \pgfqkeys{/pgf/number format}{%
+ sci generic={mantissa sep=,exponent={e##1}},
+ 1000 sep=,
+ skip 0.=false,
+ print sign=false,
+ dec sep=.,
+ assume math mode,
+ frac TeX=\pgfmathfloatfrac@verbatim,
+ frac whole format/.code={\def\pgfmathresult{##1 }},
+ @dec sep mark=,
+ @sci exponent mark=,
+ }%
+ },
+ retain unit mantissa/.is if=pgfmathfloatround@allow@empty@mantissa,
+ retain unit mantissa/.default=true,
+ retain unit mantissa=true,
+ %
+ % allows to replace the implementation, for example
+ % 'implementation=\num'. This is experimental -- it is unclear
+ % if all consumers work well since they rely on the keys in
+ % /pgf/number format.
+ implementation/.code={\def\pgfmathprintnumber@protected{#1}},
+}
+
+
+
+\def\pgfmathprintnumber@STD#1{%
+ % parse the input:
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathprintnumber@STD@issci\pgfmathresult\relax
+}
+
+\def\pgfmathprintnumber@STD@setparam#1{%
+ \edef\pgfmathfloat@loc@TMPb{#1}%
+ \ifx\pgfmathfloat@loc@TMPb\pgfutil@empty
+ % DEFAULT for lower and upper bound.
+ \def\pgfmathprintnumber@STD@getlowerbound{%
+ \c@pgf@counta=\pgfmathfloat@round@precision@orig\relax
+ \divide\c@pgf@counta by-2\relax
+ }%
+ \def\pgfmathprintnumber@STD@upperbound{4}%
+ \else
+ \expandafter\pgfutil@in@\expandafter:\expandafter{\pgfmathfloat@loc@TMPb}%
+ \ifpgfutil@in@
+ % we have -4:5 or something like that.
+ % parse both values:
+ \def\pgfmathfloat@loc@TMPa##1:##2\relax{%
+ \edef\pgfmathprintnumber@STD@getlowerbound{%
+ \noexpand\c@pgf@counta=##1\space
+ }%
+ \edef\pgfmathprintnumber@STD@upperbound{##2}%
+ }%
+ \expandafter\pgfmathfloat@loc@TMPa\pgfmathfloat@loc@TMPb\relax
+ \else
+ % we have just the lower bound:
+ \def\pgfmathprintnumber@STD@upperbound{4}%
+ \edef\pgfmathprintnumber@STD@getlowerbound{%
+ \noexpand\c@pgf@counta=\pgfmathfloat@loc@TMPb\space
+ }%
+ \fi
+ \fi
+}%
+
+\def\pgfmathprintnumber@STD@issci#1#2e#3\relax{%
+ \expandafter\ifnum#1<3
+ \expandafter\ifnum#3>\pgfmathprintnumber@STD@upperbound\relax
+ \pgfmathprintnumber@SCI@issci#1#2e#3\relax%
+ \else
+ \begingroup
+ \pgfmathprintnumber@STD@getlowerbound
+ \ifnum#3<\c@pgf@counta
+ \pgfmathprintnumber@SCI@issci#1#2e#3\relax%
+ \else
+ \pgfmathprintnumber@FIXED@issci#1#2e#3\relax%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+ \fi
+ \else% nan or inf:
+ \pgfmathfloatrounddisplaystyle#1#2e#3\relax%
+ \fi
+}
+
+\def\pgfmathprintnumber@RELATIVE#1{%
+ % parse the input:
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathprintnumber@RELATIVE@issci\pgfmathresult\relax
+}
+
+\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn{%
+ \pgf@typeout{! Package pgf warning: the use of /pgf/number format/relative is discouraged (buggy). Please use 'relative*' instead or type \string\pgfkeys{/pgf/number format/relative round mode=fixed} into your preamble.}%
+ \global\let\pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn=\relax
+}
+
+\def\pgfmathprintnumber@RELATIVE@issci#1#2e#3\relax{%
+ \begingroup
+ % format X / 10^{relative}:
+ \c@pgf@counta=#3\relax
+ \advance\c@pgf@counta by-\pgfmathprintnumber@RELATIVE@param\relax
+ \pgfmathfloatcreate{#1}{#2}{\the\c@pgf@counta}%
+ % OK, round it to the desired precision:
+ \if0\pgfmathprintnumber@RELATIVE@choice@roundtofixed
+ % relative round mode=mantissa
+ \def\b@round@fixed{0}%
+ \else
+ \if1\pgfmathprintnumber@RELATIVE@choice@roundtofixed
+ % relative round mode=fixed
+ \def\b@round@fixed{1}%
+ \else
+ \pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn
+ % relative round mode=compatible
+ \ifnum\c@pgf@counta>0
+ % hm. for positive exponents, we should round the
+ % mantissa rather than only the fractional part.
+ \def\b@round@fixed{0}%
+ \else
+ % negative exponent -> round fixed representation:
+ \def\b@round@fixed{1}%
+ \fi
+ \fi
+ \fi
+ \if1\b@round@fixed
+ % round fixed representation:
+ \pgfmathfloattofixed\pgfmathresult
+ \expandafter\pgfmathroundto\expandafter{\pgfmathresult}%
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ \pgfmathfloatroundhasperiodtrue% make sure the code below works:
+ \else
+ % round the mantissa:
+ \expandafter\pgfmathfloatround\expandafter{\pgfmathresult}%
+ \fi
+ % Now, compute result * 10^{relative} and format the result:
+ \pgfmathfloattoregisterstok\pgfmathresult\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifnum\pgfmathfloat@a@S=0
+ \pgfmathfloat@a@E=\pgfmathfloat@a@S % avoid 0 * 10^8
+ \else
+ \advance\pgfmathfloat@a@E by+\pgfmathprintnumber@RELATIVE@param\relax
+ \fi
+ \edef\pgfmathresultX{%
+ \the\pgfmathfloat@a@S
+ \the\pgfmathfloat@a@Mtok
+ \ifpgfmathfloatroundhasperiod\else.0\fi
+ e\the\pgfmathfloat@a@E}%
+ % call another formatter for the result (but avoid rounding inside of it):
+ \pgfqkeys{/pgf/number format}{/pgf/number format/every relative,
+ fixed zerofill=false,% useless here!
+ sci zerofill=false}%
+ \ifx\pgfmathprintnumber@issci\pgfmathprintnumber@RELATIVE@issci
+ \pgfmath@error{The '/pgf/number format/every relative' style should set a valid display style}{}%
+ \fi
+ \let\pgfmathfloat@round@precision@orig=\pgfmathfloat@round@precision
+ \def\pgfmathfloat@round@precision{9999}%
+ \expandafter\pgfmathprintnumber@issci\pgfmathresultX\relax%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+\def\pgfmathprintnumber@FIXED@RELATIVE#1{%
+ % parse the input:
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathprintnumber@FIXED@RELATIVE@issci\pgfmathresult\relax
+}
+
+\def\pgfmathprintnumber@FIXED@RELATIVE@issci#1#2e#3\relax{%
+ \begingroup
+ \pgfmathfloatcreate{#1}{#2}{#3}%
+ % we want the first <precision> digits - not the first
+ % <precision>+1 digits:
+ \c@pgf@counta=\pgfmathfloat@round@precision\relax
+ \advance\c@pgf@counta by-1
+ \edef\pgfmathfloat@round@precision{\the\c@pgf@counta}%
+ \pgfmathfloatround{\pgfmathresult}%
+ \pgfmathfloattoregisterstok\pgfmathresult\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \ifnum\pgfmathfloat@a@S=0
+ \pgfmathfloat@a@E=\pgfmathfloat@a@S % avoid 0 * 10^8
+ \fi
+ \edef\pgfmathresultX{%
+ \the\pgfmathfloat@a@S
+ \the\pgfmathfloat@a@Mtok
+ \ifpgfmathfloatroundhasperiod\else.0\fi
+ e\the\pgfmathfloat@a@E}%
+ \let\pgfmathfloat@round@precision@orig=\pgfmathfloat@round@precision
+ \pgfmathfloat@usezerofill@fixedfalse
+ \def\pgfmathfloat@round@precision{9999}% typeset all remaining digits!
+ \expandafter\pgfmathprintnumber@FIXED@issci\pgfmathresultX\relax%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+\def\pgfmathprintnumber@frac#1{%
+ % parse the input:
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloatgetfrac{\pgfmathresult}%
+ \expandafter\pgfmathprintnumber@frac@formatresult\pgfmathresult
+}
+\def\pgfmathprintnumber@frac@issci#1#2e#3\relax{%
+ \pgfmathfloatcreate{#1}{#2}{#3}%
+ \pgfmathfloatgetfrac{\pgfmathresult}%
+ \expandafter\pgfmathprintnumber@frac@formatresult\pgfmathresult
+}
+\def\pgfmathprintnumber@frac@formatresult#1#2#3{%
+ \begingroup
+ \pgfkeysgetvalue{/pgf/number format/frac TeX}\pgfmathresult
+ \toks0=\expandafter{\pgfmathresult}%
+ \def\pgfmathfloat@loc@TMPa{#1}%
+ \ifx\pgfmathfloat@loc@TMPa\pgfutil@empty
+ \ifpgfmathprintnumber@showpositive
+ \def\pgfmathfloat@loc@TMPa{+}%
+ \fi
+ \else
+ \ifx\pgfmathfloat@loc@TMPa-%
+ \else
+ \ifx\pgfmathfloat@loc@TMPa+%
+ \else
+ \ifpgfmathprintnumber@showpositive
+ \edef\pgfmathfloat@loc@TMPa{+\pgfmathfloat@loc@TMPa}%
+ \fi
+ \def\pgfmathfloat@loc@TMPb{\pgfkeysvalueof{/pgf/number format/frac whole format/.@cmd}}%
+ \expandafter\pgfmathfloat@loc@TMPb\pgfmathfloat@loc@TMPa\pgfeov
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \fi
+ \fi
+ \fi
+ \toks1=\expandafter{\pgfmathfloat@loc@TMPa}%
+ \edef\pgfmathresult{%
+ \the\toks1 \ifnum#2=0 \else\the\toks0 {#2}{#3}\fi%
+ }%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+% Defines \pgfmathresult to contain three sets of braces containing
+% the sign (optionally containing any components >1), the numerator and the denominator for #1.
+%
+% \pgfmathfloatgetfrac{0.5} -> \pgfmathresult contains {}{1}{2}
+% \pgfmathfloatgetfrac{-0.5} -> \pgfmathresult contains {-}{1}{2}
+% \pgfmathfloatgetfrac{1.5} -> \pgfmathresult contains {1}{1}{2}
+%
+% special cases:
+% \pgfmathfloatgetfrac{0} -> \pgfmathresult contains {0}{0}{1}
+% \pgfmathfloatgetfrac{1} -> \pgfmathresult contains {1}{0}{1}
+%
+% The numerator and denominator is always a number (not empty)
+\def\pgfmathfloatgetfrac#1{%
+ \pgfutil@ifundefined{pgfmathfloatmultiply@}{%
+ \pgfmath@error{Sorry, the number format 'frac' requires '\string\usetikzlibrary{fpu}' (and, optionally, \string\usepackage{fp}) in order to work correctly}{}%
+ \edef\pgfmathresult{{#1}{0}{1}}%
+ }{%
+ \pgfmathfloatgetfrac@{#1}%
+ }%
+}%
+\def\pgfmathfloatgetfrac@#1{%
+ \begingroup
+ \edef\pgfmathfloat@arg{#1}%
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathfloat@arg\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \def\pgfmathfloat@loc@TMPa{0}%
+ \ifcase\pgfmathfloat@a@S
+ % #1 = 0:
+ \def\pgfmathresult{{0}{0}{1}}%
+ \or% #1 > 0
+ \pgfmathfloat@a@S=1
+ \def\pgfmathfloat@loc@TMPa{1}%
+ \or% #1 < 0
+ \pgfmathfloat@a@S=-1
+ \def\pgfmathfloat@loc@TMPa{1}%
+ \or
+ \edef\pgfmathresult{{}{NaN}{1}}%
+ \or
+ \edef\pgfmathresult{{}{\infty}{1}}%
+ \or
+ \edef\pgfmathresult{{-}{\infty}{1}}%
+ \fi
+ \if1\pgfmathfloat@loc@TMPa
+ \ifnum\pgfmathfloat@a@E<0
+ \def\pgfmathfloat@wholenumber{}%
+ \else
+ \pgfmathfloatcreate{1}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \pgfmathfloattofixed\pgfmathresult%
+ \def\pgfmathfloat@loc@TMPa##1.##2\relax{%
+ \def\pgfmathfloat@wholenumber{##1}%
+ \pgfmathfloatparsenumber{0.##2}%
+ }%
+ \expandafter\pgfmathfloat@loc@TMPa\pgfmathresult\relax
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@b@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \fi
+ %
+ \def\pgfmathfloat@loc@TMPa##1.##2\relax{%
+ \def\pgfmathfloat@mantissa@first{##1}%
+ \def\pgfmathfloat@mantissa@ltone{0.##2}%
+ }%
+ \expandafter\pgfmathfloat@loc@TMPa\the\pgfmathfloat@a@Mtok\relax
+ %
+ \def\pgfmathfloat@loc@@to@int##1.##2\relax##3{%
+ ##3=##1
+ \ifdim0.##2pt>0.5pt
+ \advance##3 by1
+ \fi
+ }%
+ %
+ % alias registers names:
+ \let\pgfmathresultnumerator=\pgfmathfloat@b@S
+ \let\pgfmathresultdenom=\pgfmathfloat@b@E
+ %
+ \pgfkeysgetvalue{/pgf/number format/frac denom}\pgfmath@target@denominator
+ \ifx\pgfmath@target@denominator\pgfutil@empty
+ %
+ \pgfmathfloat@a@E=-\pgfmathfloat@a@E
+ \ifdim\pgfmathfloat@mantissa@ltone pt=0pt
+ \def\pgfmathfloat@factor{1}%
+ \edef\pgfmathfloat@scaled@numerator{\the\pgfmathfloat@a@Mtok}%
+ \else
+ % FIXME : this here is numerically instable.
+ %
+ % The errors of 1/r are magnified by 10^k which
+ % doesn't work.
+ \pgfutil@ifundefined{FPdiv}{%
+ \pgfmathfloatparsenumber{\pgfmathfloat@mantissa@ltone}%
+ \pgfmathfloatreciprocal@{\pgfmathresult}%
+ }{%
+ % \usepackage{fp}.
+ % yields higher absolute precision.
+ \FPmessagesfalse%
+ \FPdebugfalse%
+ \FPdiv\pgfmathresult{1}{\pgfmathfloat@mantissa@ltone}%
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ }%
+ \let\pgfmathfloat@inv=\pgfmathresult
+ \pgfmathfloatcreate{1}{1.0}{\pgfkeysvalueof{/pgf/number format/frac shift}}%
+ \let\pgfmathfloat@scalebaseten=\pgfmathresult
+ \pgfmathfloatmultiply@{\pgfmathfloat@inv}{\pgfmathfloat@scalebaseten}%
+ \let\pgfmathfloat@factor=\pgfmathresult
+ %
+ \expandafter\pgfmathfloatparsenumber\expandafter{\the\pgfmathfloat@a@Mtok}%
+ \let\pgfmathfloat@loc@TMPa=\pgfmathresult
+ \pgfmathfloatmultiply@{\pgfmathfloat@factor}{\pgfmathfloat@loc@TMPa}%
+ \pgfmathfloattofixed\pgfmathresult
+ \let\pgfmathfloat@scaled@numerator=\pgfmathresult
+ %
+ \pgfmathfloattofixed\pgfmathfloat@factor
+ \expandafter\pgfmathfloat@loc@@to@int\pgfmathresult\relax{\pgfmathfloat@b@S}%
+ \edef\pgfmathfloat@factor{\the\pgfmathfloat@b@S}%
+ \fi
+ %
+ %
+ \pgfmathresultdenom=\pgfmathfloat@factor\relax
+ \pgfmathfloat@multiply@ten@to@the@E\pgfmathresultdenom
+ %
+ \expandafter\pgfmathfloat@loc@@to@int\pgfmathfloat@scaled@numerator\relax{\pgfmathresultnumerator}%
+ %\message{scale = \pgfmathfloat@factor; Z = \the\pgfmathresultnumerator\space ( von \pgfmathfloat@scaled@numerator), N = \the\pgfmathresultdenom.}%
+ %
+ \pgfmathgreatestcommondivisor{\pgfmathresultnumerator}{\pgfmathresultdenom}%
+ \divide\pgfmathresultnumerator by\pgfmathresult\relax
+ \divide\pgfmathresultdenom by\pgfmathresult\relax
+ \ifpgfmathprintnumber@frac@warn
+ \ifnum\pgfmathresultdenom>1000
+ \pgfutil@ifundefined{FPdiv}{%
+ \pgfmathfloattosci@\pgfmathfloat@arg
+ \pgf@typeout{! Package pgf /pgf/number format/frac warning=true: /pgf/number format/frac of `\pgfmathresult' = \the\pgfmathresultnumerator\space / \the\pgfmathresultdenom\space might be large due to instabilities. Try \string\usepackage{fp} to improve accuracy.}%
+ }{}%
+ \fi
+ \fi
+ \else
+ % use target denominator:
+ \pgfmathresultdenom=\pgfmath@target@denominator\relax
+ \pgfmathfloatcreate{1}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}%
+ \pgfmathfloattofixed\pgfmathresult
+ \pgf@xa=\pgfmathresult pt
+ \multiply\pgf@xa by\pgfmathresultdenom
+ \edef\pgfmathfloat@scaled@numerator{\pgfmath@tonumber\pgf@xa}%
+ \expandafter\pgfmathfloat@loc@@to@int\pgfmathfloat@scaled@numerator\relax{\pgfmathresultnumerator}%
+ \fi
+ \ifpgfmathprintnumber@frac@whole
+ \else
+ \ifx\pgfmathfloat@wholenumber\pgfutil@empty
+ \else
+ \count0=\pgfmathfloat@wholenumber\relax
+ \multiply\count0 by\pgfmathresultdenom
+ \advance\pgfmathresultnumerator by\count0
+ \def\pgfmathfloat@wholenumber{}%
+ \fi
+ \fi
+ \ifnum\pgfmathfloat@a@S<0
+ \edef\pgfmathresult{{-\pgfmathfloat@wholenumber}{\the\pgfmathresultnumerator}{\the\pgfmathresultdenom}}%
+ \else
+ \edef\pgfmathresult{{\pgfmathfloat@wholenumber}{\the\pgfmathresultnumerator}{\the\pgfmathresultdenom}}%
+ \fi
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+\def\pgfmathfloat@gobble@until@relax#1\relax{}
+
+% computes the greatest common divisor of two integer numbers (in
+% integer arithmetics).
+\def\pgfmathgreatestcommondivisor#1#2{%
+ \begingroup
+ \count0=#1\relax
+ \count1=#2\relax
+ \ifnum\count0=0
+ \edef\pgfmathresult{\the\count1}%
+ \else
+ \pgfmathgreatestcommondivisor@loop
+ \edef\pgfmathresult{\the\count0}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+\def\pgfmathgreatestcommondivisor@loop{%
+ \ifnum\count1=0
+ \else
+ \ifnum\count0>\count1
+ \advance\count0 by-\count1
+ \else
+ \advance\count1 by-\count0
+ \fi
+ \expandafter\pgfmathgreatestcommondivisor@loop
+ \fi
+}%
+
+% multiplies a TeX register by 10^E where E is stored in the register
+% \pgfmathfloat@a@E (and it should be positive!)%
+%
+% #1 a TeX register
+\def\pgfmathfloat@multiply@ten@to@the@E#1{%
+ \ifnum\pgfmathfloat@a@E>0
+ \multiply#1 by10
+ \advance\pgfmathfloat@a@E by-1
+ \def\pgfmathfloat@multiply@ten@to@the@E@next{\pgfmathfloat@multiply@ten@to@the@E{#1}}%
+ \else
+ \let\pgfmathfloat@multiply@ten@to@the@E@next=\relax%
+ \fi
+ \pgfmathfloat@multiply@ten@to@the@E@next
+}%
+
+\def\pgfmathprintnumber@INT@TRUNC#1{%
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathprintnumber@INT@TRUNC@issci\pgfmathresult\relax
+}
+
+\def\pgfmathprintnumber@INT@TRUNC@impl#1.#2\relax#3#4e#5\relax{%
+ \pgfmathfloatroundhasperiodfalse
+ \pgfmathprintnumber@fixed@style{#1}#3#4e#5\relax%
+}
+\def\pgfmathprintnumber@INT@TRUNC@issci#1#2e#3\relax{%
+ \ifnum#1<3\relax
+ \pgfmathfloatcreate{#1}{#2}{#3}%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \expandafter\pgfmathprintnumber@INT@TRUNC@impl\pgfmathresult\relax#1#2e#3\relax
+ \else
+ \pgfmathfloatrounddisplaystyle#1#2e#3\relax%
+ \fi
+}
+
+% Invokes '#2' if '#1' is actually an integer or '#3' if not.
+%
+% As a side-effect, \pgfretval will be set to the integer value if it
+% actually *is* an integer. Otherwise, \pgfretval will contain the
+% parsed floating point number.
+%
+% #1 a number constant (not necessarily a parsed float).
+\def\pgfmathifisint#1#2#3{%
+ \gdef\pgfmathfloatisint@@{0}%
+ \begingroup
+ \pgfmathfloatparsenumber{#1}%
+ \let\pgfretval\pgfmathresult
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathfloatisint@\pgfmathresult\relax
+ \pgfmath@smuggleone\pgfretval
+ \endgroup
+ \if1\pgfmathfloatisint@@ #2\else #3\fi
+}%
+\def\pgfmathfloatisint@#1#2e#3\relax{%
+ \ifnum#1<3\relax
+ \pgfmathfloatcreate{#1}{#2}{#3}%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \def\pgfmathfloat@round@precision{6}%
+ \expandafter\pgfmathroundto\expandafter{\pgfmathresult}%
+ \ifpgfmathfloatroundhasperiod
+ \else
+ \let\pgfretval\pgfmathresult%
+ \gdef\pgfmathfloatisint@@{1}%
+ \fi
+ \fi
+}
+
+\def\pgfmathprintnumber@INT@DETECT#1{%
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathprintnumber@INT@DETECT@issci\pgfmathresult\relax
+}
+
+\def\pgfmathprintnumber@INT@DETECT@issci#1#2e#3\relax{%
+ \begingroup
+ \ifnum#1<3\relax
+ \pgfmathfloatcreate{#1}{#2}{#3}%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \let\pgfmathfloat@round@precision@=\pgfmathfloat@round@precision
+ \def\pgfmathfloat@round@precision{6}%
+ \expandafter\pgfmathroundto\expandafter{\pgfmathresult}%
+ \let\pgfmathfloat@round@precision=\pgfmathfloat@round@precision@
+ \ifpgfmathfloatroundhasperiod
+ \pgfmathprintnumber@SCI@issci#1#2e#3\relax
+ \else
+ \expandafter\pgfmathprintnumber@fixed@style\expandafter{\pgfmathresult}#1#2e#3\relax
+ \fi
+ \else
+ \pgfmathfloatrounddisplaystyle#1#2e#3\relax%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+\def\pgfmathprintnumber@FIXED#1{%
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathprintnumber@FIXED@issci\pgfmathresult\relax
+}
+
+\def\pgfmathprintnumber@FIXED@issci#1#2e#3\relax{%
+ \begingroup
+ \ifnum#1<3
+ \pgfmathfloatcreate{#1}{#2}{#3}%
+ \pgfmathfloattofixed{\pgfmathresult}%
+ \ifpgfmathfloat@usezerofill@fixed
+ \expandafter\pgfmathroundtozerofill\expandafter{\pgfmathresult}%
+ \else
+ \expandafter\pgfmathroundto\expandafter{\pgfmathresult}%
+ \fi
+ \ifpgfmathfloatroundmayneedrenormalize
+ \pgfmathfloat@a@E=#3\relax
+ \advance\pgfmathfloat@a@E by1
+ \edef\pgfmathfloat@loc@TMPb{\noexpand\pgfmathprintnumber@fixed@style{\pgfmathresult}#1#2e\the\pgfmathfloat@a@E}%
+ \pgfmathfloat@loc@TMPb\relax%
+ \else
+ \expandafter\pgfmathprintnumber@fixed@style\expandafter{\pgfmathresult}#1#2e#3\relax%
+ \fi
+ \else% nan or inf:
+ \pgfmathfloatrounddisplaystyle#1#2e#3\relax%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+
+\def\pgfmathprintnumber@SCI#1{%
+ \pgfmathfloatparsenumber{#1}%
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathprintnumber@SCI@issci\pgfmathresult\relax
+}
+
+\def\pgfmathprintnumber@SCI@issci#1#2e#3\relax{%
+ \begingroup
+ \pgfmathfloatcreate{#1}{#2}{#3}%
+ \edef\pgfmathfloat@round@precision{\pgfmathprintnumber@sci@precision}%
+ \ifpgfmathfloat@usezerofill@sci
+ \pgfmathfloatroundzerofill{\pgfmathresult}%
+ \else
+ \pgfmathfloatround{\pgfmathresult}%
+ \fi
+ \pgfmathfloat@to@FMeE@style\pgfmathresult
+ \expandafter\pgfmathfloatrounddisplaystyle\pgfmathresult\relax
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+% Prints argument #1 using the current pretty printer environment (all
+% variables in /pgf/number format).
+%
+% You may specify optional arguments with \pgfmathprintnumber[...].
+\pgfutil@protected\def\pgfmathprintnumber{%
+ \pgfutil@ifnextchar[%
+ {\pgfmathprintnumber@OPT}%
+ {\pgfmathprintnumber@noopt}%
+}
+
+\def\pgfmathprintnumber@noopt#1{%
+ \pgfmathprintnumber@{#1}%
+ \ifpgfmathprintnumber@assumemathmode
+ \pgfmathresult
+ \else
+ \pgfutilensuremath{\pgfmathresult}%
+ \fi
+}%
+\def\pgfmathprintnumber@OPT[#1]#2{%
+ \begingroup
+ \pgfqkeys{/pgf/number format}{#1}%
+ \pgfmathprintnumber@{#2}%
+ \ifpgfmathprintnumber@assumemathmode
+ \pgfmathresult
+ \else
+ \pgfutilensuremath{\pgfmathresult}%
+ \fi
+ \endgroup
+}%
+
+% As \pgfmathprintnumber, but it produces its output into the second
+% argument.
+\def\pgfmathprintnumberto{%
+ \pgfutil@ifnextchar[%
+ {\pgfmathprintnumberto@OPT}%
+ {\pgfmathprintnumberto@noopt}%
+}
+
+\def\pgfmathprintnumberto@noopt#1#2{%
+ \begingroup
+ \pgfmathprintnumber@{#1}%
+ \ifpgfmathprintnumber@assumemathmode
+ \global\let\pgfmathfloat@glob@TMP=\pgfmathresult
+ \else
+ \toks0=\expandafter{\pgfmathresult}%
+ \xdef\pgfmathfloat@glob@TMP{\noexpand\pgfutilensuremath{\the\toks0 }}%
+ \fi
+ \endgroup
+ \let#2=\pgfmathfloat@glob@TMP
+}%
+\def\pgfmathprintnumberto@OPT[#1]#2#3{%
+ \begingroup
+ \pgfqkeys{/pgf/number format}{#1}%
+ \pgfmathprintnumber@{#2}%
+ \ifpgfmathprintnumber@assumemathmode
+ \global\let\pgfmathfloat@glob@TMP=\pgfmathresult
+ \else
+ \toks0=\expandafter{\pgfmathresult}%
+ \xdef\pgfmathfloat@glob@TMP{\noexpand\pgfutilensuremath{\the\toks0 }}%
+ \fi
+ \endgroup
+ \let#3=\pgfmathfloat@glob@TMP
+}%
+
+
+% Changes the current number pretty printer to #1.
+%
+% #1 is the macro base name for the pretty print routine, without the
+% leading '\'.
+\def\pgfmath@set@number@printer#1{%
+ \expandafter\let\expandafter\pgfmathprintnumber@\csname #1\endcsname
+ \expandafter\let\expandafter\pgfmathprintnumber@issci\csname #1@issci\endcsname
+}
+
+\pgfkeys{/pgf/number format/std}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IMPL
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% equals only itself when compared with \ifx:
+\def\pgfmathfloat@EOI{\pgfmathfloat@EOI}%
+
+% Re-use counters internally.
+%
+% They are always grouped and only used inside of the rounding
+% routines.
+\let\c@pgfmathroundto@prec=\pgfmathfloat@b@S% ATTENTION: DOUBLE-USED REGISTERS!
+\let\c@pgfmathroundto@offsetbehindperiod=\pgfmathfloat@b@E
+\newcount\c@pgfmathroundto@lastzeros
+
+\newif\ifpgfmathround@impl@PREPERIOD@is@negative@zero
+
+% PRECONDITION:
+% \ifpgfmathfloatroundhasperiod=\iftrue holds outside of the current TeX group.
+%
+% POSTCONDITION:
+% \ifpgfmathfloatroundhasperiod will be set correctly AFTER the
+% current TeX group.
+% \ifpgfmathfloatroundmayneedrenormalize will be set globally
+\def\pgfmathroundto@impl#1{%
+ \edef\pgfmathround@input{#1}%
+ \global\pgfmathfloatroundmayneedrenormalizefalse
+ \pgfmathfloat@tmptoks={}%
+ \let\pgfmathround@next=\pgfutil@empty
+ \let\pgfmathround@cur=\pgfutil@empty
+ \let\pgfmathresult=\pgfutil@empty
+ \expandafter\c@pgfmathroundto@prec\pgfmathfloat@round@precision\relax
+ \c@pgfmathroundto@lastzeros=0
+ \c@pgfmathroundto@offsetbehindperiod=-1 % means: no period found so far
+ \pgfmathround@impl@PREPERIOD@is@negative@zerotrue
+ \expandafter\pgfmathroundto@impl@ITERATE@NODOT@firstcall\pgfmathround@input\pgfmathfloat@EOI
+}
+
+% \pgfmathroundto implementation in WORDS:
+%
+% coarse idea:
+% 1. collect all digits/sign BEFORE the first period in REVERSE order
+% 2. then, collect UP TO \prec digits after the period in REVERSE order
+% Steps 1. and 2. lead to the digit [sign] sequence
+% "x_{-p} x_{-p+1} ... x_{-2} x_{-1} '.' x_0 ... x_r"
+% where 'r' is the total number of digits. The integer 'p' denotes the
+% ACTUALLY collected number of digits behind the period.
+%
+% Let 'k' be the desired precision.
+%
+% Please note that pgfmathroundto rounds the mantissa, that means |abs(x)|.
+%
+% There are exactly TWO cases:
+% 1. The case with p<=k and x_{-p-1} = end of input.
+% 2. The case with p=k and x_{-p-1} is a further, next character.
+%
+% Then, for case 1.):
+% discard any unused zeros at the tail of our number (possibly
+% including the period)
+%
+% and in case 2.)
+% if NEXT DIGIT < 5:
+% do exactly the same as in case 1.) above and discard any
+% following digits.
+% else
+% let q := -p
+% while(x_q = 9 and q<=r )
+% if q>=0
+% set x_q = '0'
+% else
+% discard digit x_q='9'
+% fi
+% ++q
+% if q=0
+% discard the period
+% fi
+% end while
+% if q = r+1
+% insert a '1'
+% else
+% set x_q = x_q + 1
+% fi
+% fi
+%
+% All these loops have been implemented in spaghetti-code below.
+% Sorry, I fear its hard to understand. In principle, everything is
+% realised using more or less finite state machines (with some number
+% counting logic).
+%
+% Some comments:
+% - The token register \pgfmathfloat@tmptoks is used to accumulate the REVERSED input number.
+% - \pgfmathfloat@EOI always denotes 'END OF INPUT'.
+% - in the second stage, we need to reverse \pgfmathfloat@tmptoks.
+% This is -- again -- done with \pgfmathfloat@tmptoks.
+
+\def\pgfmathroundto@impl@discard@period#1.#2\pgfmathfloat@EOI{%
+ \pgfmathfloatroundhasperiodfalse
+ \aftergroup\pgfmathfloatroundhasperiodfalse
+ \def\pgfmathresult{#1}%
+}
+
+\def\pgfmathroundto@impl@gobble@rest@and@start#1\pgfmathfloat@EOI{%
+ \pgfmathroundto@impl@start
+}
+\def\pgfmathroundto@impl@gobble@and@start\pgfmathfloat@EOI{%
+ \pgfmathroundto@impl@start
+}
+\def\pgfmathroundto@impl@gobble\pgfmathfloat@EOI{}%
+\def\pgfmathroundto@impl@gobble@rest#1\pgfmathfloat@EOI{}%
+
+% This method will be invoked as soon as the first step, the reverse
+% collection of up to PREC digits after the period, has finished.
+\def\pgfmathroundto@impl@start{%
+ \ifx\pgfmathround@next\pgfutil@empty
+ \ifnum\c@pgfmathroundto@offsetbehindperiod<0
+ % no period found.
+ \ifpgfmathfloat@fixed@digits@after@period
+ \ifnum\c@pgfmathroundto@prec=0\relax
+ \pgfmathfloatroundhasperiodfalse
+ \aftergroup\pgfmathfloatroundhasperiodfalse
+ \edef\pgfmathresult{\pgfmathround@input}%
+ \else
+ \pgfmathfloat@tmptoks=\expandafter{\pgfmathround@input.}%
+ \c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec
+ \pgfmathroundto@impl@append@zeros
+ \edef\pgfmathresult{\the\pgfmathfloat@tmptoks}%
+ \fi
+ \else
+ \pgfmathfloatroundhasperiodfalse
+ \aftergroup\pgfmathfloatroundhasperiodfalse
+ \edef\pgfmathresult{\pgfmathround@input}%
+ \fi
+ \else
+ %\ifnum\c@pgfmathroundto@offsetbehindperiod>\c@pgfmathroundto@prec
+ % \pgfmath@error{Internal logic error in pgfmathroundto at [I] - should not have happened!?}{}%
+ %\fi
+ \pgfmathroundto@impl@finish@with@truncation
+ \fi
+ \else
+ %\ifnum\c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec
+ %\else
+ % \pgfmath@error{Internal logic error in pgfmathroundto at [II] - should not have happened!? I have offsetbehindperiod=\the\c@pgfmathroundto@offsetbehindperiod and prec = \the\c@pgfmathroundto@prec}{}%
+ %\fi
+ \expandafter\ifnum\pgfmathround@next<5\relax
+ \pgfmathroundto@impl@finish@with@truncation
+ \else
+ \multiply\c@pgfmathroundto@offsetbehindperiod by-1
+ \expandafter\pgfmathroundto@impl@ADD@ONE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI
+ \fi
+ \fi
+}
+
+% takes the current input and decides whether trailing zeros shall be
+% discarded or more zeros need to be filled in.
+\def\pgfmathroundto@impl@finish@with@truncation{%
+ \ifpgfmathfloat@fixed@digits@after@period
+ \expandafter\pgfmathroundto@impl@REVERSE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI
+ \ifnum\c@pgfmathroundto@lastzeros=\c@pgfmathroundto@offsetbehindperiod
+ \ifpgfmathround@impl@PREPERIOD@is@negative@zero
+ % write '0.0000' instead of '-0.0000':
+ \expandafter\pgfmathroundto@impl@discard@minus\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI
+ \fi
+ \fi
+ \ifnum\c@pgfmathroundto@prec=0\relax
+ \expandafter\pgfmathroundto@impl@discard@period\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI
+ \else
+ \advance\c@pgfmathroundto@prec by-\c@pgfmathroundto@offsetbehindperiod
+ \c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec
+ \pgfmathroundto@impl@append@zeros
+ \edef\pgfmathresult{\the\pgfmathfloat@tmptoks}%
+ \fi
+ \else
+ \pgfmathroundto@impl@discard@suffix@zeros
+ \fi
+}
+
+\def\pgfmathroundto@impl@discard@minus-#1\pgfmathfloat@EOI{\pgfmathfloat@tmptoks={#1}}%
+
+% appends \c@pgfmathroundto@offsetbehindperiod zeros at the end of \pgfmathfloat@tmptoks.
+\def\pgfmathroundto@impl@append@zeros{%
+ \ifnum\c@pgfmathroundto@offsetbehindperiod>0
+ \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}%
+ \advance\c@pgfmathroundto@offsetbehindperiod by-1
+ \pgfmathroundto@impl@append@zeros
+ \fi
+}
+
+\def\pgfmathroundto@impl@ADD@ONE{%
+ \pgfmathfloat@tmptoks={}% no longer needed because its old value will be read from input
+ \pgfmathroundto@impl@ADD@ONE@ITERATE
+}
+\def\pgfmathroundto@impl@ADD@ONE@ITERATE{%
+ \pgfutil@ifnextchar\pgfmathfloat@EOI{%
+ \global\pgfmathfloatroundmayneedrenormalizetrue
+ \edef\pgfmathresult{1\the\pgfmathfloat@tmptoks}%
+ \pgfmathroundto@impl@gobble
+ }{%
+ \pgfutil@ifnextchar.{%
+ \ifnum\c@pgfmathroundto@prec=0
+ % silently discard period in special case precision=0
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE@gobble@dot}%
+ \else
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@NEXT@COLLECT}%
+ \fi
+ \pgfmathround@nextcmd
+ }{%
+ \pgfutil@ifnextchar+{%
+ \global\pgfmathfloatroundmayneedrenormalizetrue
+ \edef\pgfmathresult{1\the\pgfmathfloat@tmptoks}%
+ \pgfmathroundto@impl@gobble@rest
+ }{%
+ \pgfutil@ifnextchar-{%
+ \global\pgfmathfloatroundmayneedrenormalizetrue
+ \edef\pgfmathresult{-1\the\pgfmathfloat@tmptoks}%
+ \pgfmathroundto@impl@gobble@rest
+ }{%
+ \pgfmathroundto@impl@ADD@ONE@NEXT
+ }%
+ }%
+ }%
+ }%
+}
+
+\def\pgfmathroundto@impl@ADD@ONE@ITERATE@gobble@dot.{%
+ \pgfmathfloatroundhasperiodfalse
+ \aftergroup\pgfmathfloatroundhasperiodfalse
+ \pgfmathroundto@impl@ADD@ONE@ITERATE
+}
+
+\def\pgfmathroundto@impl@ADD@ONE@NEXT@COLLECT#1{%
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}%
+ \pgfmathroundto@impl@ADD@ONE@ITERATE
+}
+\def\pgfmathroundto@impl@ADD@ONE@NEXT#1{%
+ \ifnum#1=9
+ \ifnum\c@pgfmathroundto@offsetbehindperiod<0
+ \ifpgfmathfloat@fixed@digits@after@period
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter0\the\pgfmathfloat@tmptoks}%
+ \else
+ % silently DROP digit
+ \fi
+ \else
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter0\the\pgfmathfloat@tmptoks}%
+ \fi
+ \advance\c@pgfmathroundto@offsetbehindperiod by1
+ \ifnum\c@pgfmathroundto@offsetbehindperiod=0
+ \ifpgfmathfloat@fixed@digits@after@period
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE}%
+ \else
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE@gobble@dot}%
+ \fi
+ \else
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ADD@ONE@ITERATE}%
+ \fi
+ \else
+ % re-use this counter:
+ \c@pgfmathroundto@lastzeros=#1
+ \advance\c@pgfmathroundto@lastzeros by1
+ \edef\pgfmathresult{\the\c@pgfmathroundto@lastzeros\the\pgfmathfloat@tmptoks}%
+ \pgfmathfloat@tmptoks=\expandafter{\pgfmathresult}%
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@REVERSE@ITERATE}%
+ \fi
+ \pgfmathround@nextcmd
+}
+
+
+\def\pgfmathroundto@impl@discard@suffix@zeros{%
+ \ifnum\c@pgfmathroundto@lastzeros=\c@pgfmathroundto@offsetbehindperiod
+ \ifpgfmathround@impl@PREPERIOD@is@negative@zero
+ \pgfmathfloatroundhasperiodfalse
+ \aftergroup\pgfmathfloatroundhasperiodfalse
+ \def\pgfmathresult{0}% write '0' instead of '-0'
+ \else
+ \expandafter\pgfmathroundto@impl@discard@period\pgfmathround@input\pgfmathfloat@EOI
+ \fi
+ \else
+ \ifnum\c@pgfmathroundto@lastzeros=0
+ \expandafter\pgfmathroundto@impl@REVERSE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI
+ \else
+ \expandafter\pgfmathroundto@impl@discard@suffix@zeros@ITERATE\the\pgfmathfloat@tmptoks\pgfmathfloat@EOI
+ \fi
+ \fi
+}
+
+% PRECONDITION:
+% \c@pgfmathroundto@lastzeros > 0
+\def\pgfmathroundto@impl@discard@suffix@zeros@ITERATE#1{%
+ \advance\c@pgfmathroundto@lastzeros by-1
+ \ifnum\c@pgfmathroundto@lastzeros=0
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@REVERSE}%
+ \else
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@discard@suffix@zeros@ITERATE}%
+ \fi
+ \pgfmathround@nextcmd
+}
+
+% Usage:
+% \pgfmathroundto@impl@REVERSE#1\pgfmathfloat@EOI
+% -> writes #1 reversed into \pgfmathfloat@tmptoks
+\def\pgfmathroundto@impl@REVERSE{%
+ \pgfmathfloat@tmptoks={}%
+ \pgfmathroundto@impl@REVERSE@ITERATE
+}
+
+\def\pgfmathroundto@impl@REVERSE@ITERATE{%
+ \pgfutil@ifnextchar\pgfmathfloat@EOI{%
+ \edef\pgfmathresult{\the\pgfmathfloat@tmptoks}%
+ \pgfmathroundto@impl@gobble
+ }{%
+ \pgfmathroundto@impl@REVERSE@NEXT
+ }%
+}
+
+\def\pgfmathroundto@impl@REVERSE@NEXT#1{%
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}%
+ \pgfmathroundto@impl@REVERSE@ITERATE
+}
+
+\def\pgfmathroundto@impl@BEGIN@DOT.{%
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter.\the\pgfmathfloat@tmptoks}%
+ \c@pgfmathroundto@offsetbehindperiod=0
+ \pgfmathroundto@impl@ITERATE@DOT
+}
+\def\pgfmathroundto@impl@ITERATE@DOT{%
+ \pgfutil@ifnextchar\pgfmathfloat@EOI{%
+ % finished.
+ \pgfmathroundto@impl@gobble@and@start
+ }{%
+ \pgfmathroundto@impl@NEXT@DOT
+ }%
+}
+\def\pgfmathroundto@impl@NEXT@DOT#1{%
+ \ifnum\c@pgfmathroundto@offsetbehindperiod=\c@pgfmathroundto@prec
+ \def\pgfmathround@next{#1}%
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@gobble@rest@and@start}%
+ \else
+ \advance\c@pgfmathroundto@offsetbehindperiod by1
+ \ifnum#1=0
+ \advance\c@pgfmathroundto@lastzeros by1
+ \else
+ \c@pgfmathroundto@lastzeros=0
+ \fi
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}%
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ITERATE@DOT}%
+ \fi
+ \pgfmathround@nextcmd
+}%
+
+% in contrast to pgfmathroundto@impl@ITERATE@NODOT, this method here
+% checks also for signs
+\def\pgfmathroundto@impl@ITERATE@NODOT@firstcall#1{%
+ \def\pgfmathround@cur{#1}%
+ \ifx\pgfmathround@cur\pgfmathfloat@EOI
+ \pgfmathround@impl@PREPERIOD@is@negative@zerofalse
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@start}%
+ \else
+ \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@PERIOD
+ \pgfmathround@impl@PREPERIOD@is@negative@zerofalse
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@BEGIN@DOT.}%
+ \else
+ \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@MINUS
+ \else
+ \pgfmathround@impl@PREPERIOD@is@negative@zerofalse
+ \fi
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}%
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ITERATE@NODOT}%
+ \fi
+ \fi
+ \pgfmathround@nextcmd
+}
+
+\def\pgfmathroundto@impl@ITERATE@NODOT#1{%
+ \def\pgfmathround@cur{#1}%
+ \ifx\pgfmathround@cur\pgfmathfloat@EOI
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@start}%
+ \else
+ \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@PERIOD
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@BEGIN@DOT.}%
+ \else
+ \ifx\pgfmathround@cur\pgfmathfloatparsenumber@tok@ZERO
+ \else
+ \pgfmathround@impl@PREPERIOD@is@negative@zerofalse
+ \fi
+ \pgfmathfloat@tmptoks=\expandafter{\expandafter#1\the\pgfmathfloat@tmptoks}%
+ \def\pgfmathround@nextcmd{\pgfmathroundto@impl@ITERATE@NODOT}%
+ \fi
+ \fi
+ \pgfmathround@nextcmd
+}
+
+%--------------------------------------------
+% END of pgfmathroundto implementation.
+%--------------------------------------------
+
+
+% flags, mantissa and exponent has already been stored into
+% \pgfmathfloat@a@* [using ...@Mtok]
+%
+% PRECONDITION:
+% \ifpgfmathfloatroundhasperiod = \iftrue outside of the current
+% group
+%
+% POSTCONDITION:
+% \ifpgfmathfloatroundhasperiod will be set after the current TeX
+% group.
+\def\pgfmathfloatround@impl{%
+ \expandafter\pgfmathroundto@impl\expandafter{\the\pgfmathfloat@a@Mtok}%
+ \ifpgfmathfloatroundmayneedrenormalize
+ \ifpgfmathfloatroundhasperiod
+ \expandafter\pgfmathfloatround@impl@renormalize\pgfmathresult\pgfmathfloat@EOI%
+ \else
+ \expandafter\pgfmathfloatround@impl@renormalize\pgfmathresult.\pgfmathfloat@EOI%
+ \fi
+ \advance\pgfmathfloat@a@E by1
+ \fi
+ \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\pgfmathresult}{\the\pgfmathfloat@a@E}%
+}
+
+\def\pgfmathfloatround@impl@renormalize#1#2.#3\pgfmathfloat@EOI{%
+ \pgfmathroundto@impl{#1.#2#3}%
+}
+
+
+
+
+
+% ATTENTION: this thing REQUIRES a period in the mantissa!
+% collects everything into \pgfmathresult
+\def\pgfmathfloattofixed@impl#1.#2\relax{%
+ \ifnum\pgfmathfloat@a@E<0
+ \ifcase-\pgfmathfloat@a@E
+ \or%e-1
+ \pgfmathfloat@a@Mtok={0.}%
+ \or%e-2
+ \pgfmathfloat@a@Mtok={0.0}%
+ \or%e-3
+ \pgfmathfloat@a@Mtok={0.00}%
+ \or%e-4
+ \pgfmathfloat@a@Mtok={0.000}%
+ \or%e-5
+ \pgfmathfloat@a@Mtok={0.0000}%
+ \or%e-6
+ \pgfmathfloat@a@Mtok={0.00000}%
+ \or%e-7
+ \pgfmathfloat@a@Mtok={0.000000}%
+ \or%e-8
+ \pgfmathfloat@a@Mtok={0.0000000}%
+ \or%e-9
+ \pgfmathfloat@a@Mtok={0.00000000}%
+ \or%e-10
+ \pgfmathfloat@a@Mtok={0.000000000}%
+ \else%<= -11
+ \pgfmathfloat@a@Mtok={0.0000000000}%
+ \advance\pgfmathfloat@a@E by10
+ \pgfutil@loop
+ \ifnum\pgfmathfloat@a@E<-1
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok 0}%
+ \advance\pgfmathfloat@a@E by1
+ \pgfutil@repeat
+ \fi
+ \def\pgfmathfloat@loc@TMPb{#2}%
+ \def\pgfmathfloat@loc@TMPc{0}%
+ \ifx\pgfmathfloat@loc@TMPb\pgfmathfloat@loc@TMPc
+ \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok #1}%
+ \else
+ \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok #1#2}%
+ \fi
+ \else
+ %--------------------------------------------------
+ % \ifnum\pgfmathfloat@a@E=0%
+ % \edef\pgfmathresult{#1.#2}%
+ % \else
+ % \pgfmathfloat@a@Mtok={#1}%
+ % \pgfmathfloattofixed@impl@collectmantissa#2\count\pgfmathfloat@a@E
+ % \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok}%
+ % \fi
+ %--------------------------------------------------
+ \pgfmathfloat@a@Mtok{#1}%
+ \pgfmathfloattofixed@impl@pos#2000000000\pgfmathfloat@EOI
+ \edef\pgfmathresult{\the\pgfmathfloat@a@Mtok}%
+ \fi
+}
+
+% FIXME: this implementation here is very fast, but it introduces trailing zeros. Is that acceptable?
+\def\pgfmathfloattofixed@impl@pos#1#2#3#4#5#6#7#8#9\pgfmathfloat@EOI{%
+ \ifcase\pgfmathfloat@a@E
+ % e+0
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok .#1#2#3#4#5#6#7#8#9}%
+ \or%e+1
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1.#2#3#4#5#6#7#8#9}%
+ \or%e+2
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2.#3#4#5#6#7#8#9}%
+ \or%e+3
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2#3.#4#5#6#7#8#9}%
+ \or%e+4
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2#3#4.#5#6#7#8#9}%
+ \or%e+5
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2#3#4#5.#6#7#8#9}%
+ \or%e+6
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2#3#4#5#6.#7#8#9}%
+ \or%e+7
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2#3#4#5#6#7.#8#9}%
+ \or%e+8
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2#3#4#5#6#7#8.#9}%
+ \else%>=9
+ \pgfmathfloat@a@Mtok\expandafter{\the\pgfmathfloat@a@Mtok #1#2#3#4#5#6#7#8}%
+ \advance\pgfmathfloat@a@E by-8
+ \pgfmathfloattofixed@impl@collectmantissa#9\count\pgfmathfloat@a@E
+ \fi
+}%
+
+\def\pgfmathfloattofixed@impl@collectmantissa#1#2\count#3{%
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok #1}%
+ \advance\pgfmathfloat@a@E by-1%
+ \def\pgfmathfloat@loc@TMPb{#2}%
+ \ifx\pgfmathfloat@loc@TMPb\pgfutil@empty
+ \pgfutil@loop
+ \ifnum\pgfmathfloat@a@E>0%
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok 0}%
+ \advance\pgfmathfloat@a@E by-1%
+ \pgfutil@repeat
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok .0}%
+ \else
+ \ifnum\pgfmathfloat@a@E=0
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok .#2}%
+ \else
+ \pgfmathfloattofixed@impl@collectmantissa#2\count#3%
+ \fi
+ \fi
+}
+
+
+% ============================================
+%
+%
+% \pgfmathfloatparsenumber implementation
+%
+%
+% ============================================
+
+% accepted parser tokens:
+\def\pgfmathfloatparsenumber@tok@ZERO{0}
+\def\pgfmathfloatparsenumber@tok@PLUS{+}
+\def\pgfmathfloatparsenumber@tok@MINUS{-}
+\def\pgfmathfloatparsenumber@tok@PERIOD{.}
+
+\newif\ifpgfmathfloatparsenumberpendingperiod
+
+\def\pgfflt@EOI{p@EOI}%
+\def\pgfflt@EOI@unexpanded{\pgfflt@EOI}%
+
+% Starts a finite-start-machine parser to read a number.
+%
+% The machine's state is represented by the macro which is currently
+% processed; state transitions are realised using \csname...#1\endcsname
+% constructions.
+%
+% It assigns \pgfmathfloat@a@S, \pgfmathfloat@a@Mtok, \pgfmathfloat@a@E.
+\def\pgfflt@impl#1{%
+ \pgfmathfloatparsenumberpendingperiodfalse
+ \pgfmathfloat@tmptoks={}% this register is used to collect PENDING ZEROS
+ \pgfmathfloat@a@E=0
+ % start parsing: check for sign:
+ \expandafter\ifx\csname pgfflt@#1\endcsname\relax
+ \pgfmathfloat@a@S=1
+ \expandafter\pgfflt@init\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgfflt@#1\endcsname
+ \fi
+}
+% State transitions:
+\expandafter\def\csname pgfflt@+\endcsname{%
+ \pgfmathfloat@a@S=1 %
+ \pgfflt@init}%
+\expandafter\def\csname pgfflt@-\endcsname{%
+ \pgfmathfloat@a@S=2 %
+ \pgfflt@init}%
+\expandafter\def\csname pgfflt@\pgfflt@EOI\endcsname{%
+ \pgfmathfloatparsenumber@handleerror{empty number}{}{}}%
+
+\pgfkeys{
+ /pgf/fpu/handlers/empty number/.style 2 args={%
+ /pgf/fpu/handlers/invalid number={#1}{#2}%
+ },
+ /pgf/fpu/empty number is zero/.style={%
+ /pgf/fpu/handlers/empty number/.code 2 args={%
+ \pgfmathfloatcreate{0}{0.0}{0}%
+ }%
+ },%
+ /pgf/fpu/handlers/invalid separator/.code 2 args={%
+ \pgfmath@error{Could not parse input '#1' as a floating point number, sorry. The unreadable part was near the decimal separator '#2'. Do you need the option 'read comma as period'?}{}%
+ },
+ /pgf/fpu/handlers/invalid number/.code 2 args={%
+ \pgfmath@error{Could not parse input '#1' as a floating point number, sorry. The unreadable part was near '#2'.}{}%
+ },
+ /pgf/fpu/handlers/wrong lowlevel format/.code 2 args={%
+ \pgfmath@error{Sorry, an internal routine of the floating point unit got an ill-formatted floating point number `#1'. The unreadable part was near '#2'.}{}%
+ \let\pgfmathresult=\pgfutil@empty
+ },
+}
+
+% #1 the error handler
+% #2 the number which was invalid.
+% #3 the part which produced the error
+%
+% POSTCONDITION: the three registers
+% \pgfmathfloat@a@S
+% \pgfmathfloat@a@Mtok
+% \pgfmathfloat@a@E
+% will contain the number which results from the error handler.
+\def\pgfmathfloatparsenumber@handleerror#1#2#3{%
+ \let\pgfmathresult=\pgfutil@empty
+ \pgfmathfloatparsenumberpendingperiodfalse
+ \pgfkeys{/pgf/fpu/handlers/#1={#2}{#3}}%
+ \ifx\pgfmathresult\pgfutil@empty
+ \pgfmathfloat@a@S=3
+ \pgfmathfloat@a@Mtok={0.0}%
+ \pgfmathfloat@a@E=0
+ \else
+ \expandafter\pgfmathfloat@decompose@tok\pgfmathresult\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E
+ \fi
+}
+\def\pgfflt@error#1\pgfflt@EOI{%
+ \begingroup
+ \pgfmathfloat@a@Mtok={#1}%
+ \xdef\pgfmathfloat@glob@TMP{%
+ \noexpand\pgfmathfloatparsenumber@handleerror
+ {invalid number}{\pgfmathresult}{\the\pgfmathfloat@a@Mtok}}%
+ \endgroup
+ \pgfmathfloat@glob@TMP
+}%
+
+
+
+% FROM: checksign.
+%
+\def\pgfflt@init#1{%
+ \expandafter\ifx\csname pgffltA@#1\endcsname\relax
+ \expandafter\pgfflt@error\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgffltA@#1\endcsname
+ \fi}
+% state transitions:
+\expandafter\def\csname pgffltA@0\endcsname{\pgfflt@leadingzero}% FIXME: inline optimization!
+\expandafter\def\csname pgffltA@1\endcsname{\pgfflt@nonzerodigit1}%
+\expandafter\def\csname pgffltA@2\endcsname{\pgfflt@nonzerodigit2}%
+\expandafter\def\csname pgffltA@3\endcsname{\pgfflt@nonzerodigit3}%
+\expandafter\def\csname pgffltA@4\endcsname{\pgfflt@nonzerodigit4}%
+\expandafter\def\csname pgffltA@5\endcsname{\pgfflt@nonzerodigit5}%
+\expandafter\def\csname pgffltA@6\endcsname{\pgfflt@nonzerodigit6}%
+\expandafter\def\csname pgffltA@7\endcsname{\pgfflt@nonzerodigit7}%
+\expandafter\def\csname pgffltA@8\endcsname{\pgfflt@nonzerodigit8}%
+\expandafter\def\csname pgffltA@9\endcsname{\pgfflt@nonzerodigit9}%
+\def\pgfflt@nonzerodigit#1{%
+ \pgfmathfloat@a@Mtok={#1}%
+ \pgfmathfloatparsenumberpendingperiodtrue
+ \pgfflt@positiveexp}%
+\expandafter\def\csname pgffltA@n\endcsname{\pgfflt@readnan}% FIXME: inlining?
+\expandafter\def\csname pgffltA@N\endcsname{\pgfflt@readnan}% FIXME: inlining?
+\expandafter\def\csname pgffltA@i\endcsname{\pgfflt@readinf}% FIXME: inlining?
+\expandafter\def\csname pgffltA@I\endcsname{\pgfflt@readinf}% FIXME: inlining?
+\expandafter\def\csname pgffltA@.\endcsname{% read '.9' like '0.9'
+ \pgfmathfloat@a@E=-1
+ \pgfflt@leadingzero@foundperiod}%
+\expandafter\def\csname pgffltA@,\endcsname{% read ',9' like '0,9'
+ \pgfmathfloat@frenchinput{%
+ \pgfmathfloat@a@E=-1
+ \pgfflt@leadingzero@foundperiod
+ }%
+}%
+
+\def\pgfmathfloat@frenchinput#1{%
+ \ifpgfmathparsenumber@comma@as@period
+ \def\pgf@marshal{#1}%
+ \expandafter\pgf@marshal
+ \else
+ \expandafter\pgfflt@error@separator\expandafter,%
+ \fi
+}%
+\def\pgfflt@error@separator#1\pgfflt@EOI{%
+ \begingroup
+ \pgfmathfloat@a@Mtok={#1}%
+ \xdef\pgfmathfloat@glob@TMP{%
+ \noexpand\pgfmathfloatparsenumber@handleerror
+ {invalid separator}{\pgfmathresult}{\the\pgfmathfloat@a@Mtok}}%
+ \endgroup
+ \pgfmathfloat@glob@TMP
+}%
+
+\def\pgfflt@finish#1\pgfflt@EOI{}
+
+\def\pgfflt@readnan #1#2{%
+ \def\pgfflt@readnan@ok{1}%
+ \if#1a\else\if#1A\else\def\pgfflt@readnan@ok{0}\fi\fi
+ \if#2n\else\if#2N\else\def\pgfflt@readnan@ok{0}\fi\fi
+ \if\pgfflt@readnan@ok1%
+ \pgfmathfloat@a@S=3\relax%
+ \pgfmathfloat@a@Mtok={0.0}%
+ \pgfmathfloat@a@E=0%
+ \expandafter\pgfflt@finish
+ \else
+ \def\pgfflt@readnan@{\pgfflt@error #1#2}%
+ \expandafter\pgfflt@readnan@
+ \fi
+}
+\def\pgfflt@readinf #1#2{%
+ \def\pgfflt@readinf@ok{1}%
+ \if#1n\else\if#1N\else\def\pgfflt@readinf@ok{0}\fi\fi
+ \if#2f\else\if#2F\else\def\pgfflt@readinf@ok{0}\fi\fi
+ \if\pgfflt@readinf@ok1%
+ \ifnum\pgfmathfloat@a@S=1 %
+ \pgfmathfloat@a@S=4 %
+ \pgfmathfloat@a@Mtok={0.0}%
+ \else
+ \pgfmathfloat@a@S=5 %
+ \pgfmathfloat@a@Mtok={0.0}%
+ \fi
+ \pgfmathfloat@a@E=0 %
+ \expandafter\pgfflt@finish
+ \else
+ \def\pgfflt@readinf@{\pgfflt@error #1#2}%
+ \expandafter\pgfflt@readinf@
+ \fi
+}
+\def\pgfflt@leadingzero#1{%
+ \expandafter\ifx\csname pgffltB@#1\endcsname\relax
+ \expandafter\pgfflt@error\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgffltB@#1\endcsname
+ \fi}
+% State transitions:
+\expandafter\def\csname pgffltB@0\endcsname{\pgfflt@leadingzero}%
+\expandafter\def\csname pgffltB@1\endcsname{\pgfmathfloat@a@Mtok={1}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@2\endcsname{\pgfmathfloat@a@Mtok={2}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@3\endcsname{\pgfmathfloat@a@Mtok={3}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@4\endcsname{\pgfmathfloat@a@Mtok={4}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@5\endcsname{\pgfmathfloat@a@Mtok={5}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@6\endcsname{\pgfmathfloat@a@Mtok={6}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@7\endcsname{\pgfmathfloat@a@Mtok={7}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@8\endcsname{\pgfmathfloat@a@Mtok={8}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@9\endcsname{\pgfmathfloat@a@Mtok={9}\pgfmathfloatparsenumberpendingperiodtrue \pgfflt@positiveexp}
+\expandafter\def\csname pgffltB@\pgfmathfloat@POSTFLAGSCHAR\endcsname{\pgfmathfloat@a@Mtok={0}\pgfflt@readlowlevelfloat}%
+\expandafter\def\csname pgffltB@.\endcsname{%
+ \pgfmathfloat@a@E=-1
+ \pgfflt@leadingzero@foundperiod}%
+\expandafter\def\csname pgffltB@,\endcsname{%
+ \pgfmathfloat@frenchinput{%
+ \pgfmathfloat@a@E=-1
+ \pgfflt@leadingzero@foundperiod
+ }%
+}%
+\expandafter\def\csname pgffltB@e\endcsname{%
+ \pgfmathfloat@a@S=0\relax%
+ \pgfmathfloat@a@Mtok={0.0}%
+ \pgfmathfloat@a@E=0%
+ \pgfflt@readexponent}%
+\let\pgffltB@E=\pgffltB@e
+\expandafter\def\csname pgffltB@\pgfflt@EOI\endcsname{%
+ \pgfmathfloat@a@S=0\relax%
+ \pgfmathfloat@a@Mtok={0.0}%
+ \pgfmathfloat@a@E=0}%
+
+\def\pgfflt@leadingzero@foundperiod#1{%
+ \expandafter\ifx\csname pgffltC@#1\endcsname\relax
+ \expandafter\pgfflt@error\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgffltC@#1\endcsname
+ \fi}
+% State transitions:
+\expandafter\def\csname pgffltC@0\endcsname{%
+ \advance\pgfmathfloat@a@E by-1
+ \pgfflt@leadingzero@foundperiod}%
+\expandafter\def\csname pgffltC@1\endcsname{\pgfmathfloat@a@Mtok={1}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@2\endcsname{\pgfmathfloat@a@Mtok={2}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@3\endcsname{\pgfmathfloat@a@Mtok={3}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@4\endcsname{\pgfmathfloat@a@Mtok={4}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@5\endcsname{\pgfmathfloat@a@Mtok={5}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@6\endcsname{\pgfmathfloat@a@Mtok={6}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@7\endcsname{\pgfmathfloat@a@Mtok={7}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@8\endcsname{\pgfmathfloat@a@Mtok={8}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@9\endcsname{\pgfmathfloat@a@Mtok={9}\pgfmathfloatparsenumberpendingperiodtrue\pgfflt@finish@number@after@period}%
+\expandafter\def\csname pgffltC@e\endcsname{%
+ \pgfmathfloat@a@S=0\relax%
+ \pgfmathfloat@a@Mtok={0.0}%
+ \pgfmathfloat@a@E=0%
+ \pgfflt@readexponent}%
+\let\pgffltC@E=\pgffltC@e
+\expandafter\def\csname pgffltC@\pgfflt@EOI\endcsname{%
+ \pgfmathfloat@a@S=0\relax%
+ \pgfmathfloat@a@Mtok={0.0}%
+ \pgfmathfloat@a@E=0}%
+
+
+\def\pgfflt@positiveexp#1{%
+ \expandafter\ifx\csname pgffltD@#1\endcsname\relax
+ \expandafter\pgfflt@error\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgffltD@#1\endcsname
+ \fi}
+% State transitions:
+\expandafter\def\csname pgffltD@0\endcsname{%
+ \advance\pgfmathfloat@a@E by1
+ \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}%
+ \pgfflt@pendingzeros@positiveexp}%
+\expandafter\def\csname pgffltD@1\endcsname{\pgffltD@nonzerodigit1}%
+\expandafter\def\csname pgffltD@2\endcsname{\pgffltD@nonzerodigit2}%
+\expandafter\def\csname pgffltD@3\endcsname{\pgffltD@nonzerodigit3}%
+\expandafter\def\csname pgffltD@4\endcsname{\pgffltD@nonzerodigit4}%
+\expandafter\def\csname pgffltD@5\endcsname{\pgffltD@nonzerodigit5}%
+\expandafter\def\csname pgffltD@6\endcsname{\pgffltD@nonzerodigit6}%
+\expandafter\def\csname pgffltD@7\endcsname{\pgffltD@nonzerodigit7}%
+\expandafter\def\csname pgffltD@8\endcsname{\pgffltD@nonzerodigit8}%
+\expandafter\def\csname pgffltD@9\endcsname{\pgffltD@nonzerodigit9}%
+\expandafter\def\csname pgffltD@\pgfmathfloat@POSTFLAGSCHAR\endcsname{\pgfflt@readlowlevelfloat}%
+\expandafter\def\csname pgffltD@.\endcsname{\pgfflt@finish@number@after@period}% FIXME : inlining?
+\expandafter\def\csname pgffltD@,\endcsname{\pgfmathfloat@frenchinput{\pgfflt@finish@number@after@period}}%
+\expandafter\def\csname pgffltD@e\endcsname{\pgfflt@readexponent}% FIXME : inlining?
+\let\pgffltD@E=\pgffltD@e
+\expandafter\def\csname pgffltD@\pgfflt@EOI\endcsname{}% NOP
+\def\pgffltD@nonzerodigit#1{%
+ \advance\pgfmathfloat@a@E by1
+ \ifpgfmathfloatparsenumberpendingperiod
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}%
+ \pgfmathfloatparsenumberpendingperiodfalse
+ \fi
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}%
+ \pgfflt@positiveexp}%
+
+% Read a low-level floating point.
+% Since we are in the second state, \pgfmathfloat@a@Mtok contains the
+% FLAGS. The post-flags-char has also been read.
+\def\pgfflt@readlowlevelfloat#1e#2]\pgfflt@EOI{%
+ \pgfmathfloatparsenumberpendingperiodfalse
+ \pgfmathfloat@a@S=\the\pgfmathfloat@a@Mtok\relax
+ \pgfmathfloat@a@Mtok={#1}%
+ \pgfmathfloat@a@E=#2
+}%
+
+\def\pgfflt@readexponent#1\pgfflt@EOI{%
+ \afterassignment\pgfflt@readexponent@
+ \pgfmathfloat@b@E=#1 \pgfflt@EOI% the white space is important, otherwise \pgfflt@EOI will be expanded.
+}
+\def\pgfflt@readexponent@#1{%
+ \advance\pgfmathfloat@a@E by\pgfmathfloat@b@E\relax
+ %
+ % sanity checking:
+ \def\pgfmathfloat@loc@TMPb{#1}%
+ \ifx\pgfmathfloat@loc@TMPb\pgfflt@EOI@unexpanded
+ \else
+ \def\pgfmathfloat@loc@TMPb{\pgfflt@error#1}%
+ \expandafter\pgfmathfloat@loc@TMPb
+ \fi
+}
+
+\def\pgfflt@pendingzeros@positiveexp#1{%
+ \expandafter\ifx\csname pgffltE@#1\endcsname\relax
+ \expandafter\pgfflt@error\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgffltE@#1\endcsname
+ \fi}
+% State transitions:
+\expandafter\def\csname pgffltE@0\endcsname{%
+ \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}%
+ \advance\pgfmathfloat@a@E by1
+ \pgfflt@pendingzeros@positiveexp}%
+\expandafter\def\csname pgffltE@1\endcsname{\pgffltE@nonzerodigit1}%
+\expandafter\def\csname pgffltE@2\endcsname{\pgffltE@nonzerodigit2}%
+\expandafter\def\csname pgffltE@3\endcsname{\pgffltE@nonzerodigit3}%
+\expandafter\def\csname pgffltE@4\endcsname{\pgffltE@nonzerodigit4}%
+\expandafter\def\csname pgffltE@5\endcsname{\pgffltE@nonzerodigit5}%
+\expandafter\def\csname pgffltE@6\endcsname{\pgffltE@nonzerodigit6}%
+\expandafter\def\csname pgffltE@7\endcsname{\pgffltE@nonzerodigit7}%
+\expandafter\def\csname pgffltE@8\endcsname{\pgffltE@nonzerodigit8}%
+\expandafter\def\csname pgffltE@9\endcsname{\pgffltE@nonzerodigit9}%
+\expandafter\def\csname pgffltE@.\endcsname{\pgfflt@finish@number@after@period}% FIXME : inlining?
+\expandafter\def\csname pgffltE@,\endcsname{\pgfmathfloat@frenchinput{\pgfflt@finish@number@after@period}}% FIXME : inlining?
+\def\pgffltE@e{\pgfflt@readexponent}% FIXME : inlining?
+\let\pgffltE@E=\pgffltE@e
+\expandafter\def\csname pgffltE@\pgfflt@EOI\endcsname{}% NOP
+\def\pgffltE@nonzerodigit#1{%
+ \advance\pgfmathfloat@a@E by1
+ \ifpgfmathfloatparsenumberpendingperiod
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}%
+ \pgfmathfloatparsenumberpendingperiodfalse
+ \fi
+ \pgfmathfloat@a@Mtok=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfmathfloat@a@Mtok\the\pgfmathfloat@tmptoks}%
+ \pgfmathfloat@tmptoks={}%
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}%
+ \pgfflt@positiveexp}%
+
+\def\pgfflt@finish@number@after@period#1{%
+ \expandafter\ifx\csname pgffltF@#1\endcsname\relax
+ \expandafter\pgfflt@error\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgffltF@#1\endcsname
+ \fi}
+% State transitions:
+\expandafter\def\csname pgffltF@0\endcsname{%
+ \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}%
+ \pgfflt@pendingzeros}%
+\expandafter\def\csname pgffltF@1\endcsname{\pgffltF@nonzerodigit1}%
+\expandafter\def\csname pgffltF@2\endcsname{\pgffltF@nonzerodigit2}%
+\expandafter\def\csname pgffltF@3\endcsname{\pgffltF@nonzerodigit3}%
+\expandafter\def\csname pgffltF@4\endcsname{\pgffltF@nonzerodigit4}%
+\expandafter\def\csname pgffltF@5\endcsname{\pgffltF@nonzerodigit5}%
+\expandafter\def\csname pgffltF@6\endcsname{\pgffltF@nonzerodigit6}%
+\expandafter\def\csname pgffltF@7\endcsname{\pgffltF@nonzerodigit7}%
+\expandafter\def\csname pgffltF@8\endcsname{\pgffltF@nonzerodigit8}%
+\expandafter\def\csname pgffltF@9\endcsname{\pgffltF@nonzerodigit9}%
+\def\pgffltF@e{\pgfflt@readexponent}%
+\let\pgffltF@E=\pgffltF@e
+\expandafter\def\csname pgffltF@\pgfflt@EOI\endcsname{}% NOP
+\def\pgffltF@nonzerodigit#1{%
+ \ifpgfmathfloatparsenumberpendingperiod
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}%
+ \pgfmathfloatparsenumberpendingperiodfalse
+ \fi
+ \pgfmathfloat@a@Mtok=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfmathfloat@a@Mtok\the\pgfmathfloat@tmptoks}%
+ \pgfmathfloat@tmptoks={}%
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}%
+ \pgfflt@finish@number@after@period}%
+
+
+\def\pgfflt@pendingzeros#1{%
+ \expandafter\ifx\csname pgffltG@#1\endcsname\relax
+ \expandafter\pgfflt@error\expandafter#1%
+ \else
+ \expandafter\expandafter\csname pgffltG@#1\endcsname
+ \fi}
+% State transitions:
+\expandafter\def\csname pgffltG@0\endcsname{%
+ \pgfmathfloat@tmptoks=\expandafter{\the\pgfmathfloat@tmptoks0}%
+ \pgfflt@pendingzeros}%
+\expandafter\def\csname pgffltG@1\endcsname{\pgffltG@nonzerodigit1}%
+\expandafter\def\csname pgffltG@2\endcsname{\pgffltG@nonzerodigit2}%
+\expandafter\def\csname pgffltG@3\endcsname{\pgffltG@nonzerodigit3}%
+\expandafter\def\csname pgffltG@4\endcsname{\pgffltG@nonzerodigit4}%
+\expandafter\def\csname pgffltG@5\endcsname{\pgffltG@nonzerodigit5}%
+\expandafter\def\csname pgffltG@6\endcsname{\pgffltG@nonzerodigit6}%
+\expandafter\def\csname pgffltG@7\endcsname{\pgffltG@nonzerodigit7}%
+\expandafter\def\csname pgffltG@8\endcsname{\pgffltG@nonzerodigit8}%
+\expandafter\def\csname pgffltG@9\endcsname{\pgffltG@nonzerodigit9}%
+\def\pgffltG@e{\pgfflt@readexponent}% FIXME: inlining?
+\let\pgffltG@E=\pgffltG@e
+\expandafter\def\csname pgffltG@\pgfflt@EOI\endcsname{}% NOP
+\def\pgffltG@nonzerodigit#1{%
+ \ifpgfmathfloatparsenumberpendingperiod
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok.}%
+ \pgfmathfloatparsenumberpendingperiodfalse
+ \fi
+ \pgfmathfloat@a@Mtok=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfmathfloat@a@Mtok\the\pgfmathfloat@tmptoks}%
+ \pgfmathfloat@tmptoks={}%
+ \pgfmathfloat@a@Mtok=\expandafter{\the\pgfmathfloat@a@Mtok#1}%
+ \pgfflt@finish@number@after@period}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.base.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.base.code.tex
new file mode 100644
index 0000000000..fcf5503b36
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.base.code.tex
@@ -0,0 +1,330 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% This file provides basic macros for converting between bases.
+%
+% Version 1.4142135 8/11/2008
+
+% Base conversion operations for the parser.
+%
+\pgfmathdeclarefunction{bin}{1}{%
+ \begingroup%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \c@pgfmath@counta=#1\relax\pgfmath@%
+ \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\the\c@pgfmath@counta}{10}{2}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+\pgfmathdeclarefunction{hex}{1}{%
+ \begingroup%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \c@pgfmath@counta=#1\relax\pgfmath@%
+ \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\the\c@pgfmath@counta}{10}{16}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+\pgfmathdeclarefunction{Hex}{1}{%
+ \begingroup%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \c@pgfmath@counta=#1\relax\pgfmath@%
+ \expandafter\pgfmathbasetoBase\expandafter\pgfmathresult\expandafter{\the\c@pgfmath@counta}{10}{16}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+\pgfmathdeclarefunction{oct}{1}{%
+ \begingroup%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \c@pgfmath@counta=#1\relax\pgfmath@%
+ \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\the\c@pgfmath@counta}{10}{8}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% Additional macros:
+
+% \pgfmathbasetodec
+%
+% Convert a representation of an integer from
+% the specified base to base 10.
+%
+% #1 - a macro to store the result.
+% #2 - the representation of a number (i.e. not a register)
+% #3 - the current base.
+%
+% e.g.
+%
+% \pgfmathbasetodec\mynumber{10111}{2}
+%
+% \mynumber <- 23
+%
+\def\pgfmathbasetodec#1#2#3{%
+ \pgfmath@checknumber{#2}%
+ \pgfmath@checkbase{#3}%
+ \def\pgfmath@base{#3}%
+ \def\pgfmath@base@macro{#1}%
+ \c@pgfmath@counta=1\relax%
+ \let\pgfmath@reversed=\pgfmath@empty%
+ \expandafter\pgfmathbasetodec@#2\pgfmath@base@stop}
+
+\def\pgfmathbasetodec@#1{%
+ \ifx#1\pgfmath@base@stop%
+ \c@pgfmath@countb=0%
+ \divide\c@pgfmath@counta by\pgfmath@base\relax%
+ \expandafter\pgfmathbasetodec@@%
+ \else%
+ \edef\pgfmath@reversed{\pgfmath@reversed#1}%
+ \expandafter\multiply\expandafter\c@pgfmath@counta\pgfmath@base\relax%
+ \expandafter\pgfmathbasetodec@%
+ \fi}
+
+\def\pgfmathbasetodec@@{\expandafter\pgfmathbasetodec@@@\pgfmath@reversed\pgfmathbasetodec}
+
+\def\pgfmathbasetodec@@@#1{%
+ \ifx\pgfmathbasetodec#1\relax%
+ \expandafter\edef\pgfmath@base@macro{\the\c@pgfmath@countb}%
+ \let\pgfmath@next=\pgfmathbasetodec@@@@%
+ \else%
+ \chardef\pgfmath@charnum`#1\relax%
+ \c@pgfmath@countc=\pgfmath@charnum\relax%
+ \ifnum\c@pgfmath@countc>96\relax%
+ \advance\c@pgfmath@countc by-87\relax%
+ \else
+ \ifnum\c@pgfmath@countc>64\relax%
+ \advance\c@pgfmath@countc by-55\relax%
+ \else
+ \advance\c@pgfmath@countc by-48\relax%
+ \fi%
+ \fi%
+ \ifnum\c@pgfmath@countc<\pgfmath@base\relax%
+ \multiply\c@pgfmath@countc by\c@pgfmath@counta%
+ \advance\c@pgfmath@countb by\c@pgfmath@countc%
+ \divide\c@pgfmath@counta by\pgfmath@base\relax%
+ \let\pgfmath@next\pgfmathbasetodec@@@%
+ \else
+ \pgfmath@error{Digit `#1' invalid for base \pgfmath@base}{}%
+ \let\pgfmath@next=\relax%
+ \fi%
+ \fi%
+ \pgfmath@next}
+\def\pgfmathbasetodec@@@@{%
+ \expandafter\pgfmath@ensurenumberlength\expandafter{\pgfmath@base@macro}%
+}
+
+% \pgfmathdectobase
+%
+% Convert a representation of an integer from
+% base 10 to the specified base. Letters for bases
+% greater than 10 are in lowercase.
+%
+% #1 - a macro to store the result.
+% #2 - a number in base 10 (in a macro, not a register)
+% #3 - the required base.
+%
+% e.g.
+%
+% \pgfmathdectobase\mynumber{127}{16}
+%
+% \mynumber <- 7f
+%
+\def\pgfmathdectobase#1#2#3{%
+ \pgfmath@checknumber{#2}%
+ \pgfmath@checkbase{#3}%
+ \c@pgfmath@counta=#2\relax%
+ \let#1=\pgfmath@empty%
+ \pgfmathloop
+ \ifnum\c@pgfmath@counta>0\relax%
+ \c@pgfmath@countb=\c@pgfmath@counta%
+ \divide\c@pgfmath@countb by#3\relax%
+ \multiply\c@pgfmath@countb by-#3\relax%
+ \advance\c@pgfmath@countb by\c@pgfmath@counta%
+ \edef#1{\csname pgfmath@lowercase digit@\the\c@pgfmath@countb\endcsname#1}%
+ \divide\c@pgfmath@counta by#3\relax%
+ \repeatpgfmathloop%
+ \pgfmath@ensurenumberlength{#1}}
+
+% \pgfmathdectoBase
+%
+% Convert a representation of an integer from
+% base 10 to the specified base. Letters for bases
+% greater than 10 are in uppercase.
+%
+% #1 - a macro to store the result.
+% #2 - a number in base 10 (in a macro, not a register)
+% #3 - the required base.
+%
+% e.g.
+%
+% \pgfmathdectoBase\mynumber{127}{16}
+%
+% \mynumber <- 7F
+%
+\def\pgfmathdectoBase#1#2#3{%
+ \pgfmath@checkbase{#3}%
+ \pgfmath@checknumber{#2}%
+ \c@pgfmath@counta=#2\relax%
+ \let#1=\pgfmath@empty%
+ \pgfmathloop
+ \ifnum\c@pgfmath@counta>0\relax%
+ \c@pgfmath@countb=\c@pgfmath@counta%
+ \divide\c@pgfmath@countb by#3\relax%
+ \multiply\c@pgfmath@countb by-#3\relax%
+ \advance\c@pgfmath@countb by\c@pgfmath@counta%
+ \edef#1{\csname pgfmath@uppercase digit@\the\c@pgfmath@countb\endcsname#1}%
+ \divide\c@pgfmath@counta by#3\relax%
+ \repeatpgfmathloop%
+ \pgfmath@ensurenumberlength{#1}}
+
+\def\pgfmath@base@digits@create{%
+ \def\pgfmath@base@digit@style{lowercase digit}%
+ \c@pgfmath@counta=0\relax%
+ \pgfmath@base@digits@create@0123456789abcdefghijklmnopqrstuvwxyz\pgfmath@base@digits@create%
+ \def\pgfmath@base@digit@style{uppercase digit}%
+ \c@pgfmath@counta=0\relax%
+ \pgfmath@base@digits@create@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\pgfmath@base@digits@create}
+
+\def\pgfmath@base@digits@create@#1{%
+ \ifx\pgfmath@base@digits@create#1\relax%
+ \else%
+ \expandafter\pgfmath@def\expandafter{\pgfmath@base@digit@style}{\the\c@pgfmath@counta}{#1}%
+ \advance\c@pgfmath@counta by1\relax%
+ \expandafter\pgfmath@base@digits@create@%
+ \fi}
+\pgfmath@base@digits@create
+
+% \pgfmathbasetobase
+%
+% Convert a representation of an integer from
+% between the specified bases. Letters for target
+% bases greater than 10 are in uppercase.
+%
+% #1 - a macro to store the result.
+% #2 - a number (in a macro, not a register)
+% #3 - the source base.
+% #4 - the target base.
+%
+% e.g.
+%
+% \pgfmathbasetobase\mynumber{4321}{5}{9}
+%
+% \mynumber <- 721
+%
+\def\pgfmathbasetobase#1#2#3#4{%
+ \pgfmathbasetodec{\pgfmath@base@temp}{#2}{#3}%
+ \pgfmathdectobase{#1}{\pgfmath@base@temp}{#4}%
+}
+
+% \pgfmathbasetobase
+%
+% Convert a representation of an integer from
+% between the specified bases. Letters for target
+% bases greater than 10 are in uppercase.
+%
+% #1 - a macro to store the result.
+% #2 - a number (in a macro, not a register)
+% #3 - the source base.
+% #4 - the target base.
+%
+% e.g.
+%
+% \pgfmathbasetobase\mynumber{1234}{5}{12}
+%
+% \mynumber <- 142
+%
+\def\pgfmathbasetoBase#1#2#3#4{%
+ \pgfmathbasetodec{\pgfmath@base@temp}{#2}{#3}%
+ \pgfmathdectoBase{#1}{\pgfmath@base@temp}{#4}%
+}
+
+\def\pgfmath@checkbase#1{%
+ \ifnum#1<2\relax%
+ \pgfmath@error{Cannot process numbers in base `#1'.}{}%
+ \else%
+ \ifnum#1>36\relax%
+ \pgfmath@error{Cannot process numbers in base `#1'.}{}%
+ \fi%
+ \fi}
+
+\def\pgfmath@checknumber#1{%
+ \expandafter\pgfmath@checknumber@#1\pgfmath@}
+\def\pgfmath@checknumber@#1#2\pgfmath@{%
+ \ifx#1-%
+ \pgfmath@error{Cannot process negative numbers.}{}%
+ \fi}
+
+% \pgfmath@ensurenumberlength
+%
+% Internal macro for making a representation of a number have
+% a specific length, byte prefixing zeros to the number.
+%
+% #1 - a macro containing a representation of an integer.
+% #2 - the number of digits to ensure.
+%
+% e.g.
+%
+% \foo <- 7FF
+%
+% \pgfmathsetnumberlength{8}%
+% \pgfmath@ensurenumberlength\foo
+%
+% \foo <- 000007FF
+%
+\def\pgfmath@ensurenumberlength#1{%
+ \def\pgfmath@base@tempa{#1}%
+ \expandafter\c@pgfmath@counta\pgfmath@basenumberlength\relax%
+ \expandafter\pgfmath@ensurenumberlength@#1\pgfmath@ensurenumberlength}
+\def\pgfmath@ensurenumberlength@#1{%
+ \ifx\pgfmath@ensurenumberlength#1\relax%
+ \expandafter\pgfmath@ensurenumberlength@@%
+ \else%
+ \advance\c@pgfmath@counta by-1\relax%
+ \expandafter\pgfmath@ensurenumberlength@
+ \fi}
+
+\def\pgfmath@ensurenumberlength@@{%
+ \edef\pgfmath@base@tempb{\pgfmath@base@tempa}%
+ \pgfmath@ensurenumberlength@@@}
+\def\pgfmath@ensurenumberlength@@@{%
+ \ifnum\c@pgfmath@counta>0\relax%
+ \advance\c@pgfmath@counta by-1\relax%
+ \edef\pgfmath@base@tempb{0\pgfmath@base@tempb}%
+ \expandafter\pgfmath@ensurenumberlength@@@%
+ \fi%
+ \expandafter\edef\pgfmath@base@tempa{\pgfmath@base@tempb}}
+
+\def\pgfmathsetbasenumberlength#1{\def\pgfmath@basenumberlength{#1}}
+\pgfmathsetbasenumberlength{1}%
+
+% \pgfmathtodigitlist\marg{macro}\marg{number}}
+%
+% This command converts \meta{number} into a comma-separated
+% list of digits and stores the result in \meta{macro}.
+% The \marg{number} is \emph{not} parsed before processing.
+%
+\def\pgfmathtodigitlist#1#2{%
+ \def\pgfmath@temp{#1}%
+ \let\pgfmath@digitlist=\pgfutil@empty%
+ \edef\pgfmath@@tmp{#2}%
+ \expandafter\pgfmath@todigitlist\pgfmath@@tmp @%
+}
+\def\pgfmath@base@atchar{@}
+\def\pgfmath@todigitlist#1{%
+ \def\pgfmath@digit{#1}%
+ \ifx\pgfmath@digit\pgfmath@base@atchar%
+ \expandafter\let\pgfmath@temp=\pgfmath@digitlist%
+ \else%
+ \ifx\pgfmath@digitlist\pgfutil@empty%
+ \edef\pgfmath@digitlist{#1}%
+ \else%
+ \edef\pgfmath@digitlist{\pgfmath@digitlist,#1}%
+ \fi%
+ \expandafter\pgfmath@todigitlist%
+ \fi%
+}
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.basic.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.basic.code.tex
new file mode 100644
index 0000000000..1607c386e8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.basic.code.tex
@@ -0,0 +1,803 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file defines the mathematical functions and operators.
+%
+% Version 1.4142135 25/8/2008
+
+% add function.
+%
+\pgfmathdeclarefunction{add}{2}{%
+ \begingroup%
+ \pgfmath@x=#1pt\relax%
+ \pgfmath@y=#2pt\relax%
+ \advance\pgfmath@x by\pgfmath@y%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+
+% subtract function.
+%
+\pgfmathdeclarefunction{subtract}{2}{%
+ \begingroup%
+ \pgfmath@x=#1pt\relax%
+ \pgfmath@y=#2pt\relax%
+ \advance\pgfmath@x by-\pgfmath@y%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% neg function.
+%
+\pgfmathdeclarefunction{neg}{1}{%
+ \begingroup%
+ \pgfmath@x=-#1pt\relax%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+% change the precedence for neg.
+% Otherwise, unary minus and exponentiation won't have the correct precedence
+% (test '-2^2')
+\def\pgfmath@operation@neg@precedence{500}
+
+% multiply function.
+%
+\pgfmathdeclarefunction{multiply}{2}{%
+ \begingroup%
+ \pgfmath@x=#1pt\relax%
+ \pgfmath@y=#2pt\relax%
+ \pgfmath@x=\pgfmath@tonumber{\pgfmath@y}\pgfmath@x%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% divide function.
+%
+\newif\ifpgfmath@divide@period
+
+\pgfmathdeclarefunction{divide}{2}{%
+ \begingroup%
+ \pgfmath@x=#1pt\relax%
+ \pgfmath@y=#2pt\relax%
+ \let\pgfmath@sign=\pgfmath@empty%
+ \ifdim0pt=\pgfmath@y%
+ \pgfmath@error{You've asked me to divide `#1' by `#2', %
+ but I cannot divide any number by `#2'}{}%
+ \fi%
+ \afterassignment\pgfmath@xa%
+ \c@pgfmath@counta\the\pgfmath@y\relax%
+ \ifdim0pt=\pgfmath@xa%
+ \divide\pgfmath@x by\c@pgfmath@counta%
+ \else%
+ \ifdim0pt>\pgfmath@x%
+ \def\pgfmath@sign{-}%
+ \pgfmath@x=-\pgfmath@x%
+ \fi%
+ \ifdim0pt>\pgfmath@y%
+ \expandafter\def\expandafter\pgfmath@sign\expandafter{\pgfmath@sign-}%
+ \pgfmath@y=-\pgfmath@y%
+ \fi%
+ \ifdim1pt>\pgfmath@y%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgfmath@y}}%
+ \pgfmath@x=\pgfmath@sign\pgfmathresult\pgfmath@x%
+ \else%
+ \def\pgfmathresult{0}%
+ \pgfmath@divide@periodtrue%
+ \c@pgfmath@counta=0\relax%
+ \pgfmathdivide@@%
+ \pgfmath@x=\pgfmath@sign\pgfmathresult pt\relax%
+ \fi%
+ \fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+\def\pgfmath@small@number{0.00002}
+
+\def\pgfmathdivide@@{%
+ \let\pgfmath@next=\relax%
+ \ifdim\pgfmath@small@number pt<\pgfmath@x%
+ \ifdim\pgfmath@small@number pt<\pgfmath@y%
+ \ifdim\pgfmath@y>\pgfmath@x%
+ \ifpgfmath@divide@period%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult.}%
+ \pgfmath@divide@periodfalse%
+ \fi%
+ \pgfmathdivide@dimenbyten\pgfmath@y%
+ \ifdim\pgfmath@y>\pgfmath@x%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult0}%
+ \fi%
+ \else%
+ \c@pgfmath@counta=\pgfmath@x%
+ \c@pgfmath@countb=\pgfmath@y%
+ \divide\c@pgfmath@counta by\c@pgfmath@countb%
+ \pgfmath@ya=\c@pgfmath@counta\pgfmath@y%
+ \advance\pgfmath@x by-\pgfmath@ya%
+ \def\pgfmath@next{%
+ \toks0=\expandafter{\pgfmathresult}%
+ \edef\pgfmathresult{\the\toks0 \the\c@pgfmath@counta}%
+ }%
+ \ifpgfmath@divide@period
+ \else
+ % we are behind the period. It may happen that the
+ % result is more than one digit - in that case,
+ % introduce special handling:
+ \ifnum\c@pgfmath@counta>9 %
+ \expandafter\pgfmathdivide@advance@last@digit\pgfmathresult CCCCC\@@
+ \advance\c@pgfmath@counta by-10 %
+ \ifnum\c@pgfmath@counta=0
+ \let\pgfmath@next=\relax
+ \fi
+ \fi
+ \fi
+ \pgfmath@next
+ \fi%
+ \let\pgfmath@next=\pgfmathdivide@@%
+ \fi%
+ \fi%
+ \pgfmath@next%
+}
+
+% advances the last digit found in the number. Any missing digits are
+% supposed to be filled with 'C'.
+\def\pgfmathdivide@advance@last@digit#1.#2#3#4#5#6#7\@@{%
+ \pgfmath@ya=\pgfmathresult pt %
+ \if#2C%
+ \pgfmath@xa=1pt %
+ \else
+ \if#3C%
+ \pgfmath@xa=0.1pt %
+ \else
+ \if#4C%
+ \pgfmath@xa=0.01pt %
+ \else
+ \if#5C%
+ \pgfmath@xa=0.001pt %
+ \else
+ \if#6C%
+ \pgfmath@xa=0.0001pt %
+ \else
+ \pgfmath@xa=0.00001pt %
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \advance\pgfmath@ya by\pgfmath@xa
+ \edef\pgfmathresult{\pgfmath@tonumber@notrailingzero\pgfmath@ya}%
+}%
+
+{
+\catcode`\p=12
+\catcode`\t=12
+\gdef\Pgf@geT@NO@TRAILING@ZERO#1.#2pt{%
+ #1.%
+ \ifnum#2=0 \else #2\fi
+}
+}
+\def\pgfmath@tonumber@notrailingzero#1{\expandafter\Pgf@geT@NO@TRAILING@ZERO\the#1}
+
+
+\def\pgfmathdivide@dimenbyten#1{%
+ \edef\pgfmath@temp{\pgfmath@tonumber{#1}}%
+ \expandafter\pgfmathdivide@@dimenbyten\pgfmath@temp\@@#1\@@}
+\def\pgfmathdivide@@dimenbyten#1.#2\@@#3\@@{%
+ \pgfmath@tempcnta=#1\relax%
+ \divide\pgfmath@tempcnta by10\relax%
+ \pgfmath@tempcntb=\pgfmath@tempcnta%
+ \multiply\pgfmath@tempcnta by-10\relax%
+ \advance\pgfmath@tempcnta by#1\relax%
+ #3=\the\pgfmath@tempcntb.\the\pgfmath@tempcnta#2pt\relax%
+}
+
+
+% reciprocal function.
+%
+\pgfmathdeclarefunction{reciprocal}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \ifdim\pgfmath@x=0pt\relax%
+ \pgfmath@error{You asked me to calculate `1/#1', but I cannot divide any number by zero}{}%
+ \fi%
+ \edef\pgfmath@reciprocaltemp{\pgfmath@tonumber{\pgfmath@x}}%
+ \expandafter\pgfmathreciprocal@@\pgfmath@reciprocaltemp0000000\pgfmath@}
+\def\pgfmathreciprocal@@#1.#2#3#4#5#6#7\pgfmath@{%
+ \c@pgfmath@counta#2#3#4#5#6\relax%
+ % If the number is an integer, use TeX arithmetic.
+ \ifnum\c@pgfmath@counta=0\relax%
+ \pgfmath@x1pt\relax%
+ \divide\pgfmath@x#1\relax%
+ \else%
+ \ifnum#1>100\relax%
+ \c@pgfmath@counta#1#2#3#4\relax%
+ \c@pgfmath@countb1000000000\relax%
+ \divide\c@pgfmath@countb\c@pgfmath@counta%
+ \c@pgfmath@counta\c@pgfmath@countb%
+ \divide\c@pgfmath@counta10000\relax%
+ \pgfmath@x\c@pgfmath@counta pt\relax%
+ \multiply\c@pgfmath@counta-10000\relax%
+ \advance\c@pgfmath@countb\c@pgfmath@counta%
+ \pgfmath@y\c@pgfmath@countb pt\relax%
+ \divide\pgfmath@y1000000\relax%
+ \advance\pgfmath@x\pgfmath@y%
+ \else%
+ \c@pgfmath@counta#1#2#3#4#5#6\relax%
+ \c@pgfmath@countb1000000000\relax%
+ \divide\c@pgfmath@countb\c@pgfmath@counta%
+ \c@pgfmath@counta\c@pgfmath@countb%
+ \divide\c@pgfmath@counta10000\relax%
+ \pgfmath@x\c@pgfmath@counta pt\relax%
+ \multiply\c@pgfmath@counta-10000\relax%
+ \advance\c@pgfmath@countb\c@pgfmath@counta%
+ \pgfmath@y\c@pgfmath@countb pt\relax%
+ \pgfmath@y.1\pgfmath@y% Yes! This way is more accurate. Go figure...
+ \pgfmath@y.1\pgfmath@y%
+ \pgfmath@y.1\pgfmath@y%
+ \pgfmath@y.1\pgfmath@y%
+ \advance\pgfmath@x\pgfmath@y%
+ \fi%
+ \fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% div function.
+%
+\pgfmathdeclarefunction{div}{2}{%
+ \begingroup%
+ \pgfmathdivide@{#1}{#2}%
+ \ifdim\pgfmathresult pt<0pt\relax%
+ \pgfmathceil@{\pgfmathresult}%
+ \else%
+ \pgfmathfloor@{\pgfmathresult}%
+ \fi%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \c@pgfmath@counta=\pgfmathresult\relax\pgfmath@%
+ \edef\pgfmathresult{\the\c@pgfmath@counta}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% mod function.
+%
+\pgfmathdeclarefunction{mod}{2}{%
+ \begingroup%
+ \pgfmath@xa#1pt%
+ \pgfmath@xb#2pt%
+ \pgfmath@x\pgfmath@xa%
+ \c@pgfmath@counta\pgfmath@xa%
+ \c@pgfmath@countb\pgfmath@xb%
+ \divide\c@pgfmath@counta\c@pgfmath@countb%
+ \multiply\pgfmath@xb\c@pgfmath@counta%
+ \advance\pgfmath@x-\pgfmath@xb%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% Mod function (never negative).
+%
+\pgfmathdeclarefunction{Mod}{2}{%
+ \begingroup%
+ \pgfmathmod@{#1}{#2}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \ifdim\pgfmath@x<0pt\relax%
+ \advance\pgfmath@x by#2pt\relax%
+ \fi%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% abs function.
+%
+\pgfmathdeclarefunction{abs}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \ifdim\pgfmath@x<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% sign(x)
+\pgfmathdeclarefunction{sign}{1}{%
+ \begingroup
+ \ifdim#1pt>0sp %
+ \def\pgfmathresult{1}%
+ \else
+ \ifdim#1pt=0sp %
+ \def\pgfmathresult{0}%
+ \else
+ \def\pgfmathresult{-1}%
+ \fi
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}
+
+% e constant.
+%
+\pgfmathdeclarefunction{e}{0}{\def\pgfmathresult{2.718281828}}
+
+% ln function.
+%
+% This is based on an algorithm due to Rouben Rostamian and
+% uses coefficients contributed by Alain Matthes.
+%
+\pgfmathdeclarefunction{ln}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \ifdim\pgfmath@x>0pt\else%
+ \pgfmath@error{I cannot calculate the logarithm of `#1'}{}%
+ \fi%
+ \c@pgfmath@counta=0\relax%
+ \ifdim\pgfmath@x>2pt\relax%
+ \ifdim\pgfmath@x<128pt\relax%
+ \ifdim\pgfmath@x<8pt\relax%
+ \ifdim\pgfmath@x<4pt\relax%
+ \divide\pgfmath@x by2\relax%
+ \c@pgfmath@counta=1\relax%
+ \else%
+ \divide\pgfmath@x by4\relax%
+ \c@pgfmath@counta=2\relax%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x<32pt\relax%
+ \ifdim\pgfmath@x<16pt\relax%
+ \divide\pgfmath@x by8\relax%
+ \c@pgfmath@counta=3\relax%
+ \else%
+ \divide\pgfmath@x by16\relax%
+ \c@pgfmath@counta=4\relax%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x<64pt\relax%
+ \divide\pgfmath@x by32\relax%
+ \c@pgfmath@counta=5\relax%
+ \else%
+ \divide\pgfmath@x by64\relax%
+ \c@pgfmath@counta=6\relax%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x<2048pt\relax%
+ \ifdim\pgfmath@x<512pt\relax%
+ \ifdim\pgfmath@x<256pt\relax%
+ \divide\pgfmath@x by128\relax%
+ \c@pgfmath@counta=7\relax%
+ \else%
+ \divide\pgfmath@x by256\relax%
+ \c@pgfmath@counta=8\relax%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x<1024pt\relax%
+ \divide\pgfmath@x by512\relax%
+ \c@pgfmath@counta=9\relax%
+ \else%
+ \divide\pgfmath@x by1024\relax%
+ \c@pgfmath@counta=10\relax%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x<8192pt\relax%
+ \ifdim\pgfmath@x<4096pt\relax%
+ \divide\pgfmath@x by2048\relax%
+ \c@pgfmath@counta=11\relax%
+ \else%
+ \divide\pgfmath@x by4096\relax%
+ \c@pgfmath@counta =12\relax%
+ \fi%
+ \else%
+ \divide\pgfmath@x by8192\relax%
+ \c@pgfmath@counta=13\relax%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x<1pt\relax%
+ \ifdim\pgfmath@x>0.0078125pt\relax% 2^-7
+ \ifdim\pgfmath@x>0.125pt\relax% 2^-3
+ \ifdim\pgfmath@x>0.5pt\relax% 2^-1
+ \multiply\pgfmath@x by2\relax%
+ \c@pgfmath@counta=-1\relax%
+ \else%
+ \multiply\pgfmath@x by4\relax%
+ \c@pgfmath@counta=-2\relax%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x>0.03125pt\relax% 2^-5
+ \ifdim\pgfmath@x>0.0625pt\relax%
+ \multiply\pgfmath@x by8\relax%
+ \c@pgfmath@counta=-3\relax%
+ \else%
+ \multiply\pgfmath@x by16\relax%
+ \c@pgfmath@counta=-4\relax%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x>0.015625pt\relax% 2^-6
+ \multiply\pgfmath@x by32\relax%
+ \c@pgfmath@counta=-5\relax%
+ \else%
+ \multiply\pgfmath@x by64\relax%
+ \c@pgfmath@counta=-6\relax%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x>0.00048828125pt\relax% 2^-11
+ \ifdim\pgfmath@x>0.001953125pt\relax% 2^-9
+ \ifdim\pgfmath@x>0.00390625pt\relax% 2^-8
+ \multiply\pgfmath@x by128\relax%
+ \c@pgfmath@counta=-7\relax%
+ \else%
+ \multiply\pgfmath@x by256\relax%
+ \c@pgfmath@counta=-8\relax%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x>0.0009765625pt\relax% 2^-10
+ \multiply\pgfmath@x by512\relax%
+ \c@pgfmath@counta=-9\relax%
+ \else%
+ \multiply\pgfmath@x by1024\relax%
+ \c@pgfmath@counta=-10\relax%
+ \fi%
+ \fi%
+ \else%
+ \ifdim\pgfmath@x>0.0001220703125pt\relax% 2^13
+ \ifdim\pgfmath@x>0.0002441406256pt\relax% 2^12
+ \multiply\pgfmath@x by2048\relax%
+ \c@pgfmath@counta=-11\relax%
+ \else%
+ \multiply\pgfmath@x by4096\relax%
+ \c@pgfmath@counta=-12\relax%
+ \fi%
+ \else%
+ \multiply\pgfmath@x by8192\relax%
+ \c@pgfmath@counta=-13\relax%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ %
+ % Use A+(B+(C+(D+(E+F*x)*x)*x)*x)*x
+ %
+ % where:
+ % A = -2.787927935
+ % B = 5.047861502
+ % C = -3.489886985
+ % D = 1.589480044
+ % E = -.4025153233
+ % F = 0.04300521312
+ %
+ \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@x=0.04300521312\pgfmath@x%
+ \advance\pgfmath@x by-.4025153233pt\relax%
+ \pgfmath@x=\pgfmath@temp\pgfmath@x%
+ \advance\pgfmath@x by1.589480044pt\relax%
+ \pgfmath@x=\pgfmath@temp\pgfmath@x%
+ \advance\pgfmath@x by-3.489886985pt\relax%
+ \pgfmath@x=\pgfmath@temp\pgfmath@x%
+ \advance\pgfmath@x by5.047861502pt\relax%
+ \pgfmath@x=\pgfmath@temp\pgfmath@x%
+ \advance\pgfmath@x by-2.787927935pt\relax%
+ \advance\pgfmath@x by\c@pgfmath@counta pt\relax%
+ \pgfmath@x=0.6931471806\pgfmath@x%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% log2 function.
+%
+\pgfmathdeclarefunction{log2}{1}{%
+ \begingroup%
+ \pgfmathln@{#1}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \pgfmath@x=1.442695041\pgfmath@x% 1/ln(2).
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% log10 function
+%
+\pgfmathdeclarefunction{log10}{1}{%
+ \begingroup%
+ \pgfmathln@{#1}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \pgfmath@x=0.43429441\pgfmath@x% 1/ln(10).
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% This is needed since \pgfmathlog2 and \pgfmathlog10 are not legal macro names
+\expandafter\let\expandafter\pgfmathlogtwo\csname pgfmathlog2\endcsname
+\expandafter\let\expandafter\pgfmathlogtwo@\csname pgfmathlog2@\endcsname
+\expandafter\let\expandafter\pgfmathlogten\csname pgfmathlog10\endcsname
+\expandafter\let\expandafter\pgfmathlogten@\csname pgfmathlog10@\endcsname
+
+% exp function.
+%
+\pgfmathdeclarefunction{exp}{1}{%
+ \begingroup
+ \pgfmath@xc=#1pt\relax
+ \pgfmath@yc=#1pt\relax
+ \ifdim\pgfmath@xc<-9pt
+ \pgfmath@x=1sp\relax
+ \else
+ \ifdim\pgfmath@xc<0pt
+ \pgfmath@xc=-\pgfmath@xc
+ \fi
+ \pgfmath@x=1pt\relax
+ \pgfmath@xa=1pt\relax
+ \pgfmath@xb=\pgfmath@x
+ \pgfmathloop%
+ \divide\pgfmath@xa by\pgfmathcounter
+ \pgfmath@xa=\pgfmath@tonumber\pgfmath@xc\pgfmath@xa%
+ \advance\pgfmath@x by\pgfmath@xa
+ \ifdim\pgfmath@x=\pgfmath@xb
+ \else
+ \pgfmath@xb=\pgfmath@x
+ \repeatpgfmathloop%
+ \ifdim\pgfmath@yc<0pt
+ \pgfmathreciprocal@{\pgfmath@tonumber\pgfmath@x}%
+ \pgfmath@x=\pgfmathresult pt\relax
+ \fi
+ \fi
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup
+}
+
+% sqrt function.
+%
+\pgfmathdeclarefunction{sqrt}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \ifdim\pgfmath@x<0pt\relax%
+ \pgfmath@error{I cannot calculate the square-root of the negative number `#1'}{}%
+ \else%
+ \ifdim\pgfmath@x<10pt\relax%
+ \def\pgfmath@zeros{0}%
+ \def\pgfmath@targetiterations{1}%
+ \else%
+ \ifdim\pgfmath@x<100pt\relax%
+ \def\pgfmath@zeros{}%
+ \def\pgfmath@targetiterations{1}%
+ \else%
+ \ifdim\pgfmath@x<1000pt\relax%
+ \def\pgfmath@zeros{0}%
+ \def\pgfmath@targetiterations{2}%
+ \else%
+ \ifdim\pgfmath@x<10000pt\relax%
+ \def\pgfmath@zeros{}%
+ \def\pgfmath@targetiterations{2}%
+ \else%
+ \def\pgfmath@zeros{0}%
+ \def\pgfmath@targetiterations{3}%
+ \fi\fi\fi\fi\fi%
+ \edef\pgfmath@temp{\pgfmath@zeros\pgfmath@tonumber{\pgfmath@x}}%
+ \expandafter\pgfmath@sqrt@\pgfmath@temp\pgfmath@%
+}
+\def\pgfmath@sqrt@#1.#2\pgfmath@{\pgfmath@@sqrt@#1#2\pgfmath@empty\pgfmath@empty\pgfmath@}
+
+\def\pgfmath@@sqrt@#1#2{%
+ \c@pgfmath@countb=#1#2\relax%
+ \ifnum\c@pgfmath@countb>35\relax%
+ \ifnum\c@pgfmath@countb>63\relax%
+ \ifnum\c@pgfmath@countb>80\relax%
+ \c@pgfmath@counta=9\relax%
+ \else%
+ \c@pgfmath@counta=8\relax%
+ \fi%
+ \else%
+ \ifnum\c@pgfmath@countb>48\relax%
+ \c@pgfmath@counta=7\relax%
+ \else%
+ \c@pgfmath@counta=6\relax%
+ \fi%
+ \fi%
+ \else%
+ \ifnum\c@pgfmath@countb>15\relax%
+ \ifnum\c@pgfmath@countb>24\relax%
+ \c@pgfmath@counta5\relax%
+ \else%
+ \c@pgfmath@counta=4\relax%
+ \fi%
+ \else%
+ \ifnum\c@pgfmath@countb>3\relax%
+ \ifnum\c@pgfmath@countb>8\relax%
+ \c@pgfmath@counta=3\relax%
+ \else%
+ \c@pgfmath@counta=2\relax%
+ \fi%
+ \else%
+ \ifnum\c@pgfmath@countb>0\relax%
+ \c@pgfmath@counta=1\relax%
+ \else%
+ \c@pgfmath@counta=0\relax%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \edef\pgfmath@root{\the\c@pgfmath@counta}%
+ \edef\pgfmath@rootspecial{\the\c@pgfmath@counta}%
+ \multiply\c@pgfmath@counta by-\c@pgfmath@counta\relax%
+ \advance\c@pgfmath@counta by#1#2\relax%
+ \edef\pgfmath@remainder{\the\c@pgfmath@counta}%
+ \pgfmath@@@sqrt@%
+}
+
+\def\pgfmath@@@sqrt@#1#2{%
+ \ifx\pgfmath@empty#1%
+ \edef\pgfmath@remainder{\pgfmath@remainder00}%
+ \def\pgfmath@tokens{\pgfmath@empty\pgfmath@empty}%
+ \else%
+ \ifx\pgfmath@empty#2%
+ \edef\pgfmath@remainder{\pgfmath@remainder#10}%
+ \def\pgfmath@tokens{\pgfmath@empty\pgfmath@empty}%
+ \else%
+ \edef\pgfmath@remainder{\pgfmath@remainder#1#2}%
+ \def\pgfmath@tokens{}%
+ \fi\fi%
+ \c@pgfmath@counta=\pgfmath@rootspecial\relax%
+ \multiply\c@pgfmath@counta by20\relax%
+ \c@pgfmath@countb=\c@pgfmath@counta%
+ \multiply\c@pgfmath@countb by6\relax%
+ \advance\c@pgfmath@countb by36\relax%
+ \c@pgfmath@countc=\c@pgfmath@counta%
+ \multiply\c@pgfmath@countc by2\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \advance\c@pgfmath@countb by-\c@pgfmath@countc%
+ \advance\c@pgfmath@countb by-20\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \advance\c@pgfmath@countb by-\c@pgfmath@countc%
+ \advance\c@pgfmath@countb by-12\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \advance\c@pgfmath@countb by-\c@pgfmath@counta%
+ \advance\c@pgfmath@countb by-3\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \def\pgfmath@digit{0}%
+ \else%
+ \def\pgfmath@digit{1}%
+ \fi%
+ \else%
+ \advance\c@pgfmath@countb by\c@pgfmath@counta%
+ \advance\c@pgfmath@countb by5\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \def\pgfmath@digit{2}%
+ \else%
+ \def\pgfmath@digit{3}%
+ \fi%
+ \fi%
+ \else%
+ \advance\c@pgfmath@countb by\c@pgfmath@counta%
+ \advance\c@pgfmath@countb by9\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \def\pgfmath@digit{4}%
+ \else%
+ \def\pgfmath@digit{5}%
+ \fi%
+ \fi%
+ \else%
+ \advance\c@pgfmath@countb by\c@pgfmath@countc%
+ \advance\c@pgfmath@countb by28\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \advance\c@pgfmath@countb by-\c@pgfmath@counta%
+ \advance\c@pgfmath@countb by-15\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \def\pgfmath@digit{6}%
+ \else%
+ \def\pgfmath@digit{7}%
+ \fi%
+ \else%
+ \advance\c@pgfmath@countb by\c@pgfmath@counta%
+ \advance\c@pgfmath@countb by17\relax%
+ \ifnum\c@pgfmath@countb>\pgfmath@remainder\relax%
+ \def\pgfmath@digit{8}%
+ \else%
+ \def\pgfmath@digit{9}%
+ \fi%
+ \fi%
+ \fi%
+ \edef\pgfmath@rootspecial{\pgfmath@rootspecial\pgfmath@digit}%
+ \advance\c@pgfmath@counta by\pgfmath@digit\relax%
+ \multiply\c@pgfmath@counta by-\pgfmath@digit\relax%
+ \advance\c@pgfmath@counta by\pgfmath@remainder\relax%
+ \edef\pgfmath@remainder{\the\c@pgfmath@counta}%
+ \c@pgfmath@counta=\pgfmath@targetiterations\relax%
+ \advance\c@pgfmath@counta by-1\relax%
+ \edef\pgfmath@targetiterations{\the\c@pgfmath@counta}%
+ \ifnum\c@pgfmath@counta=0\relax%
+ \edef\pgfmath@root{\pgfmath@root.\pgfmath@digit}%
+ \else%
+ \edef\pgfmath@root{\pgfmath@root\pgfmath@digit}%
+ \fi%
+ \ifnum\c@pgfmath@counta=-4\relax% -n+1 digits of precision.
+ \let\pgfmath@next\pgfmath@sqrt@end%
+ \else%
+ \let\pgfmath@next\pgfmath@@@sqrt@%
+ \fi%
+ \expandafter\pgfmath@next\pgfmath@tokens%
+}
+
+\def\pgfmath@sqrt@end#1\pgfmath@{%
+ \edef\pgfmathresult{\pgfmath@root}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup}
+
+% \pgfmathpow
+%
+% Calculates #1 ^ #2
+%
+\pgfmathdeclarefunction{pow}{2}{%
+ \begingroup%
+ \pgfmath@xa=#1pt%
+ \pgfmath@xb=#2pt%
+ \ifdim\pgfmath@xa=0pt\relax%
+ \ifdim\pgfmath@xb=0pt\relax%
+ \pgfmath@x=1pt\relax%
+ \else%
+ \pgfmath@x=0pt\relax%
+ \fi%
+ \else%
+ \afterassignment\pgfmath@x%
+ \expandafter\c@pgfmath@counta\the\pgfmath@xb\relax%
+ \ifnum\c@pgfmath@counta<0\relax%
+ \c@pgfmath@counta=-\c@pgfmath@counta%
+ \pgfmathreciprocal@{#1}%
+ \pgfmath@xa=\pgfmathresult pt\relax%
+ \fi
+ \ifdim\pgfmath@x=0pt\relax%
+ \pgfmath@x=1pt\relax%
+ \pgfmathloop%
+ \ifnum\c@pgfmath@counta>0\relax%
+ \ifodd\c@pgfmath@counta%
+ \pgfmath@x=\pgfmath@tonumber{\pgfmath@x}\pgfmath@xa%
+ \fi
+ \ifnum\c@pgfmath@counta>1\relax%
+ \pgfmath@xa=\pgfmath@tonumber{\pgfmath@xa}\pgfmath@xa%
+ \fi%
+ \divide\c@pgfmath@counta by2\relax%
+ \repeatpgfmathloop%
+ \else%
+ \pgfmathln@{#1}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \pgfmath@x=\pgfmath@tonumber{\pgfmath@xb}\pgfmath@x%
+ \pgfmathexp@{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \fi%
+ \fi
+ \pgfmath@returnone\pgf@x%
+ \endgroup%
+}
+
+% factorial function.
+%
+\pgfmathdeclarefunction{factorial}{1}{%
+ \begingroup%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \c@pgfmath@counta=#1\relax\pgfmath@%
+ \pgfmath@x=1pt\relax%
+ \pgfmathloop%
+ \ifnum\c@pgfmath@counta<2\relax%
+ \else%
+ \multiply\pgfmath@x by\c@pgfmath@counta%
+ \advance\c@pgfmath@counta by-1\relax%
+ \repeatpgfmathloop%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% Local Variables:
+% coding: undecided-unix
+% End:
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.code.tex
new file mode 100644
index 0000000000..6e5d079c6b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.code.tex
@@ -0,0 +1,267 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% Declare a function for the parser.
+%
+% #1 - the name of the function.
+% #2 - arity (or ... for variable arguments).
+% #3 - the code for the function.
+%
+% Use \pgfmathdeclarefunction* to force a redefinition if the function exists already.
+\def\pgfmathdeclarefunction{\pgfmath@ifnextchar*\pgfmathdeclarefunction@force\pgfmathdeclarefunction@check}
+\def\pgfmathdeclarefunction@check#1{%
+ \expandafter\ifx\csname pgfmath@function@#1\endcsname\relax\else%
+ \pgfmath@error{The function `#1' already exists}{}%
+ \fi%
+ \pgfmath@declarefunction{#1}%
+}
+\def\pgfmathdeclarefunction@force*{\pgfmath@declarefunction}%
+
+\def\pgfmathredeclarefunction#1#2{%
+ \expandafter\ifx\csname pgfmath@function@#1\endcsname\relax%
+ \pgfmath@error{The function `#1' does not exist}{}%
+ \else%
+ % was: \pgfmath@namedef{pgfmath#1@}{#2}% TT
+ \edef\pgf@marshal{\noexpand\pgfmathdeclarefunction*{#1}{\csname pgfmath@operation@#1@arity\endcsname}}%
+ \pgf@marshal{#2}%
+ \fi%
+}
+
+\def\pgfmath@declarefunction#1#2{%
+ \pgfmath@namedef{pgfmath@function@#1}{#1}%
+ \pgfmath@namedef{pgfmath@operation@#1@type}{function}%
+ \pgfmath@namedef{pgfmath@operation@#1@arity}{#2}%
+ \pgfmath@namedef{pgfmath@operation@#1@infix}{#1}%
+ \pgfmath@namedef{pgfmath@operation@#1@precedence}{1000}%
+ \expandafter\ifx\csname pgfmath@operation@#1@arity\endcsname\pgfmath@dots%
+ \pgfmath@namedef{pgfmath@operation@#1@arity}{1}%
+ \else%
+ \ifnum\csname pgfmath@operation@#1@arity\endcsname>9\relax%
+ \pgfmath@namedef{pgfmath@operation@#1@arity}{1}%
+ \fi%
+ \fi%
+ \edef\pgfmath@marshal{%
+ \noexpand\pgfmath@@declarefunction%
+ {\expandafter\noexpand\csname pgfmath#1\endcsname}%
+ {\expandafter\noexpand\csname pgfmath#1@\endcsname}%
+ {\csname pgfmath@operation@#1@arity\endcsname}%
+ }%
+ \pgfkeysvalueof{/pgf/declare function/execute at begin function}%
+ \pgfmath@marshal%
+}
+
+% #1 - \pgfmath<name>.
+% #2 - \pgfmath<name>@.
+% #3 - arity.
+% #4 - code for function <name>.
+%
+\def\pgfmath@@declarefunction#1#2#3#4{% Function of arity 0 - 9.
+ \pgfkeysvalueof{/pgf/declare function/execute at end function}%
+ \ifcase#3\relax%
+ \def#1{#2}%
+ \def\pgfmath@@head{\def#2}%
+ \or
+ \def#1##1{\pgfmathparse{##1}\expandafter#2\expandafter{\pgfmathresult}}%
+ \def\pgfmath@@head{\def#2####1}%
+ \else%
+ \pgfmath@toks={}%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>#3\relax%
+ \else%
+ \expandafter\pgfmath@addto@toks\expandafter{\pgfmath@char@hash}%
+ \expandafter\pgfmath@addto@toks\expandafter{\pgfmathcounter}%
+ \repeatpgfmathloop%
+ \edef\pgfmath@head{\noexpand\def\noexpand#1\the\pgfmath@toks}%
+ \edef\pgfmath@@head{\noexpand\def\noexpand#2\the\pgfmath@toks}%
+ \pgfmath@toks={}%
+ \def\pgfmath@arguments{}%
+ \pgfmathloop%
+ \ifnum\pgfmathcounter>#3\relax%
+ \else%
+ \pgfmath@addto@toks{\pgfmathparse}%
+ \expandafter\expandafter\expandafter\pgfmath@addto@toks%
+ \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter%
+ {\expandafter\pgfmath@char@hash\pgfmathcounter}}%
+ \pgfmath@addto@toks{\let}%
+ \expandafter\pgfmath@addto@toks\expandafter{%
+ \csname pgfmath@argument@\pgfmathcounter\endcsname=\pgfmathresult}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgfmath@arguments\expandafter\expandafter\expandafter{\expandafter%
+ \pgfmath@arguments\expandafter{\csname pgfmath@argument@\pgfmathcounter\endcsname}}%
+ \repeatpgfmathloop%
+ \expandafter\pgfmath@addto@toks\expandafter{\expandafter#2\pgfmath@arguments}%
+ \edef\pgfmath@body{{\the\pgfmath@toks}}%
+ \expandafter\pgfmath@head\pgfmath@body%
+ \fi%
+ \pgfmath@@head{#4}%
+}
+
+\def\pgfmath@addto@toks#1{%
+ \edef\pgfmath@toks@expanded{\the\pgfmath@toks}%
+ \expandafter\pgfmath@toks\expandafter{\pgfmath@toks@expanded#1}}
+
+% Key for declaring local functions.
+%
+\pgfkeys{%
+ /pgf/declare function/.code={%
+ \pgfmath@local@functions#1@=@;%
+ },
+ /pgf/declare function/execute at begin function/.initial={},
+ /pgf/declare function/execute at end function/.initial={},
+ /pgf/declare function/ignore spaces/.is choice,
+ /pgf/declare function/ignore spaces/.default=true,
+ /pgf/declare function/ignore spaces/true/.style={%
+ /pgf/declare function/execute at begin function={%
+ \begingroup
+ \catcode`\^^I=9\relax
+ \catcode`\ =9\relax
+ \catcode`\~=10\relax
+ \endlinechar=`\ \relax
+ },
+ /pgf/declare function/execute at end function={%
+ \endgroup
+ },
+ },
+ /pgf/declare function/ignore spaces/false/.style={%
+ /pgf/declare function/execute at begin function={},
+ /pgf/declare function/execute at end function={},
+ },
+}
+
+\def\pgfmath@local@gobbleone#1{}
+\def\pgfmath@local@at{@}%
+
+\def\pgfmath@local@functions{%
+ \pgfutil@ifnextchar x{\pgfmath@local@@functions}{\pgfmath@local@@functions}%
+}
+
+\def\pgfmath@local@@functions#1=#2;{%
+ \def\pgfmath@local@temp{#1}%
+ \ifx\pgfmath@local@temp\pgfmath@local@at%
+ \let\pgfmath@local@next=\relax%
+ \else%
+ \pgfmath@local@function#1=#2;%
+ \let\pgfmath@local@next=\pgfmath@local@functions%
+ \fi%
+ \pgfmath@local@next%
+}
+
+\def\pgfmath@local@function{%
+ \let\pgfmath@local@name=\pgfutil@empty%
+ \let\pgfmath@local@args=\pgfutil@empty%
+ \let\pgfmath@local@body=\pgfutil@empty%
+ \pgfmath@local@@function}
+
+\def\pgfmath@local@@function#1{%
+ \if#1=%
+ \let\pgfmath@local@next=\pgfmath@local@function@body%
+ \else%
+ \if#1(%
+ \let\pgfmath@local@next=\pgfmath@local@function@args%
+ \else%
+ \expandafter\def\expandafter\pgfmath@local@name\expandafter{\pgfmath@local@name#1}%
+ \let\pgfmath@local@next=\pgfmath@local@@function%
+ \fi%
+ \fi%
+ \pgfmath@local@next%
+}
+
+\def\pgfmath@local@function@args#1){%
+ \def\pgfmath@local@args{#1}%
+ \pgfmath@local@@function}
+
+\def\pgfmath@local@function@body#1;{%
+ \def\pgfmath@local@body{#1}%
+ \begingroup%
+ \c@pgf@counta=0\relax%
+ \ifx\pgfmath@local@args\pgfmath@empty%
+ \expandafter\pgfmath@toks\expandafter=\expandafter{\pgfmath@local@body}%
+ \else%
+ \pgfmath@toks={}%
+ \expandafter\pgfmath@local@function@@body\pgfmath@local@args,,%
+ \fi%
+ \xdef\pgfmath@local@temp{%
+ \noexpand\pgfmathnotifynewdeclarefunction{\pgfmath@local@name}{\the\c@pgf@counta}%
+ {\the\pgfmath@toks}%
+ }%
+ \endgroup%
+ \pgfmath@local@temp%
+}
+
+% #1: the name
+% #2: the number of arguments <n>
+% #3: a math expression containing '#1', '#2', ... ,'#'<n>
+% This callback is overwritten by pgflibraryluamath.
+\def\pgfmathnotifynewdeclarefunction#1#2#3{%
+ \pgfmathdeclarefunction{#1}{#2}{\pgfmathparse{#3}}%
+}%
+
+\def\pgfmath@local@function@@body#1,{%
+ \def\pgfmath@local@test{#1}%
+ \ifx\pgfmath@local@test\pgfutil@empty%
+ \let\pgfmath@local@next=\relax%
+ \else%
+ \edef\pgfmath@local@var@string{@\expandafter\pgfmath@local@gobbleone\string#1}%
+ \advance\c@pgf@counta by1\relax%
+ \expandafter\expandafter\expandafter\pgfmath@toks\expandafter\expandafter\expandafter=%
+ \expandafter\expandafter\expandafter{\expandafter\pgfmath@char@hash\the\c@pgf@counta}%
+ \edef#1{\the\pgfmath@toks}%
+ \pgfmath@toks={}%
+ \expandafter\pgfmath@local@function@@@body\pgfmath@local@body @%
+ \edef\pgfmath@local@body{\the\pgfmath@toks}%
+ \let\pgfmath@local@next=\pgfmath@local@function@@body%
+ \fi%
+ \pgfmath@local@next%
+}
+
+\def\pgfmath@local@function@@@body{%
+ \pgfutil@ifnextchar\bgroup{\pgfmath@local@function@@@body@bgroup}%
+ {\pgfmath@local@function@@@body@nobgroup}}%
+
+\def\pgfmath@local@function@@@body@bgroup#1{%
+ \begingroup%
+ \pgfmath@toks={}%
+ \pgfmath@local@function@@@body#1 @%
+ \xdef\pgfmath@local@temp{{\the\pgfmath@toks}}%
+ \endgroup%
+ \expandafter\pgfmath@addto@toks\expandafter{\pgfmath@local@temp}%
+ \pgfmath@local@function@@@body%
+}
+
+\def\pgfmath@local@function@@@body@nobgroup#1{%
+ \ifx#1@%
+ \let\pgfmath@local@next=\relax%
+ \else%
+ \let\pgfmath@local@next=\pgfmath@local@function@@@body%
+ \edef\pgfmath@local@var@@string{@\expandafter\pgfmath@local@gobbleone\string#1}%
+ \ifx\pgfmath@local@var@@string\pgfmath@local@var@string%
+ \expandafter\pgfmath@addto@toks\expandafter{#1}%
+ \else%
+ \edef\pgfmath@local@temp{\the\pgfmath@toks}%
+ \pgfmath@toks={#1}%
+ \edef\pgfmath@local@@temp{\the\pgfmath@toks}%
+ \expandafter\pgfmath@toks\expandafter=\expandafter{\pgfmath@local@temp}%
+ \expandafter\pgfmath@addto@toks\expandafter{\pgfmath@local@@temp}%
+ \fi%
+ \fi%
+ \pgfmath@local@next%
+}
+
+% Allows to define 'x' as some \TeX command '#2'.
+\def\pgfmathdeclarepseudoconstant#1#2{%
+ \pgfmathdeclarefunction*{#1}{0}{#2}%
+}%
+% Redefines a pseudo constant '#1'.
+\def\pgfmathredeclarepseudoconstant#1#2{%
+ \pgfmathredeclarefunction{#1}{#2}%
+}%
+
+% Local Variables:
+% tab-width: 2
+% End:
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.comparison.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.comparison.code.tex
new file mode 100644
index 0000000000..a0632670d8
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.comparison.code.tex
@@ -0,0 +1,179 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file defines the mathematical functions and operators.
+%
+% Version 1.4142135 11/8/2008
+
+\pgfmathdeclarefunction{greater}{2}{%
+ \begingroup%
+ \ifdim#1pt>#2pt\relax%
+ \def\pgfmathresult{1}%
+ \else%
+ \def\pgfmathresult{0}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+\let\pgfmathgreaterthan=\pgfmathgreater
+
+\pgfmathdeclarefunction{less}{2}{%
+ \begingroup%
+ \ifdim#1pt<#2pt\relax%
+ \def\pgfmathresult{1}%
+ \else%
+ \def\pgfmathresult{0}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+\let\pgfmathlessthan=\pgfmathless
+
+\pgfmathdeclarefunction{equal}{2}{%
+ \begingroup%
+ \ifdim#1pt=#2pt\relax%
+ \def\pgfmathresult{1}%
+ \else%
+ \def\pgfmathresult{0}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+\let\pgfmathequalto=\pgfmathequal
+
+
+% approxequalto function from Christian Feuersaenger.
+%
+\newif\ifpgfmathcomparison
+\pgfmathdeclarefunction{approxequalto}{2}{%
+ \begingroup%
+ \pgfmath@x=#1pt\relax%
+ \pgfmath@y=#2pt\relax%
+ \advance\pgfmath@x by-\pgfmath@y%
+ \ifdim\pgfmath@x<0pt\relax%
+ \multiply\pgfmath@x by-1\relax%
+ \fi
+ \ifdim\pgfmath@x<0.0001pt\relax%
+ \def\pgfmathresult{1.0}%
+ \global\pgfmathcomparisontrue%
+ \else%
+ \def\pgfmathresult{0.0}%
+ \global\pgfmathcomparisonfalse%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+
+
+% ifthenelse function.
+%
+\pgfmathdeclarefunction{ifthenelse}{3}{%
+ \begingroup%
+ \ifdim#1pt=0.0pt\relax%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{#3}%
+ \else%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{#2}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% notequal function.
+%
+\pgfmathdeclarefunction{notequal}{2}{%
+ \begingroup%
+ \ifdim#1pt=#2pt\relax%
+ \def\pgfmathresult{0}%
+ \else%
+ \def\pgfmathresult{1}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% notless function.
+%
+\pgfmathdeclarefunction{notless}{2}{%
+ \begingroup%
+ \ifdim#1pt<#2pt\relax%
+ \def\pgfmathresult{0}%
+ \else%
+ \def\pgfmathresult{1}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% notgreater function.
+%
+\pgfmathdeclarefunction{notgreater}{2}{%
+ \begingroup%
+ \ifdim#1pt>#2pt\relax%
+ \def\pgfmathresult{0}%
+ \else%
+ \def\pgfmathresult{1}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% and function.
+%
+\pgfmathdeclarefunction{and}{2}{%
+ \begingroup%
+ \def\pgfmathresult{1}%
+ \ifdim#1pt=0pt\relax%
+ \def\pgfmathresult{0}%
+ \else%
+ \ifdim#2pt=0pt\relax%
+ \def\pgfmathresult{0}%
+ \fi%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% or function.
+%
+\pgfmathdeclarefunction{or}{2}{%
+ \begingroup%
+ \def\pgfmathresult{0}%
+ \ifdim#1pt=0pt\relax%
+ \ifdim#2pt=0pt\relax%
+ \else%
+ \def\pgfmathresult{1}%
+ \fi%
+ \else%
+ \def\pgfmathresult{1}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% not function.
+%
+\pgfmathdeclarefunction{not}{1}{%
+ \begingroup%
+ \ifdim#1pt=0pt\relax%
+ \def\pgfmathresult{1}%
+ \else%
+ \def\pgfmathresult{0}%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% true function.
+%
+\pgfmathdeclarefunction{true}{0}{\def\pgfmathresult{1}}
+
+% false function.
+%
+\pgfmathdeclarefunction{false}{0}{\def\pgfmathresult{0}}
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.integerarithmetics.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.integerarithmetics.code.tex
new file mode 100644
index 0000000000..ab8f4e6d3c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.integerarithmetics.code.tex
@@ -0,0 +1,124 @@
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% Macros contributed by Alain Matthes and adapted by CJ
+\pgfmathdeclarefunction{gcd}{2}{%
+ \begingroup
+ \pgfmathcontinuelooptrue
+ \pgfmath@xa=#1pt
+ \pgfmath@xb=#2pt
+ \ifdim\pgfmath@xa=0pt\relax
+ \pgfmathcontinueloopfalse
+ \pgfmath@xa=\pgfmath@xb
+ \fi
+ \ifdim\pgfmath@xb=0pt\relax
+ \pgfmathcontinueloopfalse
+ \pgfmath@xb=\pgfmath@xa
+ \fi
+ \ifdim\pgfmath@xa<0pt\relax
+ \pgfmath@xa=-\pgfmath@xa
+ \fi
+ \ifdim\pgfmath@xb<0pt\relax
+ \pgfmath@xb=-\pgfmath@xb
+ \fi
+ \loop
+ \ifpgfmathcontinueloop
+ \ifdim\pgfmath@xa=\pgfmath@xb
+ \pgfmathcontinueloopfalse
+ \else
+ \ifdim\pgfmath@xa>\pgfmath@xb
+ \advance\pgfmath@xa by-\pgfmath@xb
+ \else
+ \advance\pgfmath@xb by-\pgfmath@xa
+ \fi
+ \fi
+ \repeat
+ \pgfmathparse{int(\pgfmath@xa)}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup}
+
+\newif\ifpgfmath@isprime@unknown
+\newif\ifpgfmath@isprime
+
+\pgfmathdeclarefunction{isprime}{1}{%
+ \begingroup
+ \pgfmath@isprime@unknowntrue
+ \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}%
+ \ifcase\c@pgfmath@counta\relax
+ % |#1| = 0
+ \pgfmath@isprimefalse
+ \pgfmath@isprime@unknownfalse
+ \or
+ % |#1| = 1
+ \pgfmath@isprimefalse
+ \pgfmath@isprime@unknownfalse
+ \or
+ % |#1| = 2
+ \pgfmath@isprimetrue
+ \pgfmath@isprime@unknownfalse
+ \or
+ % |#1| = 3
+ \pgfmath@isprimetrue
+ \pgfmath@isprime@unknownfalse
+ \else
+ % |#1| > 3
+ \ifodd\c@pgfmath@counta\relax
+ \else
+ \pgfmath@isprimefalse
+ \pgfmath@isprime@unknownfalse
+ \fi
+ \fi
+ \ifpgfmath@isprime@unknown
+ \c@pgfmath@countd=3
+ \pgfmath@isprimetrue
+ \pgfmathloop
+ \c@pgfmath@countb=\c@pgfmath@counta
+ \divide\c@pgfmath@countb by\c@pgfmath@countd
+ \ifnum\c@pgfmath@countb>\c@pgfmath@countd
+ \pgfmath@isprime@unknowntrue
+ \else
+ \pgfmath@isprime@unknownfalse
+ \fi
+ \multiply\c@pgfmath@countb by\c@pgfmath@countd
+ \ifnum\c@pgfmath@countb=\c@pgfmath@counta
+ \global\pgfmath@isprimefalse
+ \pgfmath@isprime@unknownfalse
+ \fi
+ \ifpgfmath@isprime@unknown\advance\c@pgfmath@countd by 2
+ \repeatpgfmathloop
+ \fi
+ \ifpgfmath@isprime
+ \def\pgfmathresult{1}%
+ \else
+ \def\pgfmathresult{0}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup}
+
+\pgfmathdeclarefunction{isodd}{1}{%
+ \begingroup
+ \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}%
+ \ifodd\c@pgfmath@counta
+ \def\pgfmathresult{1}%
+ \else
+ \def\pgfmathresult{0}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup}
+
+\pgfmathdeclarefunction{iseven}{1}{%
+ \begingroup
+ \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}%
+ \ifodd\c@pgfmath@counta
+ \def\pgfmathresult{0}%
+ \else
+ \def\pgfmathresult{1}%
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup}
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.misc.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.misc.code.tex
new file mode 100644
index 0000000000..859d8266a9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.misc.code.tex
@@ -0,0 +1,353 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file defines the mathematical functions and operators.
+%
+% Version 1.414213 29/9/2007
+
+% veclen function adapted from ideas due to Rouben Rostamian.
+%
+% Calculate the Euclidean length of a 2D vector.
+%
+%
+\pgfmathdeclarefunction{veclen}{2}{%
+ \begingroup%
+ \pgfmath@x#1pt\relax%
+ \pgfmath@y#2pt\relax%
+ \ifdim\pgfmath@x<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \fi%
+ \ifdim\pgfmath@y<0pt\relax%
+ \pgfmath@y-\pgfmath@y%
+ \fi%
+ \ifdim\pgfmath@x=0pt\relax%
+ \pgfmath@x\pgfmath@y%
+ \else%
+ \ifdim\pgfmath@y=0pt\relax%
+ \else%
+ \ifdim\pgfmath@x>\pgfmath@y%
+ \pgfmath@xa\pgfmath@x%
+ \pgfmath@x\pgfmath@y%
+ \pgfmath@y\pgfmath@xa%
+ \fi%
+ % We use a scaling factor to reduce errors.
+ \ifdim\pgfmath@y>10000pt\relax%
+ \c@pgfmath@counta1500\relax%
+ \else%
+ \ifdim\pgfmath@y>1000pt\relax%
+ \c@pgfmath@counta150\relax%
+ \else%
+ \ifdim\pgfmath@y>100pt\relax%
+ \c@pgfmath@counta50\relax%
+ \else%
+ \c@pgfmath@counta1\relax%
+ \fi%
+ \fi%
+ \fi%
+ \divide\pgfmath@x\c@pgfmath@counta\relax%
+ \divide\pgfmath@y\c@pgfmath@counta\relax%
+ \pgfmathreciprocal@{\pgfmath@tonumber{\pgfmath@y}}%
+ \pgfmath@x\pgfmathresult\pgfmath@x%
+ \pgfmath@xa\pgfmath@tonumber{\pgfmath@x}\pgfmath@x%
+ \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@xa}}%
+ %
+ % Use A+x^2*(B+x^2*(C+x^2*(D+E*x^2)))
+ % where
+ % A = +1.000012594
+ % B = +0.4993615349
+ % C = -0.1195159052
+ % D = +0.04453994279
+ % E = -0.01019210944
+ %
+ \pgfmath@x-0.01019210944\pgfmath@xa%
+ \advance\pgfmath@x0.04453994279pt\relax%
+ \pgfmath@x\pgfmath@temp\pgfmath@x%
+ \advance\pgfmath@x-0.1195159052pt\relax%
+ \pgfmath@x\pgfmath@temp\pgfmath@x%
+ \advance\pgfmath@x0.4993615349pt\relax%
+ \pgfmath@x\pgfmath@temp\pgfmath@x%
+ \advance\pgfmath@x1.000012594pt\relax%
+ \ifdim\pgfmath@y<0pt\relax%
+ \pgfmath@y-\pgfmath@y%
+ \fi%
+ \pgfmath@x\pgfmath@tonumber{\pgfmath@y}\pgfmath@x%
+ % Invert the scaling factor.
+ \multiply\pgfmath@x\c@pgfmath@counta\relax%
+ \fi%
+ \fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% Hyperbolic functions contributed by Martin Heller.
+%
+\pgfmathdeclarefunction{cosh}{1}{%
+ \begingroup
+ \edef\pgfmath@arg{#1}%
+ \pgfmathexp@{\pgfmath@arg}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \pgfmathexp@{-\pgfmath@arg}%
+ \advance\pgfmath@x by\pgfmathresult pt\relax%
+ \divide\pgfmath@x by2\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup}
+
+\pgfmathdeclarefunction{sinh}{1}{%
+ \begingroup
+ \edef\pgfmath@arg{#1}%
+ \pgfmathexp@{\pgfmath@arg}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \pgfmathexp@{-\pgfmath@arg}%
+ \advance\pgfmath@x by-\pgfmathresult pt\relax%
+ \divide\pgfmath@x by2\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup
+}%
+
+\pgfmathdeclarefunction{tanh}{1}{%
+ \begingroup
+ \edef\pgfmath@arg{#1}%
+ \pgfmathsinh@{\pgfmath@arg}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \pgfmathcosh@{\pgfmath@arg}%
+ \pgfmath@y=\pgfmathresult pt\relax%
+ \pgfmathdivide@{\pgfmath@tonumber{\pgfmath@x}}{\pgfmath@tonumber{\pgfmath@y}}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup
+}%
+
+% \pgfmathscientific
+%
+% Return the value of #1e#2
+%
+% e.g. \pgfmathscientific{1.23456789123}{4}
+%
+% defines \pgfmathresult as 12345.67891
+%
+% NB These arguments *are not parsed*, as the long mantissa would be lost.
+%
+\def\pgfmathscientific#1#2{%
+ \begingroup%
+ \edef\pgfmath@sci@exponent{#2}%
+ \pgfmath@x#1pt\relax%
+ \ifdim\pgfmath@x<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \edef\pgfmath@sci@sign{-}%
+ \expandafter\edef\expandafter\pgfmath@temp\expandafter{\expandafter\pgfmath@gobbleone#1}%
+ \else%
+ \edef\pgfmath@sci@sign{+}%
+ \edef\pgfmath@temp{#1}%
+ \fi%
+ \expandafter\pgfmath@in@\expandafter.\expandafter{#1}%
+ \ifpgfmath@in@%
+ \else%
+ \edef\pgfmath@temp{\pgfmath@temp.0}%
+ \fi%
+ \expandafter\pgfmath@scientific@@\pgfmath@temp00000000000\pgfmath@}
+
+\def\pgfmath@scientific@@#1.#2#3#4#5#6{%
+ \edef\pgfmath@sci@int{#1}%
+ \edef\pgfmath@sci@mantissaA{#2#3#4#5#6}%
+ \pgfmath@scientific@@@}
+
+\def\pgfmath@scientific@@@#1#2#3#4#5#6\pgfmath@{%
+ \edef\pgfmath@sci@mantissaB{#1#2#3#4#5}%
+ \c@pgfmath@counta\pgfmath@sci@exponent\relax%
+ \ifnum\c@pgfmath@counta<-4\relax%
+ \pgfmath@x0pt\relax%
+ \else%
+ \c@pgfmath@countb\c@pgfmath@counta%
+ \ifnum\c@pgfmath@counta<0\relax%
+ \c@pgfmath@counta-\c@pgfmath@counta%
+ \fi%
+ \pgfmathpow@{10}{\the\c@pgfmath@counta}%
+ \afterassignment\pgfmath@gobbletilpgfmath@
+ \c@pgfmath@countc\pgfmathresult\relax\pgfmath@
+ \edef\pgfmath@sci@factor{\the\c@pgfmath@countc}%
+ \ifnum\c@pgfmath@countb<0\relax%
+ % xE-y: easy...
+ \pgfmath@x\pgfmath@sci@int.\pgfmath@sci@mantissaA pt\relax%
+ \divide\pgfmath@x\pgfmath@sci@factor\relax%
+ \else%
+ % xE+y:
+ % Must do this way so as not lose digits in a long mantissa. Sigh...
+ \c@pgfmath@counta\pgfmath@sci@int%
+ \c@pgfmath@countb\pgfmath@sci@mantissaA%
+ \multiply\c@pgfmath@counta\pgfmath@sci@factor\relax%
+ \multiply\c@pgfmath@countb\pgfmath@sci@factor\relax%
+ \c@pgfmath@countc\c@pgfmath@countb%
+ \divide\c@pgfmath@countb100000\relax%
+ \advance\c@pgfmath@counta\c@pgfmath@countb%
+ \multiply\c@pgfmath@countb100000\relax%
+ \advance\c@pgfmath@countc-\c@pgfmath@countb%
+ \c@pgfmath@countb\pgfmath@sci@mantissaB\relax%
+ \multiply\c@pgfmath@countb\pgfmath@sci@factor\relax%
+ \divide\c@pgfmath@countb100000\relax%
+ \advance\c@pgfmath@countc\c@pgfmath@countb%
+ \advance\c@pgfmath@countc100000\relax%
+ \edef\pgfmath@sci@result{\pgfmath@sci@sign\the\c@pgfmath@counta.\expandafter\pgfmath@gobbleone\the\c@pgfmath@countc pt}%
+ \pgfmath@x\pgfmath@sci@result\relax%
+ \fi\fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup}
+
+
+
+% width function.
+%
+\pgfmathdeclarefunction{width}{1}{%
+ \begingroup%
+ \setbox\pgfmath@box=\hbox{{\pgfmath@selectfont{#1}}}%
+ \pgfmath@x=\wd\pgfmath@box%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+
+% height function.
+%
+\pgfmathdeclarefunction{height}{1}{%
+ \begingroup%
+ \setbox\pgfmath@box=\hbox{{\pgfmath@selectfont{#1}}}%
+ \pgfmath@x=\ht\pgfmath@box%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+% depth function.
+%
+\pgfmathdeclarefunction{depth}{1}{%
+ \begingroup%
+ \setbox\pgfmath@box=\hbox{{\pgfmath@selectfont{#1}}}%
+ \pgfmath@x=\dp\pgfmath@box%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
+
+
+% array function.
+%
+\pgfmathdeclarefunction{array}{2}{%
+ \begingroup%
+ \afterassignment\pgfmath@gobbletilpgfmath@\pgfmath@count=#2\relax\pgfmath@%
+ \expandafter\pgfmatharray@@#1\pgfmath@stop%
+}
+
+\def\pgfmath@token@stop{\pgfmath@stop}%
+\def\pgfmatharray@@#1{%
+ \def\pgfmath@temp{#1}%
+ \advance\pgfmath@count by-1\relax%
+ \ifx\pgfmath@temp\pgfmath@token@stop%
+ \pgfmath@error{Array index out of bounds.}{}%
+ \def\pgfmathresult{0}%
+ \pgfmath@smuggleone\pgfmathresult\endgroup%
+ \let\pgfmath@next=\relax%
+ \else%
+ \ifnum\pgfmath@count=-1\relax%
+ \def\pgfmathresult{#1}%
+ \let\pgfmath@next=\pgfmatharray@@@%
+ \else%
+ \let\pgfmath@next=\pgfmatharray@@%
+ \fi%
+ \fi%
+ \pgfmath@next}
+
+\def\pgfmatharray@@@#1\pgfmath@stop{%
+ \pgfmath@smuggleone\pgfmathresult\endgroup%
+}
+
+% dim function: return dimension of an array
+% dim({1,2,3}) return 3
+% dim({{1,2,3},{4,5,6}}) return 2
+\pgfmathdeclarefunction{dim}{1}{%
+ \begingroup
+ \pgfmath@count=0\relax
+ \expandafter\pgfmath@dim@i\pgfutil@firstofone#1{\pgfmath@token@stop}%
+ \edef\pgfmathresult{\the\pgfmath@count}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup}
+
+\def\pgfmath@dim@i#1#{%
+ \pgfutil@ifempty{#1}{}{\advance\pgfmath@count by 1}%
+ \pgfmath@dim@ii{#1}}
+
+\def\pgfmath@dim@ii#1#2{%
+ \ifx\pgfmath@token@stop#2%
+ \else
+ \advance\pgfmath@count by 1\relax
+ \expandafter\pgfmath@dim@i
+ \fi}
+
+
+% max function.
+%
+\pgfmathdeclarefunction{max}{...}{%
+ \begingroup%
+ \pgfmath@x=-16383pt\relax%
+ \pgfmathmax@@#1{}}
+
+\def\pgfmathmax@@#1{%
+ \def\pgfmath@temp{#1}%
+ \ifx\pgfmath@temp\pgfmath@empty%
+ \let\pgfmath@next=\pgfmathmax@@@%
+ \else%
+ \ifdim#1pt>\pgfmath@x%
+ \pgfmath@x=#1pt\relax%
+ \fi%
+ \let\pgfmath@next=\pgfmathmax@@%
+ \fi%
+ \pgfmath@next}
+
+\def\pgfmathmax@@@{\pgfmath@returnone\pgfmath@x\endgroup}%
+
+% For computability with old code.
+\def\pgfmathmax#1#2{%
+ \pgfmathparse{#1,#2}%
+ \expandafter\pgfmathmax@\expandafter{\pgfmathresult}%
+}
+
+% min function.
+%
+\pgfmathdeclarefunction{min}{...}{%
+ \begingroup%
+ \pgfmath@x=16383pt\relax%
+ \pgfmathmin@@#1{}}
+
+\def\pgfmathmin@@#1{%
+ \def\pgfmath@temp{#1}%
+ \ifx\pgfmath@temp\pgfmath@empty%
+ \let\pgfmath@next=\pgfmathmin@@@%
+ \else%
+ \ifdim#1pt<\pgfmath@x%
+ \pgfmath@x=#1pt\relax%
+ \fi%
+ \let\pgfmath@next=\pgfmathmin@@%
+ \fi%
+ \pgfmath@next}
+
+\def\pgfmathmin@@@{\pgfmath@returnone\pgfmath@x\endgroup}%
+
+% For computability with old code.
+\def\pgfmathmin#1#2{%
+ \pgfmathparse{#1,#2}%
+ \expandafter\pgfmathmin@\expandafter{\pgfmathresult}%
+}
+
+
+
+% scalar function.
+%
+\pgfmathdeclarefunction{scalar}{1}{%
+ \def\pgfmathresult{#1}%
+ \global\pgfmathunitsdeclaredfalse%
+}
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.random.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.random.code.tex
new file mode 100644
index 0000000000..969762c6c9
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.random.code.tex
@@ -0,0 +1,246 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file defines the pseudorandom numbers.
+%
+% Version 1.414213 29/9/2007
+
+% Pseudo-random number generation.
+%
+% See:
+% \book@{pressetal1992,
+% author = {William H. Press and Brian P. Flannery and Saul A.
+% Teukolsky and William T. Vetterling},
+% title = {Numerical Recipies in C},
+% edition = {Second},
+% publisher = {Cambridge University Press}
+% }
+%
+% See also, the documentation for the lcg package by Erich Janka:
+% (http://www.ctan.org/tex-archive/macros/latex/contrib/lcg/lcg.pdf)
+%
+\def\pgfmath@rnd@m{2147483647}% LaTeX Maximum.
+
+\begingroup
+\c@pgfmath@counta=\time%
+\multiply\c@pgfmath@counta by\year%
+\ifnum\c@pgfmath@counta=0
+ \c@pgfmath@counta=1
+\fi
+\xdef\pgfmath@rnd@z{\the\c@pgfmath@counta}% The seed.
+\endgroup
+
+% \pgfmathsetseed
+%
+% Explicitly set the seed for the generator
+%
+% #1 -> the new seed.
+%
+\def\pgfmathsetseed#1{%
+ % Attention pgflibraryluamath.code.tex relies on the fact that
+ % this method also modifies \pgfmathresult:
+ \pgfmathparse{#1}\expandafter\pgfmath@setseed\pgfmathresult.0\pgfmath@stop
+}%
+\def\pgfmath@setseed#1.#2\pgfmath@stop{\def\pgfmath@rnd@z{#1}}%
+
+% Alternative parameters - see Press et al (1992) p278-279,
+% for discussion.
+%
+% a=16807 q=127773 r=2836
+% a=48271 q=4488 r=3399
+%
+\def\pgfmath@rnd@a{69621}
+\def\pgfmath@rnd@r{23902}
+\def\pgfmath@rnd@q{30845}
+
+% \pgfmathgeneratepseudorandomnumber
+%
+% A linear congruency generator for generating
+% pseudo-random numbers. Generates numbers in
+% the range 1 - 2^31-1.
+%
+\def\pgfmathgeneratepseudorandomnumber{%
+ \begingroup%
+ \c@pgfmath@counta=\pgfmath@rnd@z%
+ \c@pgfmath@countb=\pgfmath@rnd@z%
+ \c@pgfmath@countc=\pgfmath@rnd@q%
+ \divide\c@pgfmath@counta by\c@pgfmath@countc%
+ \multiply\c@pgfmath@counta by-\c@pgfmath@countc%
+ \advance\c@pgfmath@counta by\c@pgfmath@countb
+ \c@pgfmath@countc=\pgfmath@rnd@a%
+ \multiply\c@pgfmath@counta by\c@pgfmath@countc%
+ \c@pgfmath@countc=\pgfmath@rnd@q%
+ \divide\c@pgfmath@countb by\c@pgfmath@countc%
+ \c@pgfmath@countc=\pgfmath@rnd@r%
+ \multiply\c@pgfmath@countb by\c@pgfmath@countc%
+ \advance\c@pgfmath@counta by-\c@pgfmath@countb%
+ \ifnum\c@pgfmath@counta<0\relax%
+ \c@pgfmath@countb=\pgfmath@rnd@m%
+ \advance\c@pgfmath@counta by\c@pgfmath@countb%
+ \fi%
+ \xdef\pgfmath@rnd@z{\the\c@pgfmath@counta}%
+ \endgroup%
+ \edef\pgfmathresult{\pgfmath@rnd@z}%
+}
+
+% \pgfmathrnd
+%
+% Generates a pseudo-random number between 0 and 1.
+%
+\pgfmathdeclarefunction{rnd}{0}{%
+ \begingroup%
+ \pgfmathgeneratepseudorandomnumber%
+ \c@pgfmath@counta\pgfmathresult%
+ \c@pgfmath@countb\c@pgfmath@counta%
+ \divide\c@pgfmath@countb100001\relax% To get one.
+ \multiply\c@pgfmath@countb-100001\relax%
+ \advance\c@pgfmath@countb\c@pgfmath@counta%
+ \advance\c@pgfmath@countb1000000\relax%
+ \expandafter\pgfmathrnd@@\the\c@pgfmath@countb\pgfmath@%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+\def\pgfmathrnd@@#1#2#3\pgfmath@{%
+ \edef\pgfmath@temp{#2.#3}%
+ \pgfmath@x=\pgfmath@temp pt\relax%
+}%
+
+% \pgfmathrand
+%
+% Generates a pseudo-random number between -1 and 1.
+%
+\pgfmathdeclarefunction{rand}{0}{%
+ \begingroup%
+ \pgfmathgeneratepseudorandomnumber%
+ \c@pgfmath@counta\pgfmathresult%
+ \c@pgfmath@countb\c@pgfmath@counta%
+ \divide\c@pgfmath@countb200001\relax%
+ \multiply\c@pgfmath@countb-200001\relax%
+ \advance\c@pgfmath@countb\c@pgfmath@counta%
+ \advance\c@pgfmath@countb-100000\relax%
+ \ifnum\c@pgfmath@countb<0\relax%
+ \advance\c@pgfmath@countb-1000000\relax%
+ \else%
+ \advance\c@pgfmath@countb1000000\relax%
+ \fi%
+ \expandafter\pgfmathrand@@\the\c@pgfmath@countb\pgfmath@%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+\def\pgfmathrand@@#1#2#3#4\pgfmath@{%
+ \ifx#1-%
+ \edef\pgfmath@temp{-#3.#4}%
+ \else%
+ \edef\pgfmath@temp{#2.#3#4}%
+ \fi%
+ \pgfmath@x=\pgfmath@temp pt\relax%
+}%
+
+\pgfmathdeclarefunction{random}{...}{%
+ \begingroup%
+ \def\pgfmath@temp{#1}%
+ \ifx\pgfmath@temp\pgfmath@empty%
+ \pgfmathrnd@%
+ \else%
+ \expandafter\pgfmathrandom@@#1\pgfmath@stop%
+ \fi%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup}
+
+\def\pgfmathrandom@@{\futurelet\pgfmath@token\pgfmathrandom@@@}
+\def\pgfmathrandom@@@{%
+ \ifx\pgfmath@token\bgroup%
+ \expandafter\pgfmath@random@@@@%
+ \else%
+ \expandafter\pgfmath@random@@@@@%
+ \fi%
+}
+\def\pgfmath@random@@@@@#1\pgfmath@stop{%
+ \pgfmathrandominteger\pgfmathresult{1}{#1}%
+}
+\def\pgfmath@random@@@@#1#2\pgfmath@stop{%
+ \pgfmathrandominteger\pgfmathresult{#1}{#2}%
+}
+
+% \pgfmathrandominteger
+%
+% Return a 'randomly' selected integer in the range #2 - #3 (inclusive).
+%
+% #1 - a macro to store the integer (not a count register).
+% #2 - the lower limit of the range.
+% #3 - the upper limit of the range.
+%
+\def\pgfmathrandominteger#1#2#3{%
+ \begingroup%
+ \pgfmathsetcount\c@pgfmath@counta{#2}%
+ \pgfmathsetcount\c@pgfmath@countb{#3}%
+ \c@pgfmath@countc\c@pgfmath@countb%
+ % OK. Maybe #2 > #3.
+ \ifnum\c@pgfmath@counta>\c@pgfmath@countb\relax%
+ \c@pgfmath@countc\c@pgfmath@counta%
+ \c@pgfmath@counta\c@pgfmath@countb%
+ \c@pgfmath@countb\c@pgfmath@countc%
+ \fi%
+ \c@pgfmath@countd\c@pgfmath@counta
+ \advance\c@pgfmath@countc1\relax%
+ \advance\c@pgfmath@countc-\c@pgfmath@counta%
+ \pgfmathgeneratepseudorandomnumber%
+ \c@pgfmath@counta\pgfmathresult\relax%
+ \c@pgfmath@countb\c@pgfmath@counta%
+ \divide\c@pgfmath@countb\c@pgfmath@countc%
+ \multiply\c@pgfmath@countb-\c@pgfmath@countc%
+ \advance\c@pgfmath@counta\c@pgfmath@countb%
+ \advance\c@pgfmath@counta\c@pgfmath@countd
+ \edef\pgfmathresult{\the\c@pgfmath@counta}%
+ \pgfmath@smuggleone{\pgfmathresult}%
+ \endgroup%
+ \edef#1{\pgfmathresult}%
+}
+
+% \pgfmathdeclarerandomlist
+%
+% Create a list to be used with \pgfmathrandomelement.
+%
+% #1 - the name of the list
+% #2 - a list of elements (e.g., {item-1}{item-2}...{item-n}).
+%
+\def\pgfmathdeclarerandomlist#1#2{%
+ \def\pgfmath@randomlistname{#1}%
+ \begingroup%
+ \c@pgfmath@counta=1\relax%
+ % {} is a possible random element so (locally)
+ % redefine \pgfmath@empty.
+ \def\pgfmath@empty{pgfmath@empty}%
+ \expandafter\pgfmath@scanrandomlist#2{pgfmath@empty}}
+\def\pgfmath@scanrandomlist#1{%
+ \def\pgfmath@scanneditem{#1}%
+ \ifx\pgfmath@scanneditem\pgfmath@empty%
+ \advance\c@pgfmath@counta-1\relax%
+ \expandafter\xdef\csname pgfmath@randomlist@\pgfmath@randomlistname\endcsname{\the\c@pgfmath@counta}%
+ \endgroup%
+ \else%
+ \expandafter\gdef\csname pgfmath@randomlist@\pgfmath@randomlistname @\the\c@pgfmath@counta\endcsname{#1}%
+ \advance\c@pgfmath@counta1\relax%
+ \expandafter\pgfmath@scanrandomlist%
+ \fi}
+
+% \pgfmathrandomitem
+%
+% Return a 'randomly' selected element from a list.
+%
+% #1 - a macro to store the item.
+% #2 - the name of the list.
+%
+\def\pgfmathrandomitem#1#2{%
+ \pgfmath@ifundefined{pgfmath@randomlist@#2}{\pgfmath@error{Unknown random list `#2'}{}}{%
+ \edef\pgfmath@randomlistlength{\csname pgfmath@randomlist@#2\endcsname}%
+ \pgfmathrandominteger{\pgfmath@randomtemp}{1}{\pgfmath@randomlistlength}%
+ \expandafter\def\expandafter#1\expandafter{\csname pgfmath@randomlist@#2@\pgfmath@randomtemp\endcsname}}}
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.round.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.round.code.tex
new file mode 100644
index 0000000000..120e971c8c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.round.code.tex
@@ -0,0 +1,123 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file defines the mathematical functions and operators.
+%
+% Version 1.414213 29/9/2007
+
+% round function. Uses asymmetric half-up rounding.
+%
+\pgfmathdeclarefunction{round}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \afterassignment\pgfmath@xa%
+ \expandafter\c@pgfmath@counta\the\pgfmath@x\relax%
+ \pgfmath@xb\pgfmath@x%
+ \ifdim\pgfmath@xb<0pt\relax%
+ \ifdim\pgfmath@xa<0.5pt\relax%
+ \else%
+ \advance\c@pgfmath@counta-1\relax%
+ \fi%
+ \else%
+ \ifdim\pgfmath@xa<0.5pt\relax%
+ \else%
+ \advance\c@pgfmath@counta1\relax%
+ \fi%
+ \fi%
+ \pgfmath@returnone\the\c@pgfmath@counta pt%
+ \endgroup%
+}%
+
+% floor function.
+%
+\pgfmathdeclarefunction{floor}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \afterassignment\pgfmathfloor@collect@remainder%
+ \expandafter\c@pgfmath@counta\the\pgfmath@x\pgfmath@%
+ \expandafter\pgfmath@x#1pt\relax%
+ \ifdim\pgfmath@x<0pt\relax%
+ \ifdim\pgfmathfloor@remainder>0pt
+ \advance\c@pgfmath@counta by -1\relax%
+ \else
+ % ok, we stripped only '0'.
+ \fi
+ \fi%
+ \pgfmath@x\c@pgfmath@counta pt\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+\def\pgfmathfloor@collect@remainder#1\pgfmath@{%
+ \def\pgfmathfloor@remainder{#1}%
+ \ifx\pgfmathfloor@remainder\pgfutil@empty
+ \def\pgfmathfloor@remainder{0}%
+ \fi
+}%
+
+% ceil function.
+%
+\pgfmathdeclarefunction{ceil}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@%
+ \pgfmath@y\pgfmath@x%
+ \advance\pgfmath@y-\c@pgfmath@counta pt\relax%
+ \pgfmath@x\c@pgfmath@counta pt\relax%
+ \ifdim\pgfmath@y>0pt\relax%
+ \advance\pgfmath@x1pt\relax%
+ \fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+% int function
+%
+\pgfmathdeclarefunction{int}{1}{%
+ \begingroup%
+ \expandafter\pgfmathint@@#1.\pgfmath@stop
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup}
+
+\def\pgfmathint@@#1.#2\pgfmath@stop{%
+ \def\pgfmath@temp{#1}%
+ \ifx\pgfmath@temp\pgfmath@empty%
+ \def\pgfmathresult{0}%
+ \else%
+ \pgfmath@in@{#1}{+-+0-0}%
+ \ifpgfmath@in@
+ \def\pgfmathresult{0}%
+ \else%
+ \def\pgfmathresult{#1}%
+ \fi%
+ \fi}
+
+% frac function.
+%
+\pgfmathdeclarefunction{frac}{1}{%
+ \begingroup%
+ \expandafter\pgfmathfrac@@#1.\pgfmath@stop%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup}
+
+\def\pgfmathfrac@@#1.{%
+ \pgfmath@ifnextchar\pgfmath@stop{\def\pgfmathresult{0.0}\pgfmath@gobbleone}{\pgfmathfrac@@@}%
+}
+\def\pgfmathfrac@@@#1.\pgfmath@stop{\def\pgfmathresult{0.#1}}
+
+% real function.
+%
+\pgfmathdeclarefunction{real}{1}{%
+ \begingroup%
+ \pgfmath@x=#1pt\relax%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+}
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathfunctions.trigonometric.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.trigonometric.code.tex
new file mode 100644
index 0000000000..b76c5b440c
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathfunctions.trigonometric.code.tex
@@ -0,0 +1,1571 @@
+% Copyright 2019 by Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+% This file defines the trigonometric functions/functions.
+%
+% Much of this file is based on ideas and code (particularly
+% the old \pgfcoremath.code.tex) due to Till Tantau.
+%
+% Version 1.414213 29/9/2007
+
+% \pgfmathpi
+%
+\pgfmathdeclarefunction{pi}{0}{\def\pgfmathresult{3.141592654}}
+
+\pgfkeys{
+ /pgf/trig format/.is choice,
+ % attention: the luamath library will hook into these code keys.
+ /pgf/trig format/deg/.code={\def\pgfmath@trig@format@choice{0}},
+ /pgf/trig format/rad/.code={\def\pgfmath@trig@format@choice{1}},
+ /pgf/trig format/deg,
+}
+
+% Executes #1 if 'trig format=deg' and #2 otherwise.
+\def\pgfmathiftrigonometricusesdeg#1#2{%
+ \if0\pgfmath@trig@format@choice
+ #1%
+ \else
+ #2%
+ \fi
+}%
+
+% \pgfmathradians
+% (for compatibility with 1.18 beta, will be deprecated)
+%
+% Convert #1 from radians to degrees (accurate to 1 deg).
+%
+\pgfmathdeclarefunction{radians}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi)
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+% \pgfmathdeg
+%
+% Convert #1 from radians to degrees.
+%
+\pgfmathdeclarefunction{deg}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@scale@rad@to@deg\pgfmath@x
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+\def\pgfmath@scale@rad@to@deg#1{%
+ #1=57.29577#1\relax% 57.29577 = 360/(2*pi)
+}%
+
+% \pgfmathrad
+%
+% Convert #1 from degrees to radians.
+%
+\pgfmathdeclarefunction{rad}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@scale@deg@to@rad\pgfmath@x
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+\def\pgfmath@scale@deg@to@rad#1{%
+ #1=3.14159#1%
+ \divide#1180\relax%
+}%
+
+% \pgfmathsin
+%
+% Calculate the sine of #1 (in degrees).
+%
+\pgfmathdeclarefunction{sin}{1}{%
+ % Let #1 = a.b
+ % Then sin(#1) \approx (1-b)*sin(a) + b*sin(a+1)
+ %
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \if1\pgfmath@trig@format@choice
+ % trig format=rad
+ \pgfmath@scale@rad@to@deg\pgfmath@x
+ \fi
+ \advance\pgfmath@x-90pt\relax%
+ \afterassignment\pgfmath@gobbletilpgfmath@
+ \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@
+ \divide\c@pgfmath@counta360\relax%
+ \multiply\c@pgfmath@counta-360\relax%
+ \advance\pgfmath@x\c@pgfmath@counta pt\relax%
+ \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi%
+ \ifdim\pgfmath@x<180pt\relax%
+ \else
+ \pgfmath@x-\pgfmath@x%
+ \advance\pgfmath@x360pt\relax%
+ \fi%
+ % Now 0 <= x < 179. So split x into integer and decimal...
+ %
+ \afterassignment\pgfmath@xa%
+ \expandafter\c@pgfmath@counta\the\pgfmath@x\relax%
+ %
+ % ...if #1 is an integer, don't do anything fancy.
+ \ifdim\pgfmath@xa=0pt%
+ \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt\relax%
+ \else%
+ \pgfmath@x-\pgfmath@xa%
+ \advance\pgfmath@x1pt\relax%
+ \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x%
+ \advance\c@pgfmath@counta1\relax%
+ \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi%
+ \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa%
+ \fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup
+}
+
+% \pgfmathcos
+%
+% Calculate the cosine of #1 (in degrees).
+%
+\pgfmathdeclarefunction{cos}{1}{%
+ % Let x = a.b
+ % Then cos(x) \approx (1-b)*cos(a) + b*cos(a+1)
+ %
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \if1\pgfmath@trig@format@choice
+ % trig format=rad
+ \pgfmath@scale@rad@to@deg\pgfmath@x
+ \fi
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@%
+ \divide\c@pgfmath@counta360\relax%
+ \multiply\c@pgfmath@counta-360\relax%
+ \advance\pgfmath@x\c@pgfmath@counta pt\relax%
+ \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi%
+ \ifdim\pgfmath@x<180pt\relax%
+ \else%
+ \pgfmath@x-\pgfmath@x%
+ \advance\pgfmath@x360pt\relax%
+ \fi%
+ % Now 0 <= x < 179. So split x into integer and decimal...
+ %
+ \afterassignment\pgfmath@xa%
+ \expandafter\c@pgfmath@counta\the\pgfmath@x\relax%
+ %
+ % ...if #1 is an integer, don't do anything fancy.
+ \ifdim\pgfmath@xa=0pt%
+ \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt%
+ \else%
+ \pgfmath@x-\pgfmath@xa%
+ \advance\pgfmath@x1pt\relax%
+ \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x%
+ \advance\c@pgfmath@counta1\relax%
+ \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi%
+ \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa%
+ \fi%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% \pgfmathsincos
+%
+% Calculate the sin and cosine of #1 (in degrees).
+%
+\def\pgfmathsincos#1{%
+ \pgfmathparse{#1}%
+ \expandafter\pgfmathsincos@\expandafter{\pgfmathresult}}
+\def\pgfmathsincos@#1{%
+ \edef\pgfmath@temparg{#1}%
+ \pgfmathsin@{\pgfmath@temparg}\edef\pgfmathresulty{\pgfmathresult}%
+ \pgfmathcos@{\pgfmath@temparg}\edef\pgfmathresultx{\pgfmathresult}%
+}
+
+% \pgfmathtan
+%
+% Calculate the tangent of #1 (in degrees).
+%
+\pgfmathdeclarefunction{tan}{1}{%
+ \begingroup%
+ \edef\pgfmath@temparg{#1}%
+ \pgfmathcos@{\pgfmath@temparg}%
+ \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}%
+ \edef\pgfmath@tantemp{\pgfmathresult}%
+ \pgfmathsin@{\pgfmath@temparg}%
+ \pgfmath@x\pgfmathresult pt\relax%
+ \pgfmath@x\pgfmath@tantemp\pgfmath@x%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% \pgfmathcosec
+%
+% Calculate the cosec of #1 (in degrees).
+%
+\pgfmathdeclarefunction{cosec}{1}{%
+ \expandafter\pgfmathsin@\expandafter{#1}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+}
+
+% \pgfmathsec
+%
+% Calculate the sec of #1 (in degrees).
+%
+\pgfmathdeclarefunction{sec}{1}{%
+ \expandafter\pgfmathcos@\expandafter{#1}%
+ \pgfmathreciprocal@{\pgfmathresult}%
+}
+
+% \pgfmathcot
+%
+% Calculate the cotangent of #1 (in degrees).
+%
+\pgfmathdeclarefunction{cot}{1}{%
+ \begingroup%
+ \edef\pgfmath@temparg{#1}%
+ \pgfmathsin@{\pgfmath@temparg}%
+ \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}%
+ \edef\pgfmath@tantemp{\pgfmathresult}%
+ \pgfmathcos@{\pgfmath@temparg}%
+ \pgfmath@x\pgfmathresult pt\relax%
+ \pgfmath@x\pgfmath@tantemp\pgfmath@x%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+\def\pgfmath@multiply@thousand#1.#2#3#4#5\relax{%
+ \edef\pgfmathresult{#1#2#3#4.#5}%
+}%
+
+% \pgfmathasin
+%
+% The asin of #1
+%
+\pgfmathdeclarefunction{asin}{1}{%
+ \begingroup%
+ \pgfmath@x=#1pt %
+ \pgfmath@xa\pgfmath@x%
+ \edef\pgf@temp{\pgfmath@tonumber\pgfmath@x}%
+ % compute lossless '*1000' operation:
+ \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax
+ \pgfmath@x=\pgfmathresult pt %
+ \ifdim\pgfmath@x<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \fi%
+ \pgfmath@table@lookup{\pgfmath@x}{pgfmath@acos@}{1001}%
+ \pgfmath@x=-\pgfmath@x
+ \advance\pgfmath@x90pt\relax%
+ \ifdim\pgfmath@xa<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \fi%
+ \if1\pgfmath@trig@format@choice
+ % trig format=rad
+ \pgfmath@scale@deg@to@rad\pgfmath@x
+ \fi
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% Defines \pgfmath@x to be the result of the table lookup for value
+% '#1' in table '#2'
+%
+% #1: a value for which lookup should be performed
+% #2: the table's prefix name
+% #3: the table's size
+\def\pgfmath@table@lookup#1#2#3{%
+ \pgfmath@x=#1\relax
+ \expandafter\pgfmath@table@lookup@\the\pgfmath@x\relax{#2}{#3}%
+}
+\def\pgfmath@table@lookup@#1.#2\relax#3#4{%
+ \edef\pgf@temp{\Pgf@geT#2}% strip 'pt' suffix.
+ %
+ % prepare constant interpolant (i.e. the value at node '#1'):
+ \pgfmath@x=\csname #3#1\endcsname pt %
+ %
+ \c@pgfmath@countc=#1 %
+ \advance\c@pgfmath@countc by1 %
+ \ifnum\c@pgfmath@countc<#4 %
+ % Ah - we have enough elements in the table.
+ %
+ % perform linear interpolation:
+ \pgfmath@ya=\csname #3\the\c@pgfmath@countc\endcsname pt %
+ \advance\pgfmath@ya by-\pgfmath@x %
+ \advance\pgfmath@x by0.\pgf@temp\pgfmath@ya
+ \fi
+}%
+
+% \pgfmathacos
+%
+% The acos of #1
+%
+\pgfmathdeclarefunction{acos}{1}{%
+ \begingroup%
+ \pgfmath@x#1pt\relax%
+ \pgfmath@xa\pgfmath@x%
+ \edef\pgf@temp{\pgfmath@tonumber\pgfmath@x}%
+ % compute lossless '*1000' operation:
+ \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax
+ \pgfmath@x=\pgfmathresult pt %
+ \ifdim\pgfmath@x<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \fi%
+ \pgfmath@table@lookup{\pgfmath@x}{pgfmath@acos@}{1001}%
+ \ifdim\pgfmath@xa<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \advance\pgfmath@x by180pt\relax%
+ \fi%
+ \if1\pgfmath@trig@format@choice
+ % trig format=rad
+ \pgfmath@scale@deg@to@rad\pgfmath@x
+ \fi
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+\pgfmathdeclarefunction{atan}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@xa\pgfmath@x%
+ \ifdim\pgfmath@x<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \fi%
+ \pgfmath@xb\pgfmath@x%
+ \ifdim\pgfmath@x>1pt\relax%
+ \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@x}}%
+ \pgfmathreciprocal@{\pgfmath@temp}%
+ \pgfmath@x\pgfmathresult pt\relax%
+ \fi%
+ % compute lossless '*1000' operation:
+ \edef\pgf@temp{\pgfmath@tonumber\pgfmath@x}%
+ \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax
+ \pgfmath@x=\pgfmathresult pt %
+ \pgfmath@table@lookup{\pgfmath@x}{pgfmath@atan@}{1001}%xxx
+ \ifdim\pgfmath@xb>1pt\relax%
+ \pgfmath@x=-\pgfmath@x%
+ \advance\pgfmath@x90pt%
+ \fi%
+ \ifdim\pgfmath@xa<0pt\relax%
+ \pgfmath@x-\pgfmath@x%
+ \fi%
+ \if1\pgfmath@trig@format@choice
+ % trig format=rad
+ \pgfmath@scale@deg@to@rad\pgfmath@x
+ \fi
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+\pgfmathdeclarefunction{atan2}{2}{%
+ % Note: first parameter is y (!), second is x (!)
+ \begingroup%
+ \let\pgfmath@trig@format@choice@@=\pgfmath@trig@format@choice
+ \def\pgfmath@trig@format@choice{0}%
+ \pgfmath@y=#1pt\relax%
+ \ifdim\pgfmath@y<0pt\relax%
+ \pgfmath@y=-\pgfmath@y%
+ \fi%
+ \ifdim\pgfmath@y<0.001pt\relax%
+ \ifdim#2pt<0pt\relax%
+ \pgfmath@x=+180pt\relax%
+ \else%
+ \ifdim#2pt>0pt\relax%
+ \pgfmath@x=0pt\relax%
+ \else%
+ \ifdim#1pt<0pt%
+ \pgfmath@x=-90pt\relax%
+ \else%
+ \pgfmath@x=90pt\relax%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \pgfmathabs@{#1}\let\pgfmath@tempa\pgfmathresult%
+ \pgfmathabs@{#2}\let\pgfmath@tempb\pgfmathresult%
+ \ifdim\pgfmath@tempa pt>\pgfmath@tempb pt%
+ \pgfmathdivide@{#2}{\pgfmath@tempa}%
+ \expandafter\pgfmathatan@\expandafter{\pgfmathresult}%
+ \pgfmath@x=90pt%
+ \advance\pgfmath@x by-\pgfmathresult pt\relax%
+ \else%
+ \pgfmathdivide@{\pgfmath@tempa}{#2}%
+ \expandafter\pgfmathatan@\expandafter{\pgfmathresult}%
+ \pgfmath@x=\pgfmathresult pt\relax%
+ \ifdim#2pt<0pt%
+ \advance\pgfmath@x by180pt\relax%
+ \fi%
+ \fi%
+ \ifdim#1pt<0pt\relax%
+ \pgfmath@x=-\pgfmath@x%
+ \fi%
+ \fi%
+ \if1\pgfmath@trig@format@choice@@
+ % trig format=rad
+ \pgfmath@scale@deg@to@rad\pgfmath@x
+ \fi
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}
+
+% This is needed since \pgfmathatan2 is not a legal macro name
+\expandafter\let\expandafter\pgfmathatantwo\csname pgfmathatan2\endcsname
+\expandafter\let\expandafter\pgfmathatantwo@\csname pgfmathatan2@\endcsname
+
+\def\pgfmath@def#1#2#3{\expandafter\def\csname pgfmath@#1@#2\endcsname{#3}}
+\pgfmath@def{cos}{0}{1.00000} \pgfmath@def{cos}{1}{0.99985}
+\pgfmath@def{cos}{2}{0.99939} \pgfmath@def{cos}{3}{0.99863}
+\pgfmath@def{cos}{4}{0.99756} \pgfmath@def{cos}{5}{0.99619}
+\pgfmath@def{cos}{6}{0.99452} \pgfmath@def{cos}{7}{0.99255}
+\pgfmath@def{cos}{8}{0.99027} \pgfmath@def{cos}{9}{0.98769}
+\pgfmath@def{cos}{10}{0.98481} \pgfmath@def{cos}{11}{0.98163}
+\pgfmath@def{cos}{12}{0.97815} \pgfmath@def{cos}{13}{0.97437}
+\pgfmath@def{cos}{14}{0.97030} \pgfmath@def{cos}{15}{0.96593}
+\pgfmath@def{cos}{16}{0.96126} \pgfmath@def{cos}{17}{0.95630}
+\pgfmath@def{cos}{18}{0.95106} \pgfmath@def{cos}{19}{0.94552}
+\pgfmath@def{cos}{20}{0.93969} \pgfmath@def{cos}{21}{0.93358}
+\pgfmath@def{cos}{22}{0.92718} \pgfmath@def{cos}{23}{0.92050}
+\pgfmath@def{cos}{24}{0.91355} \pgfmath@def{cos}{25}{0.90631}
+\pgfmath@def{cos}{26}{0.89879} \pgfmath@def{cos}{27}{0.89101}
+\pgfmath@def{cos}{28}{0.88295} \pgfmath@def{cos}{29}{0.87462}
+\pgfmath@def{cos}{30}{0.86603} \pgfmath@def{cos}{31}{0.85717}
+\pgfmath@def{cos}{32}{0.84805} \pgfmath@def{cos}{33}{0.83867}
+\pgfmath@def{cos}{34}{0.82904} \pgfmath@def{cos}{35}{0.81915}
+\pgfmath@def{cos}{36}{0.80902} \pgfmath@def{cos}{37}{0.79864}
+\pgfmath@def{cos}{38}{0.78801} \pgfmath@def{cos}{39}{0.77715}
+\pgfmath@def{cos}{40}{0.76604} \pgfmath@def{cos}{41}{0.75471}
+\pgfmath@def{cos}{42}{0.74314} \pgfmath@def{cos}{43}{0.73135}
+\pgfmath@def{cos}{44}{0.71934} \pgfmath@def{cos}{45}{0.70711}
+\pgfmath@def{cos}{46}{0.69466} \pgfmath@def{cos}{47}{0.68200}
+\pgfmath@def{cos}{48}{0.66913} \pgfmath@def{cos}{49}{0.65606}
+\pgfmath@def{cos}{50}{0.64279} \pgfmath@def{cos}{51}{0.62932}
+\pgfmath@def{cos}{52}{0.61566} \pgfmath@def{cos}{53}{0.60182}
+\pgfmath@def{cos}{54}{0.58779} \pgfmath@def{cos}{55}{0.57358}
+\pgfmath@def{cos}{56}{0.55919} \pgfmath@def{cos}{57}{0.54464}
+\pgfmath@def{cos}{58}{0.52992} \pgfmath@def{cos}{59}{0.51504}
+\pgfmath@def{cos}{60}{0.50000} \pgfmath@def{cos}{61}{0.48481}
+\pgfmath@def{cos}{62}{0.46947} \pgfmath@def{cos}{63}{0.45399}
+\pgfmath@def{cos}{64}{0.43837} \pgfmath@def{cos}{65}{0.42262}
+\pgfmath@def{cos}{66}{0.40674} \pgfmath@def{cos}{67}{0.39073}
+\pgfmath@def{cos}{68}{0.37461} \pgfmath@def{cos}{69}{0.35837}
+\pgfmath@def{cos}{70}{0.34202} \pgfmath@def{cos}{71}{0.32557}
+\pgfmath@def{cos}{72}{0.30902} \pgfmath@def{cos}{73}{0.29237}
+\pgfmath@def{cos}{74}{0.27564} \pgfmath@def{cos}{75}{0.25882}
+\pgfmath@def{cos}{76}{0.24192} \pgfmath@def{cos}{77}{0.22495}
+\pgfmath@def{cos}{78}{0.20791} \pgfmath@def{cos}{79}{0.19081}
+\pgfmath@def{cos}{80}{0.17365} \pgfmath@def{cos}{81}{0.15643}
+\pgfmath@def{cos}{82}{0.13917} \pgfmath@def{cos}{83}{0.12187}
+\pgfmath@def{cos}{84}{0.10453} \pgfmath@def{cos}{85}{0.08716}
+\pgfmath@def{cos}{86}{0.06976} \pgfmath@def{cos}{87}{0.05234}
+\pgfmath@def{cos}{88}{0.03490} \pgfmath@def{cos}{89}{0.01745}
+\pgfmath@def{cos}{90}{0.00000} \pgfmath@def{cos}{91}{-0.01745}
+\pgfmath@def{cos}{92}{-0.03490} \pgfmath@def{cos}{93}{-0.05234}
+\pgfmath@def{cos}{94}{-0.06976} \pgfmath@def{cos}{95}{-0.08716}
+\pgfmath@def{cos}{96}{-0.10453} \pgfmath@def{cos}{97}{-0.12187}
+\pgfmath@def{cos}{98}{-0.13917} \pgfmath@def{cos}{99}{-0.15643}
+\pgfmath@def{cos}{100}{-0.17365} \pgfmath@def{cos}{101}{-0.19081}
+\pgfmath@def{cos}{102}{-0.20791} \pgfmath@def{cos}{103}{-0.22495}
+\pgfmath@def{cos}{104}{-0.24192} \pgfmath@def{cos}{105}{-0.25882}
+\pgfmath@def{cos}{106}{-0.27564} \pgfmath@def{cos}{107}{-0.29237}
+\pgfmath@def{cos}{108}{-0.30902} \pgfmath@def{cos}{109}{-0.32557}
+\pgfmath@def{cos}{110}{-0.34202} \pgfmath@def{cos}{111}{-0.35837}
+\pgfmath@def{cos}{112}{-0.37461} \pgfmath@def{cos}{113}{-0.39073}
+\pgfmath@def{cos}{114}{-0.40674} \pgfmath@def{cos}{115}{-0.42262}
+\pgfmath@def{cos}{116}{-0.43837} \pgfmath@def{cos}{117}{-0.45399}
+\pgfmath@def{cos}{118}{-0.46947} \pgfmath@def{cos}{119}{-0.48481}
+\pgfmath@def{cos}{120}{-0.50000} \pgfmath@def{cos}{121}{-0.51504}
+\pgfmath@def{cos}{122}{-0.52992} \pgfmath@def{cos}{123}{-0.54464}
+\pgfmath@def{cos}{124}{-0.55919} \pgfmath@def{cos}{125}{-0.57358}
+\pgfmath@def{cos}{126}{-0.58779} \pgfmath@def{cos}{127}{-0.60182}
+\pgfmath@def{cos}{128}{-0.61566} \pgfmath@def{cos}{129}{-0.62932}
+\pgfmath@def{cos}{130}{-0.64279} \pgfmath@def{cos}{131}{-0.65606}
+\pgfmath@def{cos}{132}{-0.66913} \pgfmath@def{cos}{133}{-0.68200}
+\pgfmath@def{cos}{134}{-0.69466} \pgfmath@def{cos}{135}{-0.70711}
+\pgfmath@def{cos}{136}{-0.71934} \pgfmath@def{cos}{137}{-0.73135}
+\pgfmath@def{cos}{138}{-0.74314} \pgfmath@def{cos}{139}{-0.75471}
+\pgfmath@def{cos}{140}{-0.76604} \pgfmath@def{cos}{141}{-0.77715}
+\pgfmath@def{cos}{142}{-0.78801} \pgfmath@def{cos}{143}{-0.79864}
+\pgfmath@def{cos}{144}{-0.80902} \pgfmath@def{cos}{145}{-0.81915}
+\pgfmath@def{cos}{146}{-0.82904} \pgfmath@def{cos}{147}{-0.83867}
+\pgfmath@def{cos}{148}{-0.84805} \pgfmath@def{cos}{149}{-0.85717}
+\pgfmath@def{cos}{150}{-0.86603} \pgfmath@def{cos}{151}{-0.87462}
+\pgfmath@def{cos}{152}{-0.88295} \pgfmath@def{cos}{153}{-0.89101}
+\pgfmath@def{cos}{154}{-0.89879} \pgfmath@def{cos}{155}{-0.90631}
+\pgfmath@def{cos}{156}{-0.91355} \pgfmath@def{cos}{157}{-0.92050}
+\pgfmath@def{cos}{158}{-0.92718} \pgfmath@def{cos}{159}{-0.93358}
+\pgfmath@def{cos}{160}{-0.93969} \pgfmath@def{cos}{161}{-0.94552}
+\pgfmath@def{cos}{162}{-0.95106} \pgfmath@def{cos}{163}{-0.95630}
+\pgfmath@def{cos}{164}{-0.96126} \pgfmath@def{cos}{165}{-0.96593}
+\pgfmath@def{cos}{166}{-0.97030} \pgfmath@def{cos}{167}{-0.97437}
+\pgfmath@def{cos}{168}{-0.97815} \pgfmath@def{cos}{169}{-0.98163}
+\pgfmath@def{cos}{170}{-0.98481} \pgfmath@def{cos}{171}{-0.98769}
+\pgfmath@def{cos}{172}{-0.99027} \pgfmath@def{cos}{173}{-0.99255}
+\pgfmath@def{cos}{174}{-0.99452} \pgfmath@def{cos}{175}{-0.99619}
+\pgfmath@def{cos}{176}{-0.99756} \pgfmath@def{cos}{177}{-0.99863}
+\pgfmath@def{cos}{178}{-0.99939} \pgfmath@def{cos}{179}{-0.99985}
+\pgfmath@def{cos}{180}{-1.00000} \pgfmath@def{cos}{181}{-0.99985}
+
+\pgfmath@def{cosfrac}{0}{1.00000} \pgfmath@def{cosfrac}{1}{0.99995}
+\pgfmath@def{cosfrac}{2}{0.99980} \pgfmath@def{cosfrac}{3}{0.99955}
+\pgfmath@def{cosfrac}{4}{0.99920} \pgfmath@def{cosfrac}{5}{0.99875}
+\pgfmath@def{cosfrac}{6}{0.99820} \pgfmath@def{cosfrac}{7}{0.99755}
+\pgfmath@def{cosfrac}{8}{0.99681} \pgfmath@def{cosfrac}{9}{0.99597}
+\pgfmath@def{cosfrac}{10}{0.99503} \pgfmath@def{cosfrac}{11}{0.99400}
+\pgfmath@def{cosfrac}{12}{0.99287} \pgfmath@def{cosfrac}{13}{0.99165}
+\pgfmath@def{cosfrac}{14}{0.99034} \pgfmath@def{cosfrac}{15}{0.98893}
+\pgfmath@def{cosfrac}{16}{0.98744} \pgfmath@def{cosfrac}{17}{0.98585}
+\pgfmath@def{cosfrac}{18}{0.98418} \pgfmath@def{cosfrac}{19}{0.98242}
+\pgfmath@def{cosfrac}{20}{0.98058} \pgfmath@def{cosfrac}{21}{0.97865}
+\pgfmath@def{cosfrac}{22}{0.97664} \pgfmath@def{cosfrac}{23}{0.97455}
+\pgfmath@def{cosfrac}{24}{0.97238} \pgfmath@def{cosfrac}{25}{0.97014}
+\pgfmath@def{cosfrac}{26}{0.96782} \pgfmath@def{cosfrac}{27}{0.96542}
+\pgfmath@def{cosfrac}{28}{0.96296} \pgfmath@def{cosfrac}{29}{0.96042}
+\pgfmath@def{cosfrac}{30}{0.95782} \pgfmath@def{cosfrac}{31}{0.95515}
+\pgfmath@def{cosfrac}{32}{0.95242} \pgfmath@def{cosfrac}{33}{0.94962}
+\pgfmath@def{cosfrac}{34}{0.94677} \pgfmath@def{cosfrac}{35}{0.94385}
+\pgfmath@def{cosfrac}{36}{0.94088} \pgfmath@def{cosfrac}{37}{0.93786}
+\pgfmath@def{cosfrac}{38}{0.93478} \pgfmath@def{cosfrac}{39}{0.93165}
+\pgfmath@def{cosfrac}{40}{0.92847} \pgfmath@def{cosfrac}{41}{0.92525}
+\pgfmath@def{cosfrac}{42}{0.92198} \pgfmath@def{cosfrac}{43}{0.91866}
+\pgfmath@def{cosfrac}{44}{0.91531} \pgfmath@def{cosfrac}{45}{0.91192}
+\pgfmath@def{cosfrac}{46}{0.90849} \pgfmath@def{cosfrac}{47}{0.90502}
+\pgfmath@def{cosfrac}{48}{0.90152} \pgfmath@def{cosfrac}{49}{0.89799}
+\pgfmath@def{cosfrac}{50}{0.89442} \pgfmath@def{cosfrac}{51}{0.89083}
+\pgfmath@def{cosfrac}{52}{0.88721} \pgfmath@def{cosfrac}{53}{0.88357}
+\pgfmath@def{cosfrac}{54}{0.87990} \pgfmath@def{cosfrac}{55}{0.87621}
+\pgfmath@def{cosfrac}{56}{0.87250} \pgfmath@def{cosfrac}{57}{0.86877}
+\pgfmath@def{cosfrac}{58}{0.86503} \pgfmath@def{cosfrac}{59}{0.86126}
+\pgfmath@def{cosfrac}{60}{0.85749} \pgfmath@def{cosfrac}{61}{0.85370}
+\pgfmath@def{cosfrac}{62}{0.84990} \pgfmath@def{cosfrac}{63}{0.84609}
+\pgfmath@def{cosfrac}{64}{0.84227} \pgfmath@def{cosfrac}{65}{0.83844}
+\pgfmath@def{cosfrac}{66}{0.83460} \pgfmath@def{cosfrac}{67}{0.83077}
+\pgfmath@def{cosfrac}{68}{0.82692} \pgfmath@def{cosfrac}{69}{0.82308}
+\pgfmath@def{cosfrac}{70}{0.81923} \pgfmath@def{cosfrac}{71}{0.81538}
+\pgfmath@def{cosfrac}{72}{0.81153} \pgfmath@def{cosfrac}{73}{0.80768}
+\pgfmath@def{cosfrac}{74}{0.80384} \pgfmath@def{cosfrac}{75}{0.80000}
+\pgfmath@def{cosfrac}{76}{0.79616} \pgfmath@def{cosfrac}{77}{0.79232}
+\pgfmath@def{cosfrac}{78}{0.78850} \pgfmath@def{cosfrac}{79}{0.78468}
+\pgfmath@def{cosfrac}{80}{0.78086} \pgfmath@def{cosfrac}{81}{0.77706}
+\pgfmath@def{cosfrac}{82}{0.77326} \pgfmath@def{cosfrac}{83}{0.76948}
+\pgfmath@def{cosfrac}{84}{0.76570} \pgfmath@def{cosfrac}{85}{0.76193}
+\pgfmath@def{cosfrac}{86}{0.75818} \pgfmath@def{cosfrac}{87}{0.75444}
+\pgfmath@def{cosfrac}{88}{0.75071} \pgfmath@def{cosfrac}{89}{0.74699}
+\pgfmath@def{cosfrac}{90}{0.74329} \pgfmath@def{cosfrac}{91}{0.73960}
+\pgfmath@def{cosfrac}{92}{0.73593} \pgfmath@def{cosfrac}{93}{0.73227}
+\pgfmath@def{cosfrac}{94}{0.72862} \pgfmath@def{cosfrac}{95}{0.72499}
+\pgfmath@def{cosfrac}{96}{0.72138} \pgfmath@def{cosfrac}{97}{0.71779}
+\pgfmath@def{cosfrac}{98}{0.71421} \pgfmath@def{cosfrac}{99}{0.71065}
+\pgfmath@def{cosfrac}{100}{0.70710}
+
+% Oh No! Some really loooooong tables.
+\pgfmath@def{atan}{0}{0.00000} \pgfmath@def{atan}{1}{0.05729}
+\pgfmath@def{atan}{2}{0.11459} \pgfmath@def{atan}{3}{0.17188}
+\pgfmath@def{atan}{4}{0.22918} \pgfmath@def{atan}{5}{0.28647}
+\pgfmath@def{atan}{6}{0.34377} \pgfmath@def{atan}{7}{0.40106}
+\pgfmath@def{atan}{8}{0.45835} \pgfmath@def{atan}{9}{0.51564}
+\pgfmath@def{atan}{10}{0.57293} \pgfmath@def{atan}{11}{0.63022}
+\pgfmath@def{atan}{12}{0.68751} \pgfmath@def{atan}{13}{0.74480}
+\pgfmath@def{atan}{14}{0.80208} \pgfmath@def{atan}{15}{0.85937}
+\pgfmath@def{atan}{16}{0.91665} \pgfmath@def{atan}{17}{0.97393}
+\pgfmath@def{atan}{18}{1.03121} \pgfmath@def{atan}{19}{1.08848}
+\pgfmath@def{atan}{20}{1.14576} \pgfmath@def{atan}{21}{1.20303}
+\pgfmath@def{atan}{22}{1.26030} \pgfmath@def{atan}{23}{1.31757}
+\pgfmath@def{atan}{24}{1.37483} \pgfmath@def{atan}{25}{1.43209}
+\pgfmath@def{atan}{26}{1.48935} \pgfmath@def{atan}{27}{1.54661}
+\pgfmath@def{atan}{28}{1.60386} \pgfmath@def{atan}{29}{1.66111}
+\pgfmath@def{atan}{30}{1.71835} \pgfmath@def{atan}{31}{1.77560}
+\pgfmath@def{atan}{32}{1.83284} \pgfmath@def{atan}{33}{1.89007}
+\pgfmath@def{atan}{34}{1.94730} \pgfmath@def{atan}{35}{2.00453}
+\pgfmath@def{atan}{36}{2.06175} \pgfmath@def{atan}{37}{2.11897}
+\pgfmath@def{atan}{38}{2.17619} \pgfmath@def{atan}{39}{2.23340}
+\pgfmath@def{atan}{40}{2.29061} \pgfmath@def{atan}{41}{2.34781}
+\pgfmath@def{atan}{42}{2.40500} \pgfmath@def{atan}{43}{2.46220}
+\pgfmath@def{atan}{44}{2.51938} \pgfmath@def{atan}{45}{2.57657}
+\pgfmath@def{atan}{46}{2.63374} \pgfmath@def{atan}{47}{2.69092}
+\pgfmath@def{atan}{48}{2.74808} \pgfmath@def{atan}{49}{2.80524}
+\pgfmath@def{atan}{50}{2.86240} \pgfmath@def{atan}{51}{2.91955}
+\pgfmath@def{atan}{52}{2.97669} \pgfmath@def{atan}{53}{3.03383}
+\pgfmath@def{atan}{54}{3.09097} \pgfmath@def{atan}{55}{3.14809}
+\pgfmath@def{atan}{56}{3.20521} \pgfmath@def{atan}{57}{3.26232}
+\pgfmath@def{atan}{58}{3.31943} \pgfmath@def{atan}{59}{3.37653}
+\pgfmath@def{atan}{60}{3.43363} \pgfmath@def{atan}{61}{3.49071}
+\pgfmath@def{atan}{62}{3.54779} \pgfmath@def{atan}{63}{3.60487}
+\pgfmath@def{atan}{64}{3.66193} \pgfmath@def{atan}{65}{3.71899}
+\pgfmath@def{atan}{66}{3.77604} \pgfmath@def{atan}{67}{3.83308}
+\pgfmath@def{atan}{68}{3.89012} \pgfmath@def{atan}{69}{3.94715}
+\pgfmath@def{atan}{70}{4.00417} \pgfmath@def{atan}{71}{4.06118}
+\pgfmath@def{atan}{72}{4.11819} \pgfmath@def{atan}{73}{4.17518}
+\pgfmath@def{atan}{74}{4.23217} \pgfmath@def{atan}{75}{4.28915}
+\pgfmath@def{atan}{76}{4.34612} \pgfmath@def{atan}{77}{4.40308}
+\pgfmath@def{atan}{78}{4.46004} \pgfmath@def{atan}{79}{4.51698}
+\pgfmath@def{atan}{80}{4.57392} \pgfmath@def{atan}{81}{4.63084}
+\pgfmath@def{atan}{82}{4.68776} \pgfmath@def{atan}{83}{4.74467}
+\pgfmath@def{atan}{84}{4.80157} \pgfmath@def{atan}{85}{4.85846}
+\pgfmath@def{atan}{86}{4.91534} \pgfmath@def{atan}{87}{4.97221}
+\pgfmath@def{atan}{88}{5.02907} \pgfmath@def{atan}{89}{5.08592}
+\pgfmath@def{atan}{90}{5.14276} \pgfmath@def{atan}{91}{5.19959}
+\pgfmath@def{atan}{92}{5.25641} \pgfmath@def{atan}{93}{5.31322}
+\pgfmath@def{atan}{94}{5.37002} \pgfmath@def{atan}{95}{5.42681}
+\pgfmath@def{atan}{96}{5.48359} \pgfmath@def{atan}{97}{5.54035}
+\pgfmath@def{atan}{98}{5.59711} \pgfmath@def{atan}{99}{5.65385}
+\pgfmath@def{atan}{100}{5.71059} \pgfmath@def{atan}{101}{5.76731}
+\pgfmath@def{atan}{102}{5.82402} \pgfmath@def{atan}{103}{5.88072}
+\pgfmath@def{atan}{104}{5.93741} \pgfmath@def{atan}{105}{5.99409}
+\pgfmath@def{atan}{106}{6.05075} \pgfmath@def{atan}{107}{6.10741}
+\pgfmath@def{atan}{108}{6.16405} \pgfmath@def{atan}{109}{6.22068}
+\pgfmath@def{atan}{110}{6.27729} \pgfmath@def{atan}{111}{6.33390}
+\pgfmath@def{atan}{112}{6.39049} \pgfmath@def{atan}{113}{6.44707}
+\pgfmath@def{atan}{114}{6.50364} \pgfmath@def{atan}{115}{6.56019}
+\pgfmath@def{atan}{116}{6.61673} \pgfmath@def{atan}{117}{6.67326}
+\pgfmath@def{atan}{118}{6.72978} \pgfmath@def{atan}{119}{6.78628}
+\pgfmath@def{atan}{120}{6.84277} \pgfmath@def{atan}{121}{6.89924}
+\pgfmath@def{atan}{122}{6.95571} \pgfmath@def{atan}{123}{7.01216}
+\pgfmath@def{atan}{124}{7.06859} \pgfmath@def{atan}{125}{7.12501}
+\pgfmath@def{atan}{126}{7.18142} \pgfmath@def{atan}{127}{7.23781}
+\pgfmath@def{atan}{128}{7.29419} \pgfmath@def{atan}{129}{7.35056}
+\pgfmath@def{atan}{130}{7.40691} \pgfmath@def{atan}{131}{7.46324}
+\pgfmath@def{atan}{132}{7.51957} \pgfmath@def{atan}{133}{7.57587}
+\pgfmath@def{atan}{134}{7.63217} \pgfmath@def{atan}{135}{7.68844}
+\pgfmath@def{atan}{136}{7.74471} \pgfmath@def{atan}{137}{7.80095}
+\pgfmath@def{atan}{138}{7.85719} \pgfmath@def{atan}{139}{7.91340}
+\pgfmath@def{atan}{140}{7.96961} \pgfmath@def{atan}{141}{8.02579}
+\pgfmath@def{atan}{142}{8.08196} \pgfmath@def{atan}{143}{8.13812}
+\pgfmath@def{atan}{144}{8.19426} \pgfmath@def{atan}{145}{8.25038}
+\pgfmath@def{atan}{146}{8.30649} \pgfmath@def{atan}{147}{8.36258}
+\pgfmath@def{atan}{148}{8.41866} \pgfmath@def{atan}{149}{8.47472}
+\pgfmath@def{atan}{150}{8.53076} \pgfmath@def{atan}{151}{8.58679}
+\pgfmath@def{atan}{152}{8.64280} \pgfmath@def{atan}{153}{8.69879}
+\pgfmath@def{atan}{154}{8.75477} \pgfmath@def{atan}{155}{8.81073}
+\pgfmath@def{atan}{156}{8.86667} \pgfmath@def{atan}{157}{8.92260}
+\pgfmath@def{atan}{158}{8.97851} \pgfmath@def{atan}{159}{9.03440}
+\pgfmath@def{atan}{160}{9.09027} \pgfmath@def{atan}{161}{9.14613}
+\pgfmath@def{atan}{162}{9.20197} \pgfmath@def{atan}{163}{9.25779}
+\pgfmath@def{atan}{164}{9.31359} \pgfmath@def{atan}{165}{9.36938}
+\pgfmath@def{atan}{166}{9.42515} \pgfmath@def{atan}{167}{9.48090}
+\pgfmath@def{atan}{168}{9.53663} \pgfmath@def{atan}{169}{9.59235}
+\pgfmath@def{atan}{170}{9.64804} \pgfmath@def{atan}{171}{9.70372}
+\pgfmath@def{atan}{172}{9.75938} \pgfmath@def{atan}{173}{9.81502}
+\pgfmath@def{atan}{174}{9.87064} \pgfmath@def{atan}{175}{9.92624}
+\pgfmath@def{atan}{176}{9.98182} \pgfmath@def{atan}{177}{10.03739}
+\pgfmath@def{atan}{178}{10.09294} \pgfmath@def{atan}{179}{10.14846}
+\pgfmath@def{atan}{180}{10.20397} \pgfmath@def{atan}{181}{10.25946}
+\pgfmath@def{atan}{182}{10.31493} \pgfmath@def{atan}{183}{10.37037}
+\pgfmath@def{atan}{184}{10.42580} \pgfmath@def{atan}{185}{10.48121}
+\pgfmath@def{atan}{186}{10.53660} \pgfmath@def{atan}{187}{10.59197}
+\pgfmath@def{atan}{188}{10.64732} \pgfmath@def{atan}{189}{10.70265}
+\pgfmath@def{atan}{190}{10.75796} \pgfmath@def{atan}{191}{10.81325}
+\pgfmath@def{atan}{192}{10.86852} \pgfmath@def{atan}{193}{10.92377}
+\pgfmath@def{atan}{194}{10.97900} \pgfmath@def{atan}{195}{11.03420}
+\pgfmath@def{atan}{196}{11.08939} \pgfmath@def{atan}{197}{11.14456}
+\pgfmath@def{atan}{198}{11.19970} \pgfmath@def{atan}{199}{11.25483}
+\pgfmath@def{atan}{200}{11.30993} \pgfmath@def{atan}{201}{11.36501}
+\pgfmath@def{atan}{202}{11.42007} \pgfmath@def{atan}{203}{11.47511}
+\pgfmath@def{atan}{204}{11.53013} \pgfmath@def{atan}{205}{11.58512}
+\pgfmath@def{atan}{206}{11.64010} \pgfmath@def{atan}{207}{11.69505}
+\pgfmath@def{atan}{208}{11.74998} \pgfmath@def{atan}{209}{11.80489}
+\pgfmath@def{atan}{210}{11.85977} \pgfmath@def{atan}{211}{11.91464}
+\pgfmath@def{atan}{212}{11.96948} \pgfmath@def{atan}{213}{12.02430}
+\pgfmath@def{atan}{214}{12.07910} \pgfmath@def{atan}{215}{12.13388}
+\pgfmath@def{atan}{216}{12.18863} \pgfmath@def{atan}{217}{12.24336}
+\pgfmath@def{atan}{218}{12.29807} \pgfmath@def{atan}{219}{12.35275}
+\pgfmath@def{atan}{220}{12.40741} \pgfmath@def{atan}{221}{12.46205}
+\pgfmath@def{atan}{222}{12.51667} \pgfmath@def{atan}{223}{12.57126}
+\pgfmath@def{atan}{224}{12.62583} \pgfmath@def{atan}{225}{12.68038}
+\pgfmath@def{atan}{226}{12.73490} \pgfmath@def{atan}{227}{12.78940}
+\pgfmath@def{atan}{228}{12.84388} \pgfmath@def{atan}{229}{12.89833}
+\pgfmath@def{atan}{230}{12.95276} \pgfmath@def{atan}{231}{13.00717}
+\pgfmath@def{atan}{232}{13.06155} \pgfmath@def{atan}{233}{13.11590}
+\pgfmath@def{atan}{234}{13.17024} \pgfmath@def{atan}{235}{13.22455}
+\pgfmath@def{atan}{236}{13.27883} \pgfmath@def{atan}{237}{13.33309}
+\pgfmath@def{atan}{238}{13.38733} \pgfmath@def{atan}{239}{13.44154}
+\pgfmath@def{atan}{240}{13.49573} \pgfmath@def{atan}{241}{13.54989}
+\pgfmath@def{atan}{242}{13.60403} \pgfmath@def{atan}{243}{13.65814}
+\pgfmath@def{atan}{244}{13.71223} \pgfmath@def{atan}{245}{13.76630}
+\pgfmath@def{atan}{246}{13.82034} \pgfmath@def{atan}{247}{13.87435}
+\pgfmath@def{atan}{248}{13.92834} \pgfmath@def{atan}{249}{13.98230}
+\pgfmath@def{atan}{250}{14.03624} \pgfmath@def{atan}{251}{14.09015}
+\pgfmath@def{atan}{252}{14.14404} \pgfmath@def{atan}{253}{14.19790}
+\pgfmath@def{atan}{254}{14.25174} \pgfmath@def{atan}{255}{14.30555}
+\pgfmath@def{atan}{256}{14.35933} \pgfmath@def{atan}{257}{14.41309}
+\pgfmath@def{atan}{258}{14.46682} \pgfmath@def{atan}{259}{14.52053}
+\pgfmath@def{atan}{260}{14.57421} \pgfmath@def{atan}{261}{14.62787}
+\pgfmath@def{atan}{262}{14.68149} \pgfmath@def{atan}{263}{14.73510}
+\pgfmath@def{atan}{264}{14.78867} \pgfmath@def{atan}{265}{14.84222}
+\pgfmath@def{atan}{266}{14.89575} \pgfmath@def{atan}{267}{14.94924}
+\pgfmath@def{atan}{268}{15.00271} \pgfmath@def{atan}{269}{15.05615}
+\pgfmath@def{atan}{270}{15.10957} \pgfmath@def{atan}{271}{15.16296}
+\pgfmath@def{atan}{272}{15.21632} \pgfmath@def{atan}{273}{15.26966}
+\pgfmath@def{atan}{274}{15.32297} \pgfmath@def{atan}{275}{15.37625}
+\pgfmath@def{atan}{276}{15.42950} \pgfmath@def{atan}{277}{15.48273}
+\pgfmath@def{atan}{278}{15.53593} \pgfmath@def{atan}{279}{15.58910}
+\pgfmath@def{atan}{280}{15.64224} \pgfmath@def{atan}{281}{15.69536}
+\pgfmath@def{atan}{282}{15.74845} \pgfmath@def{atan}{283}{15.80151}
+\pgfmath@def{atan}{284}{15.85454} \pgfmath@def{atan}{285}{15.90755}
+\pgfmath@def{atan}{286}{15.96052} \pgfmath@def{atan}{287}{16.01347}
+\pgfmath@def{atan}{288}{16.06640} \pgfmath@def{atan}{289}{16.11929}
+\pgfmath@def{atan}{290}{16.17215} \pgfmath@def{atan}{291}{16.22499}
+\pgfmath@def{atan}{292}{16.27780} \pgfmath@def{atan}{293}{16.33058}
+\pgfmath@def{atan}{294}{16.38333} \pgfmath@def{atan}{295}{16.43605}
+\pgfmath@def{atan}{296}{16.48875} \pgfmath@def{atan}{297}{16.54142}
+\pgfmath@def{atan}{298}{16.59405} \pgfmath@def{atan}{299}{16.64666}
+\pgfmath@def{atan}{300}{16.69924} \pgfmath@def{atan}{301}{16.75179}
+\pgfmath@def{atan}{302}{16.80431} \pgfmath@def{atan}{303}{16.85680}
+\pgfmath@def{atan}{304}{16.90927} \pgfmath@def{atan}{305}{16.96170}
+\pgfmath@def{atan}{306}{17.01411} \pgfmath@def{atan}{307}{17.06648}
+\pgfmath@def{atan}{308}{17.11883} \pgfmath@def{atan}{309}{17.17114}
+\pgfmath@def{atan}{310}{17.22343} \pgfmath@def{atan}{311}{17.27569}
+\pgfmath@def{atan}{312}{17.32792} \pgfmath@def{atan}{313}{17.38012}
+\pgfmath@def{atan}{314}{17.43228} \pgfmath@def{atan}{315}{17.48442}
+\pgfmath@def{atan}{316}{17.53653} \pgfmath@def{atan}{317}{17.58861}
+\pgfmath@def{atan}{318}{17.64066} \pgfmath@def{atan}{319}{17.69268}
+\pgfmath@def{atan}{320}{17.74467} \pgfmath@def{atan}{321}{17.79663}
+\pgfmath@def{atan}{322}{17.84855} \pgfmath@def{atan}{323}{17.90045}
+\pgfmath@def{atan}{324}{17.95232} \pgfmath@def{atan}{325}{18.00416}
+\pgfmath@def{atan}{326}{18.05596} \pgfmath@def{atan}{327}{18.10774}
+\pgfmath@def{atan}{328}{18.15949} \pgfmath@def{atan}{329}{18.21120}
+\pgfmath@def{atan}{330}{18.26289} \pgfmath@def{atan}{331}{18.31454}
+\pgfmath@def{atan}{332}{18.36616} \pgfmath@def{atan}{333}{18.41775}
+\pgfmath@def{atan}{334}{18.46931} \pgfmath@def{atan}{335}{18.52084}
+\pgfmath@def{atan}{336}{18.57234} \pgfmath@def{atan}{337}{18.62381}
+\pgfmath@def{atan}{338}{18.67525} \pgfmath@def{atan}{339}{18.72665}
+\pgfmath@def{atan}{340}{18.77803} \pgfmath@def{atan}{341}{18.82937}
+\pgfmath@def{atan}{342}{18.88068} \pgfmath@def{atan}{343}{18.93196}
+\pgfmath@def{atan}{344}{18.98321} \pgfmath@def{atan}{345}{19.03443}
+\pgfmath@def{atan}{346}{19.08562} \pgfmath@def{atan}{347}{19.13677}
+\pgfmath@def{atan}{348}{19.18789} \pgfmath@def{atan}{349}{19.23898}
+\pgfmath@def{atan}{350}{19.29004} \pgfmath@def{atan}{351}{19.34107}
+\pgfmath@def{atan}{352}{19.39206} \pgfmath@def{atan}{353}{19.44303}
+\pgfmath@def{atan}{354}{19.49396} \pgfmath@def{atan}{355}{19.54486}
+\pgfmath@def{atan}{356}{19.59572} \pgfmath@def{atan}{357}{19.64656}
+\pgfmath@def{atan}{358}{19.69736} \pgfmath@def{atan}{359}{19.74813}
+\pgfmath@def{atan}{360}{19.79887} \pgfmath@def{atan}{361}{19.84958}
+\pgfmath@def{atan}{362}{19.90025} \pgfmath@def{atan}{363}{19.95089}
+\pgfmath@def{atan}{364}{20.00150} \pgfmath@def{atan}{365}{20.05208}
+\pgfmath@def{atan}{366}{20.10262} \pgfmath@def{atan}{367}{20.15313}
+\pgfmath@def{atan}{368}{20.20361} \pgfmath@def{atan}{369}{20.25406}
+\pgfmath@def{atan}{370}{20.30447} \pgfmath@def{atan}{371}{20.35485}
+\pgfmath@def{atan}{372}{20.40520} \pgfmath@def{atan}{373}{20.45551}
+\pgfmath@def{atan}{374}{20.50579} \pgfmath@def{atan}{375}{20.55604}
+\pgfmath@def{atan}{376}{20.60626} \pgfmath@def{atan}{377}{20.65644}
+\pgfmath@def{atan}{378}{20.70659} \pgfmath@def{atan}{379}{20.75670}
+\pgfmath@def{atan}{380}{20.80679} \pgfmath@def{atan}{381}{20.85684}
+\pgfmath@def{atan}{382}{20.90685} \pgfmath@def{atan}{383}{20.95684}
+\pgfmath@def{atan}{384}{21.00678} \pgfmath@def{atan}{385}{21.05670}
+\pgfmath@def{atan}{386}{21.10658} \pgfmath@def{atan}{387}{21.15643}
+\pgfmath@def{atan}{388}{21.20625} \pgfmath@def{atan}{389}{21.25603}
+\pgfmath@def{atan}{390}{21.30578} \pgfmath@def{atan}{391}{21.35549}
+\pgfmath@def{atan}{392}{21.40517} \pgfmath@def{atan}{393}{21.45482}
+\pgfmath@def{atan}{394}{21.50444} \pgfmath@def{atan}{395}{21.55402}
+\pgfmath@def{atan}{396}{21.60356} \pgfmath@def{atan}{397}{21.65307}
+\pgfmath@def{atan}{398}{21.70255} \pgfmath@def{atan}{399}{21.75200}
+\pgfmath@def{atan}{400}{21.80140} \pgfmath@def{atan}{401}{21.85078}
+\pgfmath@def{atan}{402}{21.90012} \pgfmath@def{atan}{403}{21.94943}
+\pgfmath@def{atan}{404}{21.99870} \pgfmath@def{atan}{405}{22.04794}
+\pgfmath@def{atan}{406}{22.09715} \pgfmath@def{atan}{407}{22.14632}
+\pgfmath@def{atan}{408}{22.19546} \pgfmath@def{atan}{409}{22.24456}
+\pgfmath@def{atan}{410}{22.29362} \pgfmath@def{atan}{411}{22.34266}
+\pgfmath@def{atan}{412}{22.39166} \pgfmath@def{atan}{413}{22.44062}
+\pgfmath@def{atan}{414}{22.48955} \pgfmath@def{atan}{415}{22.53845}
+\pgfmath@def{atan}{416}{22.58731} \pgfmath@def{atan}{417}{22.63613}
+\pgfmath@def{atan}{418}{22.68492} \pgfmath@def{atan}{419}{22.73368}
+\pgfmath@def{atan}{420}{22.78240} \pgfmath@def{atan}{421}{22.83109}
+\pgfmath@def{atan}{422}{22.87974} \pgfmath@def{atan}{423}{22.92836}
+\pgfmath@def{atan}{424}{22.97694} \pgfmath@def{atan}{425}{23.02549}
+\pgfmath@def{atan}{426}{23.07400} \pgfmath@def{atan}{427}{23.12248}
+\pgfmath@def{atan}{428}{23.17092} \pgfmath@def{atan}{429}{23.21933}
+\pgfmath@def{atan}{430}{23.26770} \pgfmath@def{atan}{431}{23.31604}
+\pgfmath@def{atan}{432}{23.36434} \pgfmath@def{atan}{433}{23.41261}
+\pgfmath@def{atan}{434}{23.46084} \pgfmath@def{atan}{435}{23.50904}
+\pgfmath@def{atan}{436}{23.55720} \pgfmath@def{atan}{437}{23.60532}
+\pgfmath@def{atan}{438}{23.65341} \pgfmath@def{atan}{439}{23.70147}
+\pgfmath@def{atan}{440}{23.74949} \pgfmath@def{atan}{441}{23.79747}
+\pgfmath@def{atan}{442}{23.84542} \pgfmath@def{atan}{443}{23.89334}
+\pgfmath@def{atan}{444}{23.94122} \pgfmath@def{atan}{445}{23.98906}
+\pgfmath@def{atan}{446}{24.03687} \pgfmath@def{atan}{447}{24.08464}
+\pgfmath@def{atan}{448}{24.13238} \pgfmath@def{atan}{449}{24.18008}
+\pgfmath@def{atan}{450}{24.22774} \pgfmath@def{atan}{451}{24.27537}
+\pgfmath@def{atan}{452}{24.32296} \pgfmath@def{atan}{453}{24.37052}
+\pgfmath@def{atan}{454}{24.41804} \pgfmath@def{atan}{455}{24.46553}
+\pgfmath@def{atan}{456}{24.51298} \pgfmath@def{atan}{457}{24.56040}
+\pgfmath@def{atan}{458}{24.60778} \pgfmath@def{atan}{459}{24.65512}
+\pgfmath@def{atan}{460}{24.70243} \pgfmath@def{atan}{461}{24.74970}
+\pgfmath@def{atan}{462}{24.79693} \pgfmath@def{atan}{463}{24.84413}
+\pgfmath@def{atan}{464}{24.89130} \pgfmath@def{atan}{465}{24.93842}
+\pgfmath@def{atan}{466}{24.98551} \pgfmath@def{atan}{467}{25.03257}
+\pgfmath@def{atan}{468}{25.07959} \pgfmath@def{atan}{469}{25.12657}
+\pgfmath@def{atan}{470}{25.17352} \pgfmath@def{atan}{471}{25.22043}
+\pgfmath@def{atan}{472}{25.26731} \pgfmath@def{atan}{473}{25.31414}
+\pgfmath@def{atan}{474}{25.36095} \pgfmath@def{atan}{475}{25.40771}
+\pgfmath@def{atan}{476}{25.45444} \pgfmath@def{atan}{477}{25.50114}
+\pgfmath@def{atan}{478}{25.54780} \pgfmath@def{atan}{479}{25.59442}
+\pgfmath@def{atan}{480}{25.64100} \pgfmath@def{atan}{481}{25.68755}
+\pgfmath@def{atan}{482}{25.73406} \pgfmath@def{atan}{483}{25.78054}
+\pgfmath@def{atan}{484}{25.82698} \pgfmath@def{atan}{485}{25.87338}
+\pgfmath@def{atan}{486}{25.91975} \pgfmath@def{atan}{487}{25.96608}
+\pgfmath@def{atan}{488}{26.01237} \pgfmath@def{atan}{489}{26.05863}
+\pgfmath@def{atan}{490}{26.10485} \pgfmath@def{atan}{491}{26.15103}
+\pgfmath@def{atan}{492}{26.19718} \pgfmath@def{atan}{493}{26.24329}
+\pgfmath@def{atan}{494}{26.28937} \pgfmath@def{atan}{495}{26.33541}
+\pgfmath@def{atan}{496}{26.38141} \pgfmath@def{atan}{497}{26.42737}
+\pgfmath@def{atan}{498}{26.47330} \pgfmath@def{atan}{499}{26.51919}
+\pgfmath@def{atan}{500}{26.56505} \pgfmath@def{atan}{501}{26.61086}
+\pgfmath@def{atan}{502}{26.65665} \pgfmath@def{atan}{503}{26.70239}
+\pgfmath@def{atan}{504}{26.74810} \pgfmath@def{atan}{505}{26.79377}
+\pgfmath@def{atan}{506}{26.83941} \pgfmath@def{atan}{507}{26.88500}
+\pgfmath@def{atan}{508}{26.93057} \pgfmath@def{atan}{509}{26.97609}
+\pgfmath@def{atan}{510}{27.02158} \pgfmath@def{atan}{511}{27.06703}
+\pgfmath@def{atan}{512}{27.11244} \pgfmath@def{atan}{513}{27.15782}
+\pgfmath@def{atan}{514}{27.20316} \pgfmath@def{atan}{515}{27.24846}
+\pgfmath@def{atan}{516}{27.29373} \pgfmath@def{atan}{517}{27.33896}
+\pgfmath@def{atan}{518}{27.38415} \pgfmath@def{atan}{519}{27.42931}
+\pgfmath@def{atan}{520}{27.47443} \pgfmath@def{atan}{521}{27.51951}
+\pgfmath@def{atan}{522}{27.56455} \pgfmath@def{atan}{523}{27.60956}
+\pgfmath@def{atan}{524}{27.65453} \pgfmath@def{atan}{525}{27.69947}
+\pgfmath@def{atan}{526}{27.74437} \pgfmath@def{atan}{527}{27.78923}
+\pgfmath@def{atan}{528}{27.83405} \pgfmath@def{atan}{529}{27.87884}
+\pgfmath@def{atan}{530}{27.92359} \pgfmath@def{atan}{531}{27.96830}
+\pgfmath@def{atan}{532}{28.01297} \pgfmath@def{atan}{533}{28.05761}
+\pgfmath@def{atan}{534}{28.10221} \pgfmath@def{atan}{535}{28.14678}
+\pgfmath@def{atan}{536}{28.19130} \pgfmath@def{atan}{537}{28.23579}
+\pgfmath@def{atan}{538}{28.28025} \pgfmath@def{atan}{539}{28.32466}
+\pgfmath@def{atan}{540}{28.36904} \pgfmath@def{atan}{541}{28.41338}
+\pgfmath@def{atan}{542}{28.45769} \pgfmath@def{atan}{543}{28.50196}
+\pgfmath@def{atan}{544}{28.54619} \pgfmath@def{atan}{545}{28.59038}
+\pgfmath@def{atan}{546}{28.63454} \pgfmath@def{atan}{547}{28.67865}
+\pgfmath@def{atan}{548}{28.72274} \pgfmath@def{atan}{549}{28.76678}
+\pgfmath@def{atan}{550}{28.81079} \pgfmath@def{atan}{551}{28.85476}
+\pgfmath@def{atan}{552}{28.89869} \pgfmath@def{atan}{553}{28.94259}
+\pgfmath@def{atan}{554}{28.98645} \pgfmath@def{atan}{555}{29.03027}
+\pgfmath@def{atan}{556}{29.07405} \pgfmath@def{atan}{557}{29.11780}
+\pgfmath@def{atan}{558}{29.16151} \pgfmath@def{atan}{559}{29.20519}
+\pgfmath@def{atan}{560}{29.24882} \pgfmath@def{atan}{561}{29.29242}
+\pgfmath@def{atan}{562}{29.33598} \pgfmath@def{atan}{563}{29.37951}
+\pgfmath@def{atan}{564}{29.42299} \pgfmath@def{atan}{565}{29.46644}
+\pgfmath@def{atan}{566}{29.50986} \pgfmath@def{atan}{567}{29.55323}
+\pgfmath@def{atan}{568}{29.59657} \pgfmath@def{atan}{569}{29.63987}
+\pgfmath@def{atan}{570}{29.68314} \pgfmath@def{atan}{571}{29.72636}
+\pgfmath@def{atan}{572}{29.76955} \pgfmath@def{atan}{573}{29.81270}
+\pgfmath@def{atan}{574}{29.85582} \pgfmath@def{atan}{575}{29.89890}
+\pgfmath@def{atan}{576}{29.94194} \pgfmath@def{atan}{577}{29.98494}
+\pgfmath@def{atan}{578}{30.02791} \pgfmath@def{atan}{579}{30.07084}
+\pgfmath@def{atan}{580}{30.11373} \pgfmath@def{atan}{581}{30.15658}
+\pgfmath@def{atan}{582}{30.19940} \pgfmath@def{atan}{583}{30.24218}
+\pgfmath@def{atan}{584}{30.28492} \pgfmath@def{atan}{585}{30.32763}
+\pgfmath@def{atan}{586}{30.37030} \pgfmath@def{atan}{587}{30.41293}
+\pgfmath@def{atan}{588}{30.45552} \pgfmath@def{atan}{589}{30.49808}
+\pgfmath@def{atan}{590}{30.54060} \pgfmath@def{atan}{591}{30.58308}
+\pgfmath@def{atan}{592}{30.62553} \pgfmath@def{atan}{593}{30.66794}
+\pgfmath@def{atan}{594}{30.71031} \pgfmath@def{atan}{595}{30.75264}
+\pgfmath@def{atan}{596}{30.79494} \pgfmath@def{atan}{597}{30.83720}
+\pgfmath@def{atan}{598}{30.87942} \pgfmath@def{atan}{599}{30.92160}
+\pgfmath@def{atan}{600}{30.96375} \pgfmath@def{atan}{601}{31.00586}
+\pgfmath@def{atan}{602}{31.04794} \pgfmath@def{atan}{603}{31.08997}
+\pgfmath@def{atan}{604}{31.13197} \pgfmath@def{atan}{605}{31.17393}
+\pgfmath@def{atan}{606}{31.21586} \pgfmath@def{atan}{607}{31.25775}
+\pgfmath@def{atan}{608}{31.29960} \pgfmath@def{atan}{609}{31.34141}
+\pgfmath@def{atan}{610}{31.38319} \pgfmath@def{atan}{611}{31.42493}
+\pgfmath@def{atan}{612}{31.46663} \pgfmath@def{atan}{613}{31.50829}
+\pgfmath@def{atan}{614}{31.54992} \pgfmath@def{atan}{615}{31.59151}
+\pgfmath@def{atan}{616}{31.63306} \pgfmath@def{atan}{617}{31.67458}
+\pgfmath@def{atan}{618}{31.71606} \pgfmath@def{atan}{619}{31.75750}
+\pgfmath@def{atan}{620}{31.79891} \pgfmath@def{atan}{621}{31.84028}
+\pgfmath@def{atan}{622}{31.88161} \pgfmath@def{atan}{623}{31.92290}
+\pgfmath@def{atan}{624}{31.96416} \pgfmath@def{atan}{625}{32.00538}
+\pgfmath@def{atan}{626}{32.04656} \pgfmath@def{atan}{627}{32.08771}
+\pgfmath@def{atan}{628}{32.12882} \pgfmath@def{atan}{629}{32.16989}
+\pgfmath@def{atan}{630}{32.21092} \pgfmath@def{atan}{631}{32.25192}
+\pgfmath@def{atan}{632}{32.29288} \pgfmath@def{atan}{633}{32.33381}
+\pgfmath@def{atan}{634}{32.37469} \pgfmath@def{atan}{635}{32.41554}
+\pgfmath@def{atan}{636}{32.45636} \pgfmath@def{atan}{637}{32.49713}
+\pgfmath@def{atan}{638}{32.53787} \pgfmath@def{atan}{639}{32.57857}
+\pgfmath@def{atan}{640}{32.61924} \pgfmath@def{atan}{641}{32.65987}
+\pgfmath@def{atan}{642}{32.70046} \pgfmath@def{atan}{643}{32.74101}
+\pgfmath@def{atan}{644}{32.78153} \pgfmath@def{atan}{645}{32.82201}
+\pgfmath@def{atan}{646}{32.86246} \pgfmath@def{atan}{647}{32.90286}
+\pgfmath@def{atan}{648}{32.94323} \pgfmath@def{atan}{649}{32.98357}
+\pgfmath@def{atan}{650}{33.02386} \pgfmath@def{atan}{651}{33.06412}
+\pgfmath@def{atan}{652}{33.10435} \pgfmath@def{atan}{653}{33.14453}
+\pgfmath@def{atan}{654}{33.18468} \pgfmath@def{atan}{655}{33.22479}
+\pgfmath@def{atan}{656}{33.26487} \pgfmath@def{atan}{657}{33.30491}
+\pgfmath@def{atan}{658}{33.34491} \pgfmath@def{atan}{659}{33.38488}
+\pgfmath@def{atan}{660}{33.42481} \pgfmath@def{atan}{661}{33.46470}
+\pgfmath@def{atan}{662}{33.50455} \pgfmath@def{atan}{663}{33.54437}
+\pgfmath@def{atan}{664}{33.58416} \pgfmath@def{atan}{665}{33.62390}
+\pgfmath@def{atan}{666}{33.66361} \pgfmath@def{atan}{667}{33.70328}
+\pgfmath@def{atan}{668}{33.74292} \pgfmath@def{atan}{669}{33.78252}
+\pgfmath@def{atan}{670}{33.82208} \pgfmath@def{atan}{671}{33.86161}
+\pgfmath@def{atan}{672}{33.90110} \pgfmath@def{atan}{673}{33.94055}
+\pgfmath@def{atan}{674}{33.97997} \pgfmath@def{atan}{675}{34.01935}
+\pgfmath@def{atan}{676}{34.05869} \pgfmath@def{atan}{677}{34.09800}
+\pgfmath@def{atan}{678}{34.13727} \pgfmath@def{atan}{679}{34.17650}
+\pgfmath@def{atan}{680}{34.21570} \pgfmath@def{atan}{681}{34.25486}
+\pgfmath@def{atan}{682}{34.29398} \pgfmath@def{atan}{683}{34.33307}
+\pgfmath@def{atan}{684}{34.37212} \pgfmath@def{atan}{685}{34.41114}
+\pgfmath@def{atan}{686}{34.45012} \pgfmath@def{atan}{687}{34.48906}
+\pgfmath@def{atan}{688}{34.52797} \pgfmath@def{atan}{689}{34.56684}
+\pgfmath@def{atan}{690}{34.60567} \pgfmath@def{atan}{691}{34.64447}
+\pgfmath@def{atan}{692}{34.68323} \pgfmath@def{atan}{693}{34.72195}
+\pgfmath@def{atan}{694}{34.76064} \pgfmath@def{atan}{695}{34.79930}
+\pgfmath@def{atan}{696}{34.83791} \pgfmath@def{atan}{697}{34.87649}
+\pgfmath@def{atan}{698}{34.91504} \pgfmath@def{atan}{699}{34.95354}
+\pgfmath@def{atan}{700}{34.99202} \pgfmath@def{atan}{701}{35.03045}
+\pgfmath@def{atan}{702}{35.06885} \pgfmath@def{atan}{703}{35.10721}
+\pgfmath@def{atan}{704}{35.14554} \pgfmath@def{atan}{705}{35.18383}
+\pgfmath@def{atan}{706}{35.22209} \pgfmath@def{atan}{707}{35.26031}
+\pgfmath@def{atan}{708}{35.29849} \pgfmath@def{atan}{709}{35.33664}
+\pgfmath@def{atan}{710}{35.37475} \pgfmath@def{atan}{711}{35.41282}
+\pgfmath@def{atan}{712}{35.45086} \pgfmath@def{atan}{713}{35.48886}
+\pgfmath@def{atan}{714}{35.52683} \pgfmath@def{atan}{715}{35.56476}
+\pgfmath@def{atan}{716}{35.60266} \pgfmath@def{atan}{717}{35.64052}
+\pgfmath@def{atan}{718}{35.67834} \pgfmath@def{atan}{719}{35.71613}
+\pgfmath@def{atan}{720}{35.75388} \pgfmath@def{atan}{721}{35.79160}
+\pgfmath@def{atan}{722}{35.82928} \pgfmath@def{atan}{723}{35.86692}
+\pgfmath@def{atan}{724}{35.90453} \pgfmath@def{atan}{725}{35.94211}
+\pgfmath@def{atan}{726}{35.97965} \pgfmath@def{atan}{727}{36.01715}
+\pgfmath@def{atan}{728}{36.05461} \pgfmath@def{atan}{729}{36.09204}
+\pgfmath@def{atan}{730}{36.12944} \pgfmath@def{atan}{731}{36.16680}
+\pgfmath@def{atan}{732}{36.20412} \pgfmath@def{atan}{733}{36.24141}
+\pgfmath@def{atan}{734}{36.27866} \pgfmath@def{atan}{735}{36.31588}
+\pgfmath@def{atan}{736}{36.35306} \pgfmath@def{atan}{737}{36.39021}
+\pgfmath@def{atan}{738}{36.42732} \pgfmath@def{atan}{739}{36.46440}
+\pgfmath@def{atan}{740}{36.50144} \pgfmath@def{atan}{741}{36.53844}
+\pgfmath@def{atan}{742}{36.57541} \pgfmath@def{atan}{743}{36.61234}
+\pgfmath@def{atan}{744}{36.64924} \pgfmath@def{atan}{745}{36.68611}
+\pgfmath@def{atan}{746}{36.72293} \pgfmath@def{atan}{747}{36.75973}
+\pgfmath@def{atan}{748}{36.79648} \pgfmath@def{atan}{749}{36.83321}
+\pgfmath@def{atan}{750}{36.86989} \pgfmath@def{atan}{751}{36.90654}
+\pgfmath@def{atan}{752}{36.94316} \pgfmath@def{atan}{753}{36.97974}
+\pgfmath@def{atan}{754}{37.01629} \pgfmath@def{atan}{755}{37.05280}
+\pgfmath@def{atan}{756}{37.08928} \pgfmath@def{atan}{757}{37.12572}
+\pgfmath@def{atan}{758}{37.16212} \pgfmath@def{atan}{759}{37.19849}
+\pgfmath@def{atan}{760}{37.23483} \pgfmath@def{atan}{761}{37.27113}
+\pgfmath@def{atan}{762}{37.30740} \pgfmath@def{atan}{763}{37.34363}
+\pgfmath@def{atan}{764}{37.37982} \pgfmath@def{atan}{765}{37.41598}
+\pgfmath@def{atan}{766}{37.45211} \pgfmath@def{atan}{767}{37.48820}
+\pgfmath@def{atan}{768}{37.52426} \pgfmath@def{atan}{769}{37.56028}
+\pgfmath@def{atan}{770}{37.59627} \pgfmath@def{atan}{771}{37.63222}
+\pgfmath@def{atan}{772}{37.66814} \pgfmath@def{atan}{773}{37.70402}
+\pgfmath@def{atan}{774}{37.73987} \pgfmath@def{atan}{775}{37.77568}
+\pgfmath@def{atan}{776}{37.81146} \pgfmath@def{atan}{777}{37.84720}
+\pgfmath@def{atan}{778}{37.88291} \pgfmath@def{atan}{779}{37.91859}
+\pgfmath@def{atan}{780}{37.95423} \pgfmath@def{atan}{781}{37.98983}
+\pgfmath@def{atan}{782}{38.02540} \pgfmath@def{atan}{783}{38.06094}
+\pgfmath@def{atan}{784}{38.09644} \pgfmath@def{atan}{785}{38.13191}
+\pgfmath@def{atan}{786}{38.16734} \pgfmath@def{atan}{787}{38.20274}
+\pgfmath@def{atan}{788}{38.23811} \pgfmath@def{atan}{789}{38.27344}
+\pgfmath@def{atan}{790}{38.30873} \pgfmath@def{atan}{791}{38.34399}
+\pgfmath@def{atan}{792}{38.37922} \pgfmath@def{atan}{793}{38.41441}
+\pgfmath@def{atan}{794}{38.44957} \pgfmath@def{atan}{795}{38.48469}
+\pgfmath@def{atan}{796}{38.51979} \pgfmath@def{atan}{797}{38.55484}
+\pgfmath@def{atan}{798}{38.58986} \pgfmath@def{atan}{799}{38.62485}
+\pgfmath@def{atan}{800}{38.65980} \pgfmath@def{atan}{801}{38.69472}
+\pgfmath@def{atan}{802}{38.72961} \pgfmath@def{atan}{803}{38.76446}
+\pgfmath@def{atan}{804}{38.79928} \pgfmath@def{atan}{805}{38.83406}
+\pgfmath@def{atan}{806}{38.86881} \pgfmath@def{atan}{807}{38.90353}
+\pgfmath@def{atan}{808}{38.93821} \pgfmath@def{atan}{809}{38.97285}
+\pgfmath@def{atan}{810}{39.00747} \pgfmath@def{atan}{811}{39.04205}
+\pgfmath@def{atan}{812}{39.07659} \pgfmath@def{atan}{813}{39.11111}
+\pgfmath@def{atan}{814}{39.14558} \pgfmath@def{atan}{815}{39.18003}
+\pgfmath@def{atan}{816}{39.21444} \pgfmath@def{atan}{817}{39.24882}
+\pgfmath@def{atan}{818}{39.28316} \pgfmath@def{atan}{819}{39.31747}
+\pgfmath@def{atan}{820}{39.35175} \pgfmath@def{atan}{821}{39.38599}
+\pgfmath@def{atan}{822}{39.42020} \pgfmath@def{atan}{823}{39.45438}
+\pgfmath@def{atan}{824}{39.48852} \pgfmath@def{atan}{825}{39.52263}
+\pgfmath@def{atan}{826}{39.55670} \pgfmath@def{atan}{827}{39.59074}
+\pgfmath@def{atan}{828}{39.62475} \pgfmath@def{atan}{829}{39.65873}
+\pgfmath@def{atan}{830}{39.69267} \pgfmath@def{atan}{831}{39.72658}
+\pgfmath@def{atan}{832}{39.76045} \pgfmath@def{atan}{833}{39.79429}
+\pgfmath@def{atan}{834}{39.82810} \pgfmath@def{atan}{835}{39.86188}
+\pgfmath@def{atan}{836}{39.89562} \pgfmath@def{atan}{837}{39.92933}
+\pgfmath@def{atan}{838}{39.96300} \pgfmath@def{atan}{839}{39.99665}
+\pgfmath@def{atan}{840}{40.03025} \pgfmath@def{atan}{841}{40.06383}
+\pgfmath@def{atan}{842}{40.09737} \pgfmath@def{atan}{843}{40.13088}
+\pgfmath@def{atan}{844}{40.16436} \pgfmath@def{atan}{845}{40.19781}
+\pgfmath@def{atan}{846}{40.23122} \pgfmath@def{atan}{847}{40.26459}
+\pgfmath@def{atan}{848}{40.29794} \pgfmath@def{atan}{849}{40.33125}
+\pgfmath@def{atan}{850}{40.36453} \pgfmath@def{atan}{851}{40.39778}
+\pgfmath@def{atan}{852}{40.43099} \pgfmath@def{atan}{853}{40.46417}
+\pgfmath@def{atan}{854}{40.49732} \pgfmath@def{atan}{855}{40.53044}
+\pgfmath@def{atan}{856}{40.56352} \pgfmath@def{atan}{857}{40.59657}
+\pgfmath@def{atan}{858}{40.62959} \pgfmath@def{atan}{859}{40.66257}
+\pgfmath@def{atan}{860}{40.69553} \pgfmath@def{atan}{861}{40.72845}
+\pgfmath@def{atan}{862}{40.76133} \pgfmath@def{atan}{863}{40.79419}
+\pgfmath@def{atan}{864}{40.82701} \pgfmath@def{atan}{865}{40.85980}
+\pgfmath@def{atan}{866}{40.89256} \pgfmath@def{atan}{867}{40.92528}
+\pgfmath@def{atan}{868}{40.95798} \pgfmath@def{atan}{869}{40.99064}
+\pgfmath@def{atan}{870}{41.02326} \pgfmath@def{atan}{871}{41.05586}
+\pgfmath@def{atan}{872}{41.08842} \pgfmath@def{atan}{873}{41.12095}
+\pgfmath@def{atan}{874}{41.15345} \pgfmath@def{atan}{875}{41.18592}
+\pgfmath@def{atan}{876}{41.21836} \pgfmath@def{atan}{877}{41.25076}
+\pgfmath@def{atan}{878}{41.28313} \pgfmath@def{atan}{879}{41.31547}
+\pgfmath@def{atan}{880}{41.34777} \pgfmath@def{atan}{881}{41.38005}
+\pgfmath@def{atan}{882}{41.41229} \pgfmath@def{atan}{883}{41.44450}
+\pgfmath@def{atan}{884}{41.47668} \pgfmath@def{atan}{885}{41.50882}
+\pgfmath@def{atan}{886}{41.54094} \pgfmath@def{atan}{887}{41.57302}
+\pgfmath@def{atan}{888}{41.60507} \pgfmath@def{atan}{889}{41.63709}
+\pgfmath@def{atan}{890}{41.66908} \pgfmath@def{atan}{891}{41.70103}
+\pgfmath@def{atan}{892}{41.73296} \pgfmath@def{atan}{893}{41.76485}
+\pgfmath@def{atan}{894}{41.79671} \pgfmath@def{atan}{895}{41.82854}
+\pgfmath@def{atan}{896}{41.86034} \pgfmath@def{atan}{897}{41.89210}
+\pgfmath@def{atan}{898}{41.92383} \pgfmath@def{atan}{899}{41.95554}
+\pgfmath@def{atan}{900}{41.98721} \pgfmath@def{atan}{901}{42.01885}
+\pgfmath@def{atan}{902}{42.05046} \pgfmath@def{atan}{903}{42.08203}
+\pgfmath@def{atan}{904}{42.11358} \pgfmath@def{atan}{905}{42.14509}
+\pgfmath@def{atan}{906}{42.17657} \pgfmath@def{atan}{907}{42.20802}
+\pgfmath@def{atan}{908}{42.23944} \pgfmath@def{atan}{909}{42.27083}
+\pgfmath@def{atan}{910}{42.30219} \pgfmath@def{atan}{911}{42.33352}
+\pgfmath@def{atan}{912}{42.36481} \pgfmath@def{atan}{913}{42.39607}
+\pgfmath@def{atan}{914}{42.42731} \pgfmath@def{atan}{915}{42.45851}
+\pgfmath@def{atan}{916}{42.48968} \pgfmath@def{atan}{917}{42.52082}
+\pgfmath@def{atan}{918}{42.55193} \pgfmath@def{atan}{919}{42.58300}
+\pgfmath@def{atan}{920}{42.61405} \pgfmath@def{atan}{921}{42.64507}
+\pgfmath@def{atan}{922}{42.67605} \pgfmath@def{atan}{923}{42.70701}
+\pgfmath@def{atan}{924}{42.73793} \pgfmath@def{atan}{925}{42.76882}
+\pgfmath@def{atan}{926}{42.79968} \pgfmath@def{atan}{927}{42.83051}
+\pgfmath@def{atan}{928}{42.86131} \pgfmath@def{atan}{929}{42.89208}
+\pgfmath@def{atan}{930}{42.92282} \pgfmath@def{atan}{931}{42.95353}
+\pgfmath@def{atan}{932}{42.98421} \pgfmath@def{atan}{933}{43.01485}
+\pgfmath@def{atan}{934}{43.04547} \pgfmath@def{atan}{935}{43.07605}
+\pgfmath@def{atan}{936}{43.10661} \pgfmath@def{atan}{937}{43.13713}
+\pgfmath@def{atan}{938}{43.16763} \pgfmath@def{atan}{939}{43.19809}
+\pgfmath@def{atan}{940}{43.22853} \pgfmath@def{atan}{941}{43.25893}
+\pgfmath@def{atan}{942}{43.28930} \pgfmath@def{atan}{943}{43.31964}
+\pgfmath@def{atan}{944}{43.34996} \pgfmath@def{atan}{945}{43.38024}
+\pgfmath@def{atan}{946}{43.41049} \pgfmath@def{atan}{947}{43.44071}
+\pgfmath@def{atan}{948}{43.47090} \pgfmath@def{atan}{949}{43.50106}
+\pgfmath@def{atan}{950}{43.53119} \pgfmath@def{atan}{951}{43.56130}
+\pgfmath@def{atan}{952}{43.59137} \pgfmath@def{atan}{953}{43.62141}
+\pgfmath@def{atan}{954}{43.65142} \pgfmath@def{atan}{955}{43.68140}
+\pgfmath@def{atan}{956}{43.71135} \pgfmath@def{atan}{957}{43.74127}
+\pgfmath@def{atan}{958}{43.77116} \pgfmath@def{atan}{959}{43.80102}
+\pgfmath@def{atan}{960}{43.83086} \pgfmath@def{atan}{961}{43.86066}
+\pgfmath@def{atan}{962}{43.89043} \pgfmath@def{atan}{963}{43.92017}
+\pgfmath@def{atan}{964}{43.94988} \pgfmath@def{atan}{965}{43.97957}
+\pgfmath@def{atan}{966}{44.00922} \pgfmath@def{atan}{967}{44.03884}
+\pgfmath@def{atan}{968}{44.06844} \pgfmath@def{atan}{969}{44.09800}
+\pgfmath@def{atan}{970}{44.12754} \pgfmath@def{atan}{971}{44.15704}
+\pgfmath@def{atan}{972}{44.18652} \pgfmath@def{atan}{973}{44.21597}
+\pgfmath@def{atan}{974}{44.24538} \pgfmath@def{atan}{975}{44.27477}
+\pgfmath@def{atan}{976}{44.30413} \pgfmath@def{atan}{977}{44.33346}
+\pgfmath@def{atan}{978}{44.36276} \pgfmath@def{atan}{979}{44.39203}
+\pgfmath@def{atan}{980}{44.42127} \pgfmath@def{atan}{981}{44.45048}
+\pgfmath@def{atan}{982}{44.47966} \pgfmath@def{atan}{983}{44.50882}
+\pgfmath@def{atan}{984}{44.53794} \pgfmath@def{atan}{985}{44.56704}
+\pgfmath@def{atan}{986}{44.59610} \pgfmath@def{atan}{987}{44.62514}
+\pgfmath@def{atan}{988}{44.65415} \pgfmath@def{atan}{989}{44.68313}
+\pgfmath@def{atan}{990}{44.71208} \pgfmath@def{atan}{991}{44.74100}
+\pgfmath@def{atan}{992}{44.76989} \pgfmath@def{atan}{993}{44.79876}
+\pgfmath@def{atan}{994}{44.82759} \pgfmath@def{atan}{995}{44.85640}
+\pgfmath@def{atan}{996}{44.88517} \pgfmath@def{atan}{997}{44.91392}
+\pgfmath@def{atan}{998}{44.94264} \pgfmath@def{atan}{999}{44.97133}
+\pgfmath@def{atan}{1000}{45.00000}
+
+\pgfmath@def{acos}{0}{90.00000} \pgfmath@def{acos}{1}{89.94270}
+\pgfmath@def{acos}{2}{89.88540} \pgfmath@def{acos}{3}{89.82811}
+\pgfmath@def{acos}{4}{89.77081} \pgfmath@def{acos}{5}{89.71352}
+\pgfmath@def{acos}{6}{89.65622} \pgfmath@def{acos}{7}{89.59892}
+\pgfmath@def{acos}{8}{89.54162} \pgfmath@def{acos}{9}{89.48433}
+\pgfmath@def{acos}{10}{89.42703} \pgfmath@def{acos}{11}{89.36973}
+\pgfmath@def{acos}{12}{89.31243} \pgfmath@def{acos}{13}{89.25513}
+\pgfmath@def{acos}{14}{89.19783} \pgfmath@def{acos}{15}{89.14053}
+\pgfmath@def{acos}{16}{89.08322} \pgfmath@def{acos}{17}{89.02592}
+\pgfmath@def{acos}{18}{88.96862} \pgfmath@def{acos}{19}{88.91131}
+\pgfmath@def{acos}{20}{88.85400} \pgfmath@def{acos}{21}{88.79670}
+\pgfmath@def{acos}{22}{88.73939} \pgfmath@def{acos}{23}{88.68208}
+\pgfmath@def{acos}{24}{88.62476} \pgfmath@def{acos}{25}{88.56745}
+\pgfmath@def{acos}{26}{88.51014} \pgfmath@def{acos}{27}{88.45282}
+\pgfmath@def{acos}{28}{88.39550} \pgfmath@def{acos}{29}{88.33818}
+\pgfmath@def{acos}{30}{88.28086} \pgfmath@def{acos}{31}{88.22354}
+\pgfmath@def{acos}{32}{88.16622} \pgfmath@def{acos}{33}{88.10889}
+\pgfmath@def{acos}{34}{88.05156} \pgfmath@def{acos}{35}{87.99423}
+\pgfmath@def{acos}{36}{87.93690} \pgfmath@def{acos}{37}{87.87957}
+\pgfmath@def{acos}{38}{87.82223} \pgfmath@def{acos}{39}{87.76489}
+\pgfmath@def{acos}{40}{87.70755} \pgfmath@def{acos}{41}{87.65021}
+\pgfmath@def{acos}{42}{87.59286} \pgfmath@def{acos}{43}{87.53552}
+\pgfmath@def{acos}{44}{87.47817} \pgfmath@def{acos}{45}{87.42081}
+\pgfmath@def{acos}{46}{87.36346} \pgfmath@def{acos}{47}{87.30610}
+\pgfmath@def{acos}{48}{87.24874} \pgfmath@def{acos}{49}{87.19138}
+\pgfmath@def{acos}{50}{87.13401} \pgfmath@def{acos}{51}{87.07664}
+\pgfmath@def{acos}{52}{87.01927} \pgfmath@def{acos}{53}{86.96190}
+\pgfmath@def{acos}{54}{86.90452} \pgfmath@def{acos}{55}{86.84714}
+\pgfmath@def{acos}{56}{86.78975} \pgfmath@def{acos}{57}{86.73237}
+\pgfmath@def{acos}{58}{86.67497} \pgfmath@def{acos}{59}{86.61758}
+\pgfmath@def{acos}{60}{86.56018} \pgfmath@def{acos}{61}{86.50278}
+\pgfmath@def{acos}{62}{86.44538} \pgfmath@def{acos}{63}{86.38797}
+\pgfmath@def{acos}{64}{86.33056} \pgfmath@def{acos}{65}{86.27314}
+\pgfmath@def{acos}{66}{86.21572} \pgfmath@def{acos}{67}{86.15830}
+\pgfmath@def{acos}{68}{86.10087} \pgfmath@def{acos}{69}{86.04344}
+\pgfmath@def{acos}{70}{85.98601} \pgfmath@def{acos}{71}{85.92857}
+\pgfmath@def{acos}{72}{85.87113} \pgfmath@def{acos}{73}{85.81368}
+\pgfmath@def{acos}{74}{85.75623} \pgfmath@def{acos}{75}{85.69877}
+\pgfmath@def{acos}{76}{85.64131} \pgfmath@def{acos}{77}{85.58385}
+\pgfmath@def{acos}{78}{85.52638} \pgfmath@def{acos}{79}{85.46891}
+\pgfmath@def{acos}{80}{85.41143} \pgfmath@def{acos}{81}{85.35395}
+\pgfmath@def{acos}{82}{85.29646} \pgfmath@def{acos}{83}{85.23897}
+\pgfmath@def{acos}{84}{85.18147} \pgfmath@def{acos}{85}{85.12397}
+\pgfmath@def{acos}{86}{85.06646} \pgfmath@def{acos}{87}{85.00895}
+\pgfmath@def{acos}{88}{84.95144} \pgfmath@def{acos}{89}{84.89392}
+\pgfmath@def{acos}{90}{84.83639} \pgfmath@def{acos}{91}{84.77886}
+\pgfmath@def{acos}{92}{84.72132} \pgfmath@def{acos}{93}{84.66378}
+\pgfmath@def{acos}{94}{84.60623} \pgfmath@def{acos}{95}{84.54868}
+\pgfmath@def{acos}{96}{84.49112} \pgfmath@def{acos}{97}{84.43355}
+\pgfmath@def{acos}{98}{84.37598} \pgfmath@def{acos}{99}{84.31841}
+\pgfmath@def{acos}{100}{84.26083} \pgfmath@def{acos}{101}{84.20324}
+\pgfmath@def{acos}{102}{84.14564} \pgfmath@def{acos}{103}{84.08805}
+\pgfmath@def{acos}{104}{84.03044} \pgfmath@def{acos}{105}{83.97283}
+\pgfmath@def{acos}{106}{83.91521} \pgfmath@def{acos}{107}{83.85759}
+\pgfmath@def{acos}{108}{83.79996} \pgfmath@def{acos}{109}{83.74232}
+\pgfmath@def{acos}{110}{83.68468} \pgfmath@def{acos}{111}{83.62703}
+\pgfmath@def{acos}{112}{83.56938} \pgfmath@def{acos}{113}{83.51171}
+\pgfmath@def{acos}{114}{83.45405} \pgfmath@def{acos}{115}{83.39637}
+\pgfmath@def{acos}{116}{83.33869} \pgfmath@def{acos}{117}{83.28100}
+\pgfmath@def{acos}{118}{83.22330} \pgfmath@def{acos}{119}{83.16560}
+\pgfmath@def{acos}{120}{83.10789} \pgfmath@def{acos}{121}{83.05018}
+\pgfmath@def{acos}{122}{82.99245} \pgfmath@def{acos}{123}{82.93472}
+\pgfmath@def{acos}{124}{82.87698} \pgfmath@def{acos}{125}{82.81924}
+\pgfmath@def{acos}{126}{82.76149} \pgfmath@def{acos}{127}{82.70373}
+\pgfmath@def{acos}{128}{82.64596} \pgfmath@def{acos}{129}{82.58819}
+\pgfmath@def{acos}{130}{82.53040} \pgfmath@def{acos}{131}{82.47261}
+\pgfmath@def{acos}{132}{82.41482} \pgfmath@def{acos}{133}{82.35701}
+\pgfmath@def{acos}{134}{82.29920} \pgfmath@def{acos}{135}{82.24138}
+\pgfmath@def{acos}{136}{82.18355} \pgfmath@def{acos}{137}{82.12571}
+\pgfmath@def{acos}{138}{82.06786} \pgfmath@def{acos}{139}{82.01001}
+\pgfmath@def{acos}{140}{81.95215} \pgfmath@def{acos}{141}{81.89428}
+\pgfmath@def{acos}{142}{81.83640} \pgfmath@def{acos}{143}{81.77851}
+\pgfmath@def{acos}{144}{81.72062} \pgfmath@def{acos}{145}{81.66272}
+\pgfmath@def{acos}{146}{81.60480} \pgfmath@def{acos}{147}{81.54688}
+\pgfmath@def{acos}{148}{81.48895} \pgfmath@def{acos}{149}{81.43102}
+\pgfmath@def{acos}{150}{81.37307} \pgfmath@def{acos}{151}{81.31511}
+\pgfmath@def{acos}{152}{81.25715} \pgfmath@def{acos}{153}{81.19917}
+\pgfmath@def{acos}{154}{81.14119} \pgfmath@def{acos}{155}{81.08320}
+\pgfmath@def{acos}{156}{81.02520} \pgfmath@def{acos}{157}{80.96719}
+\pgfmath@def{acos}{158}{80.90917} \pgfmath@def{acos}{159}{80.85114}
+\pgfmath@def{acos}{160}{80.79310} \pgfmath@def{acos}{161}{80.73505}
+\pgfmath@def{acos}{162}{80.67699} \pgfmath@def{acos}{163}{80.61893}
+\pgfmath@def{acos}{164}{80.56085} \pgfmath@def{acos}{165}{80.50276}
+\pgfmath@def{acos}{166}{80.44466} \pgfmath@def{acos}{167}{80.38656}
+\pgfmath@def{acos}{168}{80.32844} \pgfmath@def{acos}{169}{80.27031}
+\pgfmath@def{acos}{170}{80.21218} \pgfmath@def{acos}{171}{80.15403}
+\pgfmath@def{acos}{172}{80.09587} \pgfmath@def{acos}{173}{80.03770}
+\pgfmath@def{acos}{174}{79.97953} \pgfmath@def{acos}{175}{79.92134}
+\pgfmath@def{acos}{176}{79.86314} \pgfmath@def{acos}{177}{79.80493}
+\pgfmath@def{acos}{178}{79.74671} \pgfmath@def{acos}{179}{79.68848}
+\pgfmath@def{acos}{180}{79.63024} \pgfmath@def{acos}{181}{79.57198}
+\pgfmath@def{acos}{182}{79.51372} \pgfmath@def{acos}{183}{79.45545}
+\pgfmath@def{acos}{184}{79.39716} \pgfmath@def{acos}{185}{79.33886}
+\pgfmath@def{acos}{186}{79.28056} \pgfmath@def{acos}{187}{79.22224}
+\pgfmath@def{acos}{188}{79.16391} \pgfmath@def{acos}{189}{79.10556}
+\pgfmath@def{acos}{190}{79.04721} \pgfmath@def{acos}{191}{78.98885}
+\pgfmath@def{acos}{192}{78.93047} \pgfmath@def{acos}{193}{78.87208}
+\pgfmath@def{acos}{194}{78.81368} \pgfmath@def{acos}{195}{78.75527}
+\pgfmath@def{acos}{196}{78.69685} \pgfmath@def{acos}{197}{78.63841}
+\pgfmath@def{acos}{198}{78.57997} \pgfmath@def{acos}{199}{78.52151}
+\pgfmath@def{acos}{200}{78.46304} \pgfmath@def{acos}{201}{78.40455}
+\pgfmath@def{acos}{202}{78.34606} \pgfmath@def{acos}{203}{78.28755}
+\pgfmath@def{acos}{204}{78.22903} \pgfmath@def{acos}{205}{78.17050}
+\pgfmath@def{acos}{206}{78.11195} \pgfmath@def{acos}{207}{78.05339}
+\pgfmath@def{acos}{208}{77.99482} \pgfmath@def{acos}{209}{77.93624}
+\pgfmath@def{acos}{210}{77.87764} \pgfmath@def{acos}{211}{77.81903}
+\pgfmath@def{acos}{212}{77.76041} \pgfmath@def{acos}{213}{77.70178}
+\pgfmath@def{acos}{214}{77.64313} \pgfmath@def{acos}{215}{77.58447}
+\pgfmath@def{acos}{216}{77.52579} \pgfmath@def{acos}{217}{77.46711}
+\pgfmath@def{acos}{218}{77.40841} \pgfmath@def{acos}{219}{77.34969}
+\pgfmath@def{acos}{220}{77.29096} \pgfmath@def{acos}{221}{77.23222}
+\pgfmath@def{acos}{222}{77.17347} \pgfmath@def{acos}{223}{77.11470}
+\pgfmath@def{acos}{224}{77.05591} \pgfmath@def{acos}{225}{76.99712}
+\pgfmath@def{acos}{226}{76.93831} \pgfmath@def{acos}{227}{76.87948}
+\pgfmath@def{acos}{228}{76.82064} \pgfmath@def{acos}{229}{76.76179}
+\pgfmath@def{acos}{230}{76.70292} \pgfmath@def{acos}{231}{76.64404}
+\pgfmath@def{acos}{232}{76.58515} \pgfmath@def{acos}{233}{76.52624}
+\pgfmath@def{acos}{234}{76.46731} \pgfmath@def{acos}{235}{76.40837}
+\pgfmath@def{acos}{236}{76.34942} \pgfmath@def{acos}{237}{76.29045}
+\pgfmath@def{acos}{238}{76.23147} \pgfmath@def{acos}{239}{76.17247}
+\pgfmath@def{acos}{240}{76.11346} \pgfmath@def{acos}{241}{76.05443}
+\pgfmath@def{acos}{242}{75.99538} \pgfmath@def{acos}{243}{75.93632}
+\pgfmath@def{acos}{244}{75.87725} \pgfmath@def{acos}{245}{75.81816}
+\pgfmath@def{acos}{246}{75.75906} \pgfmath@def{acos}{247}{75.69994}
+\pgfmath@def{acos}{248}{75.64080} \pgfmath@def{acos}{249}{75.58165}
+\pgfmath@def{acos}{250}{75.52248} \pgfmath@def{acos}{251}{75.46330}
+\pgfmath@def{acos}{252}{75.40410} \pgfmath@def{acos}{253}{75.34489}
+\pgfmath@def{acos}{254}{75.28566} \pgfmath@def{acos}{255}{75.22641}
+\pgfmath@def{acos}{256}{75.16715} \pgfmath@def{acos}{257}{75.10787}
+\pgfmath@def{acos}{258}{75.04857} \pgfmath@def{acos}{259}{74.98926}
+\pgfmath@def{acos}{260}{74.92993} \pgfmath@def{acos}{261}{74.87059}
+\pgfmath@def{acos}{262}{74.81123} \pgfmath@def{acos}{263}{74.75185}
+\pgfmath@def{acos}{264}{74.69245} \pgfmath@def{acos}{265}{74.63304}
+\pgfmath@def{acos}{266}{74.57361} \pgfmath@def{acos}{267}{74.51417}
+\pgfmath@def{acos}{268}{74.45471} \pgfmath@def{acos}{269}{74.39523}
+\pgfmath@def{acos}{270}{74.33573} \pgfmath@def{acos}{271}{74.27621}
+\pgfmath@def{acos}{272}{74.21668} \pgfmath@def{acos}{273}{74.15713}
+\pgfmath@def{acos}{274}{74.09757} \pgfmath@def{acos}{275}{74.03798}
+\pgfmath@def{acos}{276}{73.97838} \pgfmath@def{acos}{277}{73.91876}
+\pgfmath@def{acos}{278}{73.85912} \pgfmath@def{acos}{279}{73.79946}
+\pgfmath@def{acos}{280}{73.73979} \pgfmath@def{acos}{281}{73.68010}
+\pgfmath@def{acos}{282}{73.62039} \pgfmath@def{acos}{283}{73.56066}
+\pgfmath@def{acos}{284}{73.50091} \pgfmath@def{acos}{285}{73.44115}
+\pgfmath@def{acos}{286}{73.38136} \pgfmath@def{acos}{287}{73.32156}
+\pgfmath@def{acos}{288}{73.26174} \pgfmath@def{acos}{289}{73.20190}
+\pgfmath@def{acos}{290}{73.14204} \pgfmath@def{acos}{291}{73.08216}
+\pgfmath@def{acos}{292}{73.02226} \pgfmath@def{acos}{293}{72.96235}
+\pgfmath@def{acos}{294}{72.90241} \pgfmath@def{acos}{295}{72.84246}
+\pgfmath@def{acos}{296}{72.78248} \pgfmath@def{acos}{297}{72.72249}
+\pgfmath@def{acos}{298}{72.66248} \pgfmath@def{acos}{299}{72.60244}
+\pgfmath@def{acos}{300}{72.54239} \pgfmath@def{acos}{301}{72.48232}
+\pgfmath@def{acos}{302}{72.42223} \pgfmath@def{acos}{303}{72.36212}
+\pgfmath@def{acos}{304}{72.30198} \pgfmath@def{acos}{305}{72.24183}
+\pgfmath@def{acos}{306}{72.18166} \pgfmath@def{acos}{307}{72.12147}
+\pgfmath@def{acos}{308}{72.06125} \pgfmath@def{acos}{309}{72.00102}
+\pgfmath@def{acos}{310}{71.94077} \pgfmath@def{acos}{311}{71.88049}
+\pgfmath@def{acos}{312}{71.82019} \pgfmath@def{acos}{313}{71.75988}
+\pgfmath@def{acos}{314}{71.69954} \pgfmath@def{acos}{315}{71.63918}
+\pgfmath@def{acos}{316}{71.57880} \pgfmath@def{acos}{317}{71.51840}
+\pgfmath@def{acos}{318}{71.45798} \pgfmath@def{acos}{319}{71.39754}
+\pgfmath@def{acos}{320}{71.33707} \pgfmath@def{acos}{321}{71.27658}
+\pgfmath@def{acos}{322}{71.21608} \pgfmath@def{acos}{323}{71.15555}
+\pgfmath@def{acos}{324}{71.09499} \pgfmath@def{acos}{325}{71.03442}
+\pgfmath@def{acos}{326}{70.97382} \pgfmath@def{acos}{327}{70.91321}
+\pgfmath@def{acos}{328}{70.85257} \pgfmath@def{acos}{329}{70.79190}
+\pgfmath@def{acos}{330}{70.73122} \pgfmath@def{acos}{331}{70.67051}
+\pgfmath@def{acos}{332}{70.60978} \pgfmath@def{acos}{333}{70.54903}
+\pgfmath@def{acos}{334}{70.48826} \pgfmath@def{acos}{335}{70.42746}
+\pgfmath@def{acos}{336}{70.36664} \pgfmath@def{acos}{337}{70.30579}
+\pgfmath@def{acos}{338}{70.24493} \pgfmath@def{acos}{339}{70.18404}
+\pgfmath@def{acos}{340}{70.12312} \pgfmath@def{acos}{341}{70.06218}
+\pgfmath@def{acos}{342}{70.00122} \pgfmath@def{acos}{343}{69.94024}
+\pgfmath@def{acos}{344}{69.87923} \pgfmath@def{acos}{345}{69.81820}
+\pgfmath@def{acos}{346}{69.75714} \pgfmath@def{acos}{347}{69.69606}
+\pgfmath@def{acos}{348}{69.63496} \pgfmath@def{acos}{349}{69.57383}
+\pgfmath@def{acos}{350}{69.51268} \pgfmath@def{acos}{351}{69.45150}
+\pgfmath@def{acos}{352}{69.39030} \pgfmath@def{acos}{353}{69.32908}
+\pgfmath@def{acos}{354}{69.26783} \pgfmath@def{acos}{355}{69.20655}
+\pgfmath@def{acos}{356}{69.14525} \pgfmath@def{acos}{357}{69.08393}
+\pgfmath@def{acos}{358}{69.02258} \pgfmath@def{acos}{359}{68.96120}
+\pgfmath@def{acos}{360}{68.89980} \pgfmath@def{acos}{361}{68.83837}
+\pgfmath@def{acos}{362}{68.77692} \pgfmath@def{acos}{363}{68.71544}
+\pgfmath@def{acos}{364}{68.65394} \pgfmath@def{acos}{365}{68.59241}
+\pgfmath@def{acos}{366}{68.53086} \pgfmath@def{acos}{367}{68.46928}
+\pgfmath@def{acos}{368}{68.40767} \pgfmath@def{acos}{369}{68.34604}
+\pgfmath@def{acos}{370}{68.28438} \pgfmath@def{acos}{371}{68.22269}
+\pgfmath@def{acos}{372}{68.16098} \pgfmath@def{acos}{373}{68.09924}
+\pgfmath@def{acos}{374}{68.03748} \pgfmath@def{acos}{375}{67.97568}
+\pgfmath@def{acos}{376}{67.91386} \pgfmath@def{acos}{377}{67.85202}
+\pgfmath@def{acos}{378}{67.79014} \pgfmath@def{acos}{379}{67.72824}
+\pgfmath@def{acos}{380}{67.66631} \pgfmath@def{acos}{381}{67.60436}
+\pgfmath@def{acos}{382}{67.54237} \pgfmath@def{acos}{383}{67.48036}
+\pgfmath@def{acos}{384}{67.41832} \pgfmath@def{acos}{385}{67.35626}
+\pgfmath@def{acos}{386}{67.29416} \pgfmath@def{acos}{387}{67.23204}
+\pgfmath@def{acos}{388}{67.16988} \pgfmath@def{acos}{389}{67.10770}
+\pgfmath@def{acos}{390}{67.04550} \pgfmath@def{acos}{391}{66.98326}
+\pgfmath@def{acos}{392}{66.92099} \pgfmath@def{acos}{393}{66.85870}
+\pgfmath@def{acos}{394}{66.79637} \pgfmath@def{acos}{395}{66.73402}
+\pgfmath@def{acos}{396}{66.67164} \pgfmath@def{acos}{397}{66.60923}
+\pgfmath@def{acos}{398}{66.54679} \pgfmath@def{acos}{399}{66.48432}
+\pgfmath@def{acos}{400}{66.42182} \pgfmath@def{acos}{401}{66.35929}
+\pgfmath@def{acos}{402}{66.29673} \pgfmath@def{acos}{403}{66.23414}
+\pgfmath@def{acos}{404}{66.17152} \pgfmath@def{acos}{405}{66.10887}
+\pgfmath@def{acos}{406}{66.04619} \pgfmath@def{acos}{407}{65.98348}
+\pgfmath@def{acos}{408}{65.92074} \pgfmath@def{acos}{409}{65.85796}
+\pgfmath@def{acos}{410}{65.79516} \pgfmath@def{acos}{411}{65.73233}
+\pgfmath@def{acos}{412}{65.66946} \pgfmath@def{acos}{413}{65.60657}
+\pgfmath@def{acos}{414}{65.54364} \pgfmath@def{acos}{415}{65.48068}
+\pgfmath@def{acos}{416}{65.41769} \pgfmath@def{acos}{417}{65.35467}
+\pgfmath@def{acos}{418}{65.29161} \pgfmath@def{acos}{419}{65.22853}
+\pgfmath@def{acos}{420}{65.16541} \pgfmath@def{acos}{421}{65.10226}
+\pgfmath@def{acos}{422}{65.03908} \pgfmath@def{acos}{423}{64.97586}
+\pgfmath@def{acos}{424}{64.91261} \pgfmath@def{acos}{425}{64.84933}
+\pgfmath@def{acos}{426}{64.78602} \pgfmath@def{acos}{427}{64.72267}
+\pgfmath@def{acos}{428}{64.65929} \pgfmath@def{acos}{429}{64.59588}
+\pgfmath@def{acos}{430}{64.53244} \pgfmath@def{acos}{431}{64.46896}
+\pgfmath@def{acos}{432}{64.40544} \pgfmath@def{acos}{433}{64.34190}
+\pgfmath@def{acos}{434}{64.27832} \pgfmath@def{acos}{435}{64.21470}
+\pgfmath@def{acos}{436}{64.15105} \pgfmath@def{acos}{437}{64.08737}
+\pgfmath@def{acos}{438}{64.02365} \pgfmath@def{acos}{439}{63.95990}
+\pgfmath@def{acos}{440}{63.89611} \pgfmath@def{acos}{441}{63.83229}
+\pgfmath@def{acos}{442}{63.76844} \pgfmath@def{acos}{443}{63.70455}
+\pgfmath@def{acos}{444}{63.64062} \pgfmath@def{acos}{445}{63.57666}
+\pgfmath@def{acos}{446}{63.51266} \pgfmath@def{acos}{447}{63.44863}
+\pgfmath@def{acos}{448}{63.38456} \pgfmath@def{acos}{449}{63.32045}
+\pgfmath@def{acos}{450}{63.25631} \pgfmath@def{acos}{451}{63.19213}
+\pgfmath@def{acos}{452}{63.12792} \pgfmath@def{acos}{453}{63.06367}
+\pgfmath@def{acos}{454}{62.99938} \pgfmath@def{acos}{455}{62.93506}
+\pgfmath@def{acos}{456}{62.87070} \pgfmath@def{acos}{457}{62.80630}
+\pgfmath@def{acos}{458}{62.74187} \pgfmath@def{acos}{459}{62.67740}
+\pgfmath@def{acos}{460}{62.61289} \pgfmath@def{acos}{461}{62.54834}
+\pgfmath@def{acos}{462}{62.48376} \pgfmath@def{acos}{463}{62.41913}
+\pgfmath@def{acos}{464}{62.35447} \pgfmath@def{acos}{465}{62.28977}
+\pgfmath@def{acos}{466}{62.22504} \pgfmath@def{acos}{467}{62.16026}
+\pgfmath@def{acos}{468}{62.09545} \pgfmath@def{acos}{469}{62.03059}
+\pgfmath@def{acos}{470}{61.96570} \pgfmath@def{acos}{471}{61.90077}
+\pgfmath@def{acos}{472}{61.83580} \pgfmath@def{acos}{473}{61.77079}
+\pgfmath@def{acos}{474}{61.70574} \pgfmath@def{acos}{475}{61.64065}
+\pgfmath@def{acos}{476}{61.57552} \pgfmath@def{acos}{477}{61.51035}
+\pgfmath@def{acos}{478}{61.44514} \pgfmath@def{acos}{479}{61.37988}
+\pgfmath@def{acos}{480}{61.31459} \pgfmath@def{acos}{481}{61.24926}
+\pgfmath@def{acos}{482}{61.18389} \pgfmath@def{acos}{483}{61.11847}
+\pgfmath@def{acos}{484}{61.05302} \pgfmath@def{acos}{485}{60.98752}
+\pgfmath@def{acos}{486}{60.92199} \pgfmath@def{acos}{487}{60.85641}
+\pgfmath@def{acos}{488}{60.79078} \pgfmath@def{acos}{489}{60.72512}
+\pgfmath@def{acos}{490}{60.65941} \pgfmath@def{acos}{491}{60.59367}
+\pgfmath@def{acos}{492}{60.52787} \pgfmath@def{acos}{493}{60.46204}
+\pgfmath@def{acos}{494}{60.39616} \pgfmath@def{acos}{495}{60.33025}
+\pgfmath@def{acos}{496}{60.26428} \pgfmath@def{acos}{497}{60.19828}
+\pgfmath@def{acos}{498}{60.13223} \pgfmath@def{acos}{499}{60.06613}
+\pgfmath@def{acos}{500}{60.00000} \pgfmath@def{acos}{501}{59.93381}
+\pgfmath@def{acos}{502}{59.86759} \pgfmath@def{acos}{503}{59.80132}
+\pgfmath@def{acos}{504}{59.73500} \pgfmath@def{acos}{505}{59.66864}
+\pgfmath@def{acos}{506}{59.60224} \pgfmath@def{acos}{507}{59.53579}
+\pgfmath@def{acos}{508}{59.46929} \pgfmath@def{acos}{509}{59.40275}
+\pgfmath@def{acos}{510}{59.33617} \pgfmath@def{acos}{511}{59.26953}
+\pgfmath@def{acos}{512}{59.20285} \pgfmath@def{acos}{513}{59.13613}
+\pgfmath@def{acos}{514}{59.06936} \pgfmath@def{acos}{515}{59.00254}
+\pgfmath@def{acos}{516}{58.93568} \pgfmath@def{acos}{517}{58.86876}
+\pgfmath@def{acos}{518}{58.80180} \pgfmath@def{acos}{519}{58.73480}
+\pgfmath@def{acos}{520}{58.66774} \pgfmath@def{acos}{521}{58.60064}
+\pgfmath@def{acos}{522}{58.53349} \pgfmath@def{acos}{523}{58.46629}
+\pgfmath@def{acos}{524}{58.39905} \pgfmath@def{acos}{525}{58.33175}
+\pgfmath@def{acos}{526}{58.26441} \pgfmath@def{acos}{527}{58.19702}
+\pgfmath@def{acos}{528}{58.12957} \pgfmath@def{acos}{529}{58.06208}
+\pgfmath@def{acos}{530}{57.99454} \pgfmath@def{acos}{531}{57.92695}
+\pgfmath@def{acos}{532}{57.85931} \pgfmath@def{acos}{533}{57.79162}
+\pgfmath@def{acos}{534}{57.72388} \pgfmath@def{acos}{535}{57.65608}
+\pgfmath@def{acos}{536}{57.58824} \pgfmath@def{acos}{537}{57.52035}
+\pgfmath@def{acos}{538}{57.45240} \pgfmath@def{acos}{539}{57.38441}
+\pgfmath@def{acos}{540}{57.31636} \pgfmath@def{acos}{541}{57.24826}
+\pgfmath@def{acos}{542}{57.18010} \pgfmath@def{acos}{543}{57.11190}
+\pgfmath@def{acos}{544}{57.04364} \pgfmath@def{acos}{545}{56.97533}
+\pgfmath@def{acos}{546}{56.90697} \pgfmath@def{acos}{547}{56.83855}
+\pgfmath@def{acos}{548}{56.77008} \pgfmath@def{acos}{549}{56.70156}
+\pgfmath@def{acos}{550}{56.63298} \pgfmath@def{acos}{551}{56.56435}
+\pgfmath@def{acos}{552}{56.49567} \pgfmath@def{acos}{553}{56.42693}
+\pgfmath@def{acos}{554}{56.35813} \pgfmath@def{acos}{555}{56.28928}
+\pgfmath@def{acos}{556}{56.22038} \pgfmath@def{acos}{557}{56.15141}
+\pgfmath@def{acos}{558}{56.08240} \pgfmath@def{acos}{559}{56.01333}
+\pgfmath@def{acos}{560}{55.94420} \pgfmath@def{acos}{561}{55.87501}
+\pgfmath@def{acos}{562}{55.80577} \pgfmath@def{acos}{563}{55.73647}
+\pgfmath@def{acos}{564}{55.66712} \pgfmath@def{acos}{565}{55.59770}
+\pgfmath@def{acos}{566}{55.52823} \pgfmath@def{acos}{567}{55.45871}
+\pgfmath@def{acos}{568}{55.38912} \pgfmath@def{acos}{569}{55.31947}
+\pgfmath@def{acos}{570}{55.24977} \pgfmath@def{acos}{571}{55.18001}
+\pgfmath@def{acos}{572}{55.11019} \pgfmath@def{acos}{573}{55.04030}
+\pgfmath@def{acos}{574}{54.97036} \pgfmath@def{acos}{575}{54.90036}
+\pgfmath@def{acos}{576}{54.83030} \pgfmath@def{acos}{577}{54.76018}
+\pgfmath@def{acos}{578}{54.69000} \pgfmath@def{acos}{579}{54.61976}
+\pgfmath@def{acos}{580}{54.54945} \pgfmath@def{acos}{581}{54.47909}
+\pgfmath@def{acos}{582}{54.40866} \pgfmath@def{acos}{583}{54.33817}
+\pgfmath@def{acos}{584}{54.26762} \pgfmath@def{acos}{585}{54.19701}
+\pgfmath@def{acos}{586}{54.12633} \pgfmath@def{acos}{587}{54.05559}
+\pgfmath@def{acos}{588}{53.98479} \pgfmath@def{acos}{589}{53.91392}
+\pgfmath@def{acos}{590}{53.84299} \pgfmath@def{acos}{591}{53.77199}
+\pgfmath@def{acos}{592}{53.70093} \pgfmath@def{acos}{593}{53.62981}
+\pgfmath@def{acos}{594}{53.55862} \pgfmath@def{acos}{595}{53.48736}
+\pgfmath@def{acos}{596}{53.41604} \pgfmath@def{acos}{597}{53.34466}
+\pgfmath@def{acos}{598}{53.27320} \pgfmath@def{acos}{599}{53.20168}
+\pgfmath@def{acos}{600}{53.13010} \pgfmath@def{acos}{601}{53.05844}
+\pgfmath@def{acos}{602}{52.98672} \pgfmath@def{acos}{603}{52.91494}
+\pgfmath@def{acos}{604}{52.84308} \pgfmath@def{acos}{605}{52.77115}
+\pgfmath@def{acos}{606}{52.69916} \pgfmath@def{acos}{607}{52.62710}
+\pgfmath@def{acos}{608}{52.55497} \pgfmath@def{acos}{609}{52.48276}
+\pgfmath@def{acos}{610}{52.41049} \pgfmath@def{acos}{611}{52.33815}
+\pgfmath@def{acos}{612}{52.26574} \pgfmath@def{acos}{613}{52.19326}
+\pgfmath@def{acos}{614}{52.12070} \pgfmath@def{acos}{615}{52.04808}
+\pgfmath@def{acos}{616}{51.97538} \pgfmath@def{acos}{617}{51.90261}
+\pgfmath@def{acos}{618}{51.82976} \pgfmath@def{acos}{619}{51.75685}
+\pgfmath@def{acos}{620}{51.68386} \pgfmath@def{acos}{621}{51.61080}
+\pgfmath@def{acos}{622}{51.53766} \pgfmath@def{acos}{623}{51.46445}
+\pgfmath@def{acos}{624}{51.39117} \pgfmath@def{acos}{625}{51.31781}
+\pgfmath@def{acos}{626}{51.24437} \pgfmath@def{acos}{627}{51.17086}
+\pgfmath@def{acos}{628}{51.09728} \pgfmath@def{acos}{629}{51.02361}
+\pgfmath@def{acos}{630}{50.94987} \pgfmath@def{acos}{631}{50.87606}
+\pgfmath@def{acos}{632}{50.80216} \pgfmath@def{acos}{633}{50.72819}
+\pgfmath@def{acos}{634}{50.65414} \pgfmath@def{acos}{635}{50.58001}
+\pgfmath@def{acos}{636}{50.50580} \pgfmath@def{acos}{637}{50.43152}
+\pgfmath@def{acos}{638}{50.35715} \pgfmath@def{acos}{639}{50.28270}
+\pgfmath@def{acos}{640}{50.20818} \pgfmath@def{acos}{641}{50.13357}
+\pgfmath@def{acos}{642}{50.05888} \pgfmath@def{acos}{643}{49.98411}
+\pgfmath@def{acos}{644}{49.90926} \pgfmath@def{acos}{645}{49.83432}
+\pgfmath@def{acos}{646}{49.75930} \pgfmath@def{acos}{647}{49.68420}
+\pgfmath@def{acos}{648}{49.60902} \pgfmath@def{acos}{649}{49.53375}
+\pgfmath@def{acos}{650}{49.45839} \pgfmath@def{acos}{651}{49.38296}
+\pgfmath@def{acos}{652}{49.30743} \pgfmath@def{acos}{653}{49.23182}
+\pgfmath@def{acos}{654}{49.15613} \pgfmath@def{acos}{655}{49.08035}
+\pgfmath@def{acos}{656}{49.00448} \pgfmath@def{acos}{657}{48.92852}
+\pgfmath@def{acos}{658}{48.85248} \pgfmath@def{acos}{659}{48.77634}
+\pgfmath@def{acos}{660}{48.70012} \pgfmath@def{acos}{661}{48.62381}
+\pgfmath@def{acos}{662}{48.54741} \pgfmath@def{acos}{663}{48.47092}
+\pgfmath@def{acos}{664}{48.39434} \pgfmath@def{acos}{665}{48.31767}
+\pgfmath@def{acos}{666}{48.24091} \pgfmath@def{acos}{667}{48.16405}
+\pgfmath@def{acos}{668}{48.08710} \pgfmath@def{acos}{669}{48.01006}
+\pgfmath@def{acos}{670}{47.93293} \pgfmath@def{acos}{671}{47.85570}
+\pgfmath@def{acos}{672}{47.77838} \pgfmath@def{acos}{673}{47.70096}
+\pgfmath@def{acos}{674}{47.62345} \pgfmath@def{acos}{675}{47.54585}
+\pgfmath@def{acos}{676}{47.46814} \pgfmath@def{acos}{677}{47.39034}
+\pgfmath@def{acos}{678}{47.31244} \pgfmath@def{acos}{679}{47.23445}
+\pgfmath@def{acos}{680}{47.15635} \pgfmath@def{acos}{681}{47.07816}
+\pgfmath@def{acos}{682}{46.99987} \pgfmath@def{acos}{683}{46.92147}
+\pgfmath@def{acos}{684}{46.84298} \pgfmath@def{acos}{685}{46.76439}
+\pgfmath@def{acos}{686}{46.68569} \pgfmath@def{acos}{687}{46.60690}
+\pgfmath@def{acos}{688}{46.52800} \pgfmath@def{acos}{689}{46.44899}
+\pgfmath@def{acos}{690}{46.36989} \pgfmath@def{acos}{691}{46.29068}
+\pgfmath@def{acos}{692}{46.21136} \pgfmath@def{acos}{693}{46.13194}
+\pgfmath@def{acos}{694}{46.05241} \pgfmath@def{acos}{695}{45.97278}
+\pgfmath@def{acos}{696}{45.89304} \pgfmath@def{acos}{697}{45.81319}
+\pgfmath@def{acos}{698}{45.73323} \pgfmath@def{acos}{699}{45.65317}
+\pgfmath@def{acos}{700}{45.57299} \pgfmath@def{acos}{701}{45.49271}
+\pgfmath@def{acos}{702}{45.41231} \pgfmath@def{acos}{703}{45.33180}
+\pgfmath@def{acos}{704}{45.25118} \pgfmath@def{acos}{705}{45.17045}
+\pgfmath@def{acos}{706}{45.08961} \pgfmath@def{acos}{707}{45.00865}
+\pgfmath@def{acos}{708}{44.92757} \pgfmath@def{acos}{709}{44.84638}
+\pgfmath@def{acos}{710}{44.76508} \pgfmath@def{acos}{711}{44.68366}
+\pgfmath@def{acos}{712}{44.60212} \pgfmath@def{acos}{713}{44.52046}
+\pgfmath@def{acos}{714}{44.43869} \pgfmath@def{acos}{715}{44.35680}
+\pgfmath@def{acos}{716}{44.27478} \pgfmath@def{acos}{717}{44.19265}
+\pgfmath@def{acos}{718}{44.11039} \pgfmath@def{acos}{719}{44.02802}
+\pgfmath@def{acos}{720}{43.94552} \pgfmath@def{acos}{721}{43.86289}
+\pgfmath@def{acos}{722}{43.78014} \pgfmath@def{acos}{723}{43.69727}
+\pgfmath@def{acos}{724}{43.61427} \pgfmath@def{acos}{725}{43.53115}
+\pgfmath@def{acos}{726}{43.44790} \pgfmath@def{acos}{727}{43.36452}
+\pgfmath@def{acos}{728}{43.28101} \pgfmath@def{acos}{729}{43.19737}
+\pgfmath@def{acos}{730}{43.11360} \pgfmath@def{acos}{731}{43.02970}
+\pgfmath@def{acos}{732}{42.94567} \pgfmath@def{acos}{733}{42.86151}
+\pgfmath@def{acos}{734}{42.77721} \pgfmath@def{acos}{735}{42.69278}
+\pgfmath@def{acos}{736}{42.60821} \pgfmath@def{acos}{737}{42.52351}
+\pgfmath@def{acos}{738}{42.43867} \pgfmath@def{acos}{739}{42.35370}
+\pgfmath@def{acos}{740}{42.26858} \pgfmath@def{acos}{741}{42.18333}
+\pgfmath@def{acos}{742}{42.09793} \pgfmath@def{acos}{743}{42.01240}
+\pgfmath@def{acos}{744}{41.92672} \pgfmath@def{acos}{745}{41.84090}
+\pgfmath@def{acos}{746}{41.75493} \pgfmath@def{acos}{747}{41.66882}
+\pgfmath@def{acos}{748}{41.58257} \pgfmath@def{acos}{749}{41.49617}
+\pgfmath@def{acos}{750}{41.40962} \pgfmath@def{acos}{751}{41.32292}
+\pgfmath@def{acos}{752}{41.23607} \pgfmath@def{acos}{753}{41.14908}
+\pgfmath@def{acos}{754}{41.06193} \pgfmath@def{acos}{755}{40.97463}
+\pgfmath@def{acos}{756}{40.88717} \pgfmath@def{acos}{757}{40.79956}
+\pgfmath@def{acos}{758}{40.71180} \pgfmath@def{acos}{759}{40.62388}
+\pgfmath@def{acos}{760}{40.53580} \pgfmath@def{acos}{761}{40.44756}
+\pgfmath@def{acos}{762}{40.35916} \pgfmath@def{acos}{763}{40.27061}
+\pgfmath@def{acos}{764}{40.18189} \pgfmath@def{acos}{765}{40.09300}
+\pgfmath@def{acos}{766}{40.00396} \pgfmath@def{acos}{767}{39.91474}
+\pgfmath@def{acos}{768}{39.82537} \pgfmath@def{acos}{769}{39.73582}
+\pgfmath@def{acos}{770}{39.64611} \pgfmath@def{acos}{771}{39.55622}
+\pgfmath@def{acos}{772}{39.46617} \pgfmath@def{acos}{773}{39.37594}
+\pgfmath@def{acos}{774}{39.28554} \pgfmath@def{acos}{775}{39.19496}
+\pgfmath@def{acos}{776}{39.10421} \pgfmath@def{acos}{777}{39.01328}
+\pgfmath@def{acos}{778}{38.92218} \pgfmath@def{acos}{779}{38.83089}
+\pgfmath@def{acos}{780}{38.73942} \pgfmath@def{acos}{781}{38.64777}
+\pgfmath@def{acos}{782}{38.55594} \pgfmath@def{acos}{783}{38.46392}
+\pgfmath@def{acos}{784}{38.37171} \pgfmath@def{acos}{785}{38.27932}
+\pgfmath@def{acos}{786}{38.18673} \pgfmath@def{acos}{787}{38.09396}
+\pgfmath@def{acos}{788}{38.00100} \pgfmath@def{acos}{789}{37.90784}
+\pgfmath@def{acos}{790}{37.81448} \pgfmath@def{acos}{791}{37.72093}
+\pgfmath@def{acos}{792}{37.62719} \pgfmath@def{acos}{793}{37.53324}
+\pgfmath@def{acos}{794}{37.43909} \pgfmath@def{acos}{795}{37.34474}
+\pgfmath@def{acos}{796}{37.25019} \pgfmath@def{acos}{797}{37.15542}
+\pgfmath@def{acos}{798}{37.06046} \pgfmath@def{acos}{799}{36.96528}
+\pgfmath@def{acos}{800}{36.86989} \pgfmath@def{acos}{801}{36.77429}
+\pgfmath@def{acos}{802}{36.67848} \pgfmath@def{acos}{803}{36.58245}
+\pgfmath@def{acos}{804}{36.48621} \pgfmath@def{acos}{805}{36.38974}
+\pgfmath@def{acos}{806}{36.29305} \pgfmath@def{acos}{807}{36.19615}
+\pgfmath@def{acos}{808}{36.09901} \pgfmath@def{acos}{809}{36.00165}
+\pgfmath@def{acos}{810}{35.90406} \pgfmath@def{acos}{811}{35.80625}
+\pgfmath@def{acos}{812}{35.70820} \pgfmath@def{acos}{813}{35.60991}
+\pgfmath@def{acos}{814}{35.51139} \pgfmath@def{acos}{815}{35.41263}
+\pgfmath@def{acos}{816}{35.31364} \pgfmath@def{acos}{817}{35.21440}
+\pgfmath@def{acos}{818}{35.11491} \pgfmath@def{acos}{819}{35.01518}
+\pgfmath@def{acos}{820}{34.91520} \pgfmath@def{acos}{821}{34.81497}
+\pgfmath@def{acos}{822}{34.71449} \pgfmath@def{acos}{823}{34.61375}
+\pgfmath@def{acos}{824}{34.51276} \pgfmath@def{acos}{825}{34.41150}
+\pgfmath@def{acos}{826}{34.30999} \pgfmath@def{acos}{827}{34.20821}
+\pgfmath@def{acos}{828}{34.10616} \pgfmath@def{acos}{829}{34.00385}
+\pgfmath@def{acos}{830}{33.90126} \pgfmath@def{acos}{831}{33.79840}
+\pgfmath@def{acos}{832}{33.69526} \pgfmath@def{acos}{833}{33.59184}
+\pgfmath@def{acos}{834}{33.48814} \pgfmath@def{acos}{835}{33.38416}
+\pgfmath@def{acos}{836}{33.27989} \pgfmath@def{acos}{837}{33.17533}
+\pgfmath@def{acos}{838}{33.07047} \pgfmath@def{acos}{839}{32.96532}
+\pgfmath@def{acos}{840}{32.85988} \pgfmath@def{acos}{841}{32.75413}
+\pgfmath@def{acos}{842}{32.64807} \pgfmath@def{acos}{843}{32.54171}
+\pgfmath@def{acos}{844}{32.43504} \pgfmath@def{acos}{845}{32.32806}
+\pgfmath@def{acos}{846}{32.22076} \pgfmath@def{acos}{847}{32.11314}
+\pgfmath@def{acos}{848}{32.00520} \pgfmath@def{acos}{849}{31.89693}
+\pgfmath@def{acos}{850}{31.78833} \pgfmath@def{acos}{851}{31.67939}
+\pgfmath@def{acos}{852}{31.57012} \pgfmath@def{acos}{853}{31.46051}
+\pgfmath@def{acos}{854}{31.35056} \pgfmath@def{acos}{855}{31.24026}
+\pgfmath@def{acos}{856}{31.12961} \pgfmath@def{acos}{857}{31.01860}
+\pgfmath@def{acos}{858}{30.90724} \pgfmath@def{acos}{859}{30.79551}
+\pgfmath@def{acos}{860}{30.68341} \pgfmath@def{acos}{861}{30.57095}
+\pgfmath@def{acos}{862}{30.45811} \pgfmath@def{acos}{863}{30.34489}
+\pgfmath@def{acos}{864}{30.23128} \pgfmath@def{acos}{865}{30.11729}
+\pgfmath@def{acos}{866}{30.00291} \pgfmath@def{acos}{867}{29.88813}
+\pgfmath@def{acos}{868}{29.77294} \pgfmath@def{acos}{869}{29.65736}
+\pgfmath@def{acos}{870}{29.54136} \pgfmath@def{acos}{871}{29.42494}
+\pgfmath@def{acos}{872}{29.30810} \pgfmath@def{acos}{873}{29.19084}
+\pgfmath@def{acos}{874}{29.07315} \pgfmath@def{acos}{875}{28.95502}
+\pgfmath@def{acos}{876}{28.83645} \pgfmath@def{acos}{877}{28.71743}
+\pgfmath@def{acos}{878}{28.59796} \pgfmath@def{acos}{879}{28.47803}
+\pgfmath@def{acos}{880}{28.35763} \pgfmath@def{acos}{881}{28.23677}
+\pgfmath@def{acos}{882}{28.11542} \pgfmath@def{acos}{883}{27.99360}
+\pgfmath@def{acos}{884}{27.87128} \pgfmath@def{acos}{885}{27.74847}
+\pgfmath@def{acos}{886}{27.62516} \pgfmath@def{acos}{887}{27.50134}
+\pgfmath@def{acos}{888}{27.37700} \pgfmath@def{acos}{889}{27.25214}
+\pgfmath@def{acos}{890}{27.12675} \pgfmath@def{acos}{891}{27.00082}
+\pgfmath@def{acos}{892}{26.87434} \pgfmath@def{acos}{893}{26.74731}
+\pgfmath@def{acos}{894}{26.61973} \pgfmath@def{acos}{895}{26.49157}
+\pgfmath@def{acos}{896}{26.36283} \pgfmath@def{acos}{897}{26.23351}
+\pgfmath@def{acos}{898}{26.10359} \pgfmath@def{acos}{899}{25.97306}
+\pgfmath@def{acos}{900}{25.84193} \pgfmath@def{acos}{901}{25.71017}
+\pgfmath@def{acos}{902}{25.57778} \pgfmath@def{acos}{903}{25.44475}
+\pgfmath@def{acos}{904}{25.31106} \pgfmath@def{acos}{905}{25.17671}
+\pgfmath@def{acos}{906}{25.04169} \pgfmath@def{acos}{907}{24.90598}
+\pgfmath@def{acos}{908}{24.76958} \pgfmath@def{acos}{909}{24.63247}
+\pgfmath@def{acos}{910}{24.49464} \pgfmath@def{acos}{911}{24.35608}
+\pgfmath@def{acos}{912}{24.21678} \pgfmath@def{acos}{913}{24.07672}
+\pgfmath@def{acos}{914}{23.93588} \pgfmath@def{acos}{915}{23.79427}
+\pgfmath@def{acos}{916}{23.65185} \pgfmath@def{acos}{917}{23.50863}
+\pgfmath@def{acos}{918}{23.36457} \pgfmath@def{acos}{919}{23.21967}
+\pgfmath@def{acos}{920}{23.07391} \pgfmath@def{acos}{921}{22.92728}
+\pgfmath@def{acos}{922}{22.77975} \pgfmath@def{acos}{923}{22.63132}
+\pgfmath@def{acos}{924}{22.48195} \pgfmath@def{acos}{925}{22.33164}
+\pgfmath@def{acos}{926}{22.18036} \pgfmath@def{acos}{927}{22.02810}
+\pgfmath@def{acos}{928}{21.87483} \pgfmath@def{acos}{929}{21.72053}
+\pgfmath@def{acos}{930}{21.56518} \pgfmath@def{acos}{931}{21.40876}
+\pgfmath@def{acos}{932}{21.25124} \pgfmath@def{acos}{933}{21.09260}
+\pgfmath@def{acos}{934}{20.93281} \pgfmath@def{acos}{935}{20.77185}
+\pgfmath@def{acos}{936}{20.60969} \pgfmath@def{acos}{937}{20.44630}
+\pgfmath@def{acos}{938}{20.28165} \pgfmath@def{acos}{939}{20.11570}
+\pgfmath@def{acos}{940}{19.94844} \pgfmath@def{acos}{941}{19.77982}
+\pgfmath@def{acos}{942}{19.60981} \pgfmath@def{acos}{943}{19.43837}
+\pgfmath@def{acos}{944}{19.26546} \pgfmath@def{acos}{945}{19.09105}
+\pgfmath@def{acos}{946}{18.91509} \pgfmath@def{acos}{947}{18.73754}
+\pgfmath@def{acos}{948}{18.55835} \pgfmath@def{acos}{949}{18.37748}
+\pgfmath@def{acos}{950}{18.19487} \pgfmath@def{acos}{951}{18.01047}
+\pgfmath@def{acos}{952}{17.82423} \pgfmath@def{acos}{953}{17.63609}
+\pgfmath@def{acos}{954}{17.44598} \pgfmath@def{acos}{955}{17.25385}
+\pgfmath@def{acos}{956}{17.05962} \pgfmath@def{acos}{957}{16.86322}
+\pgfmath@def{acos}{958}{16.66457} \pgfmath@def{acos}{959}{16.46359}
+\pgfmath@def{acos}{960}{16.26020} \pgfmath@def{acos}{961}{16.05430}
+\pgfmath@def{acos}{962}{15.84580} \pgfmath@def{acos}{963}{15.63459}
+\pgfmath@def{acos}{964}{15.42057} \pgfmath@def{acos}{965}{15.20360}
+\pgfmath@def{acos}{966}{14.98357} \pgfmath@def{acos}{967}{14.76033}
+\pgfmath@def{acos}{968}{14.53374} \pgfmath@def{acos}{969}{14.30364}
+\pgfmath@def{acos}{970}{14.06986} \pgfmath@def{acos}{971}{13.83221}
+\pgfmath@def{acos}{972}{13.59049} \pgfmath@def{acos}{973}{13.34447}
+\pgfmath@def{acos}{974}{13.09392} \pgfmath@def{acos}{975}{12.83856}
+\pgfmath@def{acos}{976}{12.57811} \pgfmath@def{acos}{977}{12.31225}
+\pgfmath@def{acos}{978}{12.04060} \pgfmath@def{acos}{979}{11.76278}
+\pgfmath@def{acos}{980}{11.47834} \pgfmath@def{acos}{981}{11.18676}
+\pgfmath@def{acos}{982}{10.88748} \pgfmath@def{acos}{983}{10.57984}
+\pgfmath@def{acos}{984}{10.26309} \pgfmath@def{acos}{985}{9.93636}
+\pgfmath@def{acos}{986}{9.59863} \pgfmath@def{acos}{987}{9.24870}
+\pgfmath@def{acos}{988}{8.88512} \pgfmath@def{acos}{989}{8.50614}
+\pgfmath@def{acos}{990}{8.10961} \pgfmath@def{acos}{991}{7.69281}
+\pgfmath@def{acos}{992}{7.25224} \pgfmath@def{acos}{993}{6.78328}
+\pgfmath@def{acos}{994}{6.27958} \pgfmath@def{acos}{995}{5.73196}
+\pgfmath@def{acos}{996}{5.12640} \pgfmath@def{acos}{997}{4.43922}
+\pgfmath@def{acos}{998}{3.62430} \pgfmath@def{acos}{999}{2.56255}
+\pgfmath@def{acos}{1000}{0.00000}
+
+
+
+% Local Variables:
+% tab-width: 2
+% End:
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathode.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathode.code.tex
new file mode 100644
index 0000000000..f072c2361e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathode.code.tex
@@ -0,0 +1,178 @@
+% Copyright 2019 by Christophe Jorssen
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+\def\pgfmathode@stopadd{\pgfmathode@stopadd}
+
+\def\pgfmathode@addindextofunc[#1]#2{%
+ \begingroup
+ \gdef\pgfmathode@func{}%
+ \pgfmathode@addindextofunc@i[#1]#2\pgfmathode@stopadd}
+
+\def\pgfmathode@addindextofunc@i[#1]#2#3{%
+ \ifx#1#2
+ \expandafter\gdef\expandafter\pgfmathode@func\expandafter{%
+ \pgfmathode@func #2[\pgfmathode@timeindex]}%
+ \else
+ \expandafter\gdef\expandafter\pgfmathode@func\expandafter{%
+ \pgfmathode@func #2}%
+ \fi
+ \ifx#3\pgfmathode@stopadd
+ \expandafter\gdef\expandafter\pgfmathode@func\expandafter{%
+ \expandafter{\pgfmathode@func}}%
+ \let\next\endgroup
+ \else
+ \def\next{\pgfmathode@addindextofunc@i[#1]#3}%
+ \fi
+ \next}
+
+%**********************************************************************
+% Know limitation: fk cannot be a time function. Should be possible to
+% use \Sol[0] as time in the set of equations.
+%**********************************************************************
+
+% Numerically solve a differential system with 1st order Runge-Kutta
+% (Euler method)
+% dq1/dt = f1(t,q1,q2,...,qN)
+% dq2/dt = f2(t,q1,q2,...,qN)
+% ...
+% dqN/dt = fN(t,q1,q2,...,qN)
+%
+% #1: A pgf array where the solution will be stored.
+% At the end:
+% #1 -> {{t(0),q1(t(0)),q2(t(0)),...,qN(t(0))},
+% {t(1),q1(t(1)),q2(t(1)),...,qN(t(1))},
+% ...
+% {t(Nstep),q1(t(Nstep)),q2(t(Nstep)),...,qN(t(Nstep))}}
+% #2: A pgf array with f1,f2,...,fN
+% {f1}
+% #3: A pgf array with initial conditions.
+% {t(0),q1(t(0)),q2(t(0)),...,qN(t(0))}
+% #4: t(Nstep)
+% #5: Nstep (number of steps)
+%
+% * First order example: dq/dt = -q + 5 with IC=(t=0,q(0)=0)
+% \pgfmathodeRKI{\Sol}{{-\Sol[1]+5}}{{0,0}}{3.5}{100}
+% * Second order example: {dq1/dt=q2, dq2/dt=-q2/2-sin(q1)} (damped
+% pendulum)
+% \pgfmathodeRKI{\Sol}{{\Sol[2],-\Sol[2]/2-sin(deg(\Sol[1]))}}%
+% {{0,-1,5}}{15}{50}
+
+\def\pgfmathode@generic@init@RK{%
+ \begingroup
+ % Sol array (#1) first element is given by the set of initial
+ % conditions (#3). We need to enclose it in brace so that is a now
+ % a "matrix" array.
+ \gdef#1{{#3}}%
+ % The set of rhs {f1(t,q1,q2,...,qN),...,fN(t,q1,q2,...,qN)} is
+ % given in terms of #1[0],#1[1],...,#1[N]. We need to transform to
+ % #1[\pgfmathode@timeindex][0],...,#1[\pgfmathode@timeindex][N], that is
+ % add [\pgfmathode@timeindex] after every occurrence of #1 in #2.
+ % No need to brace #2 since it is already surrounded by braces. The
+ % result is stored in \pgfmathode@func
+ \pgfmathode@addindextofunc[#1]#2%
+ % Set time step. Actually the number of time steps is #5-1, so we
+ % divide by (#5-1)+1 = #5.
+ \pgfmathsetmacro\pgfmathode@Sol@t{#1[0][0]}%
+ \pgfmathsetmacro\pgfmathode@Deltat{(#4-\pgfmathode@Sol@t)/#5}%
+ % Compute the order of the system: it is equal to the number of IC
+ % minus one (time).
+ \pgfmathsetmacro\pgfmathode@dimfunc{dim(#3)-1}%
+ \pgfmathsetmacro\pgfmathode@numstep{#5-1}}
+
+\def\pgfmathodeRKI#1#2#3#4#5{%
+ \pgfmathode@generic@init@RK
+ % Start the time loop for Runge-Kutta 1st order
+ \foreach \pgfmathode@timeindex in {0,...,\pgfmathode@numstep} {%
+ \message{Step \pgfmathode@timeindex...}%
+ % Start the function loop
+ \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {%
+ % The RKI algorithm
+ % qk[t(i)] = Deltat*fk(t(i-1),q1(t(i-1)),...qN(t(i-1))) +
+ % qk[t(i-1)]
+ % Note: this part can be really slow due to array management in
+ % pgfmath.
+ % TODO: find a better way (at least inside this loop)
+ \pgfmathparse{%
+ \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+
+ #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}%
+ % Store the result in a helper macro
+ \expandafter\xdef\csname pgfmathode@Sol@\pgfmathode@funcindex
+ \endcsname{\pgfmathresult}%
+ }
+ % Store step i
+ \pgfmathparse{\pgfmathode@Sol@t+\pgfmathode@Deltat}%
+ \xdef\pgfmathode@Sol@t{\pgfmathresult}%
+ \xdef\pgfmathode@temp{}%
+ \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {%
+ \ifx\pgfmathode@temp\pgfutil@empty
+ \xdef\pgfmathode@temp{%
+ \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}%
+ \else
+ \xdef\pgfmathode@temp{%
+ \pgfmathode@temp,
+ \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}%
+ \fi}
+ \xdef#1{%
+ {\expandafter\pgfutil@firstofone#1,%
+ {\pgfmathode@Sol@t,\pgfmathode@temp}}}%
+ }
+ \endgroup}
+
+% RKIV: far from working yet!
+\def\pgfmathodeRKIV#1#2#3#4#5{%
+ \pgfmathode@generic@init@RK
+ % Start the time loop for Runge-Kutta 4th order
+ \foreach \pgfmathode@timeindex in {0,...,\pgfmathode@numstep} {%
+ \message{Step \pgfmathode@timeindex...}%
+ % Start the function loop
+ \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {%
+ % The RKIV algorithm
+ % qk[t(i)] = qk[t(i-1)] +
+ % (1/6) * (j1k + 2j2k + 2j3k + j4k)
+ % where j1k = fk(t(i-1),q1(t(i-1)),...qN(t(i-1))) * Deltat
+ % j2k = fk(t(i-1)+.5*Deltat,
+ % q1(t(i-1))+.5*j11,...qN(t(i-1))+.5*j1N) * Deltat
+ % j3k = fk(t(i-1)+.5*Deltat,
+ % q1(t(i-1))+.5*j21,...qN(t(i-1))+.5*j2N) * Deltat
+ % j4k = fk(t(i-1)+Deltat,
+ % q1(t(i-1))+j31,...qN(t(i-1))+j3N) * Deltat
+ %
+ % Compute j1k
+ \pgfmathparse{%
+ \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+
+ #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}%
+ \expandafter\xdef\csname pgfmathode@RKIV@1@\pgfmathode@funcindex
+ \endcsname{\pgfmathresult}%
+ % Compute j2k
+ \pgfmathparse{%
+ \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+
+ #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}%
+ \expandafter\xdef\csname pgfmathode@RKIV@1@\pgfmathode@funcindex
+ \endcsname{\pgfmathresult}%
+ }
+ % Store step i
+ \pgfmathparse{\pgfmathode@Sol@t+\pgfmathode@Deltat}%
+ \xdef\pgfmathode@Sol@t{\pgfmathresult}%
+ \xdef\pgfmathode@temp{}%
+ \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {%
+ \ifx\pgfmathode@temp\pgfutil@empty
+ \xdef\pgfmathode@temp{%
+ \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}%
+ \else
+ \xdef\pgfmathode@temp{%
+ \pgfmathode@temp,
+ \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}%
+ \fi}
+ \xdef#1{%
+ {\expandafter\pgfutil@firstofone#1,%
+ {\pgfmathode@Sol@t,\pgfmathode@temp}}}%
+ }
+ \endgroup}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathparser.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathparser.code.tex
new file mode 100644
index 0000000000..8a560ff114
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathparser.code.tex
@@ -0,0 +1,1017 @@
+
+\newdimen\pgfmath@dimen
+\newcount\pgfmath@count
+\newbox\pgfmath@box
+\newtoks\pgfmath@toks
+
+\newif\ifpgfmath@quickparse
+\newif\ifpgfmathfloat
+\newif\ifpgfmathunitsdeclared
+\newif\ifpgfmathmathunitsdeclared
+\newif\ifpgfmathignoreunitscale
+
+\let\pgfmath@protected@edef=\edef
+\ifcsname protected@edef\endcsname
+ \let\pgfmath@protected@edef=\protected@edef
+\fi
+
+\def\pgfmathprint#1{\pgfmathparse{#1}\pgfmathresult}
+
+\def\pgfmathparse{%
+ \begingroup
+ \pgfmath@catcodes
+ \pgfmath@quickparsefalse
+ % Test for the fpu library
+ \ifpgfmathfloat
+ \let\pgfmath@parse@next=\pgfmathfloatparsenumber
+ \else
+ \let\pgfmath@parse@next=\pgfmathparse@
+ \fi
+ \pgfmath@parse@next}
+
+\begingroup
+ \lccode`\~=`\"
+ \lowercase{\endgroup
+ \def\pgfmath@catcodes{%
+ \catcode`\==12 %
+ \catcode`\,=12 %
+ \catcode`\|=12 %
+ \catcode`\&=12 %
+ \let~\pgfmath@char@quote
+ }}%
+
+\def\pgfmathqparse{%
+ \begingroup
+ \pgfmath@catcodes
+ \pgfmath@quickparsetrue
+ \pgfmathparse@}
+
+\def\pgfmathparse@#1{%
+ % No (math) units yet.
+ \global\pgfmathunitsdeclaredfalse
+ \global\pgfmathmathunitsdeclaredfalse
+ % Expand expression so any remaining CSs are registers
+ % or box dimensions (i.e. |\wd|, |\ht|, |\dp|).
+ \pgfmath@protected@edef\pgfmath@expression{#1}%
+ %
+ \expandafter\pgfmathparse@trynumber@loop\pgfmath@expression\pgfmath@parse@stop
+ %
+ % this here is the _real_ parser. it is invoked by
+ % \pgfmathparse@trynumber@loop if that says "this is no number"
+ %\pgfmathparse@@\pgfmath@parse@stop%
+}
+
+\def\pgfmath@parse@stop{\pgfmath@parse@stop}% equals only itself
+
+\def\pgfmathparse@trynumber@token{numeric}
+\begingroup
+\def\\{\global\let\pgf@let@space@token= } \\ % now, \pgf@let@space@token is a space token
+\endgroup
+
+% This a "fast-lane": if the expressions consist merely of number
+% tokens, we can simply return the number as-is.
+%
+% This is significantly faster and should resemble the 80% use-case.
+%
+% #1 a single token
+\def\pgfmathparse@trynumber@loop{%
+ \futurelet\pgfmath@token@let\pgfmathparse@trynumber@loop@
+}%
+\def\pgfmathparse@trynumber@loop@#1{%
+ \ifx\pgfmath@token@let\pgf@let@space@token
+ % Hm. we found a white space... and we have no support for
+ % trimming. That means we have to assume that the white space
+ % occurred somewhere in the middle - and fall back to the
+ % expensive method.
+ \def\pgfmath@parse@next{\pgfmathparse@@#1}%
+ \else
+ \ifx\pgfmath@token@let\bgroup%
+ % oh! We found '{' #1.
+ % Well, these braces appear to be special; fall back to
+ % the complicated routine...
+ \let\pgfmath@parse@next=\pgfmathparse@@
+ \else
+ \ifx\pgfmath@token@let\pgfmath@parse@stop
+ % Ah: we have passed the check! The expression consists only
+ % of 0123456789. , so do not parse anything and return it
+ % as-is!
+ \let\pgfmath@parse@next=\pgfmathparse@expression@is@number
+ \else
+ \expandafter\ifx\csname pgfmath@token@\pgfmathparse@trynumber@token @\string#1\endcsname\relax%
+ % hm. It is none of 0123456789.
+ \let\pgfmath@parse@next=\pgfmathparse@@
+ \else
+ % continue... we only found one of 0123456789. so
+ % far...
+ \let\pgfmath@parse@next=\pgfmathparse@trynumber@loop
+ \fi
+ \fi
+ \fi
+ \fi
+ \pgfmath@parse@next
+}%
+
+\def\pgfmathparse@expression@is@number{%
+ \let\pgfmathresult=\pgfmath@expression
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup
+ \ignorespaces
+}%
+\def\pgfmathparse@@#1\pgfmath@parse@stop{%
+ % We are inside a group (opened in |\pgfmathparse| or
+ % |\pgfmathqparse|).
+ % Stuff for calc compatibility.
+ \let\real=\pgfmath@calc@real
+ \let\minof=\pgfmath@calc@minof
+ \let\maxof=\pgfmath@calc@maxof
+ \let\ratio=\pgfmath@calc@ratio
+ \let\widthof=\pgfmath@calc@widthof
+ \let\heightof=\pgfmath@calc@heightof
+ \let\depthof=\pgfmath@calc@depthof
+ % Restore font (defined in pgfmathutil.code.tex)
+ \pgfmath@selectfont
+ % Set up stack.
+ \pgfmath@stack@operation={{}{}{}}%
+ \pgfmath@stack@operand={{}{}{}}%
+ \let\pgfmath@stack@operation@top=\pgfmath@stack@empty
+ \let\pgfmath@stack@operand@top=\pgfmath@stack@empty
+ % An expression always begins with an operand.
+ \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmath@expression}%
+ % |\pgfmath@bgroup@stripped| is the result of
+ % |\pgfmath@bgroup@strip|
+ \expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped @@@@\pgfmath@parse@stop%
+}
+
+\def\pgfmath@parse@end#1\pgfmath@parse@stop{%
+ \pgfmathpostparse
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup
+ \ignorespaces}
+
+\let\pgfmathpostparse=\relax
+
+% For compatibility with older version.
+%
+\def\pgfmathscaleresult{%
+ \ifpgfmathunitsdeclared
+ \else
+ \ifpgfmathignoreunitscale
+ \else
+ \afterassignment\pgfmath@gobbletilpgfmath@%
+ \pgfmath@x\pgfmathresultunitscale pt\relax\pgfmath@%
+ \expandafter\pgfmath@x\pgfmathresult\pgfmath@x%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
+ \fi
+ \fi
+}
+
+\def\pgfmathsetresultunitscale#1{\def\pgfmathresultunitscale{#1}}
+
+\def\pgfmathresultunitscale{1}
+
+
+% A utility function which evaluates expression '#1' and invokes '#2'
+% if the expression is true and '#3' if it is false.
+\def\pgfmathifexpression#1#2#3{%
+ \pgfmathparse{#1}%
+ \pgfmath@iftrue{#2}{#3}%
+}%
+% Executes '#1' if \pgfmathresult is 'true', '#2' otherwise.
+% WARNING : overwritten in fpu lib!
+\def\pgfmath@iftrue{%
+ \ifdim\pgfmathresult pt=1.0pt %
+ \let\pgfmath@next=\pgfutil@firstoftwo
+ \else
+ \let\pgfmath@next=\pgfutil@secondoftwo
+ \fi
+ \pgfmath@next%
+}%
+
+% Stuff for computability with the calc package.
+%
+\def\pgfmath@calc@real#1{#1}
+\def\pgfmath@calc@minof#1#2{min(#1,#2)}
+\def\pgfmath@calc@maxof#1#2{max(#1,#2)}
+\def\pgfmath@calc@ratio#1#2{#1/#2}
+\def\pgfmath@calc@widthof#1{width("#1")}
+\def\pgfmath@calc@heightof#1{height("#1")}
+\def\pgfmath@calc@depthof#1{depth("#1")}
+
+\def\pgfmath@bgroup{\string\pgfmath@bgroup}
+\def\pgfmath@egroup{\string\pgfmath@egroup}
+\def\pgfmath@egroup@token{\pgfmath@egroup}
+
+\def\pgfmath@text@@{@}
+\def\pgfmath@text@operator{operator}
+\def\pgfmath@text@function{function}
+\def\pgfmath@dots{...}
+\def\pgfmath@char@zero{0}
+\def\pgfmath@char@quote{"}
+\def\pgfmath@char@exclamation{!}
+\def\pgfmath@char@plus{+}
+\def\pgfmath@char@minus{-}
+\def\pgfmath@char@period{.}
+\def\pgfmath@char@leftangle{<}
+\def\pgfmath@char@leftbracket{[}
+\pgfmath@toks={#}
+\edef\pgfmath@char@hash{\the\pgfmath@toks}
+
+\def\pgfmath@tokens@make#1#2{%
+ % Defines for each token or balanced text in |#2| a control sequence
+ % |\pgfmath@token@<#1>@\string<one token from #2>| and stores |#2|
+ % in it.
+ \def\pgfmath@prefix{#1}%
+ % Note the empty group |{}| at the end that ends the loop in
+ % |\pgfmath@token@@make|.
+ \expandafter\pgfmath@tokens@@make#2{}}
+
+\def\pgfmath@tokens@@make#1{%
+ \def\pgfmath@token{#1}%
+ \ifx\pgfmath@token\pgfmath@empty
+ % End of loop: all tokens or balanced texts were parsed.
+ \else
+ \pgfmath@namedef{pgfmath@token@\pgfmath@prefix @\string#1}{#1}%
+ \expandafter\pgfmath@tokens@@make%
+ \fi}
+
+\pgfmath@tokens@make{box}{\wd\ht\dp}
+\ifx\dimexpr\@undefined\else % needed for classic tex
+ \pgfmath@tokens@make{dimexpr}{\dimexpr\glueexpr}
+\fi
+\pgfmath@tokens@make{unit}{{bp}{cc}{cm}{dd}{em}{ex}{in}{mm}{pc}{pt}{sp}}
+\ifx\pdftexversion\@undefined\else % for pdfTeX
+ \pgfmath@tokens@make{unit}{{nc}{nd}{px}}
+\fi
+\ifx\directlua\@undefined\else % for LuaTeX
+ \pgfmath@tokens@make{unit}{{nc}{nd}{px}}
+\fi
+\ifx\kanjiskip\@undefined\else % for pTeX, upTeX
+ \pgfmath@tokens@make{unit}{{H}{Q}{zh}{zw}}
+\fi
+%
+\pgfmath@tokens@make{mathunit}{{mu}}
+\pgfmath@tokens@make{numeric}{.0123456789}
+\pgfmath@tokens@make{number}{0123456789}
+\pgfmath@tokens@make{functional}{_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+\pgfmath@tokens@make{exponent}{eE}
+\pgfmath@tokens@make{group}{{()}{[]}{\pgfmath@bgroup\pgfmath@egroup}}
+\pgfmath@tokens@make{specials}{@)]\pgfmath@egroup}
+\pgfmath@tokens@make{hexadecimal}{0123456789ABCDEFabcdef}
+\pgfmath@tokens@make{octal}{01234567}
+\pgfmath@tokens@make{binary}{01}
+
+\pgfmath@namedef{pgfmath@base@0x}{16}
+\pgfmath@namedef{pgfmath@base@0X}{16}
+\pgfmath@namedef{pgfmath@base@0b}{2}
+\pgfmath@namedef{pgfmath@base@0B}{2}
+
+% Determine if a register is a count or a dimension/skip register.
+\newif\ifpgfmath@dimen@
+\def\pgfmath@dimen@#1{%
+ \begingroup
+ \afterassignment\pgfmath@dimen@@%
+ #1=0.0pt\relax\pgfmath@}
+\def\pgfmath@dimen@@#1#2\pgfmath@{%
+ \endgroup
+ \ifx#1.%
+ \pgfmath@dimen@false
+ \else
+ \pgfmath@dimen@true
+ \fi}
+
+\def\pgfmath@parse@ifbgroup#1#2{%
+ \let\pgfmath@parse@bgroup@after=#1%
+ \let\pgfmath@parse@nobgroup@after=#2%
+ \futurelet\pgfmath@token@let%
+ \pgfmath@parse@@ifbgroup}
+
+\def\pgfmath@parse@@ifbgroup{%
+ \ifx\pgfmath@token@let\bgroup
+ \let\pgfmath@parse@next=\pgfmath@parse@@@ifbgroup
+ \else
+ % |\pgfmath@sptoken| defined in \file{pgfmathutil.code.tex}.
+ \ifx\pgfmath@token@let\pgfmath@sptoken
+ \let\pgfmath@parse@next=\pgfmath@parse@@@@ifbgroup
+ \else
+ \let\pgfmath@parse@next=\pgfmath@parse@nobgroup@after
+ \fi
+ \fi
+ \pgfmath@parse@next}
+
+% TT: If false, octal parsing is switched off (needed for time parsing)
+\newif\ifpgfmath@octalparsing
+\pgfmath@octalparsingtrue
+
+% I (CJ) *think* it replaces |{| and |}| by |\pgfmath@bgroup| and
+% |\pgfmath@egroup|?
+\def\pgfmath@parse@@@ifbgroup#1{%
+ \pgfmath@parse@bgroup@after\pgfmath@bgroup#1\pgfmath@egroup}
+
+{
+\def\:{\pgfmath@parse@@@@ifbgroup}
+\expandafter\gdef\: {\futurelet\pgfmath@token@let\pgfmath@parse@@ifbgroup}
+}
+
+% Parse an operand.
+\def\pgfmath@parse@operand{%
+ \expandafter\pgfmath@parse@@operand\pgfmath@token@next}
+
+% This is the entry point for the parser. It is called at the end of
+% |\pgfmathparse@| with the following syntax
+% |\expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped
+% @@@@\pgfmath@parse@stop|.
+% Note: we are inside a group.
+\def\pgfmath@parse@@operand{%
+ \pgfmath@parse@ifbgroup{\pgfmath@parse@@operand}{\pgfmath@parse@@operand@}}
+
+% An operand is
+% * |+| (unary plus),
+% * |-| (unary minus),
+% * a prefix operator
+\def\pgfmath@parse@@operand@#1{%
+ \def\pgfmath@token{#1}%
+ \ifx\pgfmath@token\pgfmath@char@plus
+ % Unary (prefix) plus
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand%
+ \else
+ \ifx\pgfmath@token\pgfmath@char@minus
+ % Unary (prefix) minus
+ \pgfmath@stack@push@operation{neg}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand
+ \else
+ % See |\pgfmathdeclareoperator| (below). Note that |+| and |-|
+ % that are also declared as operators have been tested before so
+ % they should never be parsed as binary (infix) operator at this stage.
+ \expandafter\ifx\csname pgfmath@operation@\expandafter\string\pgfmath@token @prefix\endcsname\pgfmath@token
+ \let\pgfmath@parse@next=\pgfmath@parse@prefix@operator
+ \else
+ \ifpgfmath@quickparse
+ \let\pgfmath@parse@next=\pgfmath@qparse@operand
+ \else
+ \let\pgfmath@number=\pgfmath@empty
+ \expandafter\ifx\csname pgfmath@token@functional@\string#1\endcsname\relax%
+ \let\pgfmath@base=\pgfmath@empty%
+ \let\pgfmath@token@next=\pgfmath@token%
+ \if#10% Check for octal prefix.
+ \ifpgfmath@octalparsing%
+ \def\pgfmath@base{8}%
+ \fi%
+ \fi%
+ \let\pgfmath@parse@next=\pgfmath@parse@number%
+ \else%
+ \let\pgfmath@function=\pgfmath@token%
+ \let\pgfmath@parse@next=\pgfmath@parse@function%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgfmath@parse@next%
+}
+
+% Parse prefix operators.
+%
+\def\pgfmath@parse@prefix@operator{%
+ \ifx\pgfmath@token\pgfmath@char@quote% Quote character.
+ \let\pgfmath@parse@next=\pgfmath@parse@operand@quote%
+ \else%
+ \ifx\pgfmath@token\pgfmath@char@exclamation% Prefix !.
+ \pgfmath@stack@push@operation{not}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand%
+ \else% Anything else, just push and hope.
+ \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@token}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand%
+ \fi%
+ \fi%
+ \pgfmath@parse@next%
+}%
+
+
+% Quote part of an expression.
+%
+\def\pgfmath@parse@operand@quote#1"{%
+ \def\pgfmathresult{#1}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \pgfmath@parse@@operator%
+}
+
+% Quick operand parsing. Should always have units.
+% No functions, base conversion, quoting or scientific notation
+% are permitted.
+\def\pgfmath@qparse@operand{%
+ \afterassignment\pgfmath@qparse@@operand%
+ \pgfmath@dimen\pgfmath@token}
+\def\pgfmath@qparse@@operand{%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \pgfmath@parse@@operator%
+}
+
+% Parse a number, which can take the form:
+%
+% 1. An integer, or a decimal, with or without units.
+% 2. A dimension/skip or a count register.
+% 3. A dimension register preceded by a number or count register.
+% 4. A box dimension (e.g., \wd\mybox).
+% 5. A box dimension preceded by a number or a count register.
+% 6. Scientific notation (e.g., 1.234567e-10).
+% 7. A binary, hexadecimal, or octal number.
+%
+\def\pgfmath@parse@number{\pgfmath@parse@ifbgroup{\pgfmath@parse@number}{\pgfmath@parse@number@}}
+\def\pgfmath@parse@number@#1{%
+ \let\pgfmath@token=\pgfmath@token@next%
+ \def\pgfmath@token@next{#1}%
+ \pgfmath@parse@@number}
+
+\def\pgfmath@parse@@number{%
+ \ifx\pgfmath@token\pgfmath@egroup@token%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmath@number}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@@operator%
+ \else%
+ \expandafter\ifcat\pgfmath@token\relax% A CS?
+ \expandafter\ifx\csname pgfmath@token@dimexpr@\expandafter\string\pgfmath@token\endcsname\relax%
+ \expandafter\ifx\pgfmath@token\numexpr%
+ \let\pgfmath@parse@next=\pgfmath@parse@numexpr%
+ \else%
+ \expandafter\ifx\pgfmath@token\muexpr%
+ \let\pgfmath@parse@next=\pgfmath@parse@muexpr%
+ \else%
+ \expandafter\ifx\csname pgfmath@token@box@\expandafter\string\pgfmath@token\endcsname\relax%
+ % So, is the CS is a dimension or a count register?
+ \expandafter\pgfmath@dimen@\pgfmath@token%
+ \ifpgfmath@dimen@% A dimension register.
+ \global\pgfmathunitsdeclaredtrue%
+ \pgfmath@dimen=\pgfmath@number\pgfmath@token%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@operator%
+ \else% A count register.
+ \pgfmath@count=\pgfmath@token%
+ \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}%
+ \expandafter\ifcat\pgfmath@token@next\relax%
+ % A CS following a count register should be \wd, \ht or \dp.
+ \let\pgfmath@parse@next=\pgfmath@parse@number%
+ \else%
+ \let\pgfmathresult=\pgfmath@number%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@operator%
+ \fi%
+ \fi%
+ \else%
+ % This should be a box specification, for example, 0.5\wd\mybox.
+ \global\pgfmathunitsdeclaredtrue%
+ \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operator%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \global\pgfmathunitsdeclaredtrue%
+ \let\pgfmath@parse@next=\pgfmath@parse@dimexpr%
+ \fi%
+ \else%
+ \expandafter\ifx\csname pgfmath@token@numeric@\expandafter\string\pgfmath@token\endcsname\relax%
+ % It isn't numeric (i.e., 012345679.), so it might be units...
+ % first double-character units...
+ \expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
+ % then single-character units...
+ \expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\endcsname\relax%
+ % ...or the exponent characters...
+ \expandafter\ifx\csname pgfmath@token@exponent@\pgfmath@token\endcsname\relax%
+ % ...or a base prefix...
+ \expandafter\ifx\csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname\relax%
+ % ...or a math unit...
+ \expandafter\ifx\csname pgfmath@token@mathunit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
+ % ...none of the above...
+ \ifx\pgfmath@base\pgfmath@empty%
+ \let\pgfmathresult=\pgfmath@number%
+ \else%
+ \ifx\pgfmath@number\pgfmath@char@zero%
+ \let\pgfmathresult=\pgfmath@number%
+ \else%
+ % Convert from octal.
+ \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{8}{10}%
+ \fi%
+ \fi%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@@operator%
+ \else%
+ % ...here, it is a math unit (mu). Treat it as a pt.
+ \global\pgfmathunitsdeclaredtrue%
+ \global\pgfmathmathunitsdeclaredtrue%
+ \pgfmath@dimen=\pgfmath@number pt\relax%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operator%
+ \fi%
+ \else%
+ % ...here, it is a base prefix 0x, 0X, 0b or 0B
+ \expandafter\let\expandafter\pgfmath@base\expandafter=%
+ \csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname%
+ \let\pgfmath@parse@next=\pgfmath@parse@base%
+ \fi%
+ \else% ... and here, it is the exponent characters.
+ \let\pgfmath@parse@next=\pgfmath@parse@exponent%
+ \fi%
+ \else% ...but here it is single-character units.
+ \global\pgfmathunitsdeclaredtrue%
+ \pgfmath@dimen=\pgfmath@number\pgfmath@token\relax%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operator%
+ \fi%
+ \else% ...but here it is double-character units.
+ \global\pgfmathunitsdeclaredtrue%
+ \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operator%
+ \fi%
+ \else% It is numeric.
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfmath@number%
+ \expandafter\expandafter\expandafter{\expandafter\pgfmath@number\pgfmath@token}%
+ \ifx\pgfmath@token\pgfmath@char@period%
+ \let\pgfmath@base=\pgfmath@empty%
+ \fi%
+ \let\pgfmath@parse@next=\pgfmath@parse@number%
+ \fi%
+ \fi%
+ \fi%
+ \pgfmath@parse@next%
+}
+
+
+% Parse a \dimexpr
+\def\pgfmath@parse@dimexpr{%
+ \afterassignment\pgfmath@parse@dimexpr@%
+ \expandafter\expandafter\expandafter\pgfmath@dimen\expandafter\pgfmath@token\pgfmath@token@next%
+}
+\def\pgfmath@parse@dimexpr@{%
+ \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \pgfmath@parse@@operator%
+}
+
+
+% Parse a \muexpr
+\def\pgfmath@parse@muexpr{%
+ \begingroup%
+ \afterassignment\pgfmath@parse@muexpr@%
+ \expandafter\expandafter\expandafter\muskip\expandafter\expandafter\expandafter0\expandafter\pgfmath@token\expandafter\pgfmath@token@next%
+}
+\def\pgfmath@parse@muexpr@{%
+ \expandafter\endgroup%
+ \expandafter\edef\expandafter\pgfmathresult\expandafter{\expandafter\pgfMATH@STRIPMU\the\muskip0}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \pgfmath@parse@@operator%
+}
+
+{
+\catcode`\m=12
+\catcode`\u=12
+\gdef\pgfMATH@STRIPMU#1mu{#1}
+}
+
+
+% Parse a \numexpr
+\def\pgfmath@parse@numexpr{%
+ \afterassignment\pgfmath@parse@numexpr@%
+ \expandafter\expandafter\expandafter\pgfmath@count\expandafter\pgfmath@token\pgfmath@token@next%
+}
+\def\pgfmath@parse@numexpr@#1{%
+ \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}%
+ \def\pgfmath@token@next{#1}%
+ \expandafter\ifcat\pgfmath@token@next\relax%
+ % A CS following a count register should be \wd, \ht or \dp.
+ \let\pgfmath@parse@next=\pgfmath@parse@number%
+ \else%
+ \let\pgfmathresult=\pgfmath@number%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@operator%
+ \fi%
+ \pgfmath@parse@next%
+}
+
+
+% Parse the exponent of a number.
+%
+% REMARK: this method will be overwritten by the FPU library. Please
+% keep changes consistent...
+\def\pgfmath@parse@exponent{%
+ \afterassignment\pgfmath@parse@@exponent%
+ \pgfmath@count\pgfmath@token@next}
+\def\pgfmath@parse@@exponent{%
+ \pgfmathscientific{\pgfmath@number}{\the\pgfmath@count}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \pgfmath@parse@@operator%
+}
+
+% Parse binary or hexadecimal numbers (octal numbers done elsewhere).
+%
+\def\pgfmath@parse@base{%
+ \ifnum\pgfmath@base=2\relax%
+ \let\pgfmath@parse@next=\pgfmath@parse@binary%
+ \else%
+ \ifnum\pgfmath@base=16\relax%
+ \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal%
+ \else%
+ \pgfmath@error{Unexpected numerical base `\pgfmath@base'}{}%
+ \def\pgfmathresult{0}%
+ \let\pgfmath@parse@next=\pgfmath@parse@end%
+ \fi%
+ \fi%
+ \let\pgfmath@number=\pgfmath@empty%
+ \expandafter\pgfmath@parse@next\pgfmath@token@next%
+}
+
+\def\pgfmath@parse@binary#1{%
+ \expandafter\ifx\csname pgfmath@token@binary@#1\endcsname\relax%
+ \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{2}{10}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \def\pgfmath@token@next{#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@operator%
+ \else%
+ \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@binary%
+ \fi%
+ \pgfmath@parse@next%
+}
+
+\def\pgfmath@parse@hexadecimal#1{%
+ \expandafter\ifx\csname pgfmath@token@hexadecimal@#1\endcsname\relax%
+ \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{16}{10}%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \def\pgfmath@token@next{#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@operator%
+ \else%
+ \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal%
+ \fi%
+ \pgfmath@parse@next%
+}
+
+% Parse a function.
+%
+\def\pgfmath@parse@function{\pgfmath@parse@ifbgroup{\pgfmath@parse@function}{\pgfmath@parse@@function}}
+\def\pgfmath@parse@function@{\futurelet\pgfmath@token@let\pgfmath@parse@@function}
+\def\pgfmath@parse@@function{%
+ \ifx\pgfmath@token@let\pgfmath@sptoken%
+ \let\pgfmath@token=\pgfmath@empty%
+ \let\pgfmath@parse@next=\pgfmath@parse@@@@function%
+ \else%
+ \let\pgfmath@parse@next=\pgfmath@parse@@@function%
+ \fi%
+ \pgfmath@parse@next}
+
+\def\pgfmath@parse@@@function#1{%
+ \expandafter\ifx\csname pgfmath@token@functional@\expandafter\string#1\endcsname\relax%
+ \expandafter\ifx\csname pgfmath@token@number@\expandafter\string#1\endcsname\relax%
+ \def\pgfmath@token{#1}% Not from A-Z, a-z, 0-9, or _.
+ \let\pgfmath@parse@next=\pgfmath@parse@@@@function%
+ \else% It is from 0-9.
+ \expandafter\def\expandafter\pgfmath@function\expandafter{\pgfmath@function#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@function@%
+ \fi%
+ \else% It is from A-Z, a-z, or _.
+ \edef\pgfmath@function{\pgfmath@function#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@function@%
+ \fi%
+ \pgfmath@parse@next}
+
+\def\pgfmath@parse@@@@function{%
+ \expandafter\ifx\csname pgfmath@function@\pgfmath@function\endcsname\relax%
+ \pgfmath@error{Unknown function `\pgfmath@function'}{}%
+ \def\pgfmathresult{0}%
+ \let\pgfmath@parse@next=\pgfmath@parse@end%
+ \else%
+ \expandafter\ifnum\csname pgfmath@operation@\pgfmath@function @arity\endcsname=0\relax%
+ % Functions with zero arity are called directly.
+ \csname pgfmath\pgfmath@function @\endcsname%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operator%
+ \else% Otherwise, they are pushed onto the operator stack
+ \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@function}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand%
+ \fi%
+ \fi%
+ \expandafter\pgfmath@parse@next\pgfmath@token}
+
+% Parse an operator.
+%
+\def\pgfmath@parse@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@operator}{\pgfmath@parse@operator@}}%
+\def\pgfmath@parse@operator@#1{% Get one token.
+ \let\pgfmath@token=\pgfmath@token@next%
+ \def\pgfmath@token@next{#1}%
+ \pgfmath@parse@@@operator}
+
+\def\pgfmath@parse@@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@@operator}{\pgfmath@parse@@operator@}}%
+\def\pgfmath@parse@@operator@#1{% Get first token...
+ \def\pgfmath@token{#1}%
+ \pgfmath@parse@ifbgroup{\pgfmath@parse@@operator@@}{\pgfmath@parse@@operator@@}}%
+\def\pgfmath@parse@@operator@@#1{% ...and second token.
+ \def\pgfmath@token@next{#1}%
+ \pgfmath@parse@@@operator}
+
+\def\pgfmath@parse@@@operator{%
+ \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
+ % Not a double character operator.
+ \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\endcsname\relax%
+ % Not a single character operator.
+ \pgfmath@error{Unknown operator `\pgfmath@token' or `\pgfmath@token\pgfmath@token@next'}{}%
+ \def\pgfmathresult{0}%
+ \let\pgfmath@parse@next=\pgfmath@parse@end%
+ \else%
+ \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}%
+ \ifx\pgfmath@token\pgfmath@text@@%
+ \let\pgfmath@parse@next=\pgfmath@parse@end%
+ \else%
+ \expandafter\ifx\csname pgfmath@operation@\pgfmath@token @postfix\endcsname\pgfmath@token%
+ % Postfix operators are followed by an operator.
+ \ifx\pgfmath@token@next\pgfmath@char@leftbracket% Except [.
+ \let\pgfmath@parse@next=\pgfmath@parse@operand%
+ \else%
+ \let\pgfmath@parse@next=\pgfmath@parse@operator%
+ \fi%
+ \else%
+ % Any other operator is followed by an operand.
+ \let\pgfmath@parse@next=\pgfmath@parse@operand%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ % A double character operator...
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgfmath@token\expandafter\expandafter\expandafter%
+ {\expandafter\pgfmath@token\pgfmath@token@next}%
+ \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}%
+ % ...is always followed by an operand.
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand%
+ \fi%
+ \pgfmath@parse@next%
+}
+
+
+% Process an operation.
+%
+\def\pgfmath@operation@process#1{%
+ \def\pgfmath@operator{#1}%
+ \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty%
+ \else%
+ \pgfmath@operation@@process%
+ \fi%
+ \expandafter\ifx\csname pgfmath@token@specials@#1\endcsname\relax%
+ \pgfmath@stack@push@operation{#1}%
+ \fi%
+}
+
+% Process the operation stack.
+%
+\def\pgfmath@operation@@process{%
+ \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty%
+ \let\pgfmath@parse@next=\relax%
+ \else%
+ \ifnum\csname pgfmath@operation@\pgfmath@operator @precedence\endcsname>%
+ \csname pgfmath@operation@\pgfmath@stack@operation@top @precedence\endcsname\relax%
+ % If the precedence of the scanned operator is greater than the
+ % precedence of the operator at the top of the stack, do nothing.
+ \let\pgfmath@parse@next=\relax%
+ \else%
+ \let\pgfmath@stack@operation@last=\pgfmath@stack@operation@top%
+ \expandafter\ifx\csname pgfmath@operator@\pgfmath@stack@operation@top\endcsname\relax%
+ \pgfmath@function@@@process%
+ \else%
+ \pgfmath@operator@@@process%
+ \fi%
+ \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
+ \expandafter\ifx\csname pgfmath@token@group@\pgfmath@stack@operation@last\pgfmath@operator\endcsname\relax%
+ \let\pgfmath@parse@next=\pgfmath@operation@@process%
+ \else%
+ \let\pgfmath@parse@next=\relax%
+ \fi%
+ \fi%
+ \fi%
+ \pgfmath@parse@next%
+}
+
+% Process an operator.
+%
+\def\pgfmath@operator@@@process{% Process an operator.
+ \pgfmath@stack@pop@operation\pgfmath@@operator%
+ \pgfmath@stack@pop@operand\pgfmath@operand@a%
+ \ifcase\csname pgfmath@operation@\pgfmath@@operator @arity\endcsname\relax%
+ % Zero arity operators (!).
+ \or%
+ \pgfmath@operator@@@@process{\pgfmath@operand@a}%
+ \or%
+ \pgfmath@stack@pop@operand\pgfmath@operand@b%
+ \pgfmath@operator@@@@process{\pgfmath@operand@b}{\pgfmath@operand@a}%
+ \or%
+ \pgfmath@stack@pop@operand\pgfmath@operand@b%
+ \expandafter\pgfmath@operator@@@@process\expandafter%
+ {\expandafter\pgfmath@operand@b\expandafter}\pgfmath@operand@a%
+ \else%
+ % No operators with more than tenary arity.
+ \fi%
+}
+
+\def\pgfmath@operator@@@@process{%
+ \csname pgfmath%
+ \csname pgfmath@operation@\pgfmath@@operator @name\endcsname%
+ @\endcsname}
+
+% Process a function.
+%
+\def\pgfmath@function@@@process{% Process a function.
+ \ifnum\csname pgfmath@operation@\pgfmath@stack@operation@top @arity\endcsname>0\relax%
+ \pgfmath@stack@pop@operation\pgfmath@@function%
+ \pgfmath@stack@pop@operand\pgfmath@@operand%
+ \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>1\relax%
+ \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>9\relax%
+ \csname pgfmath\pgfmath@@function @\endcsname{\pgfmath@@operand}%
+ \else%
+ \expandafter\pgfmath@function@@@@process\pgfmath@@operand%
+ \fi
+ \else%
+ \expandafter\pgfmath@function@@@@process\expandafter{\pgfmath@@operand}%
+ \fi%
+ \fi%
+}
+
+\def\pgfmath@function@@@@process{\csname pgfmath\pgfmath@@function @\endcsname}
+
+% Stack.
+%
+\newtoks\pgfmath@stack@operand
+\newtoks\pgfmath@stack@operation
+\let\pgfmath@stack@empty=\pgfmath@empty
+
+\def\pgfmath@stack@push#1#2{%
+ \def\pgfmath@stack@top{#2}%
+ \expandafter\expandafter\expandafter#1%
+ \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter%
+ {\expandafter\pgfmath@stack@top\expandafter}\the#1}}%
+
+\def\pgfmath@stack@pop#1#2{\expandafter\pgfmath@stack@@pop\the#1\pgfmath@stack@stop{#1}{#2}}
+\def\pgfmath@stack@@pop#1#2#3\pgfmath@stack@stop#4#5{\def#5{#1}#4={{#2}#3}\def\pgfmath@stack@top{#2}}
+
+\def\pgfmath@stack@push@operation#1{%
+ \pgfmath@stack@push\pgfmath@stack@operation{#1}%
+ \let\pgfmath@stack@operation@top=\pgfmath@stack@top}
+
+\def\pgfmath@stack@pop@operation#1{%
+ \pgfmath@stack@pop\pgfmath@stack@operation{#1}%
+ \let\pgfmath@stack@operation@top=\pgfmath@stack@top}
+
+% REMARK: This method will be overwritten by the FPU library. Please
+% keep any changes consistent.
+\def\pgfmath@stack@push@operand#1{%
+ \pgfmath@stack@push\pgfmath@stack@operand{#1}%
+ \let\pgfmath@stack@operand@top=\pgfmath@stack@top}
+
+\def\pgfmath@stack@pop@operand#1{%
+ \pgfmath@stack@pop\pgfmath@stack@operand{#1}%
+ \let\pgfmath@stack@operand@top=\pgfmath@stack@top}
+
+
+% Declare an operator for the parser.
+%
+% It is not recommended that new operators be created as
+% the parser is not fully robust for arbitrary operators.
+%
+\def\pgfmathdeclareoperator#1#2#3#4#5{%
+ \ifx\pgfmath@operatorlist\pgfutil@empty
+ \edef\pgfmath@operatorlist{{\string#1}}%
+ \else
+ \edef\pgfmath@operatorlist{\pgfmath@operatorlist,{\string#1}}%
+ \fi
+ \pgfmath@namedef{pgfmath@operator@\string#1}{#1}%
+ \pgfmath@namedef{pgfmath@operation@\string#1@name}{#2}%
+ \pgfmath@namedef{pgfmath@operation@\string#1@arity}{#3}%
+ \pgfmath@namedef{pgfmath@operation@\string#1@#4}{#1}%
+ \pgfmath@namedef{pgfmath@operation@\string#1@precedence}{#5}%
+}
+
+\def\pgfmath@operatorlist{}
+
+\pgfmathdeclareoperator{+}{add} {2}{infix}{500}
+\pgfmathdeclareoperator{-}{subtract}{2}{infix}{500}
+\pgfmathdeclareoperator{*}{multiply}{2}{infix}{700}
+\pgfmathdeclareoperator{/}{divide} {2}{infix}{700}
+\pgfmathdeclareoperator{^}{pow} {2}{infix}{900}
+
+\pgfmathdeclareoperator{<} {} {1}{prefix} {1}
+
+\pgfmathdeclareoperator{>} {greater} {2}{infix} {250}
+\pgfmathdeclareoperator{<} {less} {2}{infix} {250}
+\pgfmathdeclareoperator{==}{equal} {2}{infix} {250}
+\pgfmathdeclareoperator{>=}{notless} {2}{infix} {250}
+\pgfmathdeclareoperator{<=}{notgreater}{2}{infix} {250}
+\pgfmathdeclareoperator{&&}{and} {2}{infix} {200}
+\pgfmathdeclareoperator{||}{or} {2}{infix} {200}
+\pgfmathdeclareoperator{!=}{notequal} {2}{infix} {250}
+\pgfmathdeclareoperator{!} {not} {1}{prefix}{975}
+\pgfmathdeclareoperator{?} {ifthenelse}{3}{infix} {100}
+\pgfmathdeclareoperator{:} {@@collect} {2}{infix}{101}
+
+\pgfmathdeclareoperator{!}{factorial}{1}{postfix}{800}% Must be defined after prefix ! operator.
+\pgfmathdeclareoperator{r}{deg} {1}{postfix}{600}
+
+\pgfmathdeclareoperator{,}{@collect} {2}{infix} {10}
+\pgfmathdeclareoperator{[}{@startindex}{2}{prefix} {7}
+\pgfmathdeclareoperator{]}{@endindex} {0}{postfix}{6}
+\pgfmathdeclareoperator{(}{@startgroup}{1}{prefix} {5}
+\pgfmathdeclareoperator{)}{@endgroup} {0}{postfix}{4}
+
+\pgfmathdeclareoperator{\pgfmath@bgroup}{@startarray}{1}{prefix} {3}
+\pgfmathdeclareoperator{\pgfmath@egroup}{@endarray} {1}{postfix}{2}%
+
+% Special operators.
+\pgfmathdeclareoperator{"}{}{1}{prefix}{1}
+\pgfmathdeclareoperator{@}{}{0}{postfix}{0}
+
+% Internal functions.
+
+% Begin and end parenthesis ().
+%
+\def\pgfmath@startgroup@#1{\pgfmath@protected@edef\pgfmathresult{#1}}
+\def\pgfmath@endgroup@{}% Never actually called.
+
+% Begin and end array access [].
+%
+\def\pgfmath@startindex@#1#2{%
+ \expandafter\pgfmatharray@#1{#2}%
+ \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmathresult}%
+ \ifx\pgfmath@token@let\bgroup%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmathresult}}%
+ \fi}
+\def\pgfmath@endindex@{}% Never actually called.
+
+% Begin and end array {}.
+%
+\def\pgfmath@startarray@#1{\expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{#1}}}
+\def\pgfmath@endarray@#1{\expandafter\def\expandafter\pgfmathresult\expandafter{#1}}% Never actually called.
+
+
+\def\pgfmath@@collect@#1#2{%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgfmathresult\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter%
+ {\expandafter#1\expandafter}\expandafter{#2}}%
+}
+% Collect items separated by ,.
+%
+\def\pgfmath@collect@#1#2{%
+ \expandafter\def\expandafter\pgfmath@collect@original\expandafter{#1}%
+ \expandafter\pgfmath@bgroup@strip\expandafter{#1}%
+ \ifx\pgfmath@token@let\bgroup%
+ \ifx\pgfmath@collect@original\pgfmath@bgroup@stripped%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}%
+ \else%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}%
+ \fi%
+ \else%
+ \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}%
+ \fi%
+ \expandafter\pgfmath@bgroup@strip\expandafter{#2}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgfmathresult\expandafter\expandafter\expandafter%
+ {\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}}%
+}
+
+% Strip braces from a token sequence.
+%
+\def\pgfmath@bgroup@strip#1{%
+ \def\pgfmath@bgroup@strip@last{#1}%
+ \pgfmath@bgroup@@strip{#1}\pgfmath@\pgfmath@@\pgfmath@@@}
+
+\def\pgfmath@bgroup@strip@#1{%
+ \def\pgfmath@bgroup@strip@last{#1}%
+ \pgfmath@bgroup@@strip#1\pgfmath@\pgfmath@@\pgfmath@@@}
+
+\def\pgfmath@bgroup@pgfmath@{\pgfmath@}
+
+\def\pgfmath@bgroup@@strip{%
+ \futurelet\pgfmath@token@let\pgfmath@bgroup@@@strip}
+
+\def\pgfmath@bgroup@@@strip#1#2#3\pgfmath@@@{%
+ \ifx\pgfmath@token@let\bgroup
+ \def\pgfmath@bgroup@test{#2}%
+ \ifx\pgfmath@bgroup@test\pgfmath@bgroup@pgfmath@
+ \def\pgfmath@next{\pgfmath@bgroup@strip@{#1}}%
+ \else
+ \let\pgfmath@bgroup@stripped=\pgfmath@bgroup@strip@last
+ \let\pgfmath@next=\relax
+ \fi
+ \else
+ \pgfmath@bgroup@@@@strip#1#2#3%
+ \let\pgfmath@next=\relax
+ \fi
+ \pgfmath@next}
+
+\def\pgfmath@bgroup@@@@strip#1\pgfmath@\pgfmath@@{%
+ \def\pgfmath@bgroup@stripped{#1}}
+
+% Local Variables:
+% tab-width: 2
+% End:
diff --git a/graphics/pgf/base/tex/generic/math/pgfmathutil.code.tex b/graphics/pgf/base/tex/generic/math/pgfmathutil.code.tex
new file mode 100644
index 0000000000..d8d67dd841
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/math/pgfmathutil.code.tex
@@ -0,0 +1,298 @@
+% Copyright 2019 Mark Wibrow
+%
+% but subject to the LaTeX Project Public License
+% (http://www.latex-project.org/lppl.txt)
+%
+% and the GNU Public License
+% (http://www.gnu.org/licenses/gpl.txt)
+%
+
+% This file defines utilities common to the \pgfmath files.
+%
+% Version 1.414213 29/9/2007
+
+\def\pgfmathincluded{}
+
+% Helper macros for \pgfmath@ifregister
+%
+\def\pgfmath@grabv#1#2#3#4#5#6#7\pgfmath@grabv{#2#3#4#5\ifx#6!!\fi}
+\def\pgfmath@ifskip@extract#1{\expandafter\pgfmath@grabv\meaning#1!!!!!!\pgfmath@grabv}
+\def\pgfmath@iftoks@extract#1{\expandafter\pgfmath@grabv\meaning#1!!!!!!\pgfmath@grabv}
+
+\def\pgfmath@grabvi#1#2#3#4#5#6#7#8\pgfmath@grabvi{#2#3#4#5#6\ifx#7!!\fi}
+\def\pgfmath@ifdimen@extract#1{\expandafter\pgfmath@grabvi\meaning#1!!!!!!\pgfmath@grabvi}
+\def\pgfmath@ifcount@extract#1{\expandafter\pgfmath@grabvi\meaning#1!!!!!!\pgfmath@grabvi}
+
+\def\pgfmath@grabvii#1#2#3#4#5#6#7#8#9\pgfmath@grabvii{#2#3#4#5#6#7\ifx#8!!\fi}
+\def\pgfmath@ifmuskip@extract#1{\expandafter\pgfmath@grabvii\meaning#1!!!!!!\pgfmath@grabvii}
+
+% \pgfmath@ifdimen@unguarded
+%
+% Check if #2 is a register of type #1.
+% Credits to Frank: https://tex.stackexchange.com/a/56905
+%
+% #1 register type (count, dimen, skip, muskip, toks)
+% #2 single token
+%
+\def\pgfmath@ifregister@unguarded#1#2{%
+ \expandafter\ifx\csname\csname pgfmath@if#1@extract\endcsname{#2}\expandafter\endcsname\csname #1\endcsname
+ \expandafter\pgfutil@firstoftwo
+ \else
+ \expandafter\pgfutil@secondoftwo
+ \fi}
+
+% \pgfmath@ifregister
+%
+% Checks if a token is a a certain type of register
+%
+% #1 register type (count, dimen, skip, muskip, toks)
+% #2 single token
+%
+\def\pgfmath@ifregister#1#2{%
+ \pgfutil@IfUndefined{pgfmath@if#1@extract}%
+ {\errmessage{Package PGF Math Error: Cannot test for #1 register}}%
+ {\pgfutil@IfUndefined{\csname pgfmath@if#1@extract\endcsname{#2}}%
+ {\pgfutil@secondoftwo}}%
+ {\pgfmath@ifregister@unguarded{#1}{#2}}}
+
+% \pgfmath@ensureregister
+%
+% Ensure a control sequence exists as a TeX count/dimen register.
+%
+% #1 - count or dimen.
+% #2 - a control sequence.
+%
+\def\pgfmath@ensureregister#1#2{%
+ \pgfmath@ifregister{#1}{#2}%
+ {}%
+ {\csname new#1\endcsname#2}%
+}
+
+% Check registers exist. If not, create them.
+%
+\pgfmath@ensureregister{dimen}{\pgf@x}
+\pgfmath@ensureregister{dimen}{\pgf@xa}
+\pgfmath@ensureregister{dimen}{\pgf@xb}
+\pgfmath@ensureregister{dimen}{\pgf@xc}
+
+\pgfmath@ensureregister{dimen}{\pgf@y}
+\pgfmath@ensureregister{dimen}{\pgf@ya}
+\pgfmath@ensureregister{dimen}{\pgf@yb}
+\pgfmath@ensureregister{dimen}{\pgf@yc}
+
+\pgfmath@ensureregister{dimen}{\pgfutil@tempdima}
+\pgfmath@ensureregister{dimen}{\pgfutil@tempdimb}
+
+\pgfmath@ensureregister{count}{\c@pgf@counta}
+\pgfmath@ensureregister{count}{\c@pgf@countb}
+\pgfmath@ensureregister{count}{\c@pgf@countc}
+\pgfmath@ensureregister{count}{\c@pgf@countd}
+
+\pgfmath@ensureregister{count}{\pgfutil@tempcnta}
+\pgfmath@ensureregister{count}{\pgfutil@tempcntb}
+
+% Alias for \pgfmath.
+%
+\let\pgfmath@x\pgf@x
+\let\pgfmath@xa\pgf@xa
+\let\pgfmath@xb\pgf@xb
+\let\pgfmath@xc\pgf@xc
+
+\let\pgfmath@y\pgf@y
+\let\pgfmath@ya\pgf@ya
+\let\pgfmath@yb\pgf@yb
+\let\pgfmath@yc\pgf@yc
+
+\let\pgfmath@tempdima\pgfutil@tempdima
+\let\pgfmath@tempdimb\pgfutil@tempdimb
+
+\let\c@pgfmath@counta\c@pgf@counta
+\let\c@pgfmath@countb\c@pgf@countb
+\let\c@pgfmath@countc\c@pgf@countc
+\let\c@pgfmath@countd\c@pgf@countd
+
+\let\pgfmath@tempcnta\pgfutil@tempcnta
+\let\pgfmath@tempcntb\pgfutil@tempcntb
+
+% Now check if pgfutil and pgf@sys stuff exists. If it does, fine.
+% Just \let pgfmath versions. If not, define pgfmath versions (Arghhh).
+%
+
+% \...ifnextchar
+%
+\ifx\pgfutil@ifnextchar\pgfmath@undefined%
+ \long\def\pgfmath@ifnextchar#1#2#3{%
+ \let\pgfmath@reserved@d#1%
+ \def\pgfmath@reserved@a{#2}%
+ \def\pgfmath@reserved@b{#3}%
+ \futurelet\pgfmath@let@token\pgfmath@ifnch}
+ \def\pgfmath@ifnch{%
+ \ifx\pgfmath@let@token\pgfmath@sptoken%
+ \let\pgfmath@reserved@c\pgfmath@xifnch%
+ \else%
+ \ifx\pgfmath@let@token\pgfmath@reserved@d%
+ \let\pgfmath@reserved@c\pgfmath@reserved@a%
+ \else%
+ \let\pgfmath@reserved@c\pgfmath@reserved@b%
+ \fi%
+ \fi%
+ \pgfmath@reserved@c}
+ {%
+ \def\:{\global\let\pgfmath@sptoken= } \:
+ \def\:{\pgfmath@xifnch} \expandafter\gdef\: {\futurelet\pgfmath@let@token\pgfmath@ifnch}
+ }%
+\else%
+ \let\pgfmath@ifnextchar\pgfutil@ifnextchar%
+ % Still need to define \pgfmath@sptoken (cannot \let).
+ {%
+ \def\:{\global\let\pgfmath@sptoken= } \:
+ }%
+\fi%
+
+% \...ifundefined
+%
+\ifx\pgfutil@ifundefined\pgfmath@undefined%
+ \long\def\pgfmath@ifundefined#1{%
+ \expandafter\ifx\csname#1\endcsname\relax%
+ \expandafter\pgfmath@firstoftwo%
+ \else%
+ \expandafter\pgfmath@secondoftwo%
+ \fi}%
+\else%
+ \let\pgfmath@ifundefined\pgfutil@ifundefined%
+\fi%
+
+% \...selectfont
+%
+\ifx\pgfutil@selectfont\pgfmath@undefined%
+ \ifx\selectfont\pgfmath@undefined%
+ \let\pgfmath@selectfont\rm% Plain TeX and ConTeXt.
+ \else%
+ \let\pgfmath@selectfont\selectfont% LaTeX.
+ \fi%
+\else%
+ \let\pgfmath@selectfont\pgfutil@selectfont%
+\fi%
+
+% New definition easier than fussing around with let.
+%
+\newif\ifpgfmath@in@
+\def\pgfmath@in@#1#2{%
+ \def\pgfmath@in@@##1#1##2##3\pgfmath@in@@{%
+ \ifx\pgfmath@in@##2\pgfmath@in@false\else\pgfmath@in@true\fi}%
+ \pgfmath@in@@#2#1\pgfmath@in@\pgfmath@in@@}
+
+
+% \...tonumber
+%
+\ifx\pgf@sys@tonumber\pgfmath@undefined%
+ {\catcode`\p=12\catcode`\t=12\gdef\Pgf@geT#1pt{#1}}
+ \def\pgfmath@tonumber#1{\expandafter\Pgf@geT\the#1}
+\else%
+ \let\pgfmath@tonumber\pgf@sys@tonumber%
+\fi%
+
+
+% \PackageWarning and \PackageError
+%
+\ifx\PackageWarning\pgfmath@undefined
+ \def\pgfmath@PackageWarning#1#2{\immediate\write-1{Package #1: Warning! #2.}}%
+\else%
+ \let\pgfmath@PackageWarning\PackageWarning%
+\fi%
+\ifx\PackageError\pgfmath@undefined
+ \def\pgfmath@PackageError#1#2#3{\errmessage{Package #1 Error: #2.}}%
+\else%
+ \let\pgfmath@PackageError\PackageError%
+\fi%
+
+\def\pgfmath@error#1#2{%
+ \pgfmath@PackageError{PGF Math}{%
+ #1%
+ \pgfutil@ifundefined{pgfmath@expression}{}{ (in '\pgfmath@expression')}%
+ }{#2}%
+}
+\def\pgfmath@warning#1{%
+ \pgfmath@PackageWarning{PGF Math}{%
+ #1%
+ \pgfutil@ifundefined{pgfmath@expression}{}{ (in '\pgfmath@expression')}%
+ }%
+}
+
+% \pgfmath@pt
+%
+% Needed to test for 'pt' resulting from expansion using \the.
+%
+{\catcode`\p=12\catcode`\t=12\gdef\PgfmaTh@PT{pt}}
+\edef\pgfmath@pt{\PgfmaTh@PT}%
+
+% \pgfmath@empty
+%
+% A handy macro.
+%
+\def\pgfmath@empty{}
+
+\def\pgfmath@firstoftwo#1#2{#1}
+\def\pgfmath@secondoftwo#1#2{#2}
+
+% \pgfmath@gobbletilpgfmath@
+%
+% Gobble stream until \pgfmath@ {which is undefined}.
+%
+\def\pgfmath@gobbletilpgfmath@#1\pgfmath@{}
+\def\pgfmath@gobbleone#1{}%
+
+
+\def\pgfmath@namedef#1{\expandafter\def\csname#1\endcsname}
+\def\pgfmath@nameedef#1{\expandafter\edef\csname#1\endcsname}
+
+% \pgfmathloop
+%
+% A version of the standard TeX and LaTeX
+% \loop, with an additional macro \pgfmathcounter
+% (which is *not* a TeX counter) which keeps
+% track of the iterations.
+%
+\newif\ifpgfmathcontinueloop
+\def\pgfmathloop#1\repeatpgfmathloop{%
+ \def\pgfmathcounter{1}%
+ \def\pgfmath@iterate{%
+ #1\relax%
+ {% Do this inside a group, just in case...
+ \c@pgfmath@counta\pgfmathcounter%
+ \advance\c@pgfmath@counta1\relax%
+ \xdef\pgfmathloop@temp{\the\c@pgfmath@counta}%
+ }%
+ \edef\pgfmathcounter{\pgfmathloop@temp}%
+ \expandafter\pgfmath@iterate\fi}%
+ \pgfmath@iterate\let\pgfmath@iterate\relax}
+\let\repeatpgfmathloop\fi
+\def\pgfmathbreakloop{\let\pgfmath@iterate\relax}%
+
+% \pgfmath@returnone
+%
+% #1 - a dimension representing a number or dimension.
+%
+% Changed by TT: made faster and simpler since it is used
+% *heavily*. #1 must be something that can be assigned to a
+% dimension.
+%
+\def\pgfmath@returnone#1\endgroup{%
+ \pgfmath@x#1%
+ \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@x}}%
+ \expandafter\endgroup\expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmath@temp}%
+}
+
+\let\pgfmathreturn=\pgfmath@returnone
+
+% \pgfmath@smuggleone
+%
+% Smuggle a macro outside a group.
+%
+% Changed by TT: Speedup by insisting, that smuggleone is directly
+% followed by \endgroup
+%
+\def\pgfmath@smuggleone#1\endgroup{%
+ \expandafter\endgroup\expandafter\def\expandafter#1\expandafter{#1}}
+
+\let\pgfmathsmuggle=\pgfmath@smuggleone
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmoduleanimations.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmoduleanimations.code.tex
new file mode 100644
index 0000000000..c0a8346811
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmoduleanimations.code.tex
@@ -0,0 +1,1314 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmoduleanimations.code.tex}
+
+
+% We need the animation system abstraction:
+
+\input pgfsysanimations.code.tex
+
+
+% Animate an attribute over time
+%
+% #1 = an attribute
+% #2 = configuration keys
+%
+% This command adds animation commands for the attribute given in #1
+% of some future object to the current graphic scope. For instance,
+% when #1 is "fill opacity" then the fill opacity of the object will
+% change over time. The object to which the command refers is
+% specified using a special key in #2.
+%
+% The keys in #2 specify how the changes occur over time. There are a
+% number of keys that have an effect on the animation "as a whole"
+% (like "repeats") while the most central key is the entry key. This
+% key takes two parameters: a time and a value. It specifies that at
+% the given time the attribute should have the specified value. The
+% times must be given in ascending order. Between the times given in
+% this way, the values of the attribute will be interpolated; you can
+% influence the details of how this interpolation is done using
+% additional keys.
+%
+% The keys in #2 are given in key-value syntax and can be given in any
+% order, except that the entry keys must be given in order of
+% ascending times.
+%
+% The syntax of the second parameter of the entry key depends on
+% #1. Currently, these are:
+%
+% Attribute Value Type
+% ---------------------------------------
+% fill opacity scalar
+% stroke opacity scalar
+% opacity scalar
+% visible boolean
+% line width dimension
+% fill color
+% stroke color
+% motion motion
+% translate point
+% scale scaling
+% rotate scalar
+% xskew scalar
+% yskew scalar
+% path path
+% softpath softpath
+% view viewbox
+% dash phase dimension
+% dash pattern dashpattern
+% none any
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{entry={0s}{1}, entry={2s}{0}}
+
+\def\pgfanimateattribute#1#2{%
+ \pgfanimateattributecode{#1}{\pgfkeys{/pgf/animation/.cd,#2}}%
+}%
+
+
+% Variant of \pgfanimateattribute
+%
+% #1 = attribute
+% #2 = code
+%
+% Description:
+%
+% A version of \pgfanimateattribute where instead of keys #2 you
+% provide a code #2 that calls the animation keys itself.
+
+\def\pgfanimateattributecode#1#2{%
+ {%
+ \pgfkeys{/pgf/@animation attributes/.cd,#1}%
+ #2%
+ \csname pgf@animation@check@\pgf@animation@attribute\endcsname%
+ \pgfsysanimate{\pgf@animation@attribute}%
+ }%
+}%
+
+
+
+% Create a time snapshot
+%
+% #1 = a time
+%
+% Description:
+%
+% This command should be called in a scope prior to all calls of
+% animation commands in that scope. When called, all animations will
+% be "intercepted" and, instead of creating the animation code, normal
+% code will be generated that shows the state of the animation at the
+% specified "moment" #1. Since no animation code is involved, this
+% works with all drivers.
+%
+% The command \pgfsnapshotafter works the same way as \pgfsnapshot,
+% only the timing is slightly different: Conceptually, #1 is
+% interpreted as "#1+epsilon". For instance, if there are two values
+% specified for the time #1, then \pgfsnapshot will use the first
+% while \pgfsnapshotafter will use the second. Likewise, when an
+% animation ends at time #1, \pgfsnapshot will still us the
+% animation's value, while \pgfsnapshotafter will not.
+%
+% Example:
+%
+% {
+% \pgfsnapshot{1.2s}
+% \pgfanimateattribute{fill opacity}{entry={0s}{1}, entry={2s}{0}}
+% \fill (0,0) rectangle (1,1);
+% }
+
+\def\pgfsnapshot#1{\pgfparsetime{#1}\expandafter\pgfsysanimsnapshot\expandafter{\pgftimeresult}}%
+\def\pgfsnapshotafter#1{\pgfparsetime{#1}\expandafter\pgfsysanimsnapshotafter\expandafter{\pgftimeresult}}%
+
+
+% The animation attributes
+
+\pgfkeys{/pgf/@animation attributes/.cd,
+ visible/.code=\pgf@animate@attr{visibility}{mapped}\def\pgf@anim@map@true{visible}\def\pgf@anim@map@false{hidden},
+ stage/.code=\pgf@animate@attr{visibility}{mapped}\def\pgf@anim@map@true{visible}\def\pgf@anim@map@false{hidden}\pgfsysanimkeybase\pgfsysanimvaltext{hidden},
+ opacity/.code=\pgf@animate@attr{opacity}{scalar},
+ fill opacity/.code=\pgf@animate@attr{fillopacity}{scalar},
+ draw opacity/.code=\pgf@animate@attr{strokeopacity}{scalar},
+ stroke opacity/.style=draw opacity,
+ line width/.code=\pgf@animate@attr{linewidth}{dimension},
+ fill/.code=\pgf@animate@attr{fillcolor}{color},
+ draw/.code=\pgf@animate@attr{strokecolor}{color},
+ color/.code=\pgf@animate@attr{color}{color},
+ stroke/.style=draw,
+ motion/.code=\pgf@animate@attr{motion}{scalar},
+ translate/.code=\pgf@animate@attr{translate}{point},
+ scale/.code=\pgf@animate@attr{scale}{scaling},
+ rotate/.code=\pgf@animate@attr{rotate}{scalar},
+ xskew/.code=\pgf@animate@attr{skewx}{scalar},
+ yskew/.code=\pgf@animate@attr{skewy}{scalar},
+ skew x/.style=xskew,
+ skew y/.style=yskew,
+ path/.code=\pgf@animate@attr{path}{path},
+ softpath/.code=\pgf@animate@attr{path}{softpath},
+ view/.code=\pgf@animate@attr{viewbox}{viewbox},
+ dash/.code=\pgf@animate@attr{dash}{dash},
+ none/.code=\pgf@animate@attr{none}{none},
+}%
+
+\def\pgf@animate@attr#1#2{%
+ \def\pgf@animation@attribute{#1}%
+ \expandafter\let\expandafter\pgfanim@type@parser\csname pgfanim@parse@type@#2\endcsname%
+}%
+
+
+
+% The time parser
+%
+% #1 = a time
+%
+% This macro parses the time in #1, but adds some support for times:
+%
+% 1) The postfix operator "s" is added, which has no effect.
+% 2) The postfix operator "ms" is added, which divides a number by
+% 1000, so "2ms" equals "0.002".
+% 3) The postfix operator "min" is added, which multiplies a number by
+% 60.
+% 4) The postfix operator "h" is added, which multiplies a number by
+% 3600.
+% 5) The infix operator ":" is redefined, so that it multiplies its
+% first argument by 60 and adds the second. This implies that
+% "1:20" equals "80" and "01:00:00" equals "3600".
+% 6) The parsing of octal numbers is switched off to allow things like
+% "01:08" for 68s.
+
+\def\pgfparsetime#1{%
+ \begingroup%
+ \pgfmathdeclareoperator{s}{@seconds}{1}{postfix}{600}%
+ \pgfmathdeclareoperator{m}{m@encountered}{1}{postfix}{600}%
+ \pgfmathdeclareoperator{i}{i@encountered}{1}{postfix}{600}%
+ \pgfmathdeclareoperator{n}{@minutes}{1}{postfix}{600}%
+ \pgfmathdeclareoperator{h}{@hours}{1}{postfix}{600}%
+ \pgfmathdeclareoperator{:}{time@colon}{2}{infix}{50}%
+ \pgfmath@octalparsingfalse%
+ \pgfmathparse{#1}%
+ \expandafter\endgroup%
+ \expandafter\def\expandafter\pgftimeresult\expandafter{\pgfmathresult}%
+}%
+
+\newif\ifpgfanim@m@encountered
+\newif\ifpgfanim@i@encountered
+\pgfmathdeclarefunction{@seconds}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \ifpgfanim@m@encountered%
+ \divide\pgfmath@x by1000\relax%
+ \fi%
+ \global\pgfanim@m@encounteredfalse%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+\pgfmathdeclarefunction{m@encountered}{1}{%
+ \global\pgfanim@m@encounteredtrue%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+\pgfmathdeclarefunction{i@encountered}{1}{%
+ \ifpgfanim@m@encountered%
+ \global\pgfanim@m@encounteredfalse%
+ \global\pgfanim@i@encounteredtrue%
+ \else%
+ \pgfmath@error{Unexpected i}{}%
+ \fi%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+\pgfmathdeclarefunction{@minutes}{1}{%
+ \ifpgfanim@i@encountered%
+ \global\pgfanim@i@encounteredfalse%
+ \else%
+ \pgfmath@error{Unexpected n}{}%
+ \fi%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@x60\pgfmath@x\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+\pgfmathdeclarefunction{@hours}{1}{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \pgfmath@x3600\pgfmath@x\relax%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+\pgfmathdeclarefunction{time@colon}{2}{%
+ \begingroup%
+ \pgfmath@x=#1pt\relax%
+ \pgfmath@x=60\pgfmath@x\relax%
+ \pgfmath@y=#2pt\relax%
+ \advance\pgfmath@x by\pgfmath@y%
+ \pgfmath@returnone\pgfmath@x%
+ \endgroup%
+}%
+
+
+
+% Sets general animation attributes
+%
+% #1 = key-value pairs that are executed for the path /pgf/animation/
+
+\def\pgfanimationset{\pgfqkeys{/pgf/animation}}%
+
+
+% Sets the target animation scope that should be animated.
+%
+% #1 = A name that will be used with an idscope.
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{whom=some scope, entry={0s}{1}, entry={1s}{0}}
+% \begin{scope}[name=some scope]
+% \draw (0,0) -- (1,1);
+% \draw (1,0) -- (2,1);
+% \end{scope}
+
+\pgfanimationset{
+ whom/.code={%
+ \pgf@anim@decomp{#1}%
+ \pgfidrefnextuse\pgf@anim@id\pgf@anim@id@name%
+ \expandafter\expandafter\expandafter\pgfsysanimkeywhom\expandafter\expandafter\expandafter{\expandafter\pgf@anim@id\expandafter}\expandafter{\pgf@anim@type}%
+ \let\pgf@anim@whom@id\pgf@anim@id%
+ \let\pgf@anim@whom@type\pgf@anim@type%
+ }
+}%
+
+\def\pgf@anim@decomp#1{%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutil@in@\expandafter.\expandafter{\pgf@temp}%
+ \ifpgfutil@in@%
+ \expandafter\pgf@anim@decomp@\pgf@temp\pgf@stop%
+ \else%
+ \expandafter\pgf@anim@decomp@\pgf@temp.\pgf@stop%
+ \fi%
+}%
+\def\pgf@anim@decomp@#1.#2\pgf@stop{%
+ \def\pgf@anim@id@name{#1}%
+ \def\pgf@anim@type{#2}%
+}%
+
+
+% Assigns a name to this animation so that it can be used as an event
+% id in another animation
+%
+% #1 = A name
+%
+% The name "previous" is special and always refers to the most recent
+% animation before the animation currently being constructed.
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{name=anim 1, entry={0s}{1}, entry={1s}{0}}
+% \pgfanimateattribute{fill opacity}{begin on={end,of=anim 1}, entry={0s}{1}, entry={1s}{0}}
+
+\pgfanimationset{
+ name/.code=\pgfuseid{#1},
+}%
+
+
+
+
+% Configures whether an animation can be restarted
+%
+% Some animations can restart when certain events take place. This key
+% configures this. Setting it to
+%
+% "true" allows a restart at any time,
+% "false" does not allow a restart,
+% "when not active" allows a restart only, when the element is not
+% active.
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{entry={0s}{1}, entry={1s}{0}, restart=false}
+
+\pgfanimationset{
+ restart/.is choice,
+ restart/.default=true,
+ restart/true/.code=\pgfsysanimkeyrestartalways,
+ restart/false/.code=\pgfsysanimkeyrestartnever,
+ restart/never/.code=\pgfsysanimkeyrestartnever,
+ restart/when not active/.code=\pgfsysanimkeyrestartwhennotactive,
+}%
+
+
+% Sets the number times an animation should repeat
+%
+% #1 = A string of the following form:
+%
+% [<empty> | <number> | for <time>] ["accumulating"]
+%
+% When empty (the default value) the animation repeats forever.
+%
+% When a <number> is provided, the animation will repeat <number>
+% times, which need not be an integer.
+%
+% When a <time> is given, the repeating will stop after this much time.
+%
+% When the optional "accumulating" is specified, the repeat
+% accumulates, otherwise each repeat begins with the original start
+% value.
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{repeats, entry={0s}{1}, entry={6s}{0}}
+% \pgfanimateattribute{fill opacity}{repeats=2, entry={0s}{1}, entry={6s}{0}}
+% \pgfanimateattribute{fill opacity}{repeats=2 accumulating, entry={0s}{1}, entry={6s}{0}}
+% \pgfanimateattribute{fill opacity}{repeats=for 15s, entry={0s}{1}, entry={6s}{0}}
+
+\pgfanimationset{
+ repeats/.code={%
+ \pgfutil@in@{accumulating\pgf@stop}{#1\pgf@stop}%
+ \ifpgfutil@in@%
+ \pgfsysanimkeyaccumulate%
+ \pgfanim@parse@acc#1\pgf@stop%
+ \else%
+ \pgfsysanimkeynoaccumulate%
+ \pgfanim@parse@noacc{#1}%
+ \fi%
+ },
+ repeats/.default=,
+ repeat/.style={repeats={#1}},
+ repeat/.default=,
+}%
+\def\pgfanim@parse@acc#1accumulating\pgf@stop{%
+ \pgfanim@parse@noacc{#1}%
+}%
+\def\pgfanim@parse@noacc#1{%
+ \pgfutil@in@{\pgf@stop for}{\pgf@stop#1}%
+ \ifpgfutil@in@%
+ \pgfanim@parse@for#1\pgf@stop%
+ \else%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \pgfsysanimkeyrepeatindefinite%
+ \else%
+ \pgfmathparse{#1}%
+ \expandafter\pgfsysanimkeyrepeat\expandafter{\pgfmathresult}%
+ \fi%
+ \fi%
+}%
+\def\pgfanim@parse@for for#1\pgf@stop{\pgfparsetime{#1}\expandafter\pgfsysanimkeyrepeatdur\expandafter{\pgftimeresult}}%
+
+
+
+
+
+% Specifies that an animation should begin or end at a certain time
+% (relative to the current context). The "begin..." options may be
+% used multiple times and their effects accumulate, likewise for the
+% "end..." options.
+%
+% #1 = A time
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{begin=2s, end=2.5s, entry={0s}{1}, entry={1s}{0}}
+
+\pgfanimationset{
+ begin/.code=\pgfparsetime{#1}\expandafter\pgfsysanimkeyoffset\expandafter{\pgftimeresult}{begin},
+ end/.code=\pgfparsetime{#1}\expandafter\pgfsysanimkeyoffset\expandafter{\pgftimeresult}{end},
+}%
+
+
+
+% Specifies that an animation should begin (or end) when a certain
+% event takes place.
+%
+% #1 = A list of key-value pairs.
+%
+% The following keys are allowed:
+%
+% event=some event : The begin / end is triggered by that event. The
+% list of allowed events is defined in the SVG
+% standard.
+% of=some name : The event does not refer to the current group,
+% but to the object named "some name", which must
+% previously have been named \pgfuseid. If some
+% name contains a period, the part before the
+% period must be the name of the id, the part
+% following it the type of the id.
+% key=some key : The trigger is some key being pressed
+% repeat=number : The trigger is that an animation has been
+% repeated number times.
+% delay=time : A delay, may be negative.
+%
+% These keys are executed with the path prefix /pgf/animation/events.
+%
+% Some of them are predefined:
+%
+% "click" is a shorthand for "event=click"
+% "focus in" is a shorthand for "event=focusin"
+% "focus out" is a shorthand for "event=focusout"
+% "activate" is a shorthand for "event=activate"
+% "mouse down" is a shorthand for "event=mousedown"
+% "mouse up" is a shorthand for "event=mouseup"
+% "mouse over" is a shorthand for "event=mouseover"
+% "mouse move" is a shorthand for "event=mousemove"
+% "mouse out" is a shorthand for "event=mouseout"
+% "begin" is a shorthand for "event=begin"
+% "end" is a shorthand for "event=end"
+%
+% Example:
+%
+% % Begin after 5s or when clicked:
+% \pgfanimateattribute{fill opacity}{begin=5s, begin on=click, entry={0s}{1}, entry={1s}{0}}
+%
+% % Begin, when an object named "button" is clicked
+% \pgfanimateattribute{fill opacity}{begin on={click, of=button}, entry={0s}{1}, entry={1s}{0}, name=another animation}
+%
+% % Begin 1s after some other animation ends
+% \pgfanimateattribute{fill opacity}{begin on={end, of=another animation, delay=1s}, entry={0s}{1}, entry={1s}{0}}
+
+\pgfanimationset{
+ begin on/.code={\pgfanim@make@event{#1}{begin}},%
+ end on/.code={\pgfanim@make@event{#1}{end}},
+}%
+
+\def\pgfanim@make@event#1#2{%
+ \let\pgfanim@event@event\pgfutil@empty%
+ \let\pgf@anim@id\pgfutil@empty%
+ \let\pgf@anim@type\pgfutil@empty%
+ \let\pgfanim@event@key\pgfutil@empty%
+ \let\pgfanim@event@repeat\pgfutil@empty%
+ \let\pgfanim@event@delay\pgfutil@empty%
+ \pgfkeys{/pgf/animation/events/.cd,#1}%
+ \ifx\pgfanim@event@key\pgfutil@empty%
+ \ifx\pgfanim@event@repeat\pgfutil@empty%
+ \ifx\pgfanim@event@event\pgfutil@empty%
+ \pgferror{No event specified}%
+ \else%
+ \pgfsysanimkeyevent{\pgf@anim@id}{\pgf@anim@type}{\pgfanim@event@event}{\pgfanim@event@delay}{#2}%
+ \fi%
+ \else%
+ \pgfsysanimkeyrepeatevent{\pgf@anim@id}{\pgf@anim@type}{\pgfanim@event@repeat}{\pgfanim@event@delay}{#2}%
+ \fi%
+ \else%
+ \pgfsysanimkeyaccesskey{\pgfanim@event@key}{\pgfanim@event@delay}{#2}%
+ \fi%
+}%
+
+\pgfkeys{/pgf/animation/events/.cd,
+ event/.store in=\pgfanim@event@event,
+ of/.code={%
+ \pgf@anim@decomp{#1}%
+ \pgfidrefprevuse\pgf@anim@id\pgf@anim@id@name%
+ \ifx\pgf@anim@id\pgfutil@empty%
+ \pgferror{Unknown object/node name '\pgf@anim@id@name'. Did you
+ mean 'of next=\pgf@anim@id@name'?}%
+ \fi%
+ },
+ of next/.code={%
+ \pgf@anim@decomp{#1}%
+ \pgfidrefnextuse\pgf@anim@id\pgf@anim@id@name%
+ },
+ of id/.code=\def\pgf@anim@id{#1},
+ key/.store in=\pgfanim@event@key,
+ repeat/.code=\pgfmathparse{#1}\let\pgfanim@event@repeat\pgfmathresult,
+ delay/.code=\pgfparsetime{#1}\let\pgfanim@event@delay\pgftimeresult,
+ click/.style={event=click},
+ focus in/.style={event=focusin},
+ focus out/.style={event=focusout},
+ mouse down/.style={event=mousedown},
+ mouse up/.style={event=mouseup},
+ mouse over/.style={event=mouseover},
+ mouse move/.style={event=mousemove},
+ mouse out/.style={event=mouseout},
+ begin/.style={event=begin},
+ end/.style={event=end},
+}%
+
+
+% Specifies the timeline start for a snapshot
+%
+% #1 = a time
+%
+% Description:
+%
+% What a snapshot is taken of an animation (using \pgfsnapshot), all
+% animations normally start at time 0s. When this key is used, the
+% animation's timeline start is considered to be at moment #1
+% instead.
+
+\pgfanimationset{
+ begin snapshot/.code=
+ \pgfparsetime{#1}\expandafter\pgfsysanimkeysnapshotstart\expandafter{\pgftimeresult}
+}%
+
+
+% Specifies the origin for transforming animations
+%
+% #1 = a pgf point
+%
+% Specifies the origin of transformations (for instance, a rotate will
+% rotate around this point).
+%
+% Example:
+%
+% \pgfanimateattribute{rotate}{entry={0s}{0}, entry={1s}{90}, origin=\pgfpoint{1cm}{1cm}}
+
+\pgfanimationset{
+ origin/.code={%
+ \pgf@process{#1}%
+ \edef\pgf@marshal{%
+ \noexpand\pgfsysanimkeycanvastransform%
+ {\noexpand\pgftransformshift{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}{\noexpand\pgflowlevelsynccm}}%
+ {\noexpand\pgftransforminvert\noexpand\pgflowlevelsynccm}%
+ \noexpand\pgf@anim@save@transform{\noexpand\pgftransformshift{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ }%
+ \pgf@marshal%
+ },
+}%
+
+\pgfsysanimkeycanvastransform{{\pgflowlevelsynccm}}{\pgftransforminvert\pgflowlevelsynccm}%
+
+
+
+% Specifies the transforming for the animation coordinate system
+%
+% #1 = code that changes the pgf coordinate system
+%
+% Specifies an additional transformation of the coordinate system for
+% animations.
+%
+% Example:
+%
+% \pgfanimateattribute{shift}{entry={0s}{\pgfpointorigin}, entry={1s}{\pgfpoint{1cm}{0cm}}, transform=\pgftransformrotate{30}}
+
+\pgfanimationset{
+ transform/.code={%
+ \pgfsysanimkeycanvastransform{#1{\pgflowlevelsynccm}}{\pgftransforminvert\pgflowlevelsynccm}%
+ \pgf@anim@save@transform{#1}%
+ },
+}%
+
+
+
+% Specifies a motion path.
+%
+% #1 = pgf commands for constructing a path
+%
+% Use this key to specify a motion path for the motion attribute. The
+% values of the "entry" key specify fractions along this path.
+%
+% Example:
+%
+% \pgfanimateattribute{motion}{
+% entry={0s}{0}, entry={1s}{1},
+% along=\pgfpathmoveto{\pgfpointorigin} \pgfpathlineto{\pgfpoint{1cm}{1cm}}
+% }
+
+\pgfanimationset{
+ along/.code=%
+ {%
+ \pgfsyssoftpath@getcurrentpath\pgfanim@save@path%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ #1%
+ \pgfsyssoftpath@getcurrentpath\pgfanim@the@path%
+ \global\let\pgfanim@the@path\pgfanim@the@path%
+ \pgfsyssoftpath@setcurrentpath\pgfanim@save@path%
+ }%
+ \expandafter\pgf@anim@protocol@path@size\pgfanim@the@path\pgf@stop%
+ \expandafter\pgfsysanimkeymovealong\expandafter{\pgfanim@the@path}%
+}%
+
+
+% Specifies a motion soft path.
+%
+% #1 = a pgf soft path (result of calling \pgfsyssoftpath@getcurrentpath)
+%
+% Use this key to specify a motion path for the motion attribute when
+% a softpath has already been constructed.
+%
+% Example:
+%
+% \pgfanimateattribute{motion}{entry={0s}{0}, entry={1s}{1},
+% along softpath=\pgfsyssoftpath@movetotoken {0pt}{0pt}\pgfsyssoftpath@linetotoken {10pt}{10pt}}
+
+\pgfanimationset{
+ along softpath/.code=%
+ \pgf@anim@protocol@path@size#1\pgf@stop%
+ \pgfsysanimkeymovealong{#1}%
+}%
+
+
+\def\pgf@anim@protocol@path@size{%
+ \pgfutil@ifnextchar\pgf@stop\pgfutil@gobble\pgf@anim@protocol@path@size@%
+}%
+\def\pgf@anim@protocol@path@size@#1#2#3{%
+ \pgf@protocolanimsizes@direct{#2}{#3}%
+ \pgf@anim@protocol@path@size%
+}%
+
+
+% Configures whether the motion is rotated along the path.
+%
+% Example:
+%
+% \pgfanimateattribute{motion}{rotate along, entry={0s}{0}, entry={1s}{1},
+% along=\pgfpathmoveto{\pgfpointorigin} \pgfpathlineto{\pgfpoint{1cm}{1cm}}}
+
+\pgfanimationset{
+ rotate along/.is choice,
+ rotate along/.default=true,
+ rotate along/true/.code=\pgfsysanimkeyrotatealong,
+ rotate along/false/.code=\pgfsysanimkeynorotatealong,
+}%
+
+
+
+% Specifies an entry
+%
+% #1 = A time. This time will be parsed using \pgfparsetime
+% #2 = A value. The format of this value depends on the current type
+% of the animation attribute. (So for an animation of the "fill
+% opacity", #1 must be a scalar value, for an animation of the "fill"
+% color, #1 must be a color, and so on.)
+% If #2 is the special text "current value", then the current
+% value will be used. For SVG, this is allowed only when exactly
+% two entries are specified and this special value is used for
+% the first one.
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{entry={0s}{0}, entry={1s}{1}}
+
+\pgfanimationset{entry/.code 2 args=\pgf@anim@entry{#1}{#2}}%
+\def\pgf@anim@entry#1#2{%
+ \pgf@anim@entry@giventrue%
+ \pgfparsetime{#1}%
+ \edef\pgf@marshal{\noexpand\pgfsysanimkeytime{\pgftimeresult}\pgf@anim@entry@spline\pgf@anim@exit@spline}%
+ \pgf@marshal%
+ \def\pgf@temp{#2}%
+ \ifx\pgf@temp\pgf@special@current@text%
+ \pgfsysanimvalcurrent%
+ \else%
+ \pgfanim@type@parser{#2}%
+ \fi%
+}%
+\def\pgf@special@current@text{current value}%
+\newif\ifpgf@anim@entry@given
+
+
+% Specifies a base value
+%
+% #1 = A value. The format is as for the entry key.
+%
+% Description:
+%
+% Will set the "base" value of the animation, which is a value that is
+% used when the animation is not active.
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{base = 0.5, entry={0s}{0.5}, entry={1s}{1}}
+
+\pgfanimationset{base/.code=\pgf@anim@base{#1}}%
+\def\pgf@anim@base#1{%
+ \pgfsysanimkeybase%
+ \pgfanim@type@parser{#1}%
+}%
+
+
+% Specifies that there is an entry "at infinity".
+%
+% When an animation ends, its "effect" can either persist or it can be
+% removed. Setting "freeze at end" to true will cause it to persist,
+% otherwise it will be removed.
+%
+% Example:
+%
+% \pgfanimateattribute{fill opacity}{entry={0s}{1}, entry={1s}{0}, freeze at end}
+
+\pgfanimationset{
+ freeze at end/.is choice,
+ freeze at end/.default=true,
+ freeze at end/true/.code=\pgfsysanimkeyfreezeatend,
+ freeze at end/false/.code=\pgfsysanimkeyremoveatend,
+}%
+
+
+
+% Specifies an entry or exit spline control
+%
+% #1 = time fraction
+% #2 = attribute fraction
+%
+% Description:
+%
+% Suppose that an animation is supposed to interpolate a attribute's
+% value between the two values "50" and "100" over a time of 10s. The
+% simplest way of doing so is to do a linear interpolation, where the
+% value as, say, 1s is 55, at 2s it is 60, and so on.
+%
+% Unfortunately, the linear interpolation does not "look" nice in many
+% cases since the acceleration of a linear interpolation is zero
+% during the animation, but infinite at the beginning and at the end;
+% which looks "jerky".
+%
+% To avoid this, you can specify that the time--attribute curve should
+% not be a straight line, but rather a curve. You specify this curve
+% using a spline.
+%
+% The most logical "coordinate rectangle" used for this spline in our
+% example would be (0s,50) and (10s,100) and we would like to specify
+% something like "(0s,50) .. controls (5s,50) and (9s,100)
+% .. (10s,100)". This would result in a time--attribute curve where
+% the attribute at 50 changes slowly at 0s and also arrives slowly at
+% 100 at 10s, but speeds up between these values.
+%
+% We call the first control point (5s,50) the "exit control" and call
+% (9s,100) the "entry control": The first control dictates how quickly
+% or slowly a time point is left, the second dictates how quickly or
+% slowly we enter the next one.
+%
+% The control points are, however, not specified in the coordinate
+% system indicated above. Rather, the rectangle (0s,50) to (10s, 100),
+% gets normalized to (0,0) to (1,1). The control point (5s,50) would
+% thus become (0.5,0) and (9s,100) becomes (0.9,1).
+%
+% Example:
+%
+% \pgfanimateattribute{rotate}{
+% exit control={0.5}{0},
+% entry control={0.9}{1},
+% entry={0s}{50},
+% entry={10s}{100}}
+
+\pgfanimationset{
+ entry control/.code 2 args={%
+ \pgfmathsetmacro\pgf@temp@t{#1}%
+ \pgfmathsetmacro\pgf@temp@a{#2}%
+ \edef\pgf@anim@entry@spline{{\pgf@temp@t}{\pgf@temp@a}}%
+ },
+ exit control/.code 2 args={%
+ \pgfmathsetmacro\pgf@temp@t{#1}%
+ \pgfmathsetmacro\pgf@temp@a{#2}%
+ \edef\pgf@anim@exit@spline{{\pgf@temp@t}{\pgf@temp@a}}%
+ },
+ stay/.code=\let\pgf@anim@exit@spline\pgfsys@stay@text,%
+ jump/.code=\let\pgf@anim@entry@spline\pgfsys@jump@text,%
+ linear/.style={entry control={1}{1},exit control={0}{0}},
+}%
+\def\pgf@anim@entry@spline@base{{1}{1}}%
+\def\pgf@anim@exit@spline@base{{0}{0}}%
+
+\def\pgf@anim@reset@linear{\let\pgf@anim@entry@spline\pgf@anim@entry@spline@base\let\pgf@anim@exit@spline\pgf@anim@exit@spline@base}%
+\pgf@anim@reset@linear
+
+
+
+% Specifies how much arrow tips should be shortened (as in
+% \pgfsetshortenstart)
+%
+% #1 = an additional shortening distance the path start.
+%
+% Description:
+%
+% Works like \pgfsetshortenstart, only for animated paths.
+
+\pgfanimationset{
+ shorten </.code={%
+ \ifpgf@anim@entry@given%
+ \pgferror{You must specify shorten < prior to the path entries}%
+ \else%
+ \pgfmathsetmacro\pgf@anim@marker@extra@shorten@start{#1}%
+ \edef\pgf@anim@marker@extra@shorten@start{\pgf@anim@marker@extra@shorten@start pt}%
+ \fi%
+ },
+ shorten >/.code={%
+ \ifpgf@anim@entry@given%
+ \pgferror{You must specify shorten < prior to the path entries}%
+ \else%
+ \pgfmathsetmacro\pgf@anim@marker@extra@shorten@end{#1}%
+ \edef\pgf@anim@marker@extra@shorten@end{\pgf@anim@marker@extra@shorten@end pt}%
+ \fi%
+ },
+}%
+\def\pgf@anim@marker@extra@shorten@start{0pt}%
+\def\pgf@anim@marker@extra@shorten@end{0pt}%
+\def\pgf@anim@marker@shorten@start{0pt}%
+\def\pgf@anim@marker@shorten@end{0pt}%
+
+% Specifies the arrow tips used for path animations
+%
+% #1 = an arrow specification of the form <start>-<end> as for the
+% command \pgfsetarrows
+%
+% Description:
+%
+% Specifies arrow tips that are used in a path animation. Note that in
+% order to set the arrow tips of a path that is animated, you always
+% have to use this command. In particular, you should *not* set arrow
+% tips for the to-be-animated path, but use this key and the base key
+% to install a base path with arrow tips.
+
+\pgfanimationset{
+ arrows/.code={%
+ \ifpgf@anim@entry@given%
+ \pgferror{You must specify animation arrows prior to the path entries}%
+ \else%
+ \pgf@anim@parser@arrows#1\pgf@stop%
+ \fi%
+ },
+}%
+
+\def\pgf@anim@parser@arrows#1-#2\pgf@stop{%
+ \pgf@anim@prepare@arrow@start{#1}%
+ \pgf@anim@prepare@arrow@end{#2}%
+ \expandafter\expandafter\expandafter\pgfsysanimkeytipmarkers\expandafter\expandafter\expandafter{\expandafter\pgf@anim@marker@id@start\expandafter}\expandafter{\pgf@anim@marker@id@end}%
+}%
+
+\def\pgf@anim@prepare@arrow@start#1{%
+ \def\pgf@anim@temp{#1}%
+ \ifx\pgf@anim@temp\pgfutil@empty%
+ \let\pgf@anim@marker@id@start\pgfutil@empty%
+ \def\pgf@anim@marker@shorten@start{0pt}%
+ \else%
+ {%
+ \pgfsetarrowsstart{#1}%
+ \pgf@anim@prep@marker@arrow\pgf@start@tip@sequence\pgf@anim@marker@id\pgf@anim@marker@shorten%
+ \global\let\pgf@anim@marker@id@start\pgf@anim@marker@id%
+ \global\let\pgf@anim@temp\pgf@anim@marker@shorten%
+ }%
+ \let\pgf@anim@marker@shorten@start\pgf@anim@temp%
+ \fi%
+}%
+
+\def\pgf@anim@prepare@arrow@end#1{%
+ \def\pgf@anim@temp{#1}%
+ \ifx\pgf@anim@temp\pgfutil@empty%
+ \let\pgf@anim@marker@id@end\pgfutil@empty%
+ \def\pgf@anim@marker@shorten@end{0pt}%
+ \else%
+ {%
+ \pgfsetarrowsend{#1}%
+ \pgf@anim@prep@marker@arrow\pgf@end@tip@sequence\pgf@anim@marker@id\pgf@anim@marker@shorten%
+ \global\let\pgf@anim@marker@id@end\pgf@anim@marker@id%
+ }%
+ \let\pgf@anim@marker@shorten@end\pgf@anim@marker@shorten%
+ \fi%
+}%
+
+
+% Draw an arrow using markers
+
+\def\pgf@anim@prep@marker@arrow#1#2#3{%
+ % #1 = tip sequence
+ % #2 = macro for storing marker code
+ % #3 = macro for storing shortening length
+ %
+ % First, compute id's:
+ {%
+ \let\pgf@arrow@handle\pgf@anim@marker@id@test%
+ \let\pgf@arrow@handle@dot\relax%?
+ \global\let\pgf@anim@marker@id@list\pgfutil@empty%
+ #1%
+ }%
+ \expandafter\let\expandafter#2\csname pgfanim@marker@cache@\pgf@anim@marker@id@list\endcsname%
+ \expandafter\let\expandafter#3\csname pgfanim@marker@cachel@\pgf@anim@marker@id@list\endcsname%
+ \ifx#2\relax% ok, have to create it!
+ \pgf@relevantforpicturesizefalse%
+ \pgfinterruptpath%
+ \pgf@arrow@compute@shortening{#1}%
+ \xdef#3{\the\pgf@xa}%
+ {%
+ \let\pgf@arrow@handle\pgf@anim@drawer@marker
+ \let\pgf@arrow@handle@dot\relax%
+ \pgfsys@marker@declare#2{%
+ \pgftransformxshift{-\pgf@xb}%
+ \pgftransformxshift{\pgf@xa}%
+ #1%
+ }%
+ }%
+ \endpgfinterruptpath%
+ \expandafter\global\expandafter\let\csname pgfanim@marker@cache@\pgf@anim@marker@id@list\endcsname#2%
+ \expandafter\global\expandafter\let\csname pgfanim@marker@cachel@\pgf@anim@marker@id@list\endcsname#3%
+ \fi%
+}%
+
+\def\pgf@anim@marker@id@test#1#2{%
+ \pgfarrows@getid{#1}{#2}%
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
+ \xdef\pgf@anim@marker@id@list{\pgf@anim@marker@id@list:\pgf@arrow@id\ifpgfarrowswap s\else n\fi\pgfarrows@slant w\the\pgf@xc}%
+}%
+
+\def\pgf@anim@drawer@marker#1#2{%
+ % Prepare:
+ {%
+ \pgfarrows@getid{#1}{#2}%
+ % Do shift:
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
+ % Do slant:
+ \ifdim\pgfarrows@slant pt=0pt%
+ \else%
+ \pgftransformxslant{\pgfarrows@slant}%
+ \fi%
+ % do swap:
+ \ifpgfarrowswap%
+ \pgftransformyscale{-1}%
+ \fi%
+ {%
+ \csname pgf@ar@saves@\pgf@arrow@id\endcsname%
+ \pgfsys@beginscope%
+ \pgf@arrows@color@setup%
+ \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname%
+ \pgfsys@endscope%
+ }%
+ \expandafter}%
+ % Transform to next tip:
+ \expandafter\pgftransformxshift\expandafter{\the\pgf@xc}%
+}%
+
+
+
+
+
+
+
+
+
+% The parsers
+
+% Parse no value
+%
+% #1 is ignored
+%
+% Example:
+%
+% entry = {0s}{5+6}
+
+\def\pgfanim@parse@type@none#1{%
+ \pgfsysanimvalnone%
+}%
+
+% Parse a scalar
+%
+% #1 is a number parsed using \pgfmathparse
+%
+% Example:
+%
+% entry = {0s}{5+6}
+
+\def\pgfanim@parse@type@scalar#1{%
+ \pgfmathparse{#1}%
+ \expandafter\pgfsysanimvalscalar\expandafter{\pgfmathresult}%
+}%
+
+
+% Parse a dimension
+%
+% #1 is a number parsed using \pgfmathparse
+%
+% Example:
+%
+% entry = {0s}{5cm + 2pt}
+
+\def\pgfanim@parse@type@dimension#1{%
+ \pgfmathparse{#1}%
+ \expandafter\pgfsysanimvaldimension\expandafter{\pgfmathresult pt}%
+}%
+
+
+
+% Parse a mapped text
+%
+% #1 is a text. It is looked up in \pgf@anim@map@#1 and gets replaced
+% by what this macro expands to.
+%
+% Example:
+%
+% entry = {0s}{true}
+
+\def\pgfanim@parse@type@mapped#1{%
+ {%
+ \expandafter\let\expandafter\pgf@temp\csname pgf@anim@map@#1\endcsname\relax%
+ \ifx\pgf@temp\relax%
+ \pgferror{Value '#1' not allowed for an animation for this attribute}%
+ \let\pgf@temp\pgfutil@empty%
+ \fi%
+ \expandafter}%
+ \expandafter\pgfsysanimvaltext\expandafter{\pgf@temp}%
+}%
+
+
+% Parse a color
+%
+% #1 is a color
+%
+% entry = {0s}{blue!20}
+
+\def\pgfanim@parse@type@color#1{%
+ \pgfsysanimvalcolor{#1}%
+}%
+
+
+% Parse a path
+%
+% #1 is a sequence of pgf path construction commands
+%
+% entry = {0s}{\pgfpathmoveto{\pgfpointorigin} \pgfpathlineto{\pgfpoint{1cm}{1cm}}}
+
+\def\pgfanim@parse@type@path#1{%
+ {%
+ \pgfsyssoftpath@getcurrentpath\pgfanim@save@path%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ #1%
+ \pgfsyssoftpath@getcurrentpath\pgfanim@the@path%
+ \pgfprocessround{\pgfanim@the@path}{\pgfanim@the@path}%
+ \global\let\pgfanim@the@path\pgfanim@the@path%
+ \pgfsyssoftpath@setcurrentpath\pgfanim@save@path%
+ }%
+ \expandafter\pgfanim@parse@type@softpath\expandafter{\pgfanim@the@path}%
+}%
+
+
+% Parse a softpath
+%
+% #1 is a sequence of pgf softpath token commands
+%
+% entry = {0s}{\pgfsyssoftpath@movetotoken {0pt}{0pt}\pgfsyssoftpath@linetotoken {10pt}{10pt}}
+
+\def\pgfanim@parse@type@softpath#1{%
+ {%
+ \def\pgf@anim@path{#1}%
+ % Shorten?
+ \pgf@worryfalse%
+ \pgf@xb=\pgf@anim@marker@extra@shorten@start%
+ \advance\pgf@xb by\pgf@anim@marker@shorten@start%
+ \pgf@xc=\pgf@anim@marker@extra@shorten@end%
+ \advance\pgf@xc by\pgf@anim@marker@shorten@end%
+ \ifdim\pgf@xb=0pt\else\pgf@worrytrue\fi%
+ \ifdim\pgf@xc=0pt\else\pgf@worrytrue\fi%
+ \ifpgf@worry%
+ \edef\pgf@path@shortening@distance@end{\the\pgf@xc}%
+ \edef\pgf@path@shortening@distance@start{\the\pgf@xb}%
+ % Yes! Need to shorten.
+ \pgf@anim@shorten@path%
+ \fi%
+ \expandafter}%
+ \expandafter\pgfsysanimvalpath\expandafter{\pgf@anim@path}%
+}%
+
+
+\def\pgf@anim@shorten@path{%
+ \pgf@precise@shorteningfalse%
+ \let\pgf@path@shortening@distance\pgf@path@shortening@distance@end%
+ %
+ % Step 1: Split
+ %
+ \pgfprocesssplitpath{\pgf@anim@path}%
+ \pgfprocesssplitsubpath{\pgfprocessresultpathsuffix}%
+ %
+ % Step 2: extract
+ %
+ \expandafter\pgf@parse@end\pgfprocessresultsubpathsuffix\pgf@stop\pgf@stop\pgf@stop%
+ %
+ % Step 3: prep end
+ %
+ \pgf@prep@end%
+ %
+ % Step 4: shorten end
+ %
+ \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@end\fi%
+ %
+ \let\pgf@path@shortening@distance\pgf@path@shortening@distance@start%
+ %
+ % Step 5: extract
+ %
+ \expandafter\pgf@parse@start\pgfprocessresultpathsuffix\pgf@stop\pgf@stop\pgf@stop%
+ %
+ % Step 6: prep start
+ %
+ \pgf@prep@start%
+ %
+ % Step 7: shorten start
+ %
+ \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@start\fi%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@anim@path%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix}%
+}%
+
+
+
+% Parse a point
+%
+% #1 is a point
+%
+% entry = {0s}{\pgfpoint{1cm}{2cm}}
+
+\def\pgfanim@parse@type@point#1{%
+ \pgf@process{#1}%
+ \pgf@protocolanimsizes\pgf@x\pgf@y%
+ \expandafter\expandafter\expandafter\pgfsysanimvaltranslate\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgf@x\expandafter}\expandafter{\the\pgf@y}%
+}%
+
+
+% Parse a scaling
+%
+% #1 = if #1 contains a comma, the two parts are passed to
+% pgfmathparse, otherwise the whole thing is passed to pgfmathparse.
+%
+% entry = {0s}{2}
+% entry = {0s}{2,1}
+
+\def\pgfanim@parse@type@scaling#1{%
+ \pgfutil@in@{,}{#1}%
+ \ifpgfutil@in@%
+ \pgfanim@unpack@comma#1\pgf@stop%
+ \else%
+ \pgfmathparse{#1}%
+ \expandafter\pgfsysanimvalscale\expandafter{\pgfmathresult}{\pgfmathresult}%
+ \fi%
+}%
+\def\pgfanim@unpack@comma#1,#2\pgf@stop{%
+ \pgfmathsetmacro{\pgf@anim@temp@x}{#1}%
+ \pgfmathsetmacro{\pgf@anim@temp@y}{#2}%
+ \expandafter\expandafter\expandafter\pgfsysanimvalscale\expandafter\expandafter\expandafter{\expandafter\pgf@anim@temp@x\expandafter}\expandafter{\pgf@anim@temp@y}%
+}%
+
+
+
+% Parse a viewbox
+%
+% #1 consists of two points, each in parentheses
+%
+% entry = {0s}{{\pgfpoint{1cm}{2cm}}{\pgfpoint{3cm}{4cm}}}
+
+\def\pgfanim@parse@type@viewbox#1{%
+ {%
+ \pgfanim@unpack@viewbox#1%
+ \xdef\pgf@anim@caller{\noexpand\pgfsysanimvalviewbox{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}}%
+ }%
+ \pgf@anim@caller%
+}%
+\def\pgfanim@unpack@viewbox#1#2{%
+ \pgfpointtransformed{#2}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfpointtransformed{#1}%
+ \ifdim\pgf@xa<\pgf@x% swap needed
+ \pgf@xb=\pgf@x%
+ \pgf@x=\pgf@xa%
+ \pgf@xa=\pgf@xb%
+ \fi%
+ \ifdim\pgf@ya<\pgf@y% swap needed
+ \pgf@yb=\pgf@y%
+ \pgf@y=\pgf@ya%
+ \pgf@ya=\pgf@yb%
+ \fi%
+}%
+
+
+
+
+% Parse a dash pattern
+%
+% #1,#2 is a dash pattern as in \pgfsetdash
+%
+% entry = {0s}{{{1pt}{2pt}{3pt}{1pt}}{1pt}}
+
+\def\pgfanim@parse@type@dash#1{\pgfanim@parse@type@dash@#1}%
+\def\pgfanim@parse@type@dash@#1#2{%
+ \def\pgf@temp{}%
+ \def\pgf@next{\pgf@strip}%
+ \pgf@strip#1{pgf@stop}%
+ \expandafter\pgfsysanimvaldash\expandafter{\pgf@temp}{#2}%
+}%
+
+
+
+
+
+%
+%
+% Bounding box adjustments in animations.
+%
+%
+
+\def\pgf@protocolanimsizes#1#2{%
+ \edef\pgf@temp{\noexpand\pgf@anim@handle@point{\the#1}{\the#2}}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@protocolanim@list\expandafter\expandafter\expandafter{\expandafter\pgf@protocolanim@list\pgf@temp}%
+}%
+\def\pgf@protocolanimsizes@direct#1#2{%
+ \expandafter\def\expandafter\pgf@protocolanim@list\expandafter{\pgf@protocolanim@list\pgf@anim@handle@point{#1}{#2}}%
+}%
+\let\pgf@protocolanim@list\pgfutil@empty
+
+\def\pgf@animation@check@translate{%
+ \ifx\pgf@protocolanim@list\pgfutil@empty%
+ \else%
+ \expandafter\expandafter\expandafter\pgf@animation@check@translate@\expandafter\expandafter\expandafter{\expandafter\pgf@protocolanim@list\expandafter}\expandafter{\pgf@anim@saved@transform}%
+ \fi%
+}%
+\let\pgf@animation@check@motion\pgf@animation@check@translate
+
+\def\pgf@animation@check@translate@#1#2{%
+ \pgfsys@attach@to@id\pgf@anim@whom@id\pgf@anim@whom@type{%
+ \pgf@size@hookedtrue%
+ {%
+ % Compute bounding box in local coordinate system
+ #2%
+ \pgf@pt@x0pt%
+ \pgf@pt@y0pt%
+ \pgf@picmaxx=-16000pt\relax%
+ \pgf@picminx=16000pt\relax%
+ \pgf@picmaxy=-16000pt\relax%
+ \pgf@picminy=16000pt\relax%
+ #1%
+ \edef\pgf@temp{{\the\pgf@picminx}{\the\pgf@picminy}{\the\pgf@picmaxx}{\the\pgf@picmaxy}}%
+ \expandafter%
+ }\expandafter%
+ \def\expandafter\pgf@temp\expandafter{\pgf@temp}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@path@size@hook\expandafter\expandafter\expandafter{%
+ \expandafter\pgf@path@size@hook\expandafter\pgf@anim@bb\pgf@temp}%
+ }{}%
+}%
+\def\pgf@anim@handle@point#1#2{%
+ \pgf@x#1\pgf@y#2%
+ \pgf@pos@transform\pgf@x\pgf@y%
+ \ifdim\pgf@x<\pgf@picminx\pgf@picminx\pgf@x\fi%
+ \ifdim\pgf@x>\pgf@picmaxx\pgf@picmaxx\pgf@x\fi%
+ \ifdim\pgf@y<\pgf@picminy\pgf@picminy\pgf@y\fi%
+ \ifdim\pgf@y>\pgf@picmaxy\pgf@picmaxy\pgf@y\fi%
+}%
+
+\newdimen\pgf@anim@dim
+
+\def\pgf@anim@bb#1#2#3#4{% (#1,#2) lower left, (#3, #4) upper right
+ \pgf@anim@dim\pgf@size@hook@x%
+ \advance\pgf@anim@dim by#1\relax%
+ \ifdim\pgf@anim@dim<\pgf@picminx\global\pgf@picminx\pgf@anim@dim\fi%
+ \pgf@anim@dim\pgf@size@hook@x%
+ \advance\pgf@anim@dim by#3\relax%
+ \ifdim\pgf@anim@dim>\pgf@picmaxx\global\pgf@picmaxx\pgf@anim@dim\fi%
+ \pgf@anim@dim\pgf@size@hook@y%
+ \advance\pgf@anim@dim by#2\relax%
+ \ifdim\pgf@anim@dim<\pgf@picminy\global\pgf@picminy\pgf@anim@dim\fi%
+ \pgf@anim@dim\pgf@size@hook@y%
+ \advance\pgf@anim@dim by#4\relax%
+ \ifdim\pgf@anim@dim>\pgf@picmaxy\global\pgf@picmaxy\pgf@anim@dim\fi%
+}%
+
+\def\pgf@anim@save@transform#1{%
+ \def\pgf@anim@saved@transform{#1}%
+}%
+\let\pgf@anim@saved@transform\pgfutil@empty%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmodulebending.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmodulebending.code.tex
new file mode 100644
index 0000000000..d2ffa8b3c5
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmodulebending.code.tex
@@ -0,0 +1,356 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmodulebending.code.tex}
+
+
+%
+% This file defines commands for drawing bending arrows and lines.
+%
+
+\usepgfmodule{nonlineartransformations}%
+\usepgflibrary{curvilinear}%
+
+
+% Configuration options for arrow tips:
+
+\pgfkeys{
+ /pgf/arrow keys/flex/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex},
+ /pgf/arrow keys/flex/.default=1,
+ /pgf/arrow keys/flex'/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex@prime},
+ /pgf/arrow keys/flex'/.default=1,
+ /pgf/arrow
+ keys/bend/.code=\pgfarrowsaddtooptions{\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@bend},
+}%
+
+
+\def\pgf@arrow@mode@is@flex{1}%
+\def\pgf@arrow@mode@is@flex@prime{2}%
+\def\pgf@arrow@mode@is@bend{3}%
+
+\newdimen\pgf@arrows@the@rigidity
+
+%
+%
+% Handle the end of a curve
+%
+%
+
+% First, the preparation. This is, essentially, setting up the
+% nonlinear transformation
+
+\def\pgf@prep@curveend{
+ \pgftransformreset%
+ \pgfsetcurvilinearbeziercurve{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath}
+}%
+
+% Second, the shortening.
+
+\def\pgf@do@shorten@curvedend{%
+ \expandafter\expandafter\expandafter\pgf@do@shorten@curvedend@unpack\expandafter\pgfpointfourthlastonpath\pgfpointthirdlastonpath%
+}%
+\def\pgf@do@shorten@curvedend@unpack\pgfqpoint#1#2\pgfqpoint#3#4{%
+ \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}%
+ % Compute new curve:
+ \pgfpointcurveattime{\pgf@x}{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath}%
+ % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector...
+ \pgf@xb#3%
+ \pgf@yb#4%
+ \pgf@xb\pgf@time@t\pgf@xb%
+ \pgf@yb\pgf@time@t\pgf@yb%
+ \advance\pgf@xb by\pgf@time@s\pgf@xc%
+ \advance\pgf@yb by\pgf@time@s\pgf@yc%
+ \edef\pgfprocessresultsubpathsuffix{%
+ \expandafter\noexpand\pgfsubpathfourthlasttoken{#1}{#2}%
+ \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xb}{\the\pgf@yb}%
+ \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xa}{\the\pgf@ya}%
+ \noexpand\pgfsyssoftpath@curvetotoken{\the\pgf@x}{\the\pgf@y}}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}%
+}%
+
+% Third, the drawing
+
+\def\pgf@do@draw@curvedend{%
+ \pgf@do@draw@curved\pgf@end@tip@sequence%
+}%
+
+\def\pgf@do@draw@curved#1{%
+ {%
+ \pgftransformreset%
+ \pgf@xb\pgf@arrow@tip@total@length% xb will keep track of the total length
+ \let\pgf@arrow@handle\pgf@draw@curved%
+ \let\pgf@arrow@handle@dot\relax%
+ #1%
+ }%
+}%
+
+\def\pgf@draw@curved#1#2{%
+ % Prepare:
+ {%
+ \pgfarrows@getid{#1}{#2}%
+ % Do shift:
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
+ \expandafter\let\expandafter\pgf@arrow@bending@mode\csname pgf@ar@bending@mode@#1\endcsname%
+ \ifx\pgf@arrow@bending@mode\pgfutil@empty\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex\fi%
+ % do swap:
+ {%
+ \csname pgf@ar@saves@\pgf@arrow@id\endcsname%
+ \ifcase\pgf@arrow@flex@mode\relax%
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% like flex
+ \or%
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname%
+ \or%
+ \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
+ \or%
+ \pgf@arrow@drawer@bend%
+ \fi%
+ % hull points inside the above
+ }%
+ \expandafter}%
+ % Transform to next tip:
+ \expandafter\pgf@xb\the\pgf@xb%
+}%
+\def\pgf@falsetext{false}%
+
+\def\pgf@arrow@drawer@rigid@shift#1#2#3{% tip end, back end, line end, sep
+ % Let xa be the actual back end of the current arrow plus the back end:
+ \advance\pgf@xb by#2%
+ \pgf@xa\pgf@xb%
+ % Update the xb:
+ \pgf@x#1%
+ \advance\pgf@x by\pgfarrowsep%
+ \advance\pgf@xb by-\pgf@x%
+}%
+
+
+\def\pgf@arrow@drawer@bend{%
+ \pgftransformnonlinear{\pgf@arrow@bending@mode{\pgf@x}{\pgf@y}}
+ \pgftransformscale{-1}%
+ \pgftransformxshift{-\pgf@xa}%
+ % Do slant:
+ \ifdim\pgfarrows@slant pt=0pt%
+ \else%
+ \pgftransformxslant{\pgfarrows@slant}%
+ \fi%
+ \ifpgfarrowswap%
+ \pgftransformyscale{-1}%
+ \fi%
+ {%
+ \pgf@relevantforpicturesizefalse%
+ \pgfscope%
+ \pgf@arrows@color@setup%
+ \csname pgf@ar@inst@code@\pgf@arrow@id\endcsname%
+ \endpgfscope%
+ }%
+ \pgf@arrows@bending@hull%
+}%
+
+\def\pgf@arrow@drawer@rigid#1#2#3{% (rigid) start, (rigid) end, dummy
+ % Compute the rigid positions:
+ \pgf@x#1% start
+ \pgf@y#2% flexibility*(end-start) + start
+ \advance\pgf@y by-\pgf@x%
+ \pgf@y\pgf@sys@tonumber\pgf@arrows@the@rigidity\pgf@y%
+ \advance\pgf@y by\pgf@x%
+ % Are they equal?
+ \ifdim\pgf@x=\pgf@y%
+ % Yes, do tangent:
+ \pgf@bending@do@tangent%
+ \else%
+ \pgf@bending@do@flex%
+ \fi%
+ \pgf@xc#1%
+ \pgf@xc-\pgf@xc%
+ \pgftransformxshift{+\pgf@xc}%
+ % Do slant:
+ \ifdim\pgfarrows@slant pt=0pt%
+ \else%
+ \pgftransformxslant{\pgfarrows@slant}%
+ \fi%
+ % do swap:
+ \ifpgfarrowswap%
+ \pgftransformyscale{-1}%
+ \fi%
+ \pgfscope%
+ \pgf@arrows@color@setup%
+ \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname%
+ \endpgfscope%
+ \pgf@arrows@rigid@hull%
+}%
+
+\def\pgf@bending@do@tangent{%
+ \pgf@xb\pgf@xa%
+ \advance\pgf@xb by-\pgf@x%
+ \pgfcurvilineardistancetotime{\pgf@xb}%
+ \pgf@xb\pgf@x%
+ % Compute points:
+ \ifdim\pgf@xb=0pt%
+ \pgf@bending@possible@degenerate%
+ \else%
+ \pgf@bending@do@tangent@normal%
+ \fi%
+ \pgf@ya-\pgf@y%
+ \pgfsettransformentries%
+ {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}%
+ {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{\pgf@xc}{\pgf@yc}%
+}%
+
+\def\pgf@bending@do@tangent@normal{%
+ \pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}%
+ \pgf@xc\pgf@x% save
+ \pgf@yc\pgf@y% save
+ % compute normal:
+ \advance\pgf@xb by-\pgf@xa%
+ \advance\pgf@yb by-\pgf@ya%
+ \pgf@process{\pgfpointnormalised{\pgf@x=\pgf@xb\pgf@y=\pgf@yb}}
+}%
+
+\def\pgf@bending@possible@degenerate{%
+ \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@b% degenerate!
+ \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@c% double degenerate!
+ \let\pgf@ref\pgf@curvilinear@line@d%
+ \else
+ \let\pgf@ref\pgf@curvilinear@line@c%
+ \fi%
+ \pgf@process{\pgf@curvilinear@line@a}%
+ \pgf@xc\pgf@x% save
+ \pgf@yc\pgf@y% save
+ \pgf@process{\pgf@ref}%
+ \advance\pgf@x by-\pgf@xc
+ \advance\pgf@y by-\pgf@yc
+ \pgf@process{\pgfpointnormalised{}}
+ \pgf@x-\pgf@x
+ \pgf@y-\pgf@y
+ \else%
+ \pgf@bending@do@tangent@normal%
+ \fi%
+}%
+
+\def\pgf@bending@do@flex{
+ \pgf@xb\pgf@xa%
+ \pgf@xc\pgf@xa%
+ \advance\pgf@xc by-\pgf@x%
+ \advance\pgf@xb by-\pgf@y%
+ \pgfcurvilineardistancetotime{\pgf@xc}%
+ \pgf@xc\pgf@x%
+ \pgfcurvilineardistancetotime{\pgf@xb}%
+ \pgf@xb\pgf@x%
+ % Compute points:
+ \pgf@process{\pgfpointcurveattime{\pgf@xc}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}%
+ \pgf@xc\pgf@x\pgf@yc\pgf@y%
+ \pgf@process{\pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}%
+ \pgf@xb\pgf@x\pgf@yb\pgf@y%
+ \pgftransformarrow{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}%
+}%
+
+
+
+
+
+
+% Convex hull stuff:
+
+\def\pgf@arrows@bending@hull{%
+ \ifpgf@relevantforpicturesize%
+ % Do bb update:
+ \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname%
+ \ifx\pgf@temp\pgfutil@empty\else%
+ \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@first%
+ \pgf@temp%
+ \pgf@arrow@bending@update@bb%
+ \fi%
+ \fi%
+}%
+
+\def\pgf@arrow@bending@hull@point@first#1#2{%
+ \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}%
+ \pgf@xa\pgf@x\pgf@xb\pgf@x%
+ \pgf@ya\pgf@y\pgf@yb\pgf@y%
+ \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@other%
+}%
+\def\pgf@arrow@bending@hull@point@other#1#2{%
+ \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}%
+ \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi%
+ \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi%
+}%
+
+\def\pgf@arrow@bending@update@bb{%
+ \ifdim\pgf@picmaxx=-16000pt\relax%
+ \global\pgf@picminx\pgf@xa%
+ \global\pgf@picmaxx\pgf@xb%
+ \global\pgf@picminy\pgf@ya%
+ \global\pgf@picmaxy\pgf@yb%
+ \else%
+ \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi%
+ \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi%
+ \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi%
+ \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi%
+ \fi%
+}%
+
+
+
+
+%
+%
+% Handle the start of a curve
+%
+%
+
+
+% First, the preparation.
+
+\def\pgf@prep@curvedstart{
+ \pgftransformreset%
+ \pgfsetcurvilinearbeziercurve{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}%
+}%
+
+% Second, the shortening.
+
+\def\pgf@do@shorten@curvedstart{%
+ \expandafter\expandafter\expandafter\pgf@do@shorten@curvedstart@unpack\expandafter\pgfpointthirdonpath\pgfpointfourthonpath%
+}%
+\def\pgf@do@shorten@curvedstart@unpack\pgfqpoint#1#2\pgfqpoint#3#4{%
+ \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}%
+ % Compute new curve:
+ \pgfpointcurveattime{\pgf@x}{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}%
+ % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector...
+ \pgf@xb#1%
+ \pgf@yb#2%
+ \pgf@xb\pgf@time@t\pgf@xb%
+ \pgf@yb\pgf@time@t\pgf@yb%
+ \advance\pgf@xb by\pgf@time@s\pgf@xc%
+ \advance\pgf@yb by\pgf@time@s\pgf@yc%
+ \edef\pgfpointfirstonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \edef\pgfpointsecondonpath{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \edef\pgfprocessresultpathsuffix{%
+ \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@x}{\the\pgf@y}%
+ \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xa}{\the\pgf@ya}%
+ \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xb}{\the\pgf@yb}%
+ \noexpand\pgfsyssoftpath@curvetotoken{#3}{#4}%
+ }
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix%
+ \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathsuffix\pgfsubpathend}%
+}%
+
+
+% Third, the drawing
+
+\def\pgf@do@draw@curvedstart{%
+ \pgf@do@draw@curved\pgf@start@tip@sequence%
+}%
+
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmoduledatavisualization.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmoduledatavisualization.code.tex
new file mode 100644
index 0000000000..96686aa73f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmoduledatavisualization.code.tex
@@ -0,0 +1,3216 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmoduledatavisualization.code.tex}
+
+\usepgfmodule{oo,shapes}%
+\usepgflibrary{fpu}%
+
+
+% This module defines the basic framework for data visualization.
+
+% In order to visualize data, you first need data. The format for this
+% data is not specified, indeed, different formats are possible. A
+% data point is created each time the command \pgfdatapoint is
+% used. The "parameters" of the data point are just the current values
+% of the keys or macros in the current scope.
+%
+% A set of data points created using the \pgfdata command.
+% When a data point is created, a number of signals are emitted, see
+% the description of \pgfdatapoint. To actually visualize something,
+% objects should be created that listen to these signals and that
+% handle them.
+%
+% The following class manages a data visualization
+
+\pgfooclass{data visualization}
+{%
+ % Class data visualization
+ %
+ % This class is used to "manage" a data visualization. It provides
+ % methods for hooking into the data visualization process and its
+ % constructor initializes the signals that are issued during a data
+ % visualization.
+ %
+ % When a data visualization object is created, a whole bunch of
+ % signal objects. You should then create objects that connect to
+ % these signals. They will be emitted when datapoints come
+ % available.
+ %
+ % It is permissible to have several data visualization objects
+ % active at the same time.
+ %
+ % To use a data visualization object, you should (possibly
+ % repeatedly) call the method add data() or the macro \pgfdata. You should also
+ % create transformation, mapping and visualization objects. Then,
+ % you should, first, call the method survey, which will "survey" the
+ % data, allowing the mapping and bounding objects to compute the
+ % correct ranges. You may then create further objects based on this
+ % data. Then, you should call the "visualize" method, which will
+ % invoke the visualization signals for the data points.
+
+
+ % These attribute store code that should be executed at certain
+ % points. The order is the following:
+ %
+ % 1. "before survey" code
+ % 2. "begin survey" phase signal
+ % 3. "at start survey" code
+ % 4. data points are processed
+ % 5. "at end survey" code
+ % 6. "end survey" phase signal
+ % 7. "after survey" code
+ %
+ % The first seven points will be repeated until the method "do
+ % another survey" is no longer called during a survey.
+ %
+ % 8. "before visualization" code
+ % 9. "begin visualization" phase signal
+ % 10. "at start visualization" code
+ % 11. data points are processed once more
+ % 12. "at end visualization" code
+ % 13. "end visualization" phase signal
+ % 14. "after visualization" code
+ \attribute before survey;%
+ \attribute at start survey;%
+ \attribute at end survey;%
+ \attribute after survey;%
+ \attribute before visualization;%
+ \attribute at start visualization;%
+ \attribute at end visualization;%
+ \attribute after visualization;%
+
+ %
+ % Survey counts and handling
+ %
+
+ \attribute survey count=1;%
+ % Each time a survey is done before the visualization is done, this
+ % count is incremented. Normally, there is only one survey, but
+ % objects may request another survey or even more surveys to be
+ % done, giving them a chance to setup further internal values. By
+ % accessing this count (via the get survey count method), you can
+ % find out which survey is currently being done.
+
+ \attribute number of surveys=1;%
+ % By increasing this count, you can request additional surveys to be
+ % done.
+
+
+ % Stores the to-be-visualized data
+ \attribute data;%
+
+
+ % Stores the signal objects
+ \attribute prepare datapoint signal;%
+ \attribute map datapoint signal;%
+ \attribute transform datapoint signal;%
+ \attribute visualize datapoint signal;%
+ \attribute finish datapoint signal;%
+ \attribute survey datapoint signal;%
+ \attribute phase signal;%
+ \attribute path signal;%
+ \attribute direction signal;%
+ \attribute style signal;%
+
+
+ % Constructor
+ %
+ % Inits the signals
+ \method data visualization() {
+ \pgfoonew{prepare datapoint signal}=new signal()%
+ \pgfoonew{map datapoint signal}=new signal()%
+ \pgfoonew{transform datapoint signal}=new signal()%
+ \pgfoonew{visualize datapoint signal}=new signal()%
+ \pgfoonew{finish datapoint signal}=new signal()%
+ \pgfoonew{survey datapoint signal}=new signal()%
+ \pgfoonew{phase signal}=new signal()%
+ \pgfoonew{path signal}=new signal()%
+ \pgfoonew{direction signal}=new signal()%
+ \pgfoonew{style signal}=new signal()%
+ %
+ % Store this object in a key
+ %
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeyslet{/pgf/data visualization/obj}\pgf@dv@me
+ }%
+
+ % The phase signal will emit the following constants:
+ \def\pgfdvbeforesurvey{1}%
+ \def\pgfdvbeginsurvey{2}%
+ \def\pgfdvendsurvey{3}%
+ \def\pgfdvaftersurvey{4}%
+ \def\pgfdvbeforevisualization{5}%
+ \def\pgfdvbeginvisualization{6}%
+ \def\pgfdvendvisualization{7}%
+ \def\pgfdvaftervisualization{8}%
+
+ % The path signale will meit the following constants:
+ \def\pgfdvpathmovetotoken{5}%
+ \def\pgfdvpathlinetotoken{6}%
+ \def\pgfdvdirectionfromtoken{7}%
+ \def\pgfdvdirectiontotoken{8}%
+ \def\pgfdvdirectionattoken{9}%
+
+ % Method
+ %
+ % Connect the object #1's slot "#2" to the signal named "#3"
+ \method connect(#1,#2,#3) {
+ \pgfoovalueof{#3}.connect(#1,#2)
+ }%
+
+ % Method
+ %
+ % Add data that is to be visualized. The code #1 should call the
+ % \pgfdatapoint macro for each data point it creates.
+ \method add data(#1) {
+ \pgf@dv@stripped@add#1\pgf@stop
+ }%
+ \def\pgf@dv@stripped@add#1\pgf@stop{%
+ \pgfooappend{data}{#1}%
+ }%
+
+
+ % Setters
+ \method before survey(#1) {
+ \pgfooappend{before survey}{#1}
+ }%
+ \method at start survey(#1) {
+ \pgfooappend{at start survey}{#1}
+ }%
+ \method before visualization(#1) {
+ \pgfooappend{before visualization}{#1}
+ }%
+ \method at start visualization(#1) {
+ \pgfooappend{at start visualization}{#1}
+ }%
+
+ % Method
+ \method at end survey(#1) {
+ \pgfooprefix{at end survey}{#1}
+ }%
+ \method after survey(#1) {
+ \pgfooprefix{after survey}{#1}
+ }%
+ \method at end visualization(#1) {
+ \pgfooprefix{at end visualization}{#1}
+ }%
+ \method after visualization(#1) {
+ \pgfooprefix{after visualization}{#1}
+ }%
+
+
+ % Method
+ %
+ % Copy the signals to macros. This is just for efficiency (ha!)
+ \method prepare signal macros() {
+ \pgfooget{prepare datapoint signal}\pgf@signalpreparedatapoint
+ \pgfooget{map datapoint signal}\pgf@signalmapdatapoint
+ \pgfooget{transform datapoint signal}\pgf@signaltransformdatapoint
+ \pgfooget{visualize datapoint signal}\pgf@signalvisualizedatapoint
+ \pgfooget{finish datapoint signal}\pgf@signalfinishdatapoint
+ \pgfooget{survey datapoint signal}\pgf@signalsurveydatapoint
+ \pgfooget{phase signal}\pgf@signalphase
+ \pgfooget{path signal}\pgf@signalpath
+ \pgfooget{direction signal}\pgf@signaldirection
+ \pgfooget{style signal}\pgf@signalstyle
+ }%
+
+
+ % Survey method
+ %
+ % Call this method to "survey" the data. This should be done before
+ % the "visualize" method is called.
+ \method survey() {
+ % Survey phase.
+ \let\pgfdatapoint=\pgfdatapoint@surveyphase%
+ \pgfoothis.prepare signal macros()
+ \pgfooset{survey count}{1}
+ \pgfutil@loop
+ \pgf@signalphase.emit(\pgfdvbeforesurvey)
+ \pgfoovalueof{before survey}%
+ \pgf@signalphase.emit(\pgfdvbeginsurvey)
+ \pgfoovalueof{at start survey}
+ \pgfoovalueof{data}%
+ \pgfoovalueof{at end survey}
+ \pgf@signalphase.emit(\pgfdvendsurvey)%
+ \pgfoovalueof{after survey}
+ \pgf@signalphase.emit(\pgfdvaftersurvey)
+ \c@pgf@counta=\pgfoovalueof{survey count}\relax
+ \c@pgf@countb=\pgfoovalueof{number of surveys}\relax
+ \ifnum\c@pgf@counta<\c@pgf@countb
+ \advance\c@pgf@counta by1\relax
+ \pgfooeset{survey count}{\the\c@pgf@counta}
+ \pgfutil@repeat
+ }%
+
+ % Getter
+ \method get survey count(#1) {
+ \pgfooget{survey count}{#1}
+ }%
+
+ % Request another survey to be done
+ \method do an additional survey() {
+ \c@pgf@counta=\pgfoovalueof{number of surveys}\relax
+ \advance\c@pgf@counta by1\relax
+ \pgfooeset{number of surveys}{\the\c@pgf@counta}
+ }%
+
+ % Visualize method
+ %
+ % This method will cause the actual visualization.
+ \method visualize() {
+ % Visualization phase.
+ \let\pgfdatapoint=\pgfdatapoint@visualizationphase%
+ \pgfoothis.prepare signal macros()
+ \pgf@signalphase.emit(\pgfdvbeforevisualization)%
+ \pgfoovalueof{before visualization}
+ \pgf@signalphase.emit(\pgfdvbeginvisualization)%
+ \pgfoovalueof{at start visualization}
+ \pgfoovalueof{data}%
+ \pgfoovalueof{at end visualization}
+ \pgf@signalphase.emit(\pgfdvendvisualization)%
+ \pgfoovalueof{after visualization}
+ \pgf@signalphase.emit(\pgfdvaftervisualization)%
+ }%
+}%
+
+
+%
+% The data point keys
+%
+% Unlike other keys, the subkeys of /data point/ can simply be set
+% directly. If the key has not been initialized, it will automatically
+% be.
+\pgfkeys{/data point/.unknown/.code={%
+ \pgfkeyssetvalue{/data point/\pgfkeyscurrentname}{#1}
+ },
+}%
+
+
+
+
+% Create and handle a data point
+%
+% Description:
+%
+% This command is called by the survey and the visualize methods
+% whenever a complete data point has been produced. Depending on the
+% current circumstances, different signals will be emitted.
+%
+% The data that is represented by the data point is not given as a
+% parameter. Rather, it is stored in macros and keys, that is, the
+% data point is conceptually given by the settings of all the keys and
+% macros in the local scope.
+%
+% There are two phases to data processing: In the survey phase data
+% points are produced and handled in order to find out things like
+% their number or the minimum and maximum values of attributes, so
+% that axes and picture sizes can be prepared correctly. In the
+% visualization phase, data point are actually shown.
+%
+% During the survey phase, for each data point the signal
+% "surveydatapoint" is emitted.
+%
+% During the visualization phase, more signals are emitted. A prepare
+% signal is emitted first, giving all objects a
+% chance to "prepare" for the data point. Note that it is permissible
+% for an object to manipulate the data point here (and also
+% in later on).
+%
+% Next, the command \pgfdvmapdatapointtocanvas is called. Mainly,
+% the effect of this command is to setup the keys /data point/canvas x
+% and /data point/canvas y, see the description of this command for
+% more details.
+%
+% The next step consists of signaling "visualize data point". Objects
+% listening to this will cause some form of visualization of the
+% data point to occur.
+%
+% Before the visualization is started, it is checked whether the key
+% /data point/name is set (to a non-empty value). If so,
+% a coordinate is created with the given canvas x and y values and
+% this key's value as name.
+%
+% Finally, finish data point allows objects to do any final processing
+% of the data point.
+
+\def\pgfdatapoint@surveyphase{%
+ \pgf@signalpreparedatapoint.emit()%
+ \pgf@signalmapdatapoint.emit()%
+ \pgf@signalsurveydatapoint.emit()%
+}%
+
+\def\pgfdatapoint@visualizationphase{%
+ \pgf@signalpreparedatapoint.emit()%
+ \pgfdvmapdatapointtocanvas%
+ \pgfkeysifdefined{/data point/name}
+ {%
+ \pgfcoordinate{\pgfkeysvalueof{/data point/name}}{\pgfpointdvdatapoint}%
+ }{}%
+ \pgf@signalvisualizedatapoint.emit()%
+ \pgf@signalfinishdatapoint.emit()%
+}%
+
+
+
+% Compute a position of a data point
+%
+% Description:
+%
+% This command uses a special signal to compute the position where a
+% data point should be visualized on the canvas. In detail, the
+% following happens:
+%
+% A local scope is created and the
+% transformation matrix is reset. Then, two signals are emitted: First,
+% "map data points" and then "transform data point". The first
+% lets listening objects "map" the object by setting up
+% attributes of the data point. The second asks objects
+% listening to this signal to transform the current transformation
+% matrix. After the signals, we compute where
+% the origin lies inside this transformed coordinate system. Then the
+% two keys /data point/canvas x and /data point/canvas y are set to
+% the values of this position. The local scope ends (but the settings
+% of the keys persist by a bit of magic), thus restoring the
+% transformation matrix to its original value.
+
+\def\pgfdvmapdatapointtocanvas{%
+ {%
+ \pgfpointdvlocaldatapoint
+ % Smuggle outside group
+ \expandafter%
+ }%
+ \edef\pgf@marshal{%
+ \noexpand\pgfkeyssetvalue{/data point/canvas x}{\the\pgf@x}
+ \noexpand\pgfkeyssetvalue{/data point/canvas y}{\the\pgf@y}
+ }%
+ \pgf@marshal%
+}%
+
+% Help functions for locating a canvas data point
+%
+% Description:
+%
+% The first function returns the data point computed by a
+% canvasposition... call.
+
+\def\pgfpointdvdatapoint{%
+ \pgfqpoint{\pgfkeysvalueof{/data point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}%
+}%
+
+\def\pgfpointdvlocaldatapoint{%
+ {%
+ % only returns the data point in \pgf@x and \pgf@y, does not set
+ % canvas x and canvas y
+ \pgf@signalmapdatapoint.emit()%
+ \pgftransformreset%
+ \pgf@signaltransformdatapoint.emit()%
+ \pgfpointtransformed{\pgfpointorigin}%
+ }%
+}%
+
+
+
+%
+% Special path constructions commands
+%
+%
+% The following commands are used to construct paths based on
+% datapoints.
+%
+% Normally, all these methods need to do is to compute the current
+% canvas position of the current data point and then do a moveto,
+% lineto or some other operation to this position.
+%
+% However, when the coordinate system is weird, like with polar
+% coordinates or spherical or log-polar coordinate or whatever, a
+% straight line "along an attribute" is no longer a straight line.
+% In this case, two actions can be taken:
+%
+% 1. The problem can be ignored, resulting in a wrong line.
+% 2. Some clever algorithm kicks in an replaces the straight line by
+% the correct replacement.
+%
+% As always, when a computer tries to be clever, things can go
+% wrong... Nevertheless, some support for the second method is
+% given. This works as follows: Objects can register to the data
+% visualization path signal. This signal is emitted every time the
+% lineto or moveto commands are executed. If an object reacts to such
+% a command and handles it, it should set
+% \pgfdvhandledtrue.
+
+\newif\ifpgfdvhandled
+
+\def\pgfdv@generic#1#2#3{%
+ {%
+ \pgfdvhandledfalse%
+ \pgf@signalmapdatapoint.emit()%
+ #1.emit(#2)%
+ \ifpgfdvhandled%
+ \else%
+ \pgf@process{%
+ \pgftransformreset%
+ \pgf@signaltransformdatapoint.emit()%
+ \pgfpointtransformed{\pgfpointorigin}%
+ }%
+ #3{}%
+ \fi%
+ }%
+}%
+
+
+% Handle a moveto
+%
+% This command has no parameters since the target of the moveto is
+% given by the canvas position of the current local data point.
+\def\pgfpathdvmoveto{%
+ \pgfdv@generic{\pgf@signalpath}{\pgfdvpathmovetotoken}{\pgfpathmoveto}
+}%
+
+
+% Handle a lineto
+%
+% This command has no parameters since the target of the moveto is
+% given by the canvas position of the current local data point.
+\def\pgfpathdvlineto{%
+ \pgfdv@generic{\pgf@signalpath}{\pgfdvpathlinetotoken}{\pgfpathlineto}
+}%
+
+
+
+% Compute a normalized vector at the current point pointing along a
+% line from #1 to #2.
+%
+% #1 = code for setting the attributes of the first point
+% #2 = code for setting the attributes of the second point
+%
+% The current point should be a point on a line from #1 to
+% #2. Both points as well as the current point are
+% localized on the canvas and a vector pointing from the first point
+% to the second one is returned. However, for instance in polar
+% coordinates the vector may actually "point along" the angle axis.
+%
+% Internally, this command first sets up the first data point and then
+% emits a "direction" signal with the \pgfdvpathdirectionfromtoken set and
+% then sets up the second point and emits the corresponding
+% ...totoken. Finally, the \pgfdvpathdirectionattoken is emitted.
+%
+
+\def\pgfpointdvdirection#1#2{%
+ {
+ {
+ #1
+ \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectionfromtoken}{\xdef\pgf@dv@from{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}
+ }
+ {
+ #2
+ \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{\xdef\pgf@dv@to{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}
+ }
+ {\pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectionattoken}{%
+ \pgf@process{
+ \pgfpointnormalised{%
+ \pgfpointdiff{\pgf@dv@from}{\pgf@dv@to}
+ }
+ }}}
+ }
+}%
+
+
+
+
+
+%
+%
+% Data parsing and formatting
+%
+%
+
+
+
+% Run the rendering pipeline on a dataset and/or save the dataset.
+%
+% #1 = options with path /pgf/data/
+% #2 = optionally data given inline in curly braces.
+%
+% Description:
+%
+% This command is used to define a data set. For a single data
+% visualization, multiple data sets can be defined, they will
+% accumulate. Data can be in different formats, as specified by the
+% "format" key, and you can define new formats.
+%
+% The settings of the following keys are important:
+%
+% /pgf/data visualization/obj
+% contains a handle to the dv-object
+%
+% /pgf/data/format
+% stores the format (see below)
+%
+% /pgf/data/read from file
+% determines where the data is.
+%
+% /pgf/data/store in group
+% when nonempty, the data is stored here instead of being fed to the
+% rendering pipeline
+%
+% /pgf/data/use group
+% when nonempty, data that has previously been stored here using
+% |define group| is read from here and all other keys are ignored
+%
+% If "read from file" is empty, the data is stored in the argument that
+% follows. Otherwise, the data is read from the specified source file.
+% This data is stored in an internal variable, which is local to the
+% current group.
+%
+% After the group, the key "/pgf/data/continue code" will be
+% executed.
+%
+% When the data is actually used later on (during a survey or a
+% visualization), independently of what source is used, a format
+% handler is started for each data set. This works as follows: first,
+% the handler's startup code is executed. Then for each line of the
+% data file/the data given inline, the line handler function is
+% called. Finally, the data format end handler is called.
+%
+% The format handler's job is to call \pgfdatapoint each time a
+% complete data point has been produced.
+%
+% Example:
+%
+% \pgfoonew \dv=new data visualization()
+% \pgfoonew \obj=new attribute mapper(...)
+% ...
+%
+% \pgfkeys{/pgf/data/.cd,
+% column 1=dax/low,
+% column 2=dax/high,
+% column 3=dax/entry,
+% column 4=dax/exit}
+%
+% \pgfdata[format=space separated columns]
+% {
+% % today
+% 2000 2300 2100 2200
+% 2000 2350 2200 2500
+% 2200 2300 2250 2260
+% 1800 2260 2260 1900
+% 2000 2300 2100 2200
+% }
+%
+% \pgfdata[format=comma separated columns]
+% {
+% % yesterday
+% 2000, 2350, 2200, 2250
+% 2200, 2300, 2250, 2260
+% }
+%
+% \pgfdata[read from file=data.csv,format=comma separated columns]
+%
+% \dv.survey()
+% \dv.visualize()
+
+\def\pgfdata{\pgfutil@ifnextchar[{\pgf@datagroup@data@opt}{\pgf@datagroup@data@opt[]}}%}%
+\def\pgf@datagroup@data@opt[#1]{%
+ % Ok, add one data thing...
+ \begingroup%
+ \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}%
+ \pgfkeysgetvalue{/pgf/data/continue code}\pgf@dv@cont@code%
+ \global\let\pgf@dv@cont@code\pgf@dv@cont@code%
+ \pgfkeysgetvalue{/pgf/data/use group}\pgf@dv@use@group%
+ \ifx\pgf@dv@use@group\pgfutil@empty%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})}%
+ \expandafter\pgf@datagroup@data@opt@cont%
+ \else%
+ \expandafter\ifx\csname pgf@dv@group@@\pgf@dv@use@group\endcsname\relax%
+ \pgferror{Undefined data group '\pgf@dv@use@group'}%
+ \else%
+ {%
+ \pgfkeys{/pgf/data/define group/.code=}% no redefinitions during use
+ \csname pgf@dv@group@@\pgf@dv@use@group\endcsname%
+ }%
+ \fi%
+ \endgroup%
+ \expandafter\pgf@dv@cont@code%
+ \fi%
+}%
+\def\pgf@datagroup@data@opt@cont{%
+ \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format%
+ \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname%
+ \ifx\pgf@dv@format@catcodes\relax
+ \pgferror{Unknown data format '\pgf@dv@format'}%
+ \else%
+ \pgfkeysgetvalue{/pgf/data/read from file}\pgf@dv@source%
+ \ifx\pgf@dv@source\pgfutil@empty%
+ \let\pgf@next\pgf@datagroup@grab@inline%
+ \else%
+ \let\pgf@next\pgf@datagroup@grab@external%
+ \fi%
+ \pgf@next%
+}%
+
+\def\pgf@datagroup@grab@inline{%
+ \pgfutil@ifnextchar\bgroup{%
+ \begingroup%
+ \catcode`\^^M=\active%
+ \pgf@dv@format@catcodes%
+ \pgf@datagroup@grab@@inline}%
+ {\pgferror{Opening brace expected}}%
+}%
+\def\pgf@datagroup@grab@external{%
+ \fi%
+ \endgroup%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@external}}})}%
+ \pgf@dv@cont@code%
+}%
+
+\def\pgf@dv@do@adddata#1{%
+ \pgfkeysgetvalue{/pgf/data/store in group}\pgf@dv@temp%
+ \ifx\pgf@dv@temp\pgfutil@empty%
+ #1%
+ \else%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@dv@group@@\pgf@dv@temp\endcsname{#1}%
+ \fi%
+}%
+
+{\catcode`\^=7 \catcode`\^^M=13
+ \gdef\pgf@datagroup@grab@@inline#1{%
+ \endgroup%
+ \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@inline#1^^M\pgf@@eol}}})}%
+ \fi%
+ \endgroup%
+ \pgf@dv@cont@code%
+ }%
+}%
+\def\pgf@@eol{\pgf@eol}%
+
+\def\pgf@do@data#1#2{%
+ \begingroup%
+ \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}%
+ \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format%
+ \expandafter\let\expandafter\pgf@dv@format@line\csname pgfdv@format@\pgf@dv@format @line\endcsname%
+ \expandafter\let\expandafter\pgf@dv@format@emptyline\csname pgfdv@format@\pgf@dv@format @empty\endcsname%
+ \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@startup\endcsname%
+ #2%
+ \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@end\endcsname%
+ \endgroup%
+}%
+
+
+%
+% Read external file
+%
+
+\def\pgf@datagroup@do@external{%
+ \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@catcodes\endcsname%
+ \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/read from file} %
+ \ifeof\r@pgf@reada\relax
+ \pgferror{Data file '\pgfkeysvalueof{/pgf/data/read from file}' not found}%
+ \else
+ \pgf@datagroup@readline%
+ \fi
+ \immediate\closein\r@pgf@reada%
+}%
+
+\def\pgf@partext{\par}%
+\def\pgf@datagroup@readline{%
+ \endlinechar=-1 % suppress white space at end; this is local to `\pgfdata`
+ \immediate\read\r@pgf@reada to \pgf@temp%
+ \ifx\pgf@temp\pgf@partext%
+ \pgf@dv@format@emptyline%
+ \else%
+ \ifx\pgf@temp\pgfutil@empty%
+ \pgf@dv@format@emptyline%
+ \else%
+ \expandafter\pgf@dv@format@line\pgf@temp\pgfeol%
+ \fi%
+ \fi%
+ \ifeof\r@pgf@reada\else\expandafter\pgf@datagroup@readline\fi%
+}%
+
+
+%
+% Read inline data
+%
+
+\def\pgf@datagroup@do@inline{%
+ \pgf@dv@handle@line%
+}%
+
+{\catcode`\^=7 \catcode`\^^M=13
+\gdef\pgf@dv@handle@line{%
+ \pgfutil@ifnextchar^^M{\pgf@dv@format@emptyline\expandafter\pgf@dv@handle@line\pgfutil@gobble}%
+ {\pgfutil@ifnextchar\pgf@@eol{\pgfutil@gobble}{\pgf@dv@handle@nonemptyline}}%
+}%
+\gdef\pgf@dv@handle@nonemptyline#1^^M{%
+ \pgf@dv@format@line#1\pgfeol%
+ \pgf@dv@handle@line%
+}%
+}%
+
+\pgfkeys{
+ /pgf/data/data visualization obj/.initial=\undefined,
+ /pgf/data/format/.initial=table,% the default format
+ /pgf/data/read from file/.initial=,
+ /pgf/data/inline/.style={read from file=},
+ /pgf/data/continue code/.initial=,
+ /pgf/data/store in group/.initial=,
+ /pgf/data/new group/.code={\expandafter\global\expandafter\let\csname pgf@dv@group@@#1\endcsname\pgfutil@empty},
+ /pgf/data/use group/.initial=,
+}%
+
+
+
+
+
+
+% Define a data format
+%
+% #1 = format name
+% #2 = catcode code
+% #3 = startup code
+% #4 = line arguments
+% #5 = line code
+% #6 = empty line code
+% #7 = end code
+%
+% Description:
+%
+% This command defines a new data format for data visualization. When
+% a data set is visualized and the format is set to #1, this handler
+% is used to parse the data.
+%
+% In detail, the \pgfdata command will select a source. Before this
+% source is read, #2 will be executed to setup the
+% catcodes. Additionally, each time the data is parsed, #3 will be
+% called. Then, for each nonempty line of the source, the
+% command #5 is executed, where the line will be matched against the
+% argument pattern given in #4. For empty lines, #6 will be executed
+% instead. At the end of the source, #7 will be executed.
+
+\def\pgfdeclaredataformat#1#2#3#4#5#6#7{%
+ \expandafter\def\csname pgfdv@format@#1@catcodes\endcsname{#2}%
+ \expandafter\def\csname pgfdv@format@#1@startup\endcsname{#3}%
+ \expandafter\def\csname pgfdv@format@#1@line\endcsname#4\pgfeol{#5}%
+ \expandafter\def\csname pgfdv@format@#1@empty\endcsname{#6}%
+ \expandafter\def\csname pgfdv@format@#1@end\endcsname{#7}%
+}%
+
+
+
+%
+% Predefined standard formats
+%
+
+% TeX code format
+%
+% Description:
+%
+% The lines of the data set are assumed to contain executable TeX
+% code that will call \pgfdatapoint.
+%
+% Example:
+%
+% \pgfdatavisualizationrender[format=TeX code]
+% \dataset{
+% \pgfkeyssetvalue{/data point/x}{5}
+% \pgfkeyssetvalue{/data point/y}{5}
+% \pgfdatapoint
+% \pgfkeyssetvalue{/data point/x}{6}
+% \pgfkeyssetvalue{/data point/y}{6}
+% \pgfdatapoint
+% }
+
+\pgfdeclaredataformat{TeX code}{}{}{#1}{#1 }{}{}%
+
+
+
+% Key-value lines format
+%
+% Description:
+%
+% The lines of the data set are passed to \pgfkeys with the path set
+% to /data point.
+%
+% Example:
+%
+% \data[format=named] {
+% x=5, y=6, hi=9
+% x=7, y=6, lo=10
+% }
+
+\pgfdeclaredataformat{named}{}{}{#1}{\pgf@dv@parse@named#1,\pgf@stop}{}{}%
+\def\pgf@dv@parse@named{%
+ \pgfutil@ifnextchar\pgf@stop{\pgfdatapoint\pgfutil@gobble}{\pgf@dv@parse@named@}
+}%
+\def\pgf@dv@parse@named@#1=#2,#3\pgf@stop{%
+ \foreach \pgf@dv@temp in {#2} {%
+ \def\pgf@dv@tempb{/data point/#1=}%
+ \expandafter\expandafter\expandafter\pgfkeys%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@dv@tempb\pgf@dv@temp}%
+ \pgf@dv@parse@named#3\pgf@stop%
+ }
+}%
+
+
+
+
+
+% Table format
+%
+% Description:
+%
+% A table consists of a head line, which contains the attribute names
+% of the values that will be found in the following lines. Each line
+% (except for the headline) contains one data point.
+%
+% Inside each line the data points are separated by a separator like a
+% comma or a space or a colon. The separator can be configured using
+% the key /pgf/data/separator (leave the separator empty or set it to
+% \space for a space as separator). The default separator is a comma.
+%
+% Some tables will miss the headline. In this case, using the
+% /pgf/data/headline key you can provide a headline yourself.
+%
+% Example:
+%
+% \data[format=table] {
+% x y
+% 10 5
+% 11 6
+% 6 7
+% }
+%
+% \data[format=table,separator={,}] {
+% x, y
+% 10, 5
+% 11, 6
+% 6, 7
+% }
+%
+% \data[format=table,headline=x y] {
+% 10 5
+% 11 6
+% 6 7
+% }
+
+\pgfdeclaredataformat{table}
+{} % no catcodes
+{
+ \pgfkeysgetvalue{/pgf/data/headline}\pgf@dv@headline
+ \pgfkeysgetvalue{/pgf/data/separator}\pgf@dv@separator
+ \ifx\pgf@dv@separator\pgfutil@empty
+ \let\pgf@dv@separator\space
+ \fi
+ \ifx\pgf@dv@separator\pgf@dv@spacetext
+ \let\pgf@dv@separator\space
+ \fi
+ \expandafter\def\expandafter\pgf@dv@till@separator%
+ \expandafter##\expandafter1\pgf@dv@separator{\pgf@dv@table@handle{##1}}
+ \expandafter\def\expandafter\pgf@dv@till@separator@head%
+ \expandafter##\expandafter1\pgf@dv@separator{\pgf@dv@head@handle{##1}}
+ \ifx\pgf@dv@headline\pgfutil@empty
+ % Ok, read headline from file
+ \pgfdv@firstlinetrue
+ \else
+ % Headline already set
+ \pgfdv@firstlinefalse
+ \expandafter\pgf@dv@parse@headline\expandafter{\pgf@dv@headline}
+ \fi
+}
+{#1} % special line pattern, so read everything
+{
+ \ifpgfdv@firstline
+ \pgfdv@firstlinefalse
+ \pgf@dv@parse@headline{#1}
+ \else
+ {
+ \c@pgf@counta=0\relax% keep track of attribute number
+ \def\pgf@marshal{\pgf@dv@parse@table#1}
+ \expandafter\expandafter\expandafter\pgf@marshal%
+ \expandafter\pgf@dv@separator\expandafter\pgfeol\pgf@dv@separator
+ \pgfdatapoint
+ }
+ \fi
+}
+{}% ignore empty lines
+{}% no special end code
+
+\newif\ifpgfdv@firstline
+
+\pgfkeys{
+ /pgf/data/separator/.initial={,},
+ /pgf/data/headline/.initial=
+}%
+\def\pgf@dv@spacetext{\space}%
+
+\def\pgf@dv@parse@table{%
+ \pgfutil@ifnextchar"% Special, but ignored right now...
+ {\pgferror{csv with quotes not yet implemented}}
+ {\pgf@dv@till@separator}
+}%
+\def\pgf@dv@table@handle#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfeoltext%
+ % Bingo! Stop
+ \let\pgf@next=\relax%
+ \else%
+ \advance\c@pgf@counta by1\relax%
+ \pgfkeysgetvalue{/pgf/data/table/attribute \the\c@pgf@counta}\pgf@dv@target
+ \ifx\pgf@dv@target\relax%
+ \edef\pgf@dv@target{attribute \the\c@pgf@counta}
+ \pgfkeyslet{/pgf/data/table/attribute \the\c@pgf@counta}\pgf@dv@target
+ \fi
+ \pgfkeyssetvalue{/data point/\pgf@dv@target}{#1}
+ \let\pgf@next=\pgf@dv@parse@table%
+ \fi%
+ \pgf@next%
+}%
+
+
+
+\def\pgf@dv@parse@headline#1{
+ \c@pgf@counta=0\relax% keep track of attribute number
+ \def\pgf@marshal{\pgf@dv@doparse@headline#1}
+ \expandafter\expandafter\expandafter\pgf@marshal%
+ \expandafter\pgf@dv@separator\expandafter\pgfeol\pgf@dv@separator
+}%
+
+\def\pgf@dv@doparse@headline{%
+ \pgfutil@ifnextchar"% Special, but ignored right now...
+ {\pgferror{csv with quotes not yet implemented}}
+ {\pgf@dv@till@separator@head}
+}%
+\def\pgf@dv@head@handle#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfeoltext%
+ % Bingo! Stop
+ \let\pgf@next=\relax%
+ \else%
+ \advance\c@pgf@counta by1\relax%
+ \pgfkeyssetvalue{/pgf/data/table/attribute \the\c@pgf@counta}{#1}
+ \let\pgf@next=\pgf@dv@doparse@headline%
+ \fi%
+ \pgf@next%
+}%
+
+\def\pgfeoltext{\pgfeol}%
+
+
+%
+%
+% Micro math kernel for dv
+%
+%
+
+% The idea behind the following methods is to "abstract away" which
+% math engine is used. In the future, something fancy build on luatex
+% might be used, so it would we should not rely directly on the
+% fpu library code.
+%
+% The system works as follows: First, you "enter" a number into the
+% engine. When you do so, it is converted into some internal
+% representation that cannot be accessed any more and is called a
+% "math variable" henceforth. All commands of the
+% math system only work on math variables.
+%
+% In order to "exit" a value stored in a math variable from the
+% engine, some other macros can be used.
+%
+% Operations like addition or multiplication take two math variables
+% and store the result in another math variable.
+
+
+
+% Store a value in a math variable of the math engine
+%
+% #1 = a math variable (a macro name) that is to store the value
+% #2 = an expression describing a number
+%
+%
+% Description:
+%
+% The #2 should be an expression that evaluates to a number. However,
+% due to the way the pgf math engine(s) work, currently, there are
+% several restrictions/the syntax is not as simple as one might
+% hope. Fortunately, the syntax is hopefully compatible with
+% easier-to-use future systems.
+%
+% The syntax is as follows: #2 may be
+%
+% 1. a simple high-precision number. This number is currently directly
+% passed to \pgfmathfloatparsenumber, so typical permissible values
+% are "100" or "10000000000000" or "nan" or "-5.673543345345e9000"
+%
+% 2. a mathematical expression, which *must* be surrounded by
+% parentheses. From a "mathematical" point of view these
+% parentheses are superfluous, but the they are used to help pgf
+% distinguish expressions from high-precision numbers. (If, in the
+% future, expressions may contain high precision numbers, the
+% parentheses will simply be ignored.)
+%
+% The expression is evaluated using \pgfmathparse, which means that
+% TeX-precision is used. This means, for instance, that numbers
+% larger than about 16500 will create error messages.
+%
+% The advantage is that you may say write things like "(5+6)" or
+% "(pi/2)".
+%
+% 3. In case #2 starts with an exclamation mark (indicating an
+% "escape"), everything following the mark is simply evaluated by
+% TeX. The effect of evaluating #2 should be that the math
+% variable "\pgfdvmathvalue" is set to some value. This value will
+% then be transferred to #1.
+%
+% 4. In case #2 is the result of calling \pgfdvmathexitbyserializing, the
+% "serialized" value is restored. The idea is that the serialized
+% will turn its internal representation of a number into something
+% that can be stored as a text somewhere.
+%
+% Currently, "@" at the beginning of #2 is used to indicate that
+% what follows is a serialized version of a math variable.
+%
+% In order to determine which of the above cases is to be used for a
+% variable, the first symbol #2 is checked, *after* the first symbol
+% of #2 has been expanded once (using \expandafter once).
+%
+% Example:
+%
+% \pgfdvmathenter{\mymacro}{20000000000000}
+% \pgfdvmathenter{\mymacro}{(5+pi)}
+% \pgfdvmathenter{\mymacro}{!\pgfdvmathadd{\pgfdvmathvalue}{\a}{\b}}
+%
+% \pgfdvmathenter{\foo}{5}
+% \pgfdvmathexitbyserializing{\somevalue}{\foo}
+% \pgfdvmathenter{\mymacro}{\somevalue}
+
+\def\pgfdvmathenter#1#2{%
+ \expandafter\pgfdvmathenter@check\expandafter#1#2\pgfdvmath@end%
+}%
+\def\pgfdvmathenter@check#1{%
+ \pgfutil@ifnextchar @{\pgfdvmath@internal#1}{%
+ \pgfutil@ifnextchar ({\pgfdvmath@expression#1}{%)
+ \pgfutil@ifnextchar !{\pgfdvmath@execute#1}{\pgfdvmath@normal#1}}}%
+}%
+
+\def\pgfdvmath@internal#1@#2\pgfdvmath@end{%
+ \def#1{#2}%
+}%
+\def\pgfdvmath@expression#1(#2)#3\pgfdvmath@end{%
+ \pgfmathparse{#2}%
+ \pgfmathfloatparsenumber{\pgfmathresult}%
+ \let#1=\pgfmathresult%
+}%
+\def\pgfdvmath@execute#1!#2\pgfdvmath@end{%
+ #2%
+ \let#1=\pgfdvmathvalue%
+}%
+\def\pgfdvmath@normal#1#2\pgfdvmath@end{%
+ \pgfmathfloatparsenumber{#2}%
+ \let#1=\pgfmathresult%
+}%
+
+
+
+% Print a math variable in the math engine using \pgfmathprintnumber
+%
+% #1 = math variable
+%
+% Description:
+%
+% See the description of \pgfmathprintnumber
+%
+% Example:
+%
+% \pgfdvmathenter{\mymacro}{20000000000000}
+% \pgfdvmathexitbyprinting{\mymacro}
+
+\def\pgfdvmathexitbyprinting#1{%
+ \pgfmathprintnumber{#1}%
+}%
+
+
+
+% Exit a math variable as a number in a scientific and portable number
+% format in a macro
+%
+% #1 = macro in which to store the value
+% #2 = math variable
+%
+% Description:
+%
+% You can exit a number using this operation. You can then directly
+% reenter the number using \pgfdvmathenter
+%
+% Example:
+%
+% \pgfdvmathenter{\mynumber}{20000000000000}
+% \pgfdvmathexitbyscientificformat{\mymacro}{\mynumber}
+
+\def\pgfdvmathexitbyscientificformat#1#2{%
+ \edef#1{\pgfmathfloatvalueof#2}%
+}%
+
+
+
+% Exit a math variable as a "serialized" (= string-based)
+% version.
+%
+% #1 = macro in which to store the value
+% #2 = math variable
+%
+% Description:
+%
+% The serialized version can be reentered using
+% \pgfmathenter and is similar to \pgfdvmathexitbyscientificformat,
+% but exiting and entering are (a bit) faster.
+%
+% Example:
+%
+% \pgfdvmathenter{\mynumber}{20000000000000}
+% \pgfdvmathexitbyserializing{\mymacro}{\mynumber}
+
+\def\pgfdvmathexitbyserializing#1#2{%
+ \edef#1{@#2}%
+}%
+
+
+
+
+
+% Operations on two numbers
+%
+% #1 = macro that should store the result of applying the
+% corresponding operation to the following:
+% #2 = entered number
+% #3 = entered number
+%
+% Description:
+%
+% Sets #1 to the result of applying an operation to #2 and #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{2000}
+% \pgfdvmathenter{\b}{5+6}
+% \pgfdvmathadd{\c}{\a}{\b}
+
+\def\pgfdvmathadd#1#2#3{%
+ \pgfmathfloatadd{#2}{#3}%
+ \let#1=\pgfmathresult%
+}%
+\def\pgfdvmathsub#1#2#3{%
+ \pgfmathfloatsubtract{#2}{#3}%
+ \let#1=\pgfmathresult%
+}%
+\def\pgfdvmathmul#1#2#3{%
+ \pgfmathfloatmultiply{#2}{#3}%
+ \let#1=\pgfmathresult%
+}%
+\def\pgfdvmathdiv#1#2#3{%
+ \pgfmathfloatdivide{#2}{#3}%
+ \let#1=\pgfmathresult%
+}%
+
+% Multiply by small number
+%
+% #1 = macro that should store the result of applying the
+% corresponding operation to the following:
+% #2 = entered number
+% #3 = fixed point number like 2 or 0.5, but not 10000000000
+%
+% Description:
+%
+% Sets #1 to the result of applying an operation to #2 and #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{2000}
+% \pgfdvmathadd{\b}{\a}{0.2}
+% % \b now stores 400
+
+\def\pgfdvmathmulfixed#1#2#3{%
+ \pgfmathfloatmultiplyfixed{#2}{#3}%
+ \let#1=\pgfmathresult%
+}%
+
+
+
+% Log, ln and exponent functions
+%
+% #1 = a math variable
+% #2 = a math variable
+%
+% Description
+%
+% \pgfdvmathln will compute #1 = ln(#2)
+% \pgfdvmathlog will compute #1 = log_{10}(#2)
+% \pgfdvmathexp will compute #1 = exp(#2)
+% \pgfdvmathpowten will compute #1 = 10^{#2}
+
+\def\pgfdvmathln#1#2{%
+ \pgfmathfloatln{#2}%
+ \let#1=\pgfmathresult%
+}%
+
+\def\pgfdvmathlog#1#2{%
+ \pgfmathfloatln{#2}%
+ \pgfmathfloatmultiply{\pgfmathresult}{\pgfdvmathalwaysloge}%
+ \let#1=\pgfmathresult%
+}%
+
+\def\pgfdvmathexp#1#2{%
+ \pgfmathfloatexp{#2}%
+ \let#1=\pgfmathresult%
+}%
+
+\def\pgfdvmathpowten#1#2{%
+ \pgfmathfloattofixed{#2}%
+ \let\pgf@dv@temp=\pgfmathresult%
+ \pgfmathround{\pgf@dv@temp}%
+ \let\pgf@dv@temp@round=\pgfmathresult%
+ \pgf@x=\pgf@dv@temp@round pt%
+ \pgf@x=-\pgf@x%
+ \advance\pgf@x by\pgf@dv@temp pt\relax%
+ \ifdim\pgf@x>0.0002pt%
+ \pgfmathfloatmultiply{#2}{\pgfdvmathalwayslnten}%
+ \pgfmathfloatexp{\pgfmathresult}%
+ \else
+ \ifdim\pgf@x<-0.0002pt%
+ \pgfmathfloatmultiply{#2}{\pgfdvmathalwayslnten}%
+ \pgfmathfloatexp{\pgfmathresult}%
+ \else
+ \pgf@x=\pgf@dv@temp@round sp%
+ \c@pgf@counta=\pgf@x%
+ \pgfmathfloatcreate{1}{1.0}{\the\c@pgf@counta}%
+ \fi
+ \fi
+ \let#1=\pgfmathresult%
+}%
+
+
+% Floor functions
+%
+% #1 = a math variable
+% #2 = a math variable
+%
+% Description
+%
+% Sets #1 to the largest integer less or equal to #2
+
+\def\pgfdvmathfloor#1#2{%
+ \pgfmathifisint{#2}{%
+ \let#1=#2%
+ }{%
+ \pgfmathfloatgetflags#2\c@pgf@counta%
+ \ifcase\c@pgf@counta
+ \let#1=\pgfdvmathalwayszero%
+ \or
+ \pgfmathfloatfloor{#2}%
+ \let#1=\pgfmathresult%
+ \or
+ \pgfmathfloatsubtract{\pgfdvmathalwaysone}{#2}%
+ \pgfmathfloatfloor{\pgfmathresult}%
+ \pgfmathfloatsubtract{\pgfdvmathalwayszero}{\pgfmathresult}%
+ \let#1=\pgfmathresult%
+ \or\let#1=#2%
+ \or\let#1=#2%
+ \or\let#1=#2%
+ \fi%
+ }%
+}%
+
+
+% Advanced unary operations
+%
+% #1 = macro that should store the result of applying the
+% operation to an entered number
+% #2 = the operation (as a string like "ln")
+% #3 = entered number
+%
+% Description:
+%
+% Sets #1 to the result of applying #2 to #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{2000}
+% \pgfdvmathunaryop{\b}{ln}{\a}
+
+\def\pgfdvmathunaryop#1#2#3{%
+ \csname pgfmathfloat#2\endcsname{#3}%
+ \let#1=\pgfmathresult%
+}%
+
+
+% Advanced binary operations
+%
+% #1 = macro that should store the result of applying the
+% operation to two entered number
+% #2 = the operation (as a string like "veclen")
+% #3 = first argument (an entered number)
+% #4 = second argument (an entered number)
+%
+% Description:
+%
+% Sets #1 to the result of applying #2 to #3
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{3}
+% \pgfdvmathenter{\b}{4}
+% \pgfdvmathbinop{\c}{veclen}{\a}{\b}
+
+\def\pgfdvmathbinop#1#2#3#4{%
+ \csname pgfmathfloat#2\endcsname{#3}{#4}%
+ \let#1=\pgfmathresult%
+}%
+
+
+
+% Comparing values
+%
+% #1 = first math variable
+% #2 = second math variable
+% #3 = code to-be-executed if #1 < #2
+% #4 = code to-be-executed if #1 >= #2
+%
+%
+% Example:
+%
+% \pgfdvmathenter{\a}{3}
+% \pgfdvmathenter{\b}{4}
+% \pgfdvmathifless{\a}{\b}{yes}{should not happen}
+
+\def\pgfdvmathifless#1#2#3#4{%
+ \pgfmathfloatlessthan{#1}{#2}%
+ \ifpgfmathfloatcomparison#3\else#4\fi%
+}%
+
+
+
+
+%
+%
+% Standard objects for data visualization
+%
+%
+
+
+%
+% Transformers
+%
+
+\pgfooclass{linear transformer}
+{%
+ % Class linear transformer
+ %
+ % This class is a transformer class. It reacts to the transform
+ % datapoint signal. When this signal is raised, it will shift the
+ % coordinate system as follows: If the current value of /data
+ % point/this.attribute is 0, then the system is shifted to the
+ % current value of this.origin. If the current value is 1, the
+ % system is shifted to this.origin + this.unit vector. For other
+ % values of /data point/this.attribuate, the shift is interpolated
+ % between these two values.
+
+
+ \attribute attribute;%
+ % The attribute (/data point/this.attribute) by which
+ % the unit vector is multiplied. If it is empty (which is
+ % different from 0), no transformation is done at all.
+
+ \attribute origin = \pgfpointorigin;%
+ % The shift in case the /data point/this.attribute is 0.
+
+ \attribute unit vector;%
+ % The coordinate system is additionally shifted by this amount
+ % times the current value of /data point/this.attribute.
+
+
+ % Constructor
+ %
+ % #1 = attribute that is being transformed. Example: x
+ % #2 = a vector corresponding to one unit of #1.
+ % Example: \pgfpoint{1cm}{0cm}
+ \method linear transformer(#1,#2) {
+ \pgfooset{attribute}{#1}
+ \pgf@process{#2}
+ \edef\pgf@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgfoolet{unit vector}\pgf@temp%
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,transform,transform datapoint signal)
+ }%
+
+ % Setter
+ \method set origin(#1) {
+ \pgf@process{#1}
+ \edef\pgf@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgfoolet{origin}\pgf@temp%
+ }%
+
+ % Slot
+ %
+ % This slot should be connected to the transform datapoint
+ % signal. When this signal is emitted, the coordinate system will be
+ % shifted according to the current value of the attribute.
+ \method transform() {
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val%
+ \ifx\pgf@dv@val\pgfutil@empty%
+ \else%
+ \ifx\pgf@dv@val\relax%
+ \else%
+ \pgfdvmathenter{\pgf@dv@math@var}{\pgf@dv@val}%
+ \pgfdvmathexitbyscientificformat{\pgf@dv@val}{\pgf@dv@math@var}%
+ \pgftransformshift{\pgfoovalueof{origin}}%
+ \pgfmathfloatgetexponent\pgf@dv@math@var\c@pgf@counta%
+ \ifnum\c@pgf@counta<-3\relax%
+ \else%
+ \pgftransformshift{\pgfpointscale{\pgf@dv@val}{\pgfoovalueof{unit vector}}}%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+%
+% Numerical mapping of attributes to other attributes
+%
+
+\pgfooclass{interval mapper}
+{%
+ % Class interval mapper
+ %
+ % This interval mapper reacts to the map datapoint signal. Its purpose is to
+ % map one attribute to another attribute. For the first attribute,
+ % an intervals is specified.
+ %
+ % In addition to the in interval [a,b] there is also an outinterval
+ % [c,d]. Values in the range [a,b] are linearly mapped to the
+ % range [c,d] and the result is stored in the second attribute.
+ %
+ % For instance, if the first range is [10,20] and the second range
+ % is [0,100], then 10 is mapped to 0, 11 is mapped to 10, 20 is
+ % mapped to 100 and 30 is mapped to 200.
+ %
+ % It is permissible to specify an additional non-linear
+ % transformation function f. In this case, for an input value x the
+ % position of f(x) inside the interval [f(a),f(b)] is determined and
+ % this position is linearly mapped to [c,d].
+ %
+ % For example, if f(x) = log_10 (x) and the first range [a,b] =
+ % [10,1000] and the second range is [1,2], then 10 is mapped to 1,
+ % 100 is mapped to 1.5 (since f(100) = 3 lies in the middle
+ % between f(10) = 2 and f(1000) = 4) and 100000 is mapped to 3.
+
+
+ \attribute in;%
+ % The name of the input attribute. If the value of this attribute
+ % is empty or undefined, no mapping is done.
+ %
+ % The in attribute may have a subkey called .../const. If this key
+ % has a value different from \relax, it will always be used instead
+ % of the in attribute itself. This can be useful to temporarily
+ % set a constant value to a key inside a mapping chain.
+ %
+ % If the subkey /is min or max is set to "min" or "max", the mapping
+ % will always be done to the respective out min or out max values.
+
+ \attribute out;%
+ % The name of the output attribute.
+
+ \attribute trans;%
+ % Stores (more or less) the transformation function.
+
+ \attribute out min;%
+ % Start of the second range (the value of c).
+
+ \attribute out min;%
+ % End of the second range (the value of d).
+
+ \attribute trans in min;%
+ % Transformed value of the start of the first range (the value
+ % f(a)).
+
+ \attribute scale;%
+ % The scaling factor, that is, the value of (f(b)-f(a))/(d-c).
+
+
+ % Constructor
+ %
+ % #1 = input attribute. Example: velocity.
+ % #2 = output attribute. Example: x
+ % #3 = optional transformation function. The input value for this
+ % function is stored in entered number \pgfvalue.
+ % The output of the function should be stored in the
+ % same entered number.
+ %
+ % The intervals are set using setter methods later on.
+ %
+ \method interval mapper(#1,#2,#3) {
+ \pgfooset{in}{#1}
+ \pgfooset{out}{#2}
+ \def\pgf@temp{#3}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgfooset{trans}{%
+ #3%
+ }%
+ \fi%
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,map,map datapoint signal)
+ }%
+
+ % Method
+ %
+ % #1 = in interval minimum
+ % #2 = in interval maximum
+ % #3 = out interval minimum
+ % #4 = out interval maximum
+ %
+ % This method will (re)compute the correct mappings for the interval
+ % mapper.
+ \method set interval values(#1,#2,#3,#4) {
+ {%
+ \pgfdvmathenter{\pgf@in@interval@min}{#1}
+ \pgfdvmathenter{\pgf@in@interval@max}{#2}
+ \pgfdvmathenter{\pgf@out@interval@min}{#3}
+ \pgfdvmathenter{\pgf@out@interval@max}{#4}
+ % Let's start with the output, it's easier...
+ \pgfoolet{out min}{\pgf@out@interval@min}
+ \pgfoolet{out max}{\pgf@out@interval@max}
+ \pgfdvmathifless{\pgf@in@interval@min}{\pgf@in@interval@max}{%
+ \pgfdvmathsub{\pgf@out@diff}{\pgf@out@interval@max}{\pgf@out@interval@min}
+ \let\pgfvalue=\pgf@in@interval@min
+ \pgfoovalueof{trans}
+ \let\pgf@in@interval@min@transformed=\pgfvalue
+ \pgfoolet{trans in min}{\pgf@in@interval@min@transformed}%
+ \let\pgfvalue=\pgf@in@interval@max
+ \pgfoovalueof{trans}
+ \let\pgf@in@interval@max@transformed=\pgfvalue
+ \pgfdvmathsub{\pgf@diff@in@transformed}{\pgf@in@interval@max@transformed}{\pgf@in@interval@min@transformed}
+ %
+ % Precompute the scaling
+ %
+ \pgfdvmathdiv{\pgf@scale}{\pgf@out@diff}{\pgf@diff@in@transformed}%
+ \pgfoolet{scale}{\pgf@scale}%
+ }{%
+ \pgfoolet{scale}\pgf@dv@no@scale%
+ }%
+ }%
+ }%
+ \def\pgf@dv@no@scale{noscale}%
+
+ % Slot
+ \method map() {
+ \pgfooget{scale}\pgf@dv@scale
+ \ifx\pgf@dv@scale\pgfutil@empty%
+ % not yet setup
+ \else%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/is min or max}\pgf@dv@is%
+ \ifx\pgf@dv@is\pgf@min@text%
+ \pgf@dv@set@out@min%
+ \else%
+ \ifx\pgf@dv@is\pgf@max@text%
+ \pgf@dv@set@out@max%
+ \else%
+ \ifx\pgf@dv@scale\pgf@dv@no@scale%
+ \pgf@dv@mapper@goto@mid%
+ \else%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/const}\pgf@dv@external@value%
+ \ifx\pgf@dv@external@value\relax%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}}\pgf@dv@external@value%
+ \fi%
+ \ifx\pgf@dv@external@value\pgfutil@empty%
+ \pgf@dv@mapper@pos@check%
+ \else%
+ \ifx\pgf@dv@external@value\relax%
+ \pgf@dv@mapper@pos@check%
+ \else%
+ \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}%
+ \pgf@dv@mapper@trans
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ }%
+
+ \def\pgf@dv@set@out@min{%
+ \pgfkeyslet{/data point/\pgfoovalueof{out}/is min or max}\pgf@min@text%
+ \pgfooget{out min}{\pgf@minmax@temp}%
+ \pgf@dv@set@out@now%
+ }%
+ \def\pgf@dv@set@out@max{%
+ \pgfkeyslet{/data point/\pgfoovalueof{out}/is min or max}\pgf@max@text%
+ \pgfooget{out max}{\pgf@minmax@temp}%
+ \pgf@dv@set@out@now%
+ }%
+ \def\pgf@dv@set@out@now{%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{out}/offset}\pgf@dv@external@offset%
+ \ifx\pgf@dv@external@offset\relax\else%
+ \ifx\pgf@dv@external@offset\pgfutil@empty\else%
+ \pgfdvmathenter{\pgfvalue}{\pgf@minmax@temp}%
+ \pgfdvmathenter{\pgf@dv@offset}{\pgf@dv@external@offset}%
+ \pgfdvmathadd{\pgfvalue}{\pgfvalue}{\pgf@dv@offset}
+ \pgfdvmathexitbyserializing{\pgf@minmax@temp}{\pgfvalue}%
+ \fi
+ \fi
+ \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@minmax@temp%
+ }%
+
+ \def\pgf@dv@mapper@trans{
+ \pgfooget{trans in min}{\pgf@dv@trans@in@min}%
+ \pgfooget{scale}{\pgf@dv@scale}%
+ \pgfooget{out min}{\pgf@dv@out@min}%
+ \pgfoovalueof{trans}%
+ \pgfdvmathsub{\pgfvalue}{\pgfvalue}{\pgf@dv@trans@in@min}%
+ \pgfdvmathmul{\pgfvalue}{\pgfvalue}{\pgf@dv@scale}%
+ \pgfdvmathadd{\pgfvalue}{\pgfvalue}{\pgf@dv@out@min}%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{out}/offset}\pgf@dv@external@offset%
+ \ifx\pgf@dv@external@offset\relax\else%
+ \ifx\pgf@dv@external@offset\pgfutil@empty\else%
+ \pgfdvmathenter{\pgf@dv@offset}{\pgf@dv@external@offset}%
+ \pgfdvmathadd{\pgfvalue}{\pgfvalue}{\pgf@dv@offset}
+ \fi
+ \fi
+ \pgfdvmathexitbyserializing{\pgf@temp}{\pgfvalue}%
+ \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@temp%
+ }%
+
+ \def\pgf@dv@mapper@pos@check{%
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/out pos}\pgf@dv@pos@value%
+ \ifx\pgf@dv@pos@value\relax\else\if\pgf@dv@pos@value\pgfutil@empty\else%
+ \pgfmathsetmacro{\pgf@dv@pos@num}{\pgf@dv@pos@value}%
+ \pgfmathsetmacro{\pgf@dv@pos@num@prime}{1-\pgf@dv@pos@num}%
+ % Ok, compute transformed min position:
+ \pgfooget{out min}{\pgf@out@interval@min}
+ \pgfooget{out max}{\pgf@out@interval@max}
+ \pgfdvmathmulfixed{\pgf@out@interval@min}{\pgf@out@interval@min}{\pgf@dv@pos@num@prime}
+ \pgfdvmathmulfixed{\pgf@out@interval@max}{\pgf@out@interval@max}{\pgf@dv@pos@num}
+ \pgfdvmathadd{\pgf@out@val}{\pgf@out@interval@min}{\pgf@out@interval@max}%
+ \pgfdvmathexitbyserializing{\pgf@temp}{\pgf@out@val}%
+ \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@temp%
+ \fi\fi%
+ }%
+
+ \def\pgf@dv@mapper@goto@mid{%
+ % Ok, compute transformed min position:
+ \pgfooget{out min}{\pgf@out@interval@min}
+ \pgfooget{out max}{\pgf@out@interval@max}
+ \pgfdvmathmulfixed{\pgf@out@interval@min}{\pgf@out@interval@min}{.5}
+ \pgfdvmathmulfixed{\pgf@out@interval@max}{\pgf@out@interval@max}{.5}
+ \pgfdvmathadd{\pgf@out@val}{\pgf@out@interval@min}{\pgf@out@interval@max}%
+ \pgfdvmathexitbyserializing{\pgf@temp}{\pgf@out@val}%
+ \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@temp%
+ }%
+}%
+
+
+
+
+
+%\newif\ifpgf@dvclip
+\newif\ifpgf@dvignore
+
+\pgfooclass{scaling mapper}
+{%
+ % Class scaling mapper
+ %
+ % A scaling mapper is (mainly) used to scale an attribute in such a way
+ % that it can be rendered easily on a page. The idea is that you
+ % specify some attribute and a desired target interval size (like
+ % [0,5]). The scaling mapper will then survey the data and will setup a
+ % interval mapper in such a way that the minimum value present in the data is
+ % mapped to 0 and the maximum to 5. However, it is also possible to,
+ % say, only have the maximum value mapped to 5 and have 0 be mapped
+ % to 0. Other, more complicated specifications are also possible.
+ %
+ % The scaling mapper internally creates several objects: First, a surveyor
+ % for determining the minimum and maximum values of the attribute
+ % and a interval mapper for then mapping the values to the scaled
+ % values. Additionally, interval objects are needed.
+
+ \attribute in;%
+ % The to-be-scaled attribute;
+
+ \attribute out;%
+ % The attribute storing the scaled value.
+
+ \attribute in range obj;%
+ % This interval keep track of the range of the in attribute
+
+ \attribute scaling spec;%
+ % A specification of how the scaling should be performed.
+ %
+ % The format is the following:
+ %
+ % #1 at #2 and #3 at #4
+ %
+ % Here, #2 and #4 must be numbers. #1 and #3 can either be numbers
+ % or #1 can be the text "min" and #3 can be the text "max".
+ %
+ % The effect of such a specification is the following: The value #1
+ % is mapped to #2, the value #3 is mapped to #4 and values between
+ % #1 and #3 (or outside this range) are mapped linearly to a value
+ % between (or outside) #2 and #4. In case #1 is set to "min", the
+ % smallest observed value of the in-attribute is mapped to #3 and
+ % similarly for a value of "max" for #3.
+ %
+ % Additionally, as for a interval mapper, a function f might be specified
+ % that deforms the linear mapping. In case f is specified,
+ % f(#1) is mapped to #2 and f(#3) is mapped to #4.
+
+ \attribute spec maps min;%
+ % When the scaling spec maps "min" to some value, rather than some
+ % specific value to that value, then spec maps min will be set to
+ % \pgfutil@firstoftwo, otherwise to \pgfutil@secondoftwo
+
+ \attribute spec maps max;%
+ % Like spec maps min
+
+ \attribute function;%
+ % Stores the function
+
+ \attribute interval mapper;%
+ % Stores the interval mapper object
+
+ \attribute range surveyor;%
+ % Stores the range surveyor object
+
+
+ % Constructor
+ %
+ % #1 = in attribute
+ % #2 = out attribute
+ % #3 = scaling specification
+ % #4 = optional function
+ %
+ \method scaling mapper(#1,#2,#3,#4) {
+ %
+ % Save the parameters in attributes
+ %
+ \pgfooset{in}{#1}
+ \pgfooset{out}{#2}
+ \pgfooset{scaling spec}{#3}
+ \pgfooset{function}{#4}
+ %
+ % Now setup the objects for the before survey phase
+ %
+ %
+ % First, the in range interval
+ \pgfoonew \pgf@dv@in@range@obj=new interval(,)
+ \pgfoolet{in range obj}\pgf@dv@in@range@obj
+ % Second, the in range surveyor. We do not need to store this
+ % object, it will "do its work in the background"
+ \pgfoonew \pgf@dv@range@obj=new range surveyor(#1,\pgf@dv@in@range@obj)
+ \pgf@dv@range@obj.default connects()
+ \pgfoolet{range surveyor}\pgf@dv@range@obj
+ %
+ %
+ % The interval mapper:
+ %
+ \pgfoonew{interval mapper}=new interval mapper(#1,#2,#4)
+ \pgfoovalueof{interval mapper}.default connects()
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }%
+
+ % Getter
+ %
+ % Returns an interval object that stores the range of the in
+ % attribute.
+ \method get in range interval() {
+ \pgfooget{in range obj}\pgfdvinrangeinterval
+ }%
+
+
+ % Getter
+ %
+ % Returns the out attribute.
+ %
+ \method get out() {
+ \pgfooget{out}\pgfdvout
+ }%
+
+ % Getter
+ %
+ % Returns the function attribute.
+ %
+ \method get function(#1) {
+ \pgfooget{function}#1
+ }%
+
+ % Method
+ %
+ % #1 = a included in value
+ %
+ % This method only affects the survey. The value #1 is recorded as
+ % if it were encountered for the in attribute at some point.
+ %
+ \method include in value(#1) {
+ \pgfoovalueof{range surveyor}.include attribute value({#1})
+ }%
+
+
+ % Method
+ %
+ % #1 = value for the attribute
+ %
+ % Sets the attribute to the (evaluated) given value (evaluation
+ % using \pgfmathparse). When the value is evaluated, the values of
+ % \pgfdvmin and \pgfdvmax will be set to the minimum and maximum
+ % values of the in interval. (See \pgfdvmathenter with the "!"-notation).
+ %
+ % In case #1 is set to the special value "min", it evaluates to
+ % \pgfdvmin, when set to "max" it evaluates to \pgfdvmax.
+ %
+ \method set in to(#1) {%
+ \edef\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@min@text%
+ \pgf@dv@lib@set@mm%
+ \let\pgf@dv@value\pgfdvmin%
+ \pgfoovalueof{spec maps min}{\pgfkeyslet{/data point/\pgfoovalueof{in}/is min or max}\pgf@min@text}{}%
+ \else%
+ \ifx\pgf@temp\pgf@max@text%
+ \pgf@dv@lib@set@mm%
+ \let\pgf@dv@value\pgfdvmax%
+ \pgfoovalueof{spec maps min}{\pgfkeyslet{/data point/\pgfoovalueof{in}/is min or max}\pgf@max@text}{}%
+ \else%
+ \pgfdvmathenter{\pgf@dv@value}{\pgf@temp}%
+ \fi%
+ \fi%
+ \pgfdvmathexitbyserializing{\pgf@dv@serial}{\pgf@dv@value}%
+ \pgfkeyslet{/data point/\pgfoovalueof{in}}\pgf@dv@serial%
+ }%
+ \def\pgf@dv@lib@set@mm{
+ \pgfooget{in range obj}\pgfdvinrangeinterval
+ \pgfdvinrangeinterval.get min and max()%
+ }%
+
+
+ % Slot
+ \method phase(#1) {
+ \ifx#1\pgfdvendsurvey
+ % Ok, we setup the interval mapper.
+ %
+ % We start by computing the interval borders:
+ \pgfoovalueof{in range obj}.get min and max()
+ \ifx\pgfdvmin\pgfutil@empty% undefined, since no data points
+ \else%
+ \pgfooget{scaling spec}\pgf@temp%
+ \expandafter\pgf@lib@dv@parse@scaling\pgf@temp\pgf@stop%
+ \pgfoovalueof{interval mapper}.set interval values(%
+ \pgf@lib@dv@min,\pgf@lib@dv@max,%
+ \pgf@lib@dv@min@at,\pgf@lib@dv@max@at)
+ \fi
+ \fi
+ }%
+
+
+ % Internal helper
+ \def\pgf@lib@dv@parse@scaling#1 at#2and #3 at#4\pgf@stop{%
+ \def\pgf@lib@dv@min{#1}%
+ \pgfdvmathenter{\pgf@lib@dv@min@at@mv}{#2}
+ \def\pgf@lib@dv@max{#3}%
+ \pgfdvmathenter{\pgf@lib@dv@max@at@mv}{#4}
+ \ifx\pgf@lib@dv@min\pgf@min@text%
+ \let\pgf@lib@dv@min@mv\pgfdvmin
+ \pgfoolet{spec maps min}\pgfutil@firstoftwo%
+ \else
+ \pgfdvmathenter{\pgf@lib@dv@min@mv}{\pgf@lib@dv@min}
+ \pgfoolet{spec maps min}\pgfutil@secondoftwo%
+ \fi
+ \ifx\pgf@lib@dv@max\pgf@max@text%
+ \let\pgf@lib@dv@max@mv\pgfdvmax
+ \pgfoolet{spec maps max}\pgfutil@firstoftwo%
+ \else
+ \pgfdvmathenter{\pgf@lib@dv@max@mv}{\pgf@lib@dv@max}
+ \pgfoolet{spec maps max}\pgfutil@secondoftwo%
+ \fi
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@min}{\pgf@lib@dv@min@mv}
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@min@at}{\pgf@lib@dv@min@at@mv}
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@max}{\pgf@lib@dv@max@mv}
+ \pgfdvmathexitbyserializing{\pgf@lib@dv@max@at}{\pgf@lib@dv@max@at@mv}
+ }%
+ \def\pgf@min@text{min}%
+ \def\pgf@max@text{max}%
+}%
+
+
+
+
+
+%
+% Surveyors
+%
+
+\pgfooclass{range surveyor}
+{%
+ % Class range surveyor
+ %
+ % A range surveyor is used only in the survey phase. Its job is to
+ % determine the minimum and maximum values of an attribute that are
+ % "seen" during the survey phase. Based on this value, the size of,
+ % say, an axis can be determined later on.
+ %
+ % You can also set the key "sub attributes" of the attribute. In
+ % this case, this key should contain -- as the name suggests -- a
+ % list of subkeys that should also be taken into account for the
+ % computation of the minimum and maximum value. Inside the "sub
+ % attributes" key, each subkey should be surrounded by a call of
+ % \pgfdvsub. For instance, if there are two sub attributes "/data
+ % point/velocity/min" and "/data point/velocity/max" for a key
+ % "/data point/velocity", then "/data point/velocity/sub attributes"
+ % should be set to "\pgfdvsub{/min}\pgfdvsub{/max}".
+
+ \attribute attribute;%
+ % The to-be-surveyed attribute
+
+ \attribute interval obj;%
+ % The interval object that protocols the minimum and maximum
+ % values.
+
+
+ % Constructor
+ %
+ % #1 = the attribute
+ % #2 = handle to the interval object
+ %
+ \method range surveyor(#1,#2) {
+ \pgfooset{attribute}{#1}
+ \pgfoolet{interval obj}#2
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,survey,survey datapoint signal)
+ }%
+
+ % Method
+ %
+ % #1 = a value
+ %
+ % Adjust the interval as if during the survey this value were
+ % encountered
+ \method include attribute value(#1) {
+ \pgf@dv@assign@val@stripped#1\pgf@stop%
+ \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)
+ }%
+ \def\pgf@dv@assign@val@stripped#1\pgf@stop{%
+ \def\pgf@dv@val{#1}
+ }%
+
+ % Slot
+ %
+ % This slot should be connected to the survey datapoint signal. For
+ % each datapoint, this method will call the adjust method of the
+ % interval.
+ %
+ \method survey() {
+ \let\pgfdvsub\pgf@dv@range@surv@sub
+ \pgfdvsub{}%
+ \pgfkeysvalueof{/data point/\pgfoovalueof{attribute}/sub attributes}
+ }%
+
+ \def\pgf@dv@range@surv@sub#1{
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}#1}\pgf@dv@val%
+ \ifx\pgf@dv@val\relax%
+ \else%
+ \edef\pgf@dv@val{\pgf@dv@val}%
+ \ifx\pgf@dv@val\pgfutil@empty%
+ \else%
+ \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)%
+ \fi%
+ \fi%
+ }%
+
+ \def\pgf@dv@range@surv{%
+ \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}%
+ % Now, protocol value
+ \ifx\pgfdvmin\pgfutil@empty%
+ \let\pgfdvmin\pgf@dv@value%
+ \else%
+ \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}%
+ \fi%
+ \ifx\pgfdvmax\pgfutil@empty%
+ \let\pgfdvmax\pgf@dv@value%
+ \else%
+ \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}%
+ \fi%
+ }%
+}%
+
+
+
+%
+% Visualizers
+%
+
+\usepgflibrary{plothandlers}%
+
+
+
+\pgfooclass{plot handler visualizer}
+{%
+ % Class plot handler visualizer
+ %
+ % This visualizer uses one or more plot handlers to visualize data points.
+ % As the data points are processed, the canvas positions of the data
+ % points are recorded. At the end of a group of data points, the
+ % recorded stream of canvas position is visualized (rendered)
+ % using plot handlers. For instance, when the lineto plot handler
+ % is used, the data points are connected by straight lines, when the
+ % curveto plot handler is used, they are connected by smooth curves
+ % and so on.
+ %
+ % Since plot lines are not drawn immediately, but only at the end,
+ % when everything has been collected, multiple plot handlers can
+ % coexist peacefully at the same time.
+ %
+ % You can specify a "filter", which will cause only those data
+ % points to be visualized by the visualizer that pass the test. The
+ % filter should set \pgfdvfilterpassedfalse for to-be-filtered data
+ % point.
+ %
+ % You can specify "projection code" that changes the canvas x and
+ % canvas y positions. This projection code allows you to draw, say,
+ % projected points instead of the actual data point.
+ %
+ % The keys /data point/<name>/execute at begin and /data
+ % point/<name>/execute at end, where <name> is the name of
+ % the visualizer, should store code that is to be executed directly
+ % before and after the stream of coordinates is created. Typically,
+ % these keys will store commands to use the path created by the plot
+ % handler.
+
+ \attribute handlers;%
+ % The to-be-used handlers
+
+ \attribute name;%
+ % The attribute
+
+ \attribute filter=\pgfdvnamedvisualizerfilter;%
+ % Filter code
+
+ \attribute positions;%
+ % An internal protocol of the positions on the stream
+
+ \attribute cache;%
+ % An internal cache. Positions are first inserted into this
+ % cache. Every 100 steps this cache is moved to positions. The idea
+ % behind this is that it will avoid the quadratic time increase that
+ % is normally caused when a protocol is build in TeX.
+
+ \attribute projection code;%
+ % This code is empty by default. However, you can set it for
+ % instance to the following
+ %
+ % \pgfkeyssetvalue{/data point/y=0}\pgfdvmapdatapointtocanvas
+ %
+ % in order to visualize the data point with its y-coordinate
+ % replaced by 0.
+
+ % Constructor
+ %
+ % #1 = A name
+ % #2 = A comma-separated list of handlers like
+ % "\pgfplothandlerlineto,\pgfplothandlercurveto"
+ %
+ \method plot handler visualizer(#1,#2) {
+ \pgfooset{name}{#1}
+ \pgfooset{handlers}{#2}
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,protocol,visualize datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }%
+
+ % Setter
+ \method set filter(#1) {
+ \pgfooset{filter}{#1}
+ }%
+
+ % Setter
+ \method set projection code(#1) {
+ \pgfooset{projection code}{#1}
+ }%
+
+ % Slot
+ \method protocol() {
+ \pgfdvfilterpassedtrue
+ \pgfoovalueof{filter}
+ \ifpgfdvfilterpassed%
+ \pgf@dv@line@cache@it
+ \fi%
+ }%
+
+ \def\pgf@dv@line@cache@it{
+ % Cache it
+ \pgfooget{cache}\pgf@dv@cache
+ \pgfkeysgetvalue{/data point/outlier}\pgf@temp%
+ \ifx\pgf@temp\pgfutil@empty
+ {%
+ \pgfoovalueof{projection code}
+ \xdef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data
+ point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}%
+ }
+ \else%
+ % An outlier!
+ \gdef\pgf@dv@add{\pgf@dv@outliner}%
+ \fi%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@dv@cache%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@dv@cache\pgf@dv@add}%
+ % Possibly flush cache
+ \global\advance\pgf@lib@dv@cache@count by1\relax%
+ \ifnum\pgf@lib@dv@cache@count=100\relax%
+ \global\pgf@lib@dv@cache@count=0\relax%
+ % Append cache to positions
+ \pgfooget{positions}\pgf@dv@temp
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@dv@temp%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@dv@temp\pgf@dv@cache}%
+ \pgfoolet{positions}\pgf@dv@temp
+ \let\pgf@dv@cache\pgfutil@empty
+ \fi
+ \pgfoolet{cache}\pgf@dv@cache
+ }%
+
+ % Slot
+ \method phase(#1) {%
+ \ifx#1\pgfdvendvisualization%
+ \pgfoothis.render()%
+ \fi%
+ }%
+
+ % Internal method
+ \method render() {
+ \pgfscope
+ \pgfooget{handlers}\tikz@dv@temp@list
+ \foreach\tikz@dv@temp in\tikz@dv@temp@list{
+ \ifx\tikz@dv@temp\pgfutil@empty
+ \else
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin}
+ \tikz@dv@temp
+ \pgfdvnewstreamtrue
+ \pgfoovalueof{positions}
+ \pgfoovalueof{cache}
+ \ifpgfdvnewstream\else\pgfplotstreamend\fi
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end}
+ \fi
+ }
+ \endpgfscope
+ \pgfoolet{positions}\pgfutil@empty
+ \pgfoolet{cache}\pgfutil@empty
+ }%
+
+ \def\pgf@dv@ph#1#2{\ifpgfdvnewstream\pgfplotstreamstart\pgfdvnewstreamfalse\fi\pgfplotstreampoint{\pgfqpoint{#1}{#2}}}%
+ \def\pgf@dv@outliner{\ifpgfdvnewstream\else\pgfplotstreamend\pgfdvnewstreamtrue\fi}%
+}%
+
+\newif\ifpgfdvnewstream
+\newcount\pgf@lib@dv@cache@count
+
+\pgfkeys{%
+ /data point/outlier/.initial=,
+ /data point/outlier/.default=true,
+}%
+
+
+% A possible filter for unnamed visualizers
+%
+% #1 = Text to be compared with key /data point/set
+%
+% Description:
+%
+% In a data visualization with multiple visualizers, data points
+% typically "belong" only to a single visualizer. It is, thus,
+% necessary to filter data points according to the current
+% visualizer. This current visualizer is assumed to be stored in /data
+% point/visualizer.
+%
+% When objects allow you to set a filter, you can use this filter to
+% test against /data point/set being equal to #1.
+
+\def\pgfdvvisualizerfilter#1{%
+ \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@dv@visualizer%
+ \else
+ \pgfdvfilterpassedfalse
+ \fi%
+}%
+
+
+
+% A filter for named visualizer
+%
+% Description:
+%
+% This filter works like \pgfdvvisualizerfilter, only it assumes the
+% the object defines a "name" attribute. In this case, the value of
+% /data point/set is tested against this attribute.
+
+\def\pgfdvnamedvisualizerfilter{%
+ \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer%
+ \pgfooget{name}\pgf@temp%
+ \ifx\pgf@temp\pgf@dv@visualizer%
+ \else
+ \pgfdvfilterpassedfalse
+ \fi%
+}%
+
+
+
+\pgfooclass{rectangle visualizer}
+{%
+ % Class rectangle visualizer
+ %
+ % This visualizer visualizes a datapoint as a rectangle. It needs
+ % a name, so that /data point/<name>/attribute 1 and /data
+ % point/<name>/attribute 2 store two attributes names a1 to a2. Then,
+ % provided the current value of /data point/set equals name, for
+ % each data point a rectangle between (a1/min,a2/min) and
+ % (a1/max,a2/max) is created.
+
+
+ \attribute name;%
+ % The name
+
+ \attribute a1;%
+ \attribute a2;%
+ % The attributes, filled from /data point/<name>/attribute 1 and 2
+
+
+ % Constructor
+ %
+ % #1 = first attribute
+ % #2 = second attribute
+ %
+ \method rectangle visualizer(#1) {
+ \pgfooset{name}{#1}
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,visualize,visualize datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }%
+
+ % Slot
+ \method phase(#1) {%
+ \ifx#1\pgfdvbeginsurvey%
+ \pgfooeset{a1}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 1}}
+ \pgfooeset{a2}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 2}}
+ \pgfkeyssetvalue{\pgfoovalueof{a1}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}}
+ \pgfkeyssetvalue{\pgfoovalueof{a2}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}}
+ \fi%
+ }%
+
+ % Slot
+ \method visualize() {
+ {
+ \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer%
+ \pgfooget{name}\pgf@temp%
+ \ifx\pgf@temp\pgf@dv@visualizer%
+ \pgf@dv@rect@do
+ \fi
+ }
+ }%
+
+ \def\pgf@dv@rect@do{
+ \pgfkeysgetvalue{\pgfoovalueof{a1}/min}\pgf@dv@amin
+ \ifx\pgf@dv@amin\relax\else\ifx\pgf@dv@amin\pgfutil@empty\else
+ \pgfkeysgetvalue{\pgfoovalueof{a1}/max}\pgf@dv@amax
+ \ifx\pgf@dv@amax\relax\else\ifx\pgf@dv@amax\pgfutil@empty\else
+ \pgfkeysgetvalue{\pgfoovalueof{a2}/min}\pgf@dv@bmin
+ \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else
+ \pgfkeysgetvalue{\pgfoovalueof{a2}/max}\pgf@dv@bmax
+ \ifx\pgf@dv@bmax\relax\else\ifx\pgf@dv@bmax\pgfutil@empty\else
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin}
+ \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin}
+ \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin}
+ \pgfpathdvmoveto
+ \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmax}
+ \pgfpathdvlineto
+ \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amax}
+ \pgfpathdvlineto
+ \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin}
+ \pgfpathdvlineto
+ \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin}
+ \pgfpathdvlineto
+ \pgfpathclose
+ \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end}
+ \fi\fi
+ \fi\fi
+ \fi\fi
+ \fi\fi
+ }%
+}%
+
+\newcount\pgf@lib@dv@cache@count
+
+
+
+%
+% Label positioning classes
+%
+
+\pgfooclass{label visualizer}
+{%
+ % Class label visualizer
+ %
+ % The job of this class is to visualize a label of a curve or some
+ % other object.
+ %
+ % The idea is as follows: This class monitors a certain
+ % attribute. When this attribute reaches a certain value for the
+ % first time, the following happens: A normalized vector of the line
+ % connecting the current canvas position to the canvas position of
+ % the previous data point is computed and stored in pgf@x/pgf@y. The
+ % coordinate system is shifted so that the current data point is at
+ % the origin. Then, some drawing code is executed.
+
+ \attribute attribute;%
+ % The monitored attribute
+
+ \attribute filter;%
+ % Filter code, see plot handler visualizer doc.
+
+ \attribute threshold;%
+ % When the attribute exceeds this threshold, the drawing code is
+ % executed
+
+ \attribute before canvas position=;%
+ % Stores canvas position of the data point before the interesting one
+
+ \attribute canvas position=;%
+ % Stores canvas position of the data point
+
+ \attribute code;%
+ % To-be-executed code when the label should be drawn
+
+
+ % Constructor
+ %
+ % #1 = attribute
+ % #2 = a macro, storing the threshold
+ % #3 = code
+ % #4 = filter code
+ %
+ \method label visualizer(#1,#2,#3,#4) {
+ \pgfooset{attribute}{#1}
+ \expandafter\pgfdvmathenter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{#2}
+ \pgfoolet{threshold}\pgf@temp
+ \pgfooset{code}{#3}
+ \pgfooset{filter}{#4}
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,test,visualize datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }%
+
+ % Slot
+ \method test() {
+ \pgfdvfilterpassedtrue
+ \pgfoovalueof{filter}
+ \ifpgfdvfilterpassed%
+ \pgfooget{attribute}\pgf@dv@attribute
+ \ifx\pgf@dv@attribute\pgfutil@empty%
+ % nothing to do (anymore)
+ \else%
+ \pgf@dv@label@vis@record
+ \fi%
+ \fi%
+ }%
+
+ \def\pgf@dv@label@vis@record{
+ % Record current position
+ \edef\pgf@dv@pos{%
+ \noexpand\pgfqpoint%
+ {\pgfkeysvalueof{/data point/canvas x}}%
+ {\pgfkeysvalueof{/data point/canvas y}}}%
+ \pgfooget{canvas position}\pgf@dv@temp%
+ \pgfoolet{before canvas position}\pgf@dv@temp%
+ \pgfoolet{canvas position}\pgf@dv@pos%
+ % Now check threshold
+ \pgfooget{threshold}\pgf@dv@thres%
+ \ifx\pgf@dv@thres\pgfutil@empty%
+ \else%
+ % Hmm, have to check, whether the value is, indeed, correct
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val
+ \ifx\pgf@dv@val\relax%
+ \else\ifx\pgf@dv@val\pgfutil@empty%
+ \else%
+ \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}%
+ \pgfooget{threshold}{\pgf@dv@thres}
+ % Now, protocol value
+ \pgfdvmathifless{\pgf@dv@value}{\pgf@dv@thres}{}{%
+ \pgfoolet{attribute}\pgfutil@empty% Stop!
+ }%
+ \fi\fi%
+ \fi%
+ }%
+
+ % Slot
+ \method phase(#1) {%
+ \ifx#1\pgfdvendvisualization%
+ \scope
+ \pgfcoordinate{label visualizer coordinate}{\pgfoovalueof{canvas position}}
+ \pgfcoordinate{label visualizer coordinate'}{\pgfoovalueof{before canvas position}}
+ \pgfoovalueof{code}
+ \endscope
+ \fi%
+ }%
+}%
+
+
+
+%
+% Style sheets
+%
+\pgfooclass{style attribute}
+{%
+ % Class style attribute
+ %
+ % Instances of this class are used to select a style based on the
+ % current value of an attribute.
+ %
+ % Instances of this class monitor an attribute. Whenever the "style"
+ % signal is raised, the object investigates the current value of the
+ % attribute. It then looks up /pgf/data visualization/style
+ % sheets/<name of style sheet>/<value of the attribute> and executes
+ % this key, provided it is defined. If it not defined, the key
+ % /pgf/data visualization/style sheets/<name of style sheet>/default
+ % style is executed with the value as a parameter.
+
+ \attribute attribute;%
+ % The name of the attribute
+
+ \attribute style sheet name;%
+ % The styling function
+
+ % Constructor
+ %
+ % #1 = attribute (including, if present, /data point/)
+ % #2 = style sheet name
+ %
+ \method style attribute(#1,#2) {
+ \pgfooset{attribute}{#1}
+ \pgfooset{style sheet name}{#2}
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,invoke style,style signal)
+ }%
+
+ % Slots
+ \method invoke style() {
+ \pgfooget{attribute}\pgf@dv@temp
+ \pgfkeysgetvalue{\pgf@dv@temp}\pgf@dv@temp@val
+ \ifx\pgf@dv@temp@val\pgfutil@empty%do nothing
+ \else\ifx\pgf@dv@temp@val\relax%do nothing
+ \else%
+ \pgfkeysifdefined{\pgf@dv@temp/\pgf@dv@temp@val}{\pgfkeysgetvalue{\pgf@dv@temp/\pgf@dv@temp@val}\pgf@dv@temp@val}{}% redirect
+ \edef\pgf@temp{/pgf/data visualization/style sheets/\pgfoovalueof{style sheet name}}
+ \pgfkeysifassignable{\pgf@temp/\pgf@dv@temp@val}{%
+ \pgfkeysalso{\pgf@temp/\pgf@dv@temp@val}}{%
+ \pgfkeysalso{\pgf@temp/default style/.expand once=\pgf@dv@temp@val}
+ }
+ \fi\fi%
+ }%
+}%
+
+
+% Declares a new style sheet
+%
+% #1 = name of style sheet
+% #2 = settings
+%
+% Description:
+%
+% This is a shortcut for doing a /.cd to /pgf/data visualization/style sheets/#1
+
+\def\pgfdvdeclarestylesheet#1#2{
+ \pgfkeys{/pgf/data visualization/style sheets/#1/.cd,#2}
+}%
+
+
+
+
+
+
+
+
+
+%
+% Legend container class
+%
+
+\pgfooclass{legend}
+{%
+ % Class legend
+ %
+ % This class is used to collect entries into a legend. The idea is
+ % that, say, for each line of a picture you would like to have an
+ % entry in a legend. Then you prepare these entries and send
+ % them to a legend container object. It will collect the entries
+ % and, at the end, arrange them in rows and columns by
+ % separating them using \pgfdvnextcell and \pgfdvendrow.
+ %
+ % By surrounding the resulting arrangement by a call to \pgfmatrix or
+ % a call to \halign you can then create a legend.
+ %
+ % To specify how the entries should be arranged, a size
+ % specification and two directions are needed.
+ %
+ % For the size specification you specify either the ideal number of
+ % columns and the maximum number of rows or you specify the ideal
+ % number of rows and the maximum number of columns. In the first
+ % case, the class first tries to create as many columns as specified
+ % by the "ideal" parameter. If there are less entries than this
+ % parameter, you obviously get less columns, namely as many as there
+ % are entries, each column containing only one entry. If there are
+ % more entries that the ideal number of columns, you get multiple
+ % columns, each containing as many entries to make sure that the
+ % ideal number is met. However, if a column would get more than the
+ % specified maximum number of elements per column, you get more
+ % columns that the ideal number -- to ensure that no column contains
+ % more than the desired number. The case is symmetric, but with the
+ % roles of columns and rows exchanged.
+ %
+ % Here is an example: You specify that you want 2 columns, ideally,
+ % each having a maximum of 4 entries. Here is what you would get:
+ %
+ % Number of entries & Number of resulting columns ... & ... and rows
+ % 1 & 1 & 1
+ % 2 & 2 & 1
+ % 3 & 2 & 2
+ % 4 & 2 & 2
+ % 5 & 2 & 3
+ % 6 & 2 & 3
+ % 7 & 2 & 4
+ % 8 & 2 & 4
+ % 9 & 3 & 4
+ % 10 & 3 & 4
+ % 11 & 3 & 4
+ % 12 & 3 & 4
+ % 13 & 4 & 4
+ %
+ %
+ % Once the number of columns and rows has been computed, the next
+ % step is to "fill" the table. For this, eight strategies may be
+ % specified: right then down, right then up, left then down, left
+ % then up, up then right, up then left, down then right, down then
+ % left. A strategy like "right then up" means the following: Each
+ % new entry should placed right of the previous entry in the
+ % arrangement. However, once the maximum number of elements in a row
+ % has been reached, the a new row should be started that is placed
+ % above ("up") then just-assembled row.
+ %
+ %
+ %
+ %
+ % Example:
+ %
+ % You create an object \legend and then call
+ %
+ % \pgfoofnew \legend=new legend(columns,2,3,down then right)
+ % \legend.add entry(first)
+ % \legend.add entry(second)
+ % \legend.add entry(third)
+ % \legend.add entry(fourth)
+ % \legend.add entry(fifth)
+ % \legend.add entry(sixth)
+ % \legend.add entry(seventh)
+ % \legend.get arrangement(\arrangement)
+ %
+ % Then \arrangment will expand to
+ %
+ % first \pgfdvnextcell fourth \pgfdvnextcell seventh \pgfdvendrow
+ % second \pgfdvnextcell fifth \pgfdvnextcell third \pgfdvendrow
+ % third \pgfdvendrow sixth \pgfdvnextcell \pgfdvendrow
+ %
+ % By saying \let\pgfdvendrow=\\ and \let\pgfdvnextcell=&, you
+ % can use \arrangment inside a table.
+
+
+ \attribute entries;%
+ % Collects the entries
+
+ \attribute columns or rows;%
+ % Specifies whether columns or rows are specified
+
+ \attribute ideal;%
+ % The ideal number of columns/rows
+
+ \attribute max;%
+ % The maximum number of entries per column/row
+
+ \attribute strategy;%
+ % Specifies how the matrix should be filled
+
+ \attribute number of entries=0;%
+ % Counts the number of entries that have been stored
+
+
+ % Constructor
+ %
+ % #1 = "columns" or "rows" -> specifies whether the ideal number and
+ % the max entries number refer to columns or the row
+ % #2 = the ideal number of #1's
+ % #3 = the maximum number of entries in a #1
+ % #4 = one of the eight strategies
+ %
+ \method legend(#1,#2,#3,#4) {
+ \pgfooset{columns or rows}{#1}
+ \pgfooset{ideal}{#2}
+ \pgfooset{max}{#3}
+ \pgfooset{strategy}{#4}
+ }%
+
+ % Method
+ \method default connects() {
+ }%
+
+ % Method
+ \method add entry(#1) {
+ \pgfooappend{entries}{{#1}}
+ \c@pgf@counta=\pgfoovalueof{number of entries}\relax%
+ \advance\c@pgf@counta by1\relax%
+ \pgfooeset{number of entries}{\the\c@pgf@counta}
+ }%
+
+ % Method
+ \method get arrangement(#1) {
+ {
+ %
+ % Step 1: Compute the desired number of rows or columns
+ %
+ %
+ % Compute the ideal number of entries per row/column (called
+ % "target" in the following) and entries per colum/row (called
+ % "per target" in the following)
+ %
+ % if (number of entries > ideal)
+ \ifnum\pgfoovalueof{number of entries}>\pgfoovalueof{ideal}\relax%
+ % {
+ % if (ideal * max > number of entries)
+ \c@pgf@counta=\pgfoovalueof{ideal}\relax%
+ \multiply\c@pgf@counta by\pgfoovalueof{max}\relax%
+ \ifnum\c@pgf@counta>\pgfoovalueof{number of entries}\relax
+ % {
+ % target = ideal;
+ % per target = ceil (number of entries / ideal);
+ \c@pgf@counta=\pgfoovalueof{ideal}\relax%
+ \c@pgf@countb=\pgfoovalueof{number of entries}\relax
+ \advance\c@pgf@countb by-1\relax
+ \divide\c@pgf@countb by\c@pgf@counta\relax%
+ \advance\c@pgf@countb by1\relax%
+ % }
+ % else
+ % {
+ % target = ceil(number of entries / max);
+ % per target = max;
+ \else
+ \c@pgf@countb=\pgfoovalueof{max}\relax%
+ \c@pgf@counta=\pgfoovalueof{number of entries}\relax
+ \advance\c@pgf@counta by-1\relax
+ \divide\c@pgf@counta by\c@pgf@countb\relax%
+ \advance\c@pgf@counta by1\relax%
+ \fi
+ % }
+ % }
+ % else
+ % {
+ % target = number of entries;
+ % per target = 1;
+ % }
+ \else
+ \c@pgf@counta=\pgfoovalueof{number of entries}\relax%
+ \c@pgf@countb=1\relax%
+ \fi%
+ %
+ % Ensure that counta = rows, countb = columns
+ %
+ \pgfooget{columns or rows}\pgf@temp
+ \ifx\pgf@temp\pgf@dv@columnstext%
+ \c@pgf@countc=\c@pgf@counta\relax
+ \c@pgf@counta=\c@pgf@countb\relax
+ \c@pgf@countb=\c@pgf@countc\relax
+ \fi
+ %\edef\temp{rows: \the\c@pgf@counta, columns: \the\c@pgf@countb}\temp
+ %
+ % Now arrange the matrix
+ %
+ \csname pgf@dv@legend@init@\pgfoovalueof{strategy}\endcsname
+ \expandafter\let\expandafter\pgf@dv@updater\csname pgf@dv@legend@update@\pgfoovalueof{strategy}\endcsname
+ \pgfooget{entries}\pgf@temp
+ \expandafter\pgf@dv@legend@arrange\pgf@temp\pgf@stop
+ %
+ % Now assemble the matrix
+ %
+ \edef\pgf@dv@row@list{1,...,\the\c@pgf@counta}
+ \edef\pgf@dv@column@list{1,...,\the\c@pgf@countb}
+ \global\let\pgf@dv@matrix\pgfutil@empty
+ \foreach \pgf@dv@row in \pgf@dv@row@list
+ {
+ \global\let\pgf@dv@matrix@row\pgf@dv@first@mark
+ \foreach \pgf@dv@column in \pgf@dv@column@list
+ {
+ \expandafter\let\expandafter\pgf@temp\csname pgf@dv@legend@entry@\pgf@dv@row @\pgf@dv@column\endcsname
+ \ifx\pgf@temp\relax
+ \let\pgf@temp\pgfutil@empty
+ \fi
+ \ifx\pgf@dv@matrix@row\pgf@dv@first@mark
+ \global\let\pgf@dv@matrix@row\pgf@temp
+ \else
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgf@dv@matrix@row\expandafter{\expandafter\pgfdvnextcell\pgf@temp}
+ \fi
+ }
+ \pgfutil@g@addto@macro\pgf@dv@matrix@row{\pgfdvendrow}
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgf@dv@matrix\expandafter{\pgf@dv@matrix@row}
+ }
+ \global\let\pgf@dv@matrix@row\relax
+ }
+ \let#1\pgf@dv@matrix
+ \global\let\pgf@dv@matrix\relax
+ }%
+
+ \def\pgf@dv@first@mark{\pgf@dv@first@mark}%
+
+ \def\pgf@dv@legend@arrange{%
+ \pgfutil@ifnextchar\pgf@stop{\pgfutil@gobble}{\pgf@dv@legend@handle@entry}
+ }%
+
+ \def\pgf@dv@legend@handle@entry#1{
+ \expandafter\def\csname pgf@dv@legend@entry@\the\c@pgf@countc @\the\c@pgf@countd\endcsname{#1}%
+ \pgf@dv@updater%
+ \pgf@dv@legend@arrange%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@down then right\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=1\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@down then right\endcsname{%
+ \advance\c@pgf@countc by1\relax
+ \ifnum\c@pgf@countc>\c@pgf@counta\relax%
+ \c@pgf@countc=1\relax%
+ \advance\c@pgf@countd by1\relax%
+ \fi%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@right then down\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=1\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@right then down\endcsname{%
+ \advance\c@pgf@countd by1\relax
+ \ifnum\c@pgf@countd>\c@pgf@countb\relax%
+ \c@pgf@countd=1\relax%
+ \advance\c@pgf@countc by1\relax%
+ \fi%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@up then right\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=1\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@up then right\endcsname{%
+ \advance\c@pgf@countc by-1\relax
+ \ifnum\c@pgf@countc=0\relax%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \advance\c@pgf@countd by1\relax%
+ \fi%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@right then up\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=1\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@right then up\endcsname{%
+ \advance\c@pgf@countd by1\relax
+ \ifnum\c@pgf@countd>\c@pgf@countb\relax%
+ \c@pgf@countd=1\relax%
+ \advance\c@pgf@countc by-1\relax%
+ \fi%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@left then up\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@left then up\endcsname{%
+ \advance\c@pgf@countd by-1\relax
+ \ifnum\c@pgf@countd=0\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ \advance\c@pgf@countc by-1\relax%
+ \fi%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@up then left\endcsname{%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@up then left\endcsname{%
+ \advance\c@pgf@countc by-1\relax
+ \ifnum\c@pgf@countc=0\relax%
+ \c@pgf@countc=\c@pgf@counta\relax%
+ \advance\c@pgf@countd by-1\relax%
+ \fi%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@left then down\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@left then down\endcsname{%
+ \advance\c@pgf@countd by-1\relax
+ \ifnum\c@pgf@countd=0\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ \advance\c@pgf@countc by1\relax%
+ \fi%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@init@down then left\endcsname{%
+ \c@pgf@countc=1\relax%
+ \c@pgf@countd=\c@pgf@countb\relax%
+ }%
+
+ \expandafter\def\csname pgf@dv@legend@update@down then left\endcsname{%
+ \advance\c@pgf@countc by1\relax
+ \ifnum\c@pgf@countc>\c@pgf@countb\relax%
+ \c@pgf@countc=1\relax%
+ \advance\c@pgf@countd by-1\relax%
+ \fi%
+ }%
+
+ \def\pgf@dv@columnstext{columns}%
+}%
+
+
+
+%
+% Help classes
+%
+
+\pgfooclass{interval}
+{%
+ % Class interval
+ %
+ % Instances of this class store intervals. When either the min or
+ % the max value is empty, this corresponds to "not yet set", (not to
+ % "infinity).
+
+ \attribute min;%
+ % The minimum value of the interval
+
+ \attribute max;%
+ % The maximum value of the interval
+
+ % Constructor
+ %
+ % #1 = initial minimum value
+ % #2 = initial maximum value
+ %
+ \method interval(#1,#2) {
+ \pgfooset{min}{#1}
+ \pgfooset{max}{#2}
+ }%
+
+ % Method
+ \method default connects() {
+ }%
+
+ % Sets the minimum/maximum to a new value
+ \method set min(#1) {
+ \pgfooset{min}{#1}
+ }%
+ \method set max(#1) {
+ \pgfooset{max}{#1}
+ }%
+ \method let min(#1) {
+ \pgfoolet{min}{#1}
+ }%
+ \method let max(#1) {
+ \pgfoolet{max}{#1}
+ }%
+
+ % Getter
+ %
+ % Returns the current values of the minimum and maximum in the
+ % macros \pgfdvmin and \pgfdvmax.
+ \method get min and max() {
+ \pgfooget{min}\pgfdvmin
+ \pgfooget{max}\pgfdvmax
+ }%
+
+ % Adjusts the minimum and maximum values
+ %
+ % #1 = some code. When this code is executed, the values of
+ % \pgfdvmin and \pgfdvmax will be set to the current values of
+ % the minimum/maximum. The code may change these values. The
+ % changed values will then be stored.
+ %
+ % This method does nothing that cannot be achieved also by calling
+ % set/get methods, but it is easier to use and faster.
+ \method adjust(#1) {
+ {%
+ \pgfooget{min}\pgfdvmin
+ \pgfooget{max}\pgfdvmax
+ #1%
+ \pgfoolet{min}\pgfdvmin
+ \pgfoolet{max}\pgfdvmax
+ }%
+ }%
+}%
+
+
+
+\pgfooclass{count}
+{%
+ % Class count
+ %
+ % This class can be used to count the number of data points that are
+ % present or that have a certain property. By default, for every
+ % data point a counter is incremented and the value of this counter
+ % is stored in an attribute. You can also specify an increment for
+ % the counter. You can specify that certain data points should
+ % not have an effect on the counter.
+
+
+ \attribute attribute;%
+ % The attribute that will be set to the current value of the counter
+
+ \attribute val=0;%
+ % The current value of the counter
+
+ \attribute max=0;%
+ % The current value of the counter
+
+ \attribute step=1;%
+ % The stepping by which the counter is incremented for each
+ % datapoint
+
+ \attribute start val=0;%
+ % The start value of the counter
+
+ \attribute filter=;%
+ % This attribute stores some code that is executed for each
+ % data point. If the data point sets the TeX-if ifpgfdvfilterpassed to
+ % true, then the counter is not incremented.
+
+
+ % Constructor
+ %
+ % #1 = The attribute in which the counter value is stored
+ %
+ \method count(#1) {
+ \pgfooset{attribute}{#1}
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,apply,prepare datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }%
+
+ % Getter
+ \method get max(#1) {
+ \pgfooget{max}{#1}
+ }%
+
+ % Setter
+ \method set value(#1) {
+ \pgfooset{val}{#1}
+ \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute}}{#1}%
+ }%
+
+ % Setter
+ \method set start value(#1) {
+ \pgfooset{start val}{#1}
+ \pgfooset{max}{#1}
+ }%
+
+ % Setter
+ \method set filter(#1) {
+ \pgfooset{filter}{#1}
+ }%
+
+ % Setter
+ \method set step(#1) {
+ \pgfooset{step}{#1}
+ }%
+
+ % Slot
+ \method apply() {
+ \pgfdvfilterpassedtrue%
+ \pgfoovalueof{filter}%
+ \ifpgfdvfilterpassed%
+ \pgfmathparse{\pgfoovalueof{val}+\pgfoovalueof{step}}%
+ \pgfoolet{val}\pgfmathresult%
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}}\pgfmathresult%
+ \ifdim\pgfmathresult pt>\pgfoovalueof{max}pt\relax%
+ \pgfoolet{max}\pgfmathresult%
+ \fi%
+ \pgfooget{max}\pgfmathresult%
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/max}\pgfmathresult%
+ \fi%
+ }%
+
+ % Slot
+ \method phase(#1) {
+ \ifx#1\pgfdvbeginsurvey
+ \pgfooeset{val}{\pgfoovalueof{start val}}
+ \else \ifx#1\pgfdvbeginvisualization
+ \pgfooeset{val}{\pgfoovalueof{start val}}
+ \fi\fi
+ }%
+}%
+
+\newif\ifpgfdvfilterpassed
+
+
+
+
+\pgfooclass{accumulator}
+{%
+ % Class accumulator
+ %
+ % This class is used to keep track of the sum of the values of some
+ % attribute. When this object is connected to some attribute, the
+ % subkey attribute/sum will always contain the sum of all values in
+ % all previous data points with respect to this
+ % attribute. Furthermore, the subkey attribute/prev key will hold
+ % the previous sum, which is sometimes also useful to have access
+ % to.
+
+ \attribute attribute;%
+ % The attribute to-be-accumulated
+
+ \attribute sum;%
+ % The initial value of the sum
+
+ % Constructor
+ %
+ % #1 = to-be-accumulated attribute
+ \method accumulator(#1) {
+ \pgfooset{attribute}{#1}
+ \pgfoothis.reset()
+ }%
+
+ % Method
+ \method default connects() {
+ \pgfoothis.get handle(\pgf@dv@me)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,apply,prepare datapoint signal)
+ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal)
+ }%
+
+ % Slot
+ \method apply() {%
+ % Save old sum
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/sum}\pgf@temp%
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/prev sum}\pgf@temp%
+ % Add new attribute...
+ \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}{\pgf@temp@b}%
+ \pgfdvmathenter{\pgf@dv@new@val}{\pgf@temp@b}%
+ % ... to sum
+ \pgfooget{sum}\pgf@dv@sum%
+ \pgfdvmathadd{\pgf@dv@sum}{\pgf@dv@new@val}{\pgf@dv@sum}%
+ \pgfoolet{sum}\pgf@dv@sum
+ % Record in attribute
+ \pgfdvmathexitbyscientificformat{\pgf@dv@serial@sum}{\pgf@dv@sum}
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/sum}\pgf@dv@serial@sum
+ }%
+
+ % Method
+ %
+ % Use this method to reset the sum at any point.
+ %
+ \method reset() {
+ \pgfdvmathenter{\pgf@dv@temp}{0}
+ \pgfoolet{sum}{\pgf@dv@temp}
+ \pgfdvmathexitbyserializing{\pgf@dv@zero}{\pgf@dv@temp}
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/prev sum}{\pgf@dv@zero}
+ \pgfkeyslet{/data point/\pgfoovalueof{attribute}/sum}{\pgf@dv@zero}
+ }%
+
+ % Slot
+ \method phase(#1) {
+ \ifx#1\pgfdvbeginsurvey
+ \pgfoothis.reset()
+ \else \ifx#1\pgfdvbeginvisualization
+ \pgfoothis.reset()
+ \fi\fi
+ }%
+}%
+
+
+
+
+
+
+
+%
+%
+% Help keys and, attributes
+%
+%
+
+\pgfkeys{% do not even think of changing the values of the following:
+ /data point/always true/.initial=true,
+ /data point/always false/.initial=false,
+ /data point/always 0/.initial=0,
+ /data point/always 1/.initial=1,
+ /data point/always empty/.initial=,
+ /data point/always pgfusepath stroke/.initial=\pgfusepath{stroke},
+}%
+
+\pgfdvmathenter{\pgfdvmathalwaysloge}{0.434294481903252}%
+\pgfdvmathenter{\pgfdvmathalwayslnten}{2.302585092994046}%
+\pgfdvmathenter{\pgfdvmathalwayszero}{0}%
+\pgfdvmathenter{\pgfdvmathalwaysone}{1}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmoduledecorations.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmoduledecorations.code.tex
new file mode 100644
index 0000000000..c119dd622f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmoduledecorations.code.tex
@@ -0,0 +1,2191 @@
+% Copyright 2019 by Mark Wibrow and Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+% The following naming conventions are (more or less) observed:
+%
+% `decorated' : the path that is being decorated.
+% `decoration' : any path created/left by the automaton
+% `decorate' : generic use where distinction is probably unimportant
+% (e.g. internal macros).
+
+
+
+% These should be moved.
+%
+\def\pgfgetpath#1{\pgfsyssoftpath@getcurrentpath{#1}}%
+\def\pgfsetpath#1{\pgfsyssoftpath@setcurrentpath{#1}}%
+
+
+% Required registers.
+%
+\newdimen\pgfdecoratedcompleteddistance
+\newdimen\pgfdecoratedremainingdistance
+\newdimen\pgfdecoratedinputsegmentcompleteddistance
+\newdimen\pgfdecoratedinputsegmentremainingdistance
+\newdimen\pgf@decorate@distancetomove
+
+\newcount\pgf@decorate@repeatstate
+
+
+% Extra options used in all libraries
+
+\newdimen\pgfdecorationsegmentamplitude
+\newdimen\pgfdecorationsegmentlength
+\pgfdecorationsegmentamplitude2.5pt
+\pgfdecorationsegmentlength10pt
+\def\pgfdecorationsegmentangle{45}%
+\def\pgfdecorationsegmentaspect{0.5}%
+\def\pgfmetadecorationsegmentamplitude{2.5pt}%
+\def\pgfmetadecorationsegmentlength{1cm}%
+
+\pgfkeys{%
+ /pgf/decoration/.code={\pgfkeys{/pgf/decoration/.cd,#1}},
+ /pgf/decoration/.cd,
+ amplitude/.code={\pgfmathsetlength\pgfdecorationsegmentamplitude{#1}},
+ meta-amplitude/.store in=\pgfmetadecorationsegmentamplitude,
+ segment length/.code={\pgfmathsetlength\pgfdecorationsegmentlength{#1}},
+ meta-segment length/.store in=\pgfmetadecorationsegmentlength,
+ angle/.code={\pgfmathparse{#1}\let\pgfdecorationsegmentangle\pgfmathresult},
+ aspect/.code={\pgfmathparse{#1}\let\pgfdecorationsegmentaspect\pgfmathresult},
+ start radius/.initial=2.5pt,
+ end radius/.initial=2.5pt,
+ radius/.style={start radius={#1},end radius={#1}},
+ path has corners/.is if=pgfdecoratepathhascorners,
+ reverse path/.is if=pgf@decorate@inputsegmentobjects@reverse,
+}%
+\newif\ifpgfdecoratepathhascorners
+\newif\ifpgf@decorate@inputsegmentobjects@reverse
+
+% Declare a decoration
+%
+% #1 = name of the decoration
+% #2 = initial state
+% #3 = states
+%
+% This command declares a new decoration for later use.
+% Inside the code of #3 the command \state may be used. This command
+% will only be defined while #3 is executed.
+%
+% Example:
+%
+% \pgfdeclaredecoration{zigzag}{q}
+% {
+% \state{q}[width=10pt]
+% {
+% \pgfpathlineto{\pgfpoint{2.5pt}{2.5pt}}
+% \pgfpathlineto{\pgfpoint{7.5pt}{-2.5pt}}
+% \pgfpathlineto{\pgfpoint{10pt}{0pt}}
+% }
+% \state{final}
+% {
+% \pgfpathlineto{\pgfpointdecoratedpathlast}
+% }
+% }
+
+\long\def\pgfdeclaredecoration#1#2#3{%
+ \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone%
+ \pgfifmetadecoration{#1}{%
+ \pgferror{You cannot declare a decoration of the same
+ name as a meta-decoration}%
+ \let\pgf@mod@dec@next=\pgfutil@gobble%
+ }{}%
+ \pgf@mod@dec@next
+ {%
+ \def\pgf@decorate@name{#1}%
+ \pgfutil@namedef{pgf@decorate@@#1@initial}{#2}%
+ \let\pgf@orig@state\state%
+ \let\state\pgf@decorate@state
+ #3%
+ \let\state\pgf@orig@state%
+ }%
+}%
+
+\def\pgf@decorate@state#1{\pgfutil@ifnextchar[{\pgf@decorate@@start#1}{\pgf@decorate@@start#1[]}}%}%
+\def\pgf@decorate@@start#1[#2]#3{%
+ \pgfutil@namedef{pgf@decorate@@\pgf@decorate@name @#1@options}{#2}%
+ \pgfutil@namedef{pgf@decorate@@\pgf@decorate@name @#1@code}{#3}%
+}%
+\long\def\pgf@mod@dec@firstofone#1{#1}%
+
+
+% Test whether something is a decoration
+%
+% #1 = name
+% #2 = if-code
+% #3 = else-code
+%
+% Example:
+%
+% \pgfifdecoration{zigzag}{Exists}{Does not exist}
+
+\def\pgfifdecoration#1#2#3{\pgfutil@ifundefined{pgf@decorate@@#1@initial}{#3}{#2}}%
+
+
+
+% Declare a meta decoration
+%
+% #1 = name of the meta decoration
+% #2 = initial state
+% #3 = states
+%
+% This command declares a new meta decoration for later use.
+% Inside the code of #3 the command \state may be used.
+
+\long\def\pgfdeclaremetadecoration#1#2#3{%
+ \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone%
+ \pgfifdecoration{#1}{%
+ \pgferror{You cannot declare a meta-decoration of the
+ same name as a decoration}%
+ \let\pgf@mod@dec@next=\pgfutil@gobble%
+ }{}%
+ \pgf@mod@dec@next{%
+ \def\pgf@metadecoration@name{#1}%
+ \pgfutil@namedef{pgf@metadecoration@@#1@initial}{#2}%
+ \let\pgf@orig@state\state%
+ \let\state\pgf@metadecoration@state
+ #3%
+ \let\state\pgf@orig@state%
+ }%
+}%
+
+\def\pgf@metadecoration@state#1{\pgfutil@ifnextchar[{\pgf@metadecoration@@state#1}{\pgf@metadecoration@@state#1[]}}%}%
+\def\pgf@metadecoration@@state#1[#2]#3{%
+ \pgfutil@namedef{pgf@metadecoration@@\pgf@metadecoration@name @#1@options}{#2}%
+ \pgfutil@namedef{pgf@metadecoration@@\pgf@metadecoration@name @#1@code}{#3}%
+}%
+
+
+% Test whether something is a meta-decoration
+%
+% #1 = name
+% #2 = if-code
+% #3 = else-code
+%
+% Example:
+%
+% \pgfifmetadecoration{zigzag}{Exists}{Does not exist}
+
+\def\pgfifmetadecoration#1#2#3{\pgfutil@ifundefined{pgf@metadecoration@@#1@initial}{#3}{#2}}%
+
+
+
+
+
+\let\pgfdecoratebeforecode\pgfutil@empty
+\let\pgfdecorateaftercode\pgfutil@empty
+
+% \pgfdecoratepath
+%
+% Decorate a path.
+%
+% \pgfdecoratebeforecode and \pgfdecorateaftercode can be used to
+% execute code before and after the decoration.
+%
+% #1 - the name of the decoration.
+% #2 - a (non-empty) path specification.
+%
+% Example:
+%
+% \pgfdeclaredecoration{circles}{red circles}{
+% \state{red circles}[width=10pt, repeat state=2, next state=blue circles]
+% {
+% \pgfmathparse{round(rnd*100)}
+% \pgfsetstrokecolor{red!\pgfmathresult!brown}
+% \pgfsetfillcolor{orange!\pgfmathresult!yellow}
+% \pgfpathcircle{\pgfpointorigin}{2.5pt}
+% \pgfusepath{stroke,fill}
+% }
+% \state{blue circles}[width=10pt, repeat state=1, next state=red circles]
+% {
+% \pgfmathparse{round(rnd*100)}
+% \pgfsetstrokecolor{blue!\pgfmathresult!gray}
+% \pgfsetfillcolor{blue!\pgfmathresult!white}
+% \pgfpathcircle{\pgfpointorigin}{2.5pt}
+% \pgfusepath{stroke,fill}
+% }
+% \state{final}{}
+% }
+%
+% \pgfpicture
+% \pgfdecoratepath{circles}
+% {
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}}
+% }
+% \endpgfpicture
+%
+\long\def\pgfdecoratepath#1#2{%
+ \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}%
+ #2%
+ \endpgfdecoration}%
+
+
+
+
+% \pgfdecoratecurrentpath
+%
+% Decorate the current/existing path, but (unavoidably) destroys it.
+%
+% \pgfdecoratebeforecode and \pgfdecorateaftercode can be used to
+% execute code before and after the decoration.
+%
+% #1 - the name of the decoration.
+%
+% Example:
+%
+% \pgfdeclaredecoration{stars}{move}{
+% \state{move}[width=7.5pt, next state=star]{}
+% \state{star}[width=7.5pt, next state=move]
+% {
+% \pgfmathparse{round(rnd*100)}
+% \pgfsetfillcolor{yellow!\pgfmathresult!orange}
+% \pgfsetstrokecolor{yellow!\pgfmathresult!red}
+% \pgfmathparse{rnd*.75+.25}
+% \pgftransformscale{\pgfmathresult}
+% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}}
+% }
+% \state{final}
+% {
+% \pgfpathmoveto{\pgfpointdecoratedpathlast}
+% }
+% }
+%
+% \pgfpicture
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}}
+% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}}
+% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}}
+% \pgfdecoratecurrentpath{stars}
+% \endpgfpicture
+%
+\def\pgfdecoratecurrentpath#1{%
+ \pgfgetpath\pgf@decorate@currentpath%
+ \pgfsetpath\pgfutil@empty%
+ \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}%
+ \pgfsetpath\pgf@decorate@currentpath%
+ \endpgfdecoration}%
+
+
+
+
+% Environment \pgfdecoration \endpgfdecoration
+%
+% Decorates a path with multiple decorations.
+%
+% Definitions:
+%
+% `existing path'
+% - any unused path existing prior to the environment.
+%
+% `decorated path'
+% - the path that is being decorated.
+%
+% `decoration path'
+% - any unused path left by the decoration automaton.
+%
+% The action of the environment is as follows:
+%
+% 1. Any existing path is saved.
+% 2. Construction commands are executed forming the decorated path.
+% 3. If the first command in the decorated path is not a `move to',
+% the last known position from the existing path is inserted.
+% 4. The saved existing path is reinstalled.
+% 5. The decoration automaton is executed along the decorated path.
+%
+% Parameters:
+%
+% #1 - a comma separated list of decoration specifications.
+%
+% A decoration specification takes the format:
+%
+% {<name>}{<distance>}{<before code>}{<after code>}
+%
+% The decoration <name> is applied to a section of the decorated
+% path from the last point on the decorated path the decoration
+% automaton reached to <distance> from that point.
+%
+% When <distance>} is parsed, the dimension
+% \pgfdecoratedreminingdistance holds the distance remaining on the
+% entire decorated path, and the macro \pgfdecoratedpathlength holds
+% the total length of the entire decorated path.
+% After <distance> is parsed, both are set to to the value of
+% <distance> for the automaton to decorate current section of the
+% decorated path.
+%
+% <before code> is executed just before the decoration automaton
+% starts and <after code> is executed just after the automaton stops.
+% If <before code> or <after code> are empty, they can be omitted.
+% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast
+% will be set up as the first and last points on the current section
+% of the decorated path.
+%
+% When the environment exits, the following macros will be set up:
+%
+% \pgfdecorateexistingpath
+% - the existing path.
+%
+% \pgfdecoratedpath
+% - the decorated path.
+%
+% \pgfdecorationpath
+% - any unused decoration path.
+%
+% \pgfpointdecoratedpathlast
+% - the last point on the decorated path.
+%
+% Examples (require pgfdecorations library):
+%
+% \pgfpicture
+% \pgfdecoration
+% {
+% {lineto}{\pgfdecoratedpathlength/3},
+% {zigzag}{\pgfdecoratedpathlength/3},
+% {lineto}{\pgfdecoratedpathlength/3}
+% }
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}}
+% \endpgfdecoration
+% \pgfusepath{stroke}
+% \endpgfpicture
+%
+%
+% \pgfpicture
+% \pgfdecoration
+% {
+% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}},
+% {zigzag}{\pgfdecoratedpathlength/5}
+% {
+% \pgfpathmoveto{\pgfpointdecoratedpathfirst}
+% }
+% {
+% \pgfsetstrokecolor{red}
+% \pgfusepath{stroke}
+% },
+% {lineto}{\pgfdecoratedpathlength/5}
+% {
+% \pgfpathmoveto{\pgfpointdecoratedpathfirst}
+% }
+% {
+% \pgfsetstrokecolor{black}
+% \pgfusepath{stroke}
+% },
+% {zigzag}{\pgfdecoratedpathlength/5}
+% {
+% \pgfpathmoveto{\pgfpointdecoratedpathfirst}
+% }
+% {
+% \pgfsetstrokecolor{red}
+% \pgfusepath{stroke}
+% },
+% {lineto}{\pgfdecoratedpathlength/5}
+% {
+% \pgfpathmoveto{\pgfpointdecoratedpathfirst}
+% }
+% {
+% \pgfsetstrokecolor{black}
+% \pgfusepath{stroke}
+% }
+% }
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}}
+% \endpgfdecoration
+%
+% \endpgfpicture
+%
+%
+%
+% \pgfdeclaredecoration{polygons}{move}{
+% \state{move}[width=7.5pt, next state=polygon]{}
+% \state{polygon}[width=7.5pt, next state=move]
+% {
+% \pgfmathparse{round(rnd*100)}
+% \pgfsetfillcolor{green!\pgfmathresult!yellow}
+% \pgfsetstrokecolor{green!\pgfmathresult!brown}
+% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}}
+% }
+% \state{final}
+% {
+% \pgfpathmoveto{\pgfpointdecoratedpathlast}
+% }
+% }
+%
+% \pgfpicture
+% \pgfdecoration
+% {
+% {polygons}{45pt},
+% {lineto}{30pt}
+% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}}
+% {
+% \pgfsetstrokecolor{yellow!50!orange}
+% \pgfusepath{stroke}
+% },
+% {polygons}{45pt},
+% {lineto}{30pt}
+% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}}
+% {
+% \pgfsetstrokecolor{green!50!blue}
+% \pgfusepath{stroke}
+% },
+% {polygons}{\pgfdecoratedremainingdistance}
+% }
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}}
+% \endpgfdecoration
+% \endpgfpicture
+%
+%
+% \pgfpicture
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}}
+% \pgfgetpath\temppath
+% \pgfsetstrokecolor{red}
+% \pgfusepath{stroke}
+%
+% \pgfset{decoration text={Here is some text all the way along this curve!}}
+% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}}
+% \pgfsetpath\temppath
+% \endpgfdecoration
+% \endpgfpicture
+%
+\def\pgfdecoration#1{%
+ \begingroup%
+ \def\pgf@decorate@decorationlist{#1}%
+ \pgf@decoration@env%
+}%
+
+\def\endpgfdecoration{%
+ \pgf@decoration@endenv%
+ \ifx\pgfdecoratedpath\pgfutil@empty%
+ \else%
+ %
+ % Perform the decoration(s).
+ %
+ \pgf@decorate@for\pgf@temp:=\pgf@decorate@decorationlist\do{%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \expandafter\pgf@decorate@invoke\expandafter{\pgf@temp}%
+ \fi%
+ }%
+ \fi%
+ \pgfgetpath\pgfdecorationpath%
+ %
+ % Take stuff outside the group.
+ %
+ \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath%
+ \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath%
+ \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath%
+ \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast%
+ \endgroup%
+ %
+ % Are we in LaTeX?
+ %
+ \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}%
+ {\pgf@decorate@installmacrosatend}%
+}%
+
+
+
+% Environment \pgfmetadecoration \endpgfmetadecoration
+%
+% Decorate a path with decoration automatons!
+%
+% Example:
+%
+% \pgfdeclaremetadecoration{fancy line}{line to}{
+% \state{line to}[width=1cm, next state=zigzag]
+% {
+% \decoration{lineto}
+% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}}
+% \afterdecoration
+% {
+% \pgfsetstrokecolor{black}
+% \pgfusepath{stroke}
+% }
+% }
+% \state{zigzag}[width=2cm, next state=line to]
+% {
+% \decoration{zigzag}
+% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}}
+% \afterdecoration
+% {
+% \pgfsetstrokecolor{red}
+% \pgfusepath{stroke}
+% }
+% }
+% \state{final}
+% {
+% \decoration{lineto}
+% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}}
+% \afterdecoration
+% {
+% \pgfsetstrokecolor{black}
+% \pgfusepath{stroke}
+% }
+% }
+% }
+%
+% \pgfpicture
+% \pgfmetadecoration{fancy line}
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}}
+% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}}
+% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}}
+% \endpgfmetadecoration
+% \endpgfpicture
+%
+\def\pgfmetadecoration#1{%
+ \begingroup%
+ \let\decoration\pgf@metadecoration@decoration%
+ \let\beforedecoration\pgf@metadecoration@beforedecoration%
+ \let\afterdecoration\pgf@metadecoration@afterdecoration%
+ \def\pgf@metadecoration@name{#1}%
+ \pgf@decoration@env%
+}%
+
+\def\endpgfmetadecoration{%
+ \pgf@decoration@endenv%
+ \ifx\pgfdecoratedpath\pgfutil@empty%
+ \else%
+ \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength%
+ \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}%
+ \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}%
+ %
+ % Perform the meta decoration...
+ %
+ \expandafter\let\expandafter\pgf@metadecoration@current@state%
+ \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname%
+ \pgf@metadecoration@run%
+ %
+ % ..until the final state.
+ %
+ \let\pgf@decorate@tempname\pgfutil@empty%
+ \let\pgf@decorate@tempbefore\pgfutil@empty%
+ \let\pgf@decorate@tempafter\pgfutil@empty%
+ \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname%
+ \ifx\pgf@decorate@tempname\pgfutil@empty%
+ \def\pgf@decorate@tempname{moveto}
+ \fi%
+ \pgf@decorate@invoke{%
+ {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}%
+ {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}%
+ }%
+ \fi%
+ \pgfgetpath\pgfdecorationpath%
+ %
+ % Take stuff outside the group.
+ %
+ \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath%
+ \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath%
+ \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath%
+ \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast%
+ \endgroup%
+ %
+ % Are we in LaTeX?
+ %
+ \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}%
+ {\pgf@decorate@installmacrosatend}%
+}%
+
+
+
+
+
+
+% Internal macro for the decoration environment.
+%
+\def\pgf@decoration@env{%
+ \pgfgetpath\pgfdecorateexistingpath%
+ \pgfsetpath\pgfutil@empty%
+ \let\pgfdecorationpath\pgfutil@empty%
+ \let\pgfdecoratedpath\pgfutil@empty%
+ \let\pgfpoint@decorated@pathlast\pgfpointorigin%
+ \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}%
+ %
+ % Begin a group so transformations don't mess things up.
+ %
+ \bgroup%
+}%
+
+\def\pgf@decorate@path@check@moveto#1{%
+ \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop}%
+
+\def\pgf@decorate@token@stop{\pgf@decorate@stop}%
+\def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{%
+ \def\pgf@decorate@temp{#4}%
+ \pgf@x=#2\relax%
+ \pgf@y=#3\relax%
+ \ifx\pgf@decorate@temp\pgf@decorate@token@stop%
+ #5%
+ \else%
+ #6%
+ \fi%
+}%
+
+\def\pgf@decoration@endenv{%
+ \egroup%
+ \pgftransformreset%
+ %
+ % Save the existing soft path and restore the existing path.
+ %
+ \pgfgetpath\pgfdecoratedpath%
+ \pgfsetpath\pgfdecorateexistingpath%
+ %
+ \ifx\pgfdecoratedpath\pgfutil@empty%
+ \pgferror{I cannot decorate an empty path}%
+ \else%
+ %
+ % If the path consists of a single moveto token, make it
+ % a very small horizontal line.
+ %
+ \pgf@decorate@path@check@moveto\pgfdecoratedpath{%
+ \advance\pgf@x by0.0001pt\relax%
+ \edef\pgfdecoratedpath{%
+ \expandafter\noexpand\pgfdecoratedpath%
+ \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}%
+ }%
+ }%
+ {}%
+ %
+ % Remove special round tokens and get points.
+ %
+ \pgfprocessround{\pgfdecoratedpath}{\pgfdecoratedpath}%
+ %
+ % Parse the soft path into a series of decorated input segment objects.
+ %
+ \pgf@decorate@parsesoftpath{\pgfdecoratedpath}{\pgf@decorate@inputsegmentobjects}%
+ %
+ % Setup further options
+ %
+ \pgfkeys{/pgf/every decoration/.try}%
+ %
+ % Reverse objects if necessary.
+ %
+ \ifpgf@decorate@inputsegmentobjects@reverse%
+ \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}%
+ \fi%
+ %
+ \let\pgf@decorated@remainingdistance\pgf@decorate@totalpathlength%
+ %
+ \let\pgfpoint@decorated@totalpathfirst\pgfpoint@decorated@firstparsed%
+ \let\pgfpoint@decorated@totalpathlast\pgfpoint@decorate@lastnonmovetoparsed%
+ %
+ \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@totalpathfirst
+ \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast%
+ %
+ % Set up the first input segment.
+ %
+ \let\pgf@decorate@currentinputsegmentobjects\pgf@decorate@inputsegmentobjects%
+ \let\pgf@decorate@transformtoinputsegment\pgfutil@empty%
+ \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject%
+ \pgf@decorate@processnextinputsegmentobject%
+ \pgf@decorate@distancetomove0pt\relax%
+ \fi%
+}%
+
+
+
+
+\def\pgf@decorate@installmacrosatend{%
+ \let\pgfdecorationpath\pgf@decorate@decorationpathtemp%
+ \let\pgfdecoratedpath\pgf@decorate@decoratedpathtemp%
+ \let\pgfdecorateexistingpath\pgf@decorate@existingpathtemp%
+ \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@pathlasttemp%
+}%
+
+\let\pgfdecorationpath\pgfutil@empty
+\let\pgfdecoratedpath\pgfutil@empty
+\let\pgfdecorateexisitingpath\pgfutil@empty
+
+\let\pgfpoint@decorated@pathlast\pgfpointorigin
+
+
+
+% A version of \pgfutil@for which doesn't expand each value in #3.
+%
+\def\pgf@decorate@for#1:=#2\do#3{%
+ \def\pgf@decorate@for@var{#1}%
+ \def\pgf@decorate@for@action{#3}%
+ \expandafter\pgf@decorate@@for#2,\pgf@stop,}%
+
+\def\pgf@decorate@@for#1,{%
+ \ifx#1\pgf@stop%
+ \expandafter\let\pgf@decorate@for@var\pgfutil@empty%
+ \else%
+ \expandafter\def\pgf@decorate@for@var{#1}%
+ \pgf@decorate@for@action%
+ \expandafter\pgf@decorate@@for%
+ \fi%
+}%
+
+
+% Invoke a decoration.
+%
+% #1 - {<name>}{<distance>}{<before code>}{<after code>}
+%
+\def\pgf@decorate@invoke#1{%
+ \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop}%
+
+\def\pgf@decorate@@invoke#1#2#3#4#5\pgf@stop{%
+ \pgfutil@ifundefined{pgf@decorate@@#1@initial}%
+ {%
+ \pgferror{Unknown decoration `#1'}%
+ }%
+ {%
+ \def\pgf@decorate@name{#1}%
+ \ifx\pgf@decorate@invoke#3%
+ \let\pgf@decorate@beforecode\pgfutil@empty%
+ \else%
+ \def\pgf@decorate@beforecode{#3}%
+ \fi%
+ \ifx\pgf@decorate@invoke#4%
+ \let\pgf@decorate@aftercode\pgfutil@empty%
+ \else%
+ \def\pgf@decorate@aftercode{#4}%
+ \fi%
+ %
+ % Make remaining distance and the decorated path length `public'.
+ %
+ \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax%
+ \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength%
+ %
+ \pgfmathsetlength\pgf@xa{#2}%
+ \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax%
+ \pgf@xa\pgf@decorated@remainingdistance\relax%
+ \fi%
+ \edef\pgf@decorate@currentpathlength{\the\pgf@xa}%
+ %
+ % Calculate the distance remaining to the end of the entire path.
+ %
+ \pgf@xa-\pgf@decorate@currentpathlength\relax%
+ \advance\pgf@xa\pgf@decorated@remainingdistance\relax%
+ \edef\pgf@decorated@remainingdistance{\the\pgf@xa}%
+ %
+ % Set up the macros and distances for the current section
+ % of the decorated path.
+ %
+ \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength%
+ \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax%
+ \pgfdecoratedcompleteddistance0pt\relax%
+ %
+ % Execute user-defined code beore decoration.
+ %
+ \pgf@decorate@beforecode%
+ %
+ % Run the decoration...
+ %
+ \expandafter\let\expandafter\pgf@decorate@current@state%
+ \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname%
+ \pgf@decorate@run%
+ %
+ % ...until the final state.
+ %
+ \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies.
+ \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast%
+ \else%
+ %
+ % Set up \pgfpoint@decorated@pathlast if the end of
+ % the total decorated path has not been reached.
+ %
+ {%
+ \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}%
+ \pgf@decorate@transformtoinputsegment%
+ \pgfpointorigin%
+ \pgf@pos@transform@glob%
+ \global\pgf@x\pgf@x%
+ \global\pgf@y\pgf@y%
+ }%
+ \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}%
+ \fi%
+ {%
+ \pgftransformreset%
+ \pgf@decorate@transformtoinputsegment%
+ \pgf@decorate@additionaltransform%
+ \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname%
+ }%
+ \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}%
+ %
+ % Execute user-defined code after decoration.
+ %
+ \pgf@decorate@aftercode%
+ %
+ % Update the input segment objects.
+ %
+ \let\pgf@decorate@additionaltransform\pgfutil@empty%
+ \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit%
+ \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast%
+ }%
+}%
+
+
+
+\let\pgf@decorate@transformtoinputsegment\pgfutil@empty%
+\let\pgf@decorate@additionaltransform\pgfutil@empty%
+
+
+% \pgfpointdecoratedpathfirst
+%
+\def\pgfpointdecoratedpathfirst{%
+ {%
+ \pgftransforminvert%
+ \pgfpoint@decorated@pathfirst%
+ \pgf@pos@transform@glob%
+ \global\pgf@x\pgf@x%
+ \global\pgf@y\pgf@y%
+ }%
+}%
+
+% \pgfpointdecoratedpathlast
+%
+\def\pgfpointdecoratedpathlast{%
+ {%
+ \pgftransforminvert%
+ \pgfpoint@decorated@pathlast%
+ \pgf@pos@transform@glob%
+ \global\pgf@x\pgf@x%
+ \global\pgf@y\pgf@y%
+ }%
+}%
+
+% \pgfpointdecoratedinputsegmentfirst
+%
+% The first point of the current sub-path.
+%
+\def\pgfpointdecoratedinputsegmentfirst{%
+ {%
+ \pgftransforminvert%
+ \pgf@decorate@inputsegment@first%
+ \pgf@pos@transform@glob%
+ \global\pgf@x\pgf@x%
+ \global\pgf@y\pgf@y%
+ }%
+}%
+
+% \pgfpointdecoratedinputsegmentlast
+%
+% The final point of the current sub-path.
+%
+\def\pgfpointdecoratedinputsegmentlast{%
+ {%
+ \pgftransforminvert%
+ \pgf@decorate@inputsegment@last%
+ \pgf@pos@transform@glob%
+ \global\pgf@x\pgf@x%
+ \global\pgf@y\pgf@y%
+ }%
+}%
+
+
+\def\pgf@final@text{final}%
+
+% Run a normal decoration.
+%
+\def\pgf@decorate@run{%
+ \let\pgf@decorate@next\pgf@decorate@do@state%
+ \ifx\pgf@decorate@current@state\pgf@final@text%
+ \let\pgf@decorate@next\relax%
+ \fi%
+ \pgf@decorate@next%
+}%
+
+\def\pgf@decorate@do@state{%
+ \let\pgf@decorate@next\relax%
+ \let\pgf@decorate@next@state\pgf@decorate@current@state%
+ %
+ % Get the options.
+ %
+ \let\pgf@decorate@persistent@pre=\relax%
+ \let\pgf@decorate@persistent@post=\relax%
+ \expandafter\expandafter\expandafter\pgf@decorate@setter
+ \expandafter\expandafter\expandafter{\csname pgf@decorate@@\pgf@decorate@name @\pgf@decorate@current@state @options\endcsname}%
+ \ifx\pgf@decorate@next\relax%
+ \let\pgf@decorate@next\pgf@decorate@do@code%
+ \fi%
+ \pgf@decorate@next%
+}%
+
+\def\pgf@decorate@setter{\pgfqkeys{/pgf/decoration automaton}}%
+
+\pgf@decorate@repeatstate-1\relax
+
+\def\pgf@decorate@do@code{%
+ %
+ % Execute code.
+ %
+ \pgf@decorate@persistent@pre%
+ {%
+ \pgftransformreset%
+ \pgf@decorate@transformtoinputsegment%
+ \pgf@decorate@additionaltransform%
+ \csname pgf@decorate@@\pgf@decorate@name @\pgf@decorate@current@state @code\endcsname%
+ }%
+ \pgf@decorate@persistent@post%
+ \pgf@decorate@movealongpath{\pgf@decorate@width}%
+ %
+ % Next iteration.
+ %
+ \ifnum\pgf@decorate@repeatstate>0\relax%
+ \advance\pgf@decorate@repeatstate-1\relax%
+ \else%
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@current@state\pgf@decorate@next@state%
+ \fi%
+ \pgf@decorate@run%
+}%
+
+\pgfkeys{
+ /pgf/decoration automaton/width/.code=\def\pgf@decorate@width{#1}\pgf@decorate@switch@if#1 to final\pgf@stop,%
+ /pgf/decoration automaton/switch if less than/.code=\pgf@decorate@switch@if#1\pgf@stop,%
+ /pgf/decoration automaton/switch if input segment less than/.code=\pgf@decorate@switch@ifinputsegment#1\pgf@stop,%
+ /pgf/decoration automaton/next state/.store in=\pgf@decorate@next@state,%
+ /pgf/decoration automaton/persistent precomputation/.store in=\pgf@decorate@persistent@pre,%
+ /pgf/decoration automaton/persistent postcomputation/.store in=\pgf@decorate@persistent@post,%
+ /pgf/decoration automaton/repeat state/.code={%
+ \ifnum\pgf@decorate@repeatstate=-1\relax%
+ \pgfmathsetcount\pgf@decorate@repeatstate{#1}%
+ \fi%
+ },%
+ /pgf/decoration automaton/if input segment is closepath/.code={%
+ \ifpgf@decorate@is@closepath@%
+ \pgfkeysalso{#1}%
+ \fi%
+ },
+ /pgf/decoration automaton/auto end on length/.code=\pgf@decorate@auto@end{#1},
+ /pgf/decoration automaton/auto corner on length/.code=\pgf@decorate@auto@corner{#1},
+}%
+
+\def\pgf@decorate@auto@end#1{%
+ \ifx\pgf@decorate@next\relax%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifpgf@decorate@is@closepath@%
+ \ifdim\pgfdecoratedremainingdistance>\pgf@x%
+ \ifdim\pgfdecoratedinputsegmentremainingdistance>\pgf@x%
+ \else%
+ \pgfpathclose%
+ \pgf@decorate@movealongpath{\pgfdecoratedinputsegmentremainingdistance}%
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@next\pgf@decorate@run%
+ \fi%
+ \else%
+ \pgfpathclose%
+ \def\pgf@decorate@current@state{final}%
+ \def\pgf@decorate@width{\pgfdecoratedremainingdistance}
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@next\pgf@decorate@run%
+ \fi%
+ \else%
+ \ifdim\pgfdecoratedremainingdistance>\pgf@x%
+ \else%
+ {%
+ \pgftransformreset%
+ \pgf@decorate@transformtoinputsegment%
+ \pgf@decorate@additionaltransform%
+ \pgfpathlineto{\pgfpoint{\pgfdecoratedremainingdistance}{0pt}}
+ }%
+ \def\pgf@decorate@current@state{final}%
+ \def\pgf@decorate@width{\pgfdecoratedremainingdistance}
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@next\pgf@decorate@run%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+\def\pgf@decorate@auto@corner#1{%
+ \ifpgfdecoratepathhascorners%
+ \ifx\pgf@decorate@next\relax%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifdim\pgfdecoratedinputsegmentremainingdistance>\pgf@x%
+ \else%
+ {%
+ \pgftransformreset%
+ \pgf@decorate@transformtoinputsegment%
+ \pgf@decorate@additionaltransform%
+ \pgfpathlineto{\pgfqpoint{\pgfdecoratedinputsegmentremainingdistance}{0pt}}
+ }%
+ \pgf@decorate@movealongpath{\pgfdecoratedinputsegmentremainingdistance}%
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@next\pgf@decorate@run%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+\def\pgf@decorate@switch@if#1to #2\pgf@stop{%
+ \ifx\pgf@decorate@next\relax%
+ \ifdim\pgfdecoratedremainingdistance=0pt\relax%
+ \def\pgf@decorate@current@state{#2}%
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@next\pgf@decorate@run%
+ \else%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifdim\pgfdecoratedremainingdistance<\pgf@x%
+ \def\pgf@decorate@current@state{#2}%
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@next\pgf@decorate@run%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+\def\pgf@decorate@switch@ifinputsegment#1to #2\pgf@stop{%
+ \ifx\pgf@decorate@next\relax%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifdim\pgfdecoratedinputsegmentremainingdistance<\pgf@x%
+ \def\pgf@decorate@current@state{#2}%
+ \pgf@decorate@repeatstate-1\relax%
+ \let\pgf@decorate@next\pgf@decorate@run%
+ \fi%
+ \fi%
+}%
+
+
+
+
+% \pgfsetdecorationsegmenttransformation
+%
+% Set the additional transform for each decoration state.
+%
+% Example:
+%
+% \pgfsetdecorationsegmenttransformation{\pgftransformyshift{5pt}}
+%
+\def\pgfsetdecorationsegmenttransformation#1{\def\pgf@decorate@additionaltransform{#1}}%
+\let\pgf@decorate@additionaltransform\pgfutil@empty%
+
+
+
+
+\def\pgf@metadecoration@decoration#1{%
+ \edef\pgf@decorate@tempname{#1}%
+}%
+\def\pgf@metadecoration@beforedecoration#1{%
+ \def\pgf@decorate@tempbefore{#1}%
+}%
+\def\pgf@metadecoration@afterdecoration#1{%
+ \def\pgf@decorate@tempafter{#1}%
+}%
+
+
+\def\pgf@final@text{final}%
+
+% Run a meta decoration.
+%
+\def\pgf@metadecoration@run{%
+ \let\pgf@metadecoration@next\pgf@metadecoration@do@state%
+ \ifx\pgf@metadecoration@current@state\pgf@final@text%
+ \let\pgf@metadecoration@next\relax%
+ \fi%
+ \pgf@metadecoration@next%
+}%
+
+\def\pgf@metadecoration@do@state{%
+ \let\pgf@metadecoration@next\relax%
+ \let\pgf@metadecoration@next@state\pgf@metadecoration@current@state%
+ %
+ % Set up some macros.
+ %
+ \let\pgfmetadecoratedremainingdistance\pgf@decorated@remainingdistance%
+ \pgf@x-\pgfmetadecoratedremainingdistance\relax%
+ \advance\pgf@x\pgf@decorate@totalpathlength\relax%
+ \edef\pgfmetadecoratedcompleteddistance{\the\pgf@x}%
+ %
+ % Get the options.
+ %
+ \expandafter\expandafter\expandafter\pgf@metadecoration@setter
+ \expandafter\expandafter\expandafter{\csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @options\endcsname}%
+ \ifx\pgf@metadecoration@next\relax%
+ \let\pgf@metadecoration@next\pgf@metadecoration@do@code%
+ \fi%
+ \pgf@metadecoration@next%
+}%
+
+\def\pgf@metadecoration@do@code{%
+ %
+ % Execute code.
+ %
+ \let\pgf@decorate@tempname\pgfutil@empty%
+ \let\pgf@decorate@tempbefore\pgfutil@empty%
+ \let\pgf@decorate@tempafter\pgfutil@empty%
+ \let\pgfpointmetadecoratedpathfirst\pgfpointdecoratedpathfirst%
+ \let\pgfpointmetadecoratedpathlast\pgfpointdecoratedpathlast%
+ \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname%
+ \ifx\pgf@decorate@tempname\pgfutil@empty%
+ \def\pgf@decorate@tempname{moveto}
+ \fi%
+ \pgf@decorate@invoke{%
+ {\pgf@decorate@tempname}{\pgf@metadecoration@width}%
+ {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}%
+ }%
+ %
+ % Next iteration.
+ %
+ \let\pgf@metadecoration@current@state\pgf@metadecoration@next@state%
+ \pgf@metadecoration@run%
+}%
+
+\def\pgf@metadecoration@setter{\pgfqkeys{/pgf/meta-decoration automaton}}%
+
+\pgfkeys{
+ /pgf/meta-decoration automaton/width/.code=\def\pgf@metadecoration@width{#1}\pgf@metadecoration@switch@if#1 to final\pgf@stop,%
+ /pgf/meta-decoration automaton/switch if less than/.code=\pgf@metadecoration@switch@if#1\pgf@stop,%
+ /pgf/meta-decoration automaton/switch if input segment less than/.code=\pgf@metadecoration@switch@ifinputsegment#1\pgf@stop,%
+ /pgf/meta-decoration automaton/next state/.store in=\pgf@metadecoration@next@state,%
+}%
+
+\def\pgf@metadecoration@switch@if#1to #2\pgf@stop{%
+ \ifx\pgf@metadecoration@next\relax%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifdim\pgf@decorated@remainingdistance<\pgf@x%
+ \def\pgf@metadecoration@current@state{#2}%
+ \let\pgf@metadecoration@next\pgf@metadecoration@run%
+ \fi%
+ \fi%
+}%
+
+\def\pgf@metadecoration@switch@ifinputsegment#1to #2\pgf@stop{%
+ \ifx\pgf@metadecoration@next\relax%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifdim\pgfdecoratedinputsegmentremainingdistance<\pgf@x%
+ \def\pgf@metadecoration@current@state{#2}%
+ \let\pgf@metadecoration@next\pgf@metadecoration@run%
+ \fi%
+ \fi%
+}%
+
+
+
+% Move along the path by a specified distance.
+%
+\def\pgf@decorate@movealongpath#1{%
+ \pgfmathsetlength\pgf@decorate@distancetomove{#1}%
+ \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove%
+ \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove%
+ \pgf@decorate@@movealongpath%
+}%
+\def\pgf@decorate@@movealongpath{%
+ \advance\pgfdecoratedinputsegmentcompleteddistance\pgf@decorate@distancetomove%
+ \advance\pgfdecoratedinputsegmentremainingdistance-\pgf@decorate@distancetomove%
+ \ifdim\pgfdecoratedinputsegmentremainingdistance>0pt\relax%
+ \let\pgf@next\pgf@decorate@@@movealongpath%
+ \else%
+ \pgf@decorate@distancetomove-\pgfdecoratedinputsegmentremainingdistance%
+ \pgf@decorate@processnextinputsegmentobject%
+ \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty%
+ \pgfdecoratedremainingdistance0pt\relax%
+ \let\pgf@next\relax%
+ \else%
+ \let\pgf@next\pgf@decorate@@movealongpath%
+ \fi%
+ \fi%
+ \pgf@next%
+}%
+
+\def\pgf@decorate@@@movealongpath{%
+ %
+ % Move along input segment for real.
+ %
+ \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}%
+ \pgf@decorate@distancetomove0pt\relax%
+ %
+ % Grrr. Hacking to control some inaccuracies.
+ %
+ \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax%
+ \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime%
+ \pgf@decorate@processnextinputsegmentobject%
+ \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax%
+ \advance\pgf@x-1pt\relax%
+ \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}%
+ \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty%
+ \pgfdecoratedremainingdistance0pt\relax%
+ \fi%
+ \fi%
+}%
+
+% Return the next input segment object in a macro
+%
+\def\pgf@decorate@getnextinputsegmentobject#1{%
+ \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty%
+ \let\pgf@next\relax%
+ \else%
+ \def\pgf@decorate@temp{#1}%
+ \let\pgf@next\pgf@decorate@@getnextinputsegmentobject%
+ \fi%
+ \pgf@next%
+}%
+\def\pgf@decorate@@getnextinputsegmentobject{%
+ \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop}%
+\def\pgf@decorate@@@getnextinputsegmentobject#1#2\pgf@stop{%
+ \expandafter\def\pgf@decorate@temp{#1}%
+ \def\pgf@decorate@currentinputsegmentobjects{#2}}%
+
+% Process the next input segment object.
+%
+\def\pgf@decorate@processnextinputsegmentobject{%
+ \let\pgfdecorationpreviousinputsegment\pgfdecoratecurrentinputsegment%
+ \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject%
+ \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject%
+ %
+ % If the current input segment object is a moveto, execute the
+ % object macro and get the next input segment object.
+ %
+ \pgf@decorate@is@closepath@false%
+ \pgf@decorate@currentinputsegmentobject%
+ \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto%
+ \pgfpathmoveto{\pgf@decorate@inputsegment@first}%
+ \let\pgfdecorationpreviousinputsegment\pgfdecorationcurrentinputsegment%
+ \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject%
+ \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject%
+ \pgf@decorate@is@closepath@false%
+ \pgf@decorate@currentinputsegmentobject%
+ \fi%
+ %
+ % Teensy hack in case a path goes nowhere.
+ %
+ \ifdim\pgfdecoratedinputsegmentlength=0pt\relax%
+ \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt.
+ \fi%
+ \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax%
+ \pgfdecoratedinputsegmentcompleteddistance0pt\relax%
+ \def\pgf@decorate@inputsegmenttime{0}%
+ %
+ % Get the angle at the start of the input segment.
+ %
+ \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto%
+ \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}%
+ \let\pgfdecoratedangle\pgfmathresult%
+ \let\pgfdecoratedinputsegmentstartangle\pgfmathresult%
+ \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}%
+ \let\pgfdecoratedinputsegmentendangle\pgfmathresult%
+ \else%
+ \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}%
+ \let\pgfdecoratedangle\pgfmathresult%
+ \let\pgfdecoratedinputsegmentstartangle\pgfmathresult%
+ \let\pgfdecoratedinputsegmentendangle\pgfmathresult%
+ \fi%
+ %
+ % Get the angle to the next input segment.
+ %
+ \begingroup%
+ \pgf@decorate@nextinputsegmentobject%
+ \global\let\pgf@decorate@temp\pgfdecorationcurrentinputsegment%
+ \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto%
+ \expandafter\pgf@decorate@currentinputsegmentobject%
+ \fi%
+ \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto%
+ \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}%
+ \else%
+ \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}%
+ \fi%
+ \pgf@x-\pgfdecoratedangle pt\relax%
+ \advance\pgf@x\pgfmathresult pt\relax%
+ \edef\pgfdecoratedangletonextinputsegment{\the\pgf@x}%
+ \pgfmath@smuggleone\pgfdecoratedangletonextinputsegment%
+ \endgroup%
+ \let\pgfdecorationnextinputsegmentobject\pgf@decorate@temp%
+}%
+
+
+%
+% Input segment objects
+%
+
+\newif\ifpgf@decorate@is@closepath@%
+
+% Input segment types.
+%
+% These allow comparison with \ifx using
+%
+% \pgfdecorationcurrentinputsegment
+% \pgfdecorationnextinputsegment
+% \pgfdecorationcurrentprevioussegment
+%
+\def\pgfdecorationinputsegmentmoveto{moveto}%
+\def\pgfdecorationinputsegmentlineto{lineto}%
+\def\pgfdecorationinputsegmentcurveto{curveto}%
+\def\pgfdecorationinputsegmentclosepath{closepath}%
+\def\pgfdecorationinputsegmentlast{last}%
+
+% Input segment object moveto.
+%
+\def\pgf@decorate@inputsegmentobject@moveto#1{%
+ \def\pgf@decorate@inputsegment@first{#1}%
+ \def\pgf@decorate@inputsegment@supporta{#1}%
+ \def\pgf@decorate@inputsegment@supportb{#1}%
+ \def\pgf@decorate@inputsegment@last{#1}%
+ \edef\pgf@decorate@lastmoveto{#1}%
+ \def\pgfdecoratedinputsegmentlength{0pt}%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto%
+}%
+
+% Input segment object lineto.
+%
+\def\pgf@decorate@inputsegmentobject@lineto#1#2#3{%
+ \def\pgfdecoratedinputsegmentlength{#1}%
+ \def\pgf@decorate@inputsegment@first{#2}%
+ \def\pgf@decorate@inputsegment@last{#3}%
+ %
+ % Supports should be defined like this, so if treated as a curve,
+ % equal time steps will correspond to equal distances.
+ %
+ \pgfpointdiff{#2}{#3}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfextract@process\pgf@decorate@inputsegment@supporta{%
+ \pgf@process{#2}%
+ \advance\pgf@x0.333333\pgf@xa%
+ \advance\pgf@y0.333333\pgf@ya%
+ }%
+ \pgfextract@process\pgf@decorate@inputsegment@supportb{%
+ \pgf@process{#2}%
+ \advance\pgf@x0.666666\pgf@xa%
+ \advance\pgf@y0.666666\pgf@ya%
+ }%
+ \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line%
+ \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto%
+}%
+
+% Input segment object curveto.
+%
+\def\pgf@decorate@inputsegmentobject@curveto#1#2#3#4#5{%
+ \def\pgfdecoratedinputsegmentlength{#1}%
+ \def\pgf@decorate@inputsegment@first{#2}%
+ \def\pgf@decorate@inputsegment@supporta{#3}%
+ \def\pgf@decorate@inputsegment@supportb{#4}%
+ \def\pgf@decorate@inputsegment@last{#5}%
+ %
+ \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve%
+ \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto%
+}%
+
+% Input segment object closepath.
+%
+% Treated like a lineto, but flag that it is a closepath.
+%
+\def\pgf@decorate@inputsegmentobject@closepath#1#2#3{%
+ \pgf@decorate@is@closepath@true%
+ %
+ \def\pgfdecoratedinputsegmentlength{#1}%
+ \def\pgf@decorate@inputsegment@first{#2}%
+ \def\pgf@decorate@inputsegment@last{#3}%
+ %
+ \pgfpointdiff{#2}{#3}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgfextract@process\pgf@decorate@inputsegment@supporta{%
+ \pgf@process{#2}%
+ \advance\pgf@x0.333333\pgf@xa%
+ \advance\pgf@y0.333333\pgf@ya%
+ }%
+ \pgfextract@process\pgf@decorate@inputsegment@supportb{%
+ \pgf@process{#2}%
+ \advance\pgf@x0.666666\pgf@xa%
+ \advance\pgf@y0.666666\pgf@ya%
+ }%
+ %
+ \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line%
+ \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath%
+}%
+
+
+% Input segment object endofinputsegments.
+%
+\def\pgf@decorate@inputsegmentobject@endofinputsegments{%
+ \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast%
+}%
+
+
+
+
+% This macro controls how the automaton moves along a line sub-path
+%
+\def\pgf@decorate@movealonginputsegment@line#1{}% Nothing special needed.
+
+% This macro controls how the automaton moves along a curve sub-path.
+%
+\def\pgf@decorate@movealonginputsegment@curve#1{%
+ \ifdim#1=0pt\relax%
+ \else%
+ \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}%
+ {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}%
+ {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \pgf@xb\pgf@decorate@inputsegmenttime pt\relax%
+ %
+ % Reduce the initial time step, depending on the length
+ % of the path. To do: Optimise this step (should also depend on #1).
+ %
+ \ifdim\pgf@decorate@currentpathlength<128pt\relax%
+ \pgf@yb.03125pt\relax%
+ \else%
+ \ifdim\pgf@decorate@currentpathlength<512pt\relax%
+ \pgf@yb.015625pt\relax%
+ \else%
+ \ifdim\pgf@decorate@currentpathlength<2048pt\relax%
+ \pgf@yb.00390625pt\relax%
+ \else%
+ \pgf@yb.0009765625pt\relax%
+ \fi%
+ \fi%
+ \fi%
+ \c@pgf@counta1\relax%
+ \pgfutil@tempdima0pt\relax%
+ \pgfmathloop%
+ \advance\pgf@xb\c@pgf@counta\pgf@yb%
+ %
+ % We would like to use \pgfpointcurveattime. However, we must not
+ % overuse \pgf@process or \pgfmath stuff within this loop,
+ % otherwise we increase the chances of save stack overflow.
+ %
+ \edef\pgf@decorate@temp{%
+ \pgf@xa\the\pgf@xa%
+ \pgf@xb\the\pgf@xb%
+ \pgf@ya\the\pgf@ya%
+ \pgf@yb\the\pgf@yb%
+ }%
+ %
+ \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}%
+ {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}%
+ {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}%
+ \pgf@decorate@temp%
+ %
+ \pgf@xc\pgf@xa%
+ \pgf@yc\pgf@ya%
+ \pgf@xa\pgf@x%
+ \pgf@ya\pgf@y%
+ \advance\pgf@x-\pgf@xc%
+ \advance\pgf@y-\pgf@yc%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \pgfutil@tempdimb\pgfmathresult pt\relax%
+ \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb%
+ \ifnum\c@pgf@counta>0\relax%
+ \ifdim\pgfutil@tempdima>#1\relax%
+ \c@pgf@counta-\c@pgf@counta%
+ \pgf@yb.5\pgf@yb%
+ \fi%
+ \else%
+ \ifdim\pgfutil@tempdima<#1\relax%
+ \c@pgf@counta-\c@pgf@counta%
+ \pgf@yb.5\pgf@yb%
+ \fi%
+ \fi%
+ \ifdim\pgf@yb=0pt\relax% *Should* be OK.
+ \else%
+ \repeatpgfmathloop%
+ \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}%
+ %
+ % Now calculate the angle at the new time on the curve.
+ %
+ % We can use \pgfpointcurveattime safely here.
+ %
+ \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}%
+ {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}%
+ {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}%
+ \edef\pgf@marshal{%
+ \noexpand\pgfmathanglebetweenpoints%
+ {\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}%
+ {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}%
+ }%
+ \pgf@marshal%
+ \let\pgfdecoratedangle\pgfmathresult%
+ \fi%
+}%
+
+% \pgfpoint@decorate@curveattime
+%
+% A `quick' version of \pgfpointcurveattime
+%
+% No parsing and no use of \pgf@process.
+% This prevents save stack build up when used inside a loop.
+%
+\def\pgfpoint@decorate@curveattime#1#2#3#4#5{%
+ \edef\pgf@time@s{#1}%
+ \pgf@x-\pgf@time@s pt\relax%
+ \advance\pgf@x1pt\relax%
+ \edef\pgf@time@t{\pgf@sys@tonumber{\pgf@x}}%
+ #5\relax%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ #4\relax%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ #3\relax%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ #2\relax%
+ % First iteration:
+ \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya%
+ \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb%
+ \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb%
+ \pgf@xb=\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc%
+ \pgf@yb=\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc%
+ % Second iteration:
+ \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya%
+ \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb%
+ \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb%
+ % Save x/y
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ % Third iteration:
+ \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya%
+}%
+
+
+% Applies the necessary transform for a line sub-path.
+%
+\def\pgf@decorate@transformtoinputsegment@line{%
+ \pgftransformshift{%
+ \pgfpointlineatdistance{\pgfdecoratedinputsegmentcompleteddistance}{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}
+ }%
+ \pgftransformrotate{\pgfdecoratedangle}%
+}%
+
+% Applies the necessary transform for a curve sub-path.
+%
+\def\pgf@decorate@transformtoinputsegment@curve{%
+ \pgfslopedattimetrue%
+ \pgfallowupsidedownattimetrue%
+ \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}%
+ {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}%
+ {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}%
+}%
+
+
+
+
+
+% \pgf@decorate@parsesoftpath
+%
+% Parses an instance of a soft path into intermediate line and curve
+% sub-path objects which the decoration automaton can use to traverse
+% the decorated path.
+%
+% The soft path should be well formed and only contain `primative'
+% soft path tokens, that is: moveto, lineto, curvetosupporta,
+% curvetosupportb, curveto, rectcorner, rectsize, and closepath.
+% (i.e., all specialround tokens should have removed using
+% \pgfprocessround)
+%
+% The overall length of the path is also calculated and returned
+% in the macro \pgfdecoratedpathlength.
+%
+% Parameters:
+%
+% #1 - a macro containing a well formed soft path.
+% #2 - a macro to store the intermediate sub-path representations.
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointorigin}
+% \pgfpathlineto{\pgfpoint{0pt}{12pt}}
+% \pgfpathlineto{\pgfpoint{12pt}{0pt}}
+% \pgfgetpath\softpath
+%
+% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath}
+%
+% results in:
+%
+% \parsedsoftpath ->
+% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}}
+% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}}
+%
+% \pgfdecoratedpathlength ->
+% 24pt
+%
+
+\def\pgf@decorate@parsesoftpath#1#2{%
+ \def\pgf@decorate@inputsegmentobjectsmacro{#2}%
+ \let\pgf@decorate@inputsegmentobjects\pgfutil@empty%
+ \pgfutil@tempdima0pt\relax%
+ \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast%
+ \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin%
+ \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty%
+ \let\pgfpoint@decorated@firstparsed\pgfutil@empty%
+ \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop%
+}%
+
+\def\pgf@decorate@@parsesoftpath#1{%
+ \ifx#1\pgf@stop%
+ \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable).
+ \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}%
+ \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}%
+ \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects%
+ \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}%
+ \let\pgf@next\relax%
+ \else%
+ \ifx#1\pgfsyssoftpath@movetotoken%
+ \let\pgf@next\pgf@decorate@parsemoveto%
+ \else%
+ \ifx#1\pgfsyssoftpath@linetotoken%
+ \let\pgf@next\pgf@decorate@parselineto%
+ \else%
+ \ifx#1\pgfsyssoftpath@curvetosupportatoken%
+ \let\pgf@next\pgf@decorate@parsecurveto%
+ \else%
+ \ifx#1\pgfsyssoftpath@closepathtoken%
+ \let\pgf@next\pgf@decorate@parseclosepath%
+ \else%
+ \ifx#1\pgfsyssoftpath@rectcornertoken%
+ \let\pgf@next\pgf@decorate@parserect%
+ \else%
+ \pgferror{Unrecognised soft path token `#1'}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgf@next}%
+
+
+\def\pgf@decorate@addtoinputsegmentobjects#1{%
+ %
+ % If there is an input segment object waiting (i.e. a moveto), insert it here.
+ %
+ \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty%
+ \else%
+ \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject%
+ \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty%
+ \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}%
+ \fi%
+ \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty%
+ #1%
+ \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first%
+ \fi%
+ \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter%
+ {\pgf@decorate@inputsegmentobjects{#1}}%
+}%
+
+% Convert \pgfsyssoftpath@movetotoken{<X>}{<Y>} into the following
+% representation:
+%
+% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y}
+%
+% The moveto input segment object is not added immediately, so that
+% only the last of multiple movetos is inserted.
+%
+\def\pgf@decorate@parsemoveto#1#2{%
+ \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}%
+ \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}%
+ \pgf@decorate@@parsesoftpath%
+}%
+
+% Convert \pgfsyssoftpath@linetotoken{<X>}{<Y>} into the following
+% representation:
+%
+% \pgf@decorate@inputsegmentobject@lineto{<length>}{\pgf@x <Last X> \pgf@y <Last Y}{\pgf@x <X> \pgf@y <Y>}
+%
+\def\pgf@decorate@parselineto#1#2{%
+ \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}%
+ \advance\pgfutil@tempdima\pgfmathresult pt\relax%
+ \edef\pgf@decorate@temp{%
+ \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}%
+ }%
+ \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}%
+ \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed%
+ \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}%
+ \pgf@decorate@@parsesoftpath%
+}%
+
+% Convert \pgfsyssoftpath@curvetosupportatoken{<Xa>}{<Ya>}...etc
+% into the following representation:
+%
+% \pgf@decorate@inputsegmentobject@curveto{<length>}{\pgf@x <Last X> \pgf@y <Last Y}
+% {\pgf@x <Xa> \pgf@y <Ya>}{\pgf@x <Xb> \pgf@y <Yb>}{\pgf@x <X> \pgf@y <Y>}
+%
+\def\pgf@decorate@parsecurveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{%
+ \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}%
+ \advance\pgfutil@tempdima\pgfmathresult pt\relax%
+ \edef\pgf@decorate@temp{%
+ \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}%
+ {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}%
+ }%
+ \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}%
+ \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}%
+ \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed%
+ \pgf@decorate@@parsesoftpath%
+}%
+
+
+\def\pgf@decorate@parseclosepath#1#2{%
+ \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}%
+ \advance\pgfutil@tempdima\pgfmathresult pt\relax%
+ \edef\pgf@decorate@temp{%
+ \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}%
+ }%
+ \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}%
+ \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}%
+ \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed%
+ \pgf@decorate@@parsesoftpath%
+}%
+
+% Convert \pgfsyssoftpath@rectcornertoken{<X>}{<Y>}\pgfsyssoftpath@rectsizetoken{<Xa>}{<Ya>}
+% into either (clockwise)
+%
+% \pgf@decorate@inputsegmentobject@moveto{<X>}{<Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <X> \pgf@y <Y>}{\pgf@x <X> \pgf@y <Ya+Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <X> \pgf@y <Ya+Y>}{\pgf@x <Xa+X> \pgf@y <Ya+Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <Xa+X> \pgf@y <Ya+X>}{\pgf@x <Xa+X> \pgf@y <Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <Xa+X> \pgf@y <Y>}{\pgf@x <X> \pgf@y <Y>}
+% \pgf@decorate@inputsegmentobject@moveto{<Xa>}{<Ya>}
+%
+% ...or (anti-clockwise)
+%
+% \pgf@decorate@inputsegmentobject@moveto{<X>}{<Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <X> \pgf@y <Y>}{\pgf@x <Xa+X> \pgf@y <Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <Xa+X> \pgf@y <Y>}{\pgf@x <Xa+X> \pgf@y <Ya+Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 2>}{\pgf@x <Xa+X> \pgf@y <Ya+Y>}{\pgf@x <X> \pgf@y <Ya+Y>}
+% \pgf@decorate@inputsegmentobject@lineto{<length 1>}{\pgf@x <X> \pgf@y <Ya+Y>}{\pgf@x <X> \pgf@y <Y>}
+% \pgf@decorate@inputsegmentobject@moveto{<Xa>}{<Ya>}
+%
+\newif\ifpgfdecoraterectangleclockwise
+\def\pgf@decorate@parserect#1#2\pgfsyssoftpath@rectsizetoken#3#4{%
+ %
+ % Subvert \pgf@decorate@parsesoftpath so parsing macros will
+ % return here instead of continuing to parse the soft path.
+ %
+ \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath%
+ \let\pgf@decorate@@parsesoftpath\relax%
+ \pgf@decorate@parsemoveto{#1}{#2}%
+ \pgf@xa#1\relax%
+ \pgf@ya#2\relax%
+ \ifpgfdecoraterectangleclockwise%
+ \advance\pgf@ya#4%
+ \pgf@yb\pgf@ya%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgf@decorate@parselineto\pgf@temp%
+ \advance\pgf@xa#3%
+ \pgf@xb\pgf@xa%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgf@decorate@parselineto\pgf@temp%
+ \advance\pgf@ya-#4%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgf@decorate@parselineto\pgf@temp%
+ \advance\pgf@xa-#3%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgf@decorate@parseclosepath\pgf@temp%
+ \else%
+ \advance\pgf@xa#3%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \pgf@xb\pgf@xa%
+ \expandafter\pgf@decorate@parselineto\pgf@temp%
+ \advance\pgf@ya#4%
+ \pgf@yb\pgf@ya%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgf@decorate@parselineto\pgf@temp%
+ \advance\pgf@xa-#3%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgf@decorate@parselineto\pgf@temp%
+ \advance\pgf@ya-#4%
+ \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}%
+ \expandafter\pgf@decorate@parseclosepath\pgf@temp%
+ \fi%
+ %
+ % Restore the parsing.
+ %
+ \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath%
+ \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}%
+ \pgf@marshal%
+}%
+
+
+
+
+% \pgf@decorate@linelength
+%
+% Define \pgfmathresult as the distance between #1 and #2 (without units).
+%
+\def\pgf@decorate@linelength#1#2{%
+ \pgf@process{\pgfpointdiff{#1}{#2}}%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+}%
+
+% \pgf@decorate@curvelength
+%
+% Define \pgfmathresult as the length (without units) of the cubic
+% bezier described by #1,#2,#3 and #4.
+%
+% To approximate the length of the curve P (sort of) use:
+%
+% curveLength(P,q)
+% Q = subdivideLeft(P);
+% R = subdivideRight(P);
+% return curveLength'(Q,q) + curveLength'(R,q);
+%
+% curveLength'(P,q)
+% <P1,P2,P3,P4> <- P;
+% P' = P4 - P1;
+% x = P'.x();
+% y = P'.y();
+% if (x < q) && (y < q)
+% return |P'|;
+% else%
+% Q = subdivideLeft(P);
+% R = subdivideRight(P);
+% return curveLength'(Q,q) + curveLength'(R,q);
+%
+% Where q is some small value (`tolerance').
+%
+\newif\ifpgf@decorate@subdivide
+\def\pgf@decorate@curvelength#1#2#3#4{%
+ %
+ % Always begin with a subdivision in case #1 = #4.
+ %
+ \begingroup%
+ \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}%
+ \pgfutil@tempdimb\pgfmathresult pt\relax%
+ \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}%
+ \advance\pgfutil@tempdimb\pgfmathresult pt\relax%
+ \pgfmath@returnone\pgfutil@tempdimb%
+ \endgroup%
+}%
+
+\def\pgf@decorate@@curvelength#1#2#3#4{%
+ \begingroup%
+ \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}%
+ \ifpgf@decorate@subdivide%
+ \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}%
+ \pgfutil@tempdimb\pgfmathresult pt\relax%
+ \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}%
+ \advance\pgfutil@tempdimb\pgfmathresult pt\relax%
+ \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb%
+ \else%
+ \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter%
+ \fi%
+ \endgroup%
+}%
+
+\def\pgf@decorate@curvelength@tolerance{1pt}%
+
+\def\pgf@decorate@curvecordlength#1#2#3#4{%
+ %
+ % Calculate the curve cord vector.
+ %
+ #4\relax%
+ \pgf@xa\pgf@x\pgf@ya\pgf@y%
+ #1\relax%
+ \advance\pgf@xa-\pgf@x%
+ \advance\pgf@ya-\pgf@y%
+ \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi%
+ \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi%
+ %
+ % Always subdivide, unless...
+ %
+ \pgf@decorate@subdividetrue%
+ %
+ % The cord vector is small.
+ %
+ \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax%
+ \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax%
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}%
+ \pgf@decorate@subdividefalse%
+ \fi%
+ \fi%
+}%
+
+\def\pgf@decorate@recursive@subdividecurve@left#1#2#3#4{%
+ {%
+ %
+ % The left curve (from t=0 to t=.5)
+ %
+ #1\relax%
+ \pgfutil@tempdima\pgf@x%
+ \pgfutil@tempdimb\pgf@y%
+ \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y%
+ \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y%
+ \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y%
+ #2\relax%
+ \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y%
+ \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y%
+ \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y%
+ #3\relax%
+ \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y%
+ \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y%
+ #4\relax%
+ \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y%
+ \xdef\pgf@marshal{%
+ \noexpand\pgf@decorate@@curvelength%
+ {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}%
+ {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}
+ {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}%
+ }%
+ }%
+ \pgf@marshal%
+}%
+
+\def\pgf@decorate@recursive@subdividecurve@right#1#2#3#4{%
+ {%
+ %
+ % The right curve (from t=0.5 to t=1)
+ %
+ #1\relax%
+ \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y%
+ #2\relax%
+ \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y%
+ \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y%
+ #3\relax%
+ \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y%
+ \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y%
+ \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y%
+ #4\relax%
+ \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y%
+ \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y%
+ \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y%
+ \pgf@xc\pgf@x\pgf@yc\pgf@y%
+ \xdef\pgf@marshal{%
+ \noexpand\pgf@decorate@@curvelength%
+ {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}%
+ {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}
+ {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}%
+ }%
+ }%
+ \pgf@marshal%
+}%
+
+
+% Macro to reverse a set of input segment objects.
+%
+% #1 - a macro holding the input segment objects.
+% #2 - a macro holding the reversed input segment objects.
+%
+\def\pgf@decorate@inputsegmentobjects@reverse#1#2{%
+ \def\pgf@decorate@path@storein{#2}%
+ \def\pgf@decorate@inputsegments@@temp{}%
+ \expandafter\pgf@decorate@inputsegments@@reverse@pass@first#1\pgf@stop}%
+
+\def\pgf@decorate@inputsegments@@reverse@pass@first#1#2\pgf@stop{%
+ \def\pgf@decorate@temp{#1}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter%
+ {\expandafter\pgf@decorate@temp\pgf@decorate@inputsegments@@temp}%
+ \def\pgf@decorate@test{#2}
+ \ifx\pgf@decorate@test\pgfutil@empty%
+ \def\pgf@decorate@next{%
+ \expandafter\pgf@decorate@inputsegmentobjects@reverse@pass@second\pgf@decorate@inputsegments@@temp\pgf@stop%
+ }%
+ \else%
+ \def\pgf@decorate@next{\pgf@decorate@inputsegments@@reverse@pass@first#2\pgf@stop}%
+ \fi%
+ \pgf@decorate@next%
+}%
+\def\pgf@decorate@inputsegmentobjects@reverse@pass@second#1#2#3\pgf@stop{%
+ \def\pgf@decorate@inputsegments@temp{#3}%
+ \def\pgf@decorate@inputsegments@@temp{}%
+ \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty
+ \let\pgf@decorate@last@object=\pgfutil@empty
+ \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue%
+ \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse%
+ \expandafter\pgf@decorate@path@@reverse@pass@second\pgf@decorate@inputsegments@temp\pgf@stop}%
+
+
+\def\pgf@decorate@path@@reverse@pass@second#1{%
+ \ifx#1\pgf@stop%
+ \expandafter\def\expandafter\pgf@decorate@inputsegments@@temp\expandafter{%
+ \pgf@decorate@inputsegments@@temp%
+ {\pgf@decorate@inputsegmentobject@endofinputsegments}%
+ {\pgf@decorate@inputsegmentobject@endofinputsegments}
+ }%
+ \expandafter\let\pgf@decorate@path@storein=\pgf@decorate@inputsegments@@temp%
+ \let\pgf@decorate@next=\relax%
+ \else%
+ \ifx#1\pgf@decorate@inputsegmentobject@moveto%
+ \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@moveto%
+ \else%
+ \ifx#1\pgf@decorate@inputsegmentobject@lineto%
+ \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@lineto%
+ \else%
+ \ifx#1\pgf@decorate@inputsegmentobject@curveto%
+ \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@curveto%
+ \else%
+ \ifx#1\pgf@decorate@inputsegmentobject@closepath%
+ \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@closepath%
+ \else%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \pgf@decorate@next%
+}%
+
+\newif\ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting
+
+\def\pgf@decorate@inputsegmentobjects@reverse@moveto#1{%
+ \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting%
+ \edef\pgf@decorate@current@inputsegmentobject{%
+ {\noexpand\pgf@decorate@inputsegmentobject@closepath%
+ {\pgf@decorate@reverse@closepath@length}%
+ {\pgf@decorate@last}%
+ {#1}%
+ }%
+ }%
+ \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse%
+ \else%
+ \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty%
+ \fi%
+ \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue%
+ \pgf@decorate@path@@@reverse@pass@second%
+}%
+
+\newif\ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting
+
+\def\pgf@decorate@inputsegmentobjects@reverse@closepath#1#2#3{%
+ \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingtrue%
+ \def\pgf@decorate@reverse@closepath@length{#1}%
+ \def\pgf@decorate@current@inputsegmentobject{}%
+ \pgf@decorate@inputsegmentobjects@reverse@lineto{#1}{#2}{#3}%
+}%
+
+\def\pgf@decorate@inputsegmentobjects@reverse@lineto#1#2#3#4{%
+ \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting%
+ \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@moveto{#3}}}%
+ \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse%
+ \else%
+ \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty%
+ \fi%
+ \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}%
+ \ifx#4\pgf@decorate@inputsegmentobject@moveto%
+ \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting%
+ \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@closepath{#1}{#3}{#2}}}%
+ \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse%
+ \else%
+ \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}%
+ \fi%
+ \fi%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgf@decorate@current@inputsegmentobject\expandafter\expandafter\expandafter%
+ {\expandafter\pgf@decorate@current@inputsegmentobject\pgf@decorate@append@inputsegmentobject}
+ \def\pgf@decorate@last{#2}%
+ \pgf@decorate@path@@@reverse@pass@second#4%
+}%
+
+\def\pgf@decorate@inputsegmentobjects@reverse@curveto#1#2#3#4#5{%
+ \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting%
+ \def\pgf@decorate@current@inputsegmentobject{%
+ {\pgf@decorate@inputsegmentobject@moveto{#5}}%
+ {\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}%
+ }%
+ \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse%
+ \else%
+ \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}}%
+ \fi%
+ \def\pgf@decorate@last{#2}%
+ \pgf@decorate@path@@@reverse@pass@second%
+}%
+
+\def\pgf@decorate@path@@@reverse@pass@second{%
+ \ifx\pgf@decorate@current@inputsegmentobject\pgfutil@empty%
+ \else%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter%
+ {\expandafter\pgf@decorate@inputsegments@@temp\pgf@decorate@current@inputsegmentobject}%
+ \fi%
+ \pgf@decorate@path@@reverse@pass@second%
+}%
+
+
+
+
+
+\let\startpgfdecoration=\pgfdecoration
+\let\stoppgfdecoration=\endpgfdecoration
+
+\let\startpgfmetadecoration=\pgfmetadecoration
+\let\stoppgfmetadecoration=\endpgfmetadecoration
+
+
+
+%
+% Predefined decorations
+%
+
+
+% Simple decorations.
+
+\pgfdeclaredecoration{lineto}{initial}{%
+ \state{initial}[switch if input segment less than=\pgfdecoratedremainingdistance to input segment,
+ width=\pgfdecoratedremainingdistance]
+ {
+ }%
+ \state{input segment}[width=\pgfdecoratedinputsegmentlength,next state=initial]
+ {
+ \pgfpathlineto{\pgfpointdecoratedinputsegmentlast}
+ }%
+
+ \state{final}{\pgfpathlineto{\pgfpointdecoratedpathlast}}%
+}%
+
+\pgfdeclaredecoration{moveto}{initial}{%
+ \state{initial}[width=\pgfdecoratedremainingdistance]{}%
+ \state{final}{\pgfpathmoveto{\pgfpointdecoratedpathlast}}%
+}%
+
+% This decorations curves to the end along the line.
+
+\pgfdeclaredecoration{curveto}{initial}{%
+ \state{initial}[width=\pgfdecoratedinputsegmentlength/100]
+ {
+ \pgfpathlineto{\pgfpointorigin}
+ }%
+ \state{final}{\pgfpathlineto{\pgfpointdecoratedpathlast}}%
+}%
+
+
+
+
+% Compatibility with old "snakes":
+
+\let\pgfsnakeremainingdistance=\pgfdecoratedremainingdistance
+\let\pgfsnakecompleteddistance=\pgfdecoratedcompleteddistance
+\def\pgfsnakeangle{\pgfdecoratedangle}%
+\let\pgfdeclaresnake=\pgfdeclaredecoration
+\let\pgfsetsnakesegmenttransformation=\pgfsetdecorationsegmenttransformation
+\def\pgfpathsnakesto#1#2{%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfdecoration\expandafter{\pgf@temp}%
+ \pgfpathlineto{#2}%
+ \endpgfdecoration%
+}%
+\def\pgfpathsnaketo#1#2{\pgfpathsnakesto{{#1}{\pgfsnakeremainingdistance}}{#2}}%
+\def\pgfpathsnakealongvector#1#2#3{%
+ \pgf@process{#3}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgfmathparse{#2}%
+ \pgf@xa=\pgfmathresult\pgf@xa%
+ \pgf@ya=\pgfmathresult\pgf@ya%
+ \advance\pgf@xa by\pgf@path@lastx%
+ \advance\pgf@ya by\pgf@path@lasty%
+ \edef\pgf@snake@lib@temp{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \pgfpathsnaketo{#1}{\pgf@snake@lib@temp}%
+}%
+
+\let\pgfsnakesegmentamplitude=\pgfdecorationsegmentamplitude
+\let\pgfsnakesegmentlength=\pgfdecorationsegmentlength
+\def\pgfsnakesegmentangle{\pgfdecorationsegmentangle}%
+\def\pgfsnakesegmentobjectlength{\pgfkeysvalueof{/pgf/decoration/shape start width}}%
+\def\pgfsnakesegmentaspect{\pgfdecorationsegmentaspect}%
+
+\pgfset{%
+ /pgf/segment amplitude/.style={/pgf/decoration={amplitude={#1},shape height={2*(#1)}}},
+ /pgf/segment length/.style={/pgf/decoration={segment length={#1}}},
+ /pgf/segment angle/.style={/pgf/decoration={angle={#1}}},
+ /pgf/segment aspect/.style={/pgf/decoration={aspect={#1}}},
+ /pgf/segment object length/.style={/pgf/decoration={shape width={#1},radius={#1}}}}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmodulematrix.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmodulematrix.code.tex
new file mode 100644
index 0000000000..166eb47093
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmodulematrix.code.tex
@@ -0,0 +1,660 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmodulematrix.code.tex}
+
+\usepgfmodule{shapes}%
+
+\newif\ifpgfmatrix
+\newif\ifpgf@matrix@correct@call
+
+\newif\ifpgf@matrix@fixed
+
+\newcount\pgfmatrixcurrentrow
+
+\newcount\pgfmatrixcurrentcolumn
+\newcount\pgf@matrix@numberofcolumns
+
+\let\pgf@matrix@cell=\pgfnodeparttextbox % alias
+\let\pgf@matrix@box=\pgf@matrix@cell % alias
+
+\long\def\pgfmatrixbeforeassemblenode#1{%
+ \long\def\pgf@matrix@before@assemnble@node{#1}}
+\pgfmatrixbeforeassemblenode{}
+
+% Sets the default row or column sep
+%
+% #1 = default row or column sep list
+%
+% Description:
+%
+% Sets the macro \pgfmatrixrowsep or \pgfmatrixcolumnsep to #1.
+%
+% Example:
+%
+% \pgfsetmatrixrowsep{5pt}
+
+\def\pgfsetmatrixrowsep#1{\def\pgfmatrixrowsep{#1}}%
+\def\pgfsetmatrixcolumnsep#1{\def\pgfmatrixcolumnsep{#1}}%
+
+\def\pgfmatrixrowsep{0pt}%
+\def\pgfmatrixcolumnsep{0pt}%
+
+
+
+% The pgfmatrix command creates a node that contains a matrix. Like
+% the \pgfnode command, it is to be used inside a pgfpicture
+% environment.
+%
+% #1 = shape type
+% #2 = anchor
+% #3 = name for later reference
+% #4 = path usage command
+% #5 = inner shift
+% #6 = startup code
+% #7 = the matrix code (may contain verbatim stuff)
+%
+% Description:
+%
+% This command creates a node that contains a matrix. For
+% each cell of the matrix, drawing commands may be given. These
+% commands will create a cell picture and a bounding box is computed
+% for each cell picture. The cell picture is then placed inside the
+% cell. The position inside the cell is computed according to the
+% following rules:
+%
+% 1. In each column, the origins of the cell pictures are all on a
+% vertical line.
+% 2. In each row, the origins of the cell pictures are all on a
+% horizontal line.
+% 3. All cells in the same row have the same height and depth.
+% 4. All cells in the same column have the same width.
+% 5. The size of cells are chosen minimal such that the boxes fit into
+% the cells and still meet the above requirement.
+%
+% Next, the whole resulting matrix, which is given as #7, is placed
+% inside a node whose name is given as #3, whose shape is #1, and
+% whose anchor is #2. This means that the resulting node is shifted
+% such that the given anchor lies at the origin. Then, as for a normal
+% node, the #4 path usage command is used for the node.
+%
+% The parameter #5 is an additional negative shift for the node. Normally, such
+% a shift could be given beforehand (that is, the shift could be
+% preapplied to the current transformation matrix). However, when #5
+% is evaluated, you can refer to temporary positions of nodes inside
+% the matrix. In detail, the following happens: When the matrix has
+% been typeset, all nodes in the matrix temporarily get assigned their
+% positions in the matrix box. The origin of this coordinate system is
+% at the left baseline end of the matrix box, which corresponds to the
+% text anchor. The position #5 is then interpreted inside this
+% coordinate system and then used for shifting.
+%
+% The idea behind using the parameter #5 is the following: If you
+% specify "text" as anchor #2 and specify \pgfpointanchor{inner
+% node}{some anchor} for parameter #5, where inner node is a node that
+% is created in the matrix, then the whole matrix will be shifted such
+% that inner node.some anchor lies at the origin of the whole picture.
+%
+% At the beginning and at the end of each cell, the macros
+% \pgfmatrixbegincode and \pgfmatrixendcode are called. Inside these
+% macros you can use \pgfmatrixcurrentcolumn and \pgfmatrixcurrentrow
+% to access the current row and column.
+%
+% Before each column except for the first, an extra space given by the
+% macro \pgfmatrixcolumnsep is added. Additionally, an extra space
+% given by the optional argument of the \pgfmatrixnextcell commands in
+% the first line are added, which may vary between columns. Between
+% rows, an extra space given by the macro \pgfmatrixrowsep is
+% added. You can also change this value for each row by using a \gdef.
+%
+%
+% Lines are ended using the command \pgfmatrixendrow. The command \\
+% is \let to be the same, but \\ is sometimes overridden by, say,
+% minipage, so it's good to have \pgfmatrixendrow as a "fallback".
+%
+% Inside the matrix, \\ must be used to end every line ***including
+% the last***. You can pass an optional parameter to \\ as in \\[2pt]
+% to give an additional space after this particular line.
+%
+% The usage of \\ at the end of the matrix is important since this
+% command is used to find the end of the matrix. What happens is that
+% \\ followed by a closing brace ends the matrix.
+%
+% Inside the matrix, you must use \pgfmatrixnextcell to separate
+% columns. The reason is that two columns are used internally for
+% every single column shown. The macro \pgfmatrixnextcell is yields
+% (more or less) two && (and some further trickery).
+%
+% The parameter #6 is executed at the beginning of the matrix
+% group. It is inside the protecting group of the matrix, but outside
+% the matrix itself. It can be used for different purposes: 1) It can be
+% used to simplify the next cell macro. 2) It can be used to issue an
+% \aftergroup command. 3) It can be used to setup local settings. For
+% example, by setting #6 to \let\&=\pgfmatrixnextcell you can use \&
+% instead of \pgfmatrixnextcell. You can also set the catcode of & to
+% active.
+%
+%
+% Example:
+%
+% \begin{tikzpicture}
+%
+% \draw (0,0) circle (1mm); % b.north will lie on the center of this circle
+%
+% \pgfmatrix{rectangle}{text}{mymatrix}{\pgfusepath{}}{\pgfpointanchor{b}{north}}{\let\&=\pgfmatrixnextcell}
+% {
+% \draw (0,0) circle (1cm); \& \node (a) [draw] {Hallo}; \\
+% \node (b) [draw] {Welt}; \& \draw (0,0) circle (5mm); \\
+% }
+%
+% \draw [->] (a) -- (b);
+%
+% \end{tikzpicture}
+
+\def\pgfmatrix#1#2#3#4#5#6{%
+ \ifpgfmatrix%
+ \pgferror{You cannot nest pgfmatrix environments, yet}
+ \fi%
+ \bgroup%
+ \everycr{}%
+ #6%
+ \def\pgf@matrix@par@shape{#1}%
+ \def\pgf@matrix@par@anchor{#2}%
+ \def\pgf@matrix@par@name{#3}%
+ \def\pgf@matrix@par@usage{#4}%
+ \def\pgf@matrix@par@shift{#5}%
+ % the matrix must have a name:
+ \ifx\pgf@matrix@par@name\pgfutil@empty%
+ \def\pgf@matrix@par@name{pgf@matrix@internal}%
+ \fi%
+ \pgfmatrixcurrentrow=0\relax%
+ \pgfmatrixcurrentcolumn=0\relax%
+ \pgf@matrix@numberofcolumns=0\relax%
+ \let\\=\pgfmatrixendrow%
+ \tabskip=0pt%
+ \offinterlineskip%
+ \pgfmatrixtrue%
+ \let\pgf@matrix@node@list=\pgfutil@empty%
+ \expandafter\let\csname pgf@matrix@column@finish@1\endcsname=\pgfutil@empty%
+ \let\pgf@matrix@row@finish=\pgfutil@empty%
+ %
+ % Get rid of bgroup
+ %
+ \afterassignment\pgf@matrix@cont\let\pgf@next=%
+}%
+\def\pgf@matrix@cont{%
+ \setbox\pgf@matrix@box=\hbox\bgroup\vbox\bgroup%
+ \halign\bgroup%
+ \pgf@matrix@init@row%
+ \pgf@matrix@step@column%
+ {%
+ \pgf@matrix@startcell%
+ ##%
+ \pgf@matrix@endcell%
+ }%
+ &%
+ ##\pgf@matrix@padding&&%
+ \pgf@matrix@step@column%
+ {%
+ \pgf@matrix@startcell%
+ ##%
+ \pgf@matrix@endcell%
+ }&%
+ ##\pgf@matrix@padding%
+ \cr%
+}%
+
+\def\pgf@end@matrix{%
+ \egroup\egroup%
+ \egroup%
+ %
+ % Inject custom tokens before assembling the node holding the matrix. Can
+ % be used to apply additional settings.
+ %
+ \pgf@matrix@before@assemnble@node
+ %
+ % If there are named nodes, we must adjust their coordinates.
+ %
+ \ifx\pgf@matrix@node@list\pgfutil@empty%
+ \else%
+ % Ok, this means we got a lot of work to do...
+ \pgf@matrix@compute@origin%
+ \pgf@matrix@shift@nodes@initial%
+ \fi%
+ %
+ % Compute additional shift
+ %
+ \pgftransformresetnontranslations%
+ \pgftransformshift{\pgf@process{\pgftransformreset\pgf@matrix@par@shift\pgf@x=-\pgf@x\pgf@y=-\pgf@y}}%
+ %
+ % Create node
+ %
+ \pgfmultipartnode{\pgf@matrix@par@shape}{\pgf@matrix@par@anchor}{\pgf@matrix@par@name}{\pgf@matrix@par@usage}%
+ %
+ % If there are named nodes, we must adjust their coordinates, again.
+ %
+ \ifx\pgf@matrix@node@list\pgfutil@empty%
+ \else%
+ {%
+ \pgftransformreset%
+ \pgf@process{\pgfpointanchor{\pgf@matrix@par@name}{text}}%
+ \xdef\pgf@matrix@offset{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@matrix@shift@nodes@secondary{\pgf@matrix@offset}%
+ }%
+ \fi%
+}%
+
+
+
+
+% Ending a cell
+%
+% #1 = (optional) spacing between previous and next column. This
+% parameter only has an effect in the first row.
+%
+% Description:
+%
+% This command ends a cell of a matrix.
+%
+% Example:
+%
+% \pgfmatrix{rectangle}{text}{mymatrix}{\pgfusepath{}}{\pgfpointanchor{b}{north}}{}
+% {
+% \draw (0,0) circle (1cm); \pgfmatrixnextcell[1cm] \node (a) [draw] {Hallo}; \\
+% \node (b) [draw] {Welt}; \pgfmatrixnextcell \draw (0,0) circle (5mm); \\
+% }
+
+\def\pgfmatrixnextcell{%
+ % if the cell contains nothing, the following \let will be at the
+ % beginning (macro expansion has stopped here since neither \omit
+ % nor \span was found)
+ \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end%
+ \pgfutil@ifnextchar[{\pgf@matrix@cell@cont}{\pgf@matrix@cell@cont[0pt]}}%}%
+
+\def\pgf@matrix@cell@cont[#1]{%
+ \xdef\pgf@matrix@last@nextcell@options{#1}%
+ &\pgf@matrix@correct@calltrue&%
+}%
+
+
+\def\pgf@matrix@fixed@text{between origins}%
+\def\pgf@matrix@natural@text{between borders}%
+
+\def\pgf@matrix@addtolength#1#2{\edef\pgf@temp{#2}\expandafter\pgf@matrix@addtolength@\expandafter#1#2,\pgf@stop}%
+\def\pgf@matrix@addtolength@#1#2,#3\pgf@stop{%
+ \pgfkeys@spdef\pgf@temp{#2}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \ifx\pgf@temp\pgf@matrix@fixed@text%
+ \global\pgf@matrix@fixedtrue%
+ \else%
+ \ifx\pgf@temp\pgf@matrix@natural@text%
+ \global\pgf@matrix@fixedfalse%
+ \else%
+ \pgfmathaddtolength{#1}{#2}%
+ \fi%
+ \fi%
+ \fi%
+ \def\pgf@temp{#3}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgf@matrix@addtolength@#1#3\pgf@stop%
+ \fi%
+}%
+
+
+
+% Init a line
+
+\def\pgf@matrix@init@row{%
+ \relax%
+ \global\advance\pgfmatrixcurrentrow by 1\relax%
+ \global\pgfmatrixcurrentcolumn=0\relax%
+ \expandafter\gdef\csname pgf@matrix@maxy\the\pgfmatrixcurrentrow\endcsname{0pt}%
+ \expandafter\gdef\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname{0pt}%
+}%
+
+
+
+% Step the row column number
+
+\def\pgf@matrix@step@column{%
+ \relax%
+ \global\advance\pgfmatrixcurrentcolumn by1\relax%
+}%
+
+
+
+% Start a cell
+
+\def\pgf@matrix@startcell{%
+ %
+ % Step 1: Init the list of nodes for this cell
+ %
+ \let\pgf@nodecallback=\pgf@matrix@nodecallback%
+ %
+ % Step 2: Setup the bounding box
+ %
+ \pgfinterruptboundingbox%
+ %
+ % Step 3: Reset the transformation matrix
+ %
+ \pgftransformreset%
+ %
+ % Step 4: Collect everything in a cell box
+ %
+ \setbox\pgf@matrix@cell=\hbox\bgroup\bgroup%
+ % make sure that cell pictures are not affected if matrices have
+ % 'overlay' option on:
+ \pgf@relevantforpicturesizetrue
+ \pgfsys@beginpicture%
+ \normalbaselines%
+ % Find out whether the cell is empty:
+ \pgfutil@ifnextchar\let%
+ {% ok, candidate, check following symbol
+ \afterassignment\pgf@matrix@empty@check\let\pgf@matrix@temp=% get rid of \let
+ }%
+ {% no, not empty
+ \pgf@matrix@empty@cell@false%
+ \pgfmatrixbegincode%
+ }%
+}%
+
+\def\pgf@matrix@empty@check{\futurelet\pgf@matrix@check@token\pgf@matrix@empty@check@cont}%
+\def\pgf@matrix@empty@check@cont{%
+ \ifx\pgf@matrix@check@token\pgf@matrix@signal@cell@end%
+ \pgf@matrix@empty@cell@true%
+ \expandafter%
+ \pgfmatrixemptycode%
+ \expandafter%
+ \let% reinserted
+ \else%
+ \pgf@matrix@empty@cell@false%
+ \expandafter%
+ \pgfmatrixbegincode%
+ \expandafter
+ \let% reinserted
+ \fi%
+}%
+
+\newif\ifpgf@matrix@empty@cell@
+
+
+% End a cell
+
+\def\pgf@matrix@endcell{%
+ \ifpgf@matrix@empty@cell@%
+ \else%
+ \expandafter\expandafter\expandafter\pgfmatrixendcode%
+ \expandafter\ifpgf@matrix@last@cell@in@row\expandafter\pgf@matrix@last@cell@in@rowtrue\expandafter\fi%
+ \fi%
+ \pgfsys@endpicture%
+ \ifnum\pgfmatrixcurrentcolumn<\pgf@matrix@numberofcolumns%
+ \else%
+ \ifpgf@matrix@last@cell@in@row\else%
+ {%
+ \global\pgf@matrix@fixedfalse%
+ \pgf@x=0pt%
+ \pgf@matrix@addtolength{\pgf@x}{\pgfmatrixcolumnsep}%
+ \pgf@matrix@addtolength{\pgf@x}{\pgf@matrix@last@nextcell@options}%
+ \ifpgf@matrix@fixed%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname%
+ {\global\pgf@picmaxx=0pt}%
+ \fi%
+ \advance\pgfmatrixcurrentcolumn by1\relax % only temporary for the following:
+ \expandafter\xdef\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@x}%
+ \ifpgf@matrix@fixed%
+ \expandafter\gdef\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname{\global\pgf@picminx=0pt}%
+ \else%
+ \expandafter\global\expandafter\let\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname=\pgfutil@empty%
+ \fi%
+ }%
+ \fi\fi%
+ % Special case of the empty picture
+ \ifdim\pgf@picmaxx=-16000pt\relax%
+ \global\pgf@picmaxx=0pt\relax%
+ \global\pgf@picminx=0pt\relax%
+ \global\pgf@picmaxy=0pt\relax%
+ \global\pgf@picminy=0pt\relax%
+ \fi%
+ \csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname%
+ \pgf@matrix@row@finish%
+ \egroup\egroup%
+ %
+ % Step 5: Horizontal gap
+ %
+ \ifnum\pgfmatrixcurrentcolumn>1\relax%
+ \pgf@y=\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname\relax%
+ \advance\pgf@picminx by-\pgf@y%
+ \fi%
+ %
+ % Step 6: Protocol and adjust height and depth
+ %
+ % Step 6.1: Protocol...
+ %
+ \ifdim\pgf@picmaxy>\csname pgf@matrix@maxy\the\pgfmatrixcurrentrow\endcsname%
+ \expandafter\xdef\csname pgf@matrix@maxy\the\pgfmatrixcurrentrow\endcsname{\the\pgf@picmaxy}%
+ \fi%
+ \ifdim\pgf@picminy<\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname%
+ \expandafter\xdef\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname{\the\pgf@picminy}%
+ \fi%
+ %
+ % Step 6.2: and setup.
+ %
+ \ht\pgf@matrix@cell=\pgf@picmaxy%
+ \dp\pgf@matrix@cell=-\pgf@picminy%
+ %
+ % Step 7: Protocol and adjust left and right width
+ %
+ % Step 7.1: Protocol...
+ %
+ \ifnum\pgfmatrixcurrentcolumn>\pgf@matrix@numberofcolumns\relax%
+ \expandafter\xdef\csname pgf@matrix@maxx\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@picmaxx}%
+ \expandafter\xdef\csname pgf@matrix@minx\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@picminx}%
+ \global\pgf@matrix@numberofcolumns=\pgfmatrixcurrentcolumn\relax%
+ \else%
+ \ifdim\pgf@picmaxx>\csname pgf@matrix@maxx\the\pgfmatrixcurrentcolumn\endcsname%
+ \expandafter\xdef\csname pgf@matrix@maxx\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@picmaxx}%
+ \fi%
+ \ifdim\pgf@picminx<\csname pgf@matrix@minx\the\pgfmatrixcurrentcolumn\endcsname%
+ \expandafter\xdef\csname pgf@matrix@minx\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@picminx}%
+ \fi%
+ \fi%
+ %
+ % Step 7.2: and setup.
+ %
+ \xdef\pgf@matrix@paddingskip{\the\pgf@picmaxx}%
+ %
+ % Step 8: Put in the box now
+ %
+ \hfil\hskip-\pgf@picminx%
+ \wd\pgf@matrix@cell=0pt%
+ \box\pgf@matrix@cell%
+ %
+ % Step 9: End bounding box
+ \endpgfinterruptboundingbox%
+}%
+
+% Default code for the start and end code
+\let\pgfmatrixbegincode=\relax
+\let\pgfmatrixendcode=\relax
+\let\pgfmatrixemptycode=\relax
+
+
+% The following callback is called for every node that is produced
+% inside a cell
+
+\def\pgf@matrix@nodecallback#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \xdef\pgf@matrix@node@list{\pgf@matrix@node@list,{#1}}%
+ \expandafter\xdef\csname pgf@matrix@node@location@#1\endcsname{{\the\pgfmatrixcurrentrow}{\the\pgfmatrixcurrentcolumn}}%
+ \fi%
+}%
+
+
+
+% Padding code
+
+\def\pgf@matrix@padding{%
+ \ifpgf@matrix@correct@call%
+ \else%
+ \pgferror{Single ampersand used with wrong catcode}%
+ \fi%
+ \hskip\pgf@matrix@paddingskip\hfil%
+}%
+
+
+% Compute the real positions of the origins
+
+% We must now compute the real positions of the origins of all the
+% small pictures. To this end, we need to compute prefix sums. After
+% the procedure is done, the minx and the maxy will contain the origin
+% positions.
+
+\def\pgf@matrix@compute@origin{%
+ %
+ % Inverse prefix sum on the vertical positions
+ %
+ {%
+ \ifnum\pgfmatrixcurrentrow>0\relax%
+ \expandafter\gdef\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname{0pt}%
+ \fi
+ \c@pgf@counta=\pgfmatrixcurrentrow\relax%
+ \loop%
+ \ifnum\c@pgf@counta>1\relax%
+ \pgf@y=\csname pgf@matrix@miny\the\c@pgf@counta\endcsname\relax%
+ \advance\pgf@y by\csname pgf@matrix@maxy\the\c@pgf@counta\endcsname\relax
+ \advance\c@pgf@counta by-1\relax%
+ \pgf@ya=\csname pgf@matrix@miny\the\c@pgf@counta\endcsname\relax%
+ \advance\pgf@y by-\pgf@ya\relax%
+ \expandafter\xdef\csname pgf@matrix@miny\the\c@pgf@counta\endcsname{\the\pgf@y}%
+ \repeat%
+ }%
+ %
+ % Prefix sum on the horizontal positions
+ %
+ {%
+ \ifnum\pgf@matrix@numberofcolumns>0\relax%
+ \pgf@x=\csname pgf@matrix@minx1\endcsname\relax%
+ \pgf@x=-\pgf@x%
+ \expandafter\xdef\csname pgf@matrix@minx1\endcsname{\the\pgf@x}%
+ \fi
+ \c@pgf@counta=1\relax%
+ \loop%
+ \ifnum\c@pgf@counta<\pgf@matrix@numberofcolumns\relax%
+ \pgf@x=\csname pgf@matrix@minx\the\c@pgf@counta\endcsname\relax%
+ \advance\pgf@x by\csname pgf@matrix@maxx\the\c@pgf@counta\endcsname\relax%
+ \advance\c@pgf@counta by1\relax%
+ \pgf@xa=\csname pgf@matrix@minx\the\c@pgf@counta\endcsname\relax%
+ \advance\pgf@x by-\pgf@xa\relax%
+ \expandafter\xdef\csname pgf@matrix@minx\the\c@pgf@counta\endcsname{\the\pgf@x}%
+ \repeat%
+ }%
+}%
+
+
+% Shift the nodes to their origins
+
+% The following procedure shifts all nodes in
+% \pgf@matrix@node@list to their location inside a temporary
+% picture. This picture will later be shifted again to its final
+% position in the real picture.
+
+\def\pgf@matrix@shift@nodes@initial{%
+ {%
+ \pgfutil@for\pgf@matrix@node@name:=\pgf@matrix@node@list\do{%
+ \ifx\pgf@matrix@node@name\pgfutil@empty%
+ \else%
+ \expandafter\ifx\csname pgf@matrix@node@visited@\pgf@matrix@node@name\endcsname\relax%
+ \pgf@shift@node{\pgf@matrix@node@name}{%
+ \pgf@x=\csname pgf@matrix@minx%
+ \expandafter\expandafter\expandafter\pgfutil@secondoftwo\csname pgf@matrix@node@location@\pgf@matrix@node@name\endcsname\endcsname%
+ \pgf@y=\csname pgf@matrix@miny%
+ \expandafter\expandafter\expandafter\pgfutil@firstoftwo\csname pgf@matrix@node@location@\pgf@matrix@node@name\endcsname\endcsname%
+ }%
+ \expandafter\let\csname pgf@matrix@node@visited@\pgf@matrix@node@name\endcsname=\pgfutil@empty%
+ \fi%
+ \fi%
+ }%
+ }%
+}%
+
+
+% The second shifting, done in the following procedure, shifts all
+% nodes to their real positions inside the real picture.
+
+\def\pgf@matrix@shift@nodes@secondary#1{%
+ \pgfutil@for\pgf@matrix@node@name:=\pgf@matrix@node@list\do{%
+ \ifx\pgf@matrix@node@name\pgfutil@empty%
+ \else%
+ \expandafter\ifx\csname pgf@matrix@node@visited@\pgf@matrix@node@name\endcsname\relax%
+ \pgf@shift@node{\pgf@matrix@node@name}{#1}%
+ \expandafter\let\csname pgf@matrix@node@visited@\pgf@matrix@node@name\endcsname=\pgfutil@empty%
+ \fi%
+ \fi%
+ }%
+}%
+
+
+% End of line
+\def\pgfmatrixendrow{%
+ % if the cell contains nothing, the following \let will be at the
+ % beginning (macro expansion has stopped here since neither \omit
+ % nor \span was found)
+ \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end
+ \pgf@matrix@last@cell@in@rowtrue%
+ \xdef\pgf@matrix@rowsep{\pgfmatrixrowsep}%
+ &\pgf@matrix@correct@calltrue%
+ \global\pgf@matrix@fixedfalse%
+ \pgf@y=0pt%
+ \pgf@matrix@addtolength\pgf@y{\pgf@matrix@rowsep}%
+ \pgfutil@ifnextchar[{\pgfmatrixendrow@skip}{\pgf@matrix@finish@line}%
+}%
+\newif\ifpgf@matrix@last@cell@in@row
+
+\def\pgf@matrix@signal@cell@end{\pgf@matrix@signal@cell@end}%
+% exact definition does not matter, only needs to be unique.
+
+\def\pgfmatrixendrow@skip[#1]{%
+ \pgf@matrix@addtolength\pgf@y{#1}%
+ \pgf@matrix@finish@line%
+}%
+
+\def\pgf@matrix@finish@line{%
+ \global\pgf@y=\pgf@y%
+ \pgf@ya=-\pgf@y%
+ \global\advance\pgf@ya by\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname%
+ \expandafter\xdef\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname{\the\pgf@ya}%
+ \pgfutil@ifnextchar\egroup{\cr\pgf@end@matrix}{\pgf@matrix@no@eom@found}%
+}%
+
+\def\pgf@matrix@eom@found{%
+ \cr%
+ \pgf@end@matrix%
+}%
+
+\def\pgf@matrix@no@eom@found{%
+ \cr%
+ \noalign{\vskip\pgf@y%
+ \ifpgf@matrix@fixed%
+ \vskip\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname% unskip
+ \vskip\pgf@y%
+ \pgf@y=-\pgf@y%
+ \expandafter\xdef\csname pgf@matrix@miny\the\pgfmatrixcurrentrow\endcsname{\the\pgf@y}%
+ \gdef\pgf@matrix@row@finish{\global\pgf@picmaxy=0pt}%
+ \else%
+ \global\let\pgf@matrix@row@finish=\pgfutil@empty%
+ \fi%
+ }%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmodulenonlineartransformations.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmodulenonlineartransformations.code.tex
new file mode 100644
index 0000000000..55c9d6f651
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmodulenonlineartransformations.code.tex
@@ -0,0 +1,342 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmodulenonlineartransformations.code.tex}
+
+
+%
+% This file defines commands for nonlinear coordinate systems. This is
+% needed, for instance, for bend arrow heads.
+%
+%
+% Non-linear coordinate systems transform coordinates, in addition to
+% the normal linear transformations, in a, well, non-linear way. An
+% example are polar coordinates.
+%
+% Like the linear transformations, non-linear transformations are
+% applied on a low level and they are integrated into the whole path
+% construction mechanism. So, while \pgfpointpolar also "does
+% something nonlinear", it just provides a way of computing a
+% coordinate. In contrast, installing a polar transformation will
+% transform everything being drawn using the \pgfpath... commands an
+% will even turn a straight line into a circle.
+%
+% Since computing non-linear transformations is expensive, they are
+% only applied "if really necessary".
+
+
+
+
+% Return a transformed point
+%
+% #1 = a point
+%
+% Description:
+%
+% Applies the current transformation and the current nonlinear
+% transformation to the given point and returns the result in \pgf@x/y.
+
+\def\pgfpointtransformednonlinear#1{%
+ \pgf@process{%
+ #1%
+ \pgf@pos@transform@glob%
+ \pgf@nlt@list%
+ }
+}%
+
+
+
+
+% Approximate the nonlinear translation locally
+%
+% Description:
+%
+% Does a "local synchronization" of the nonlinear transformation with
+% the linear transformation regarding the translation part of the
+% current nonlinear transformation. The *linear* transformation will be
+% updated so that it translates things to the point to which the
+% nonlinear transformation transforms the origin. The nonlinear
+% transformation will be reset.
+%
+% The net effect is that you can now draw things near the origin as
+% before, but with just a linear transformation in force. Note that
+% the coordinate system will not be rotated, only a shift is done (use
+% the "real" local sync for a full sync).
+
+\def\pgfapproximatenonlineartranslation{%
+ \ifx\pgf@nlt@list\pgfutil@empty%
+ \else%
+ \pgfpointtransformednonlinear{\pgfpointorigin}%
+ \pgf@pt@x=\pgf@x%
+ \pgf@pt@y=\pgf@y%
+ \let\pgf@nlt@list\pgfutil@empty%
+ \let\pgf@nlt@moveto\pgf@lt@moveto%
+ \let\pgf@nlt@lineto\pgf@lt@lineto%
+ \let\pgf@nlt@curveto\pgf@lt@curveto%
+ \let\pgf@nlt@closepath\pgf@lt@closepath%
+ \fi%
+}%
+
+
+
+% Local sync translation
+%
+% Description:
+%
+% Does a "complete local synchronization" of the nonlinear
+% transformation with the linear transformation. The *linear*
+% transformation will be updated so that it transforms things to the
+% point to which the nonlinear transformation transforms the
+% origin. The nonlinear transformation will be reset.
+%
+% The net effect is that you can now draw things near the origin as
+% before, but with just a linear transformation in force.
+
+\def\pgfapproximatenonlineartransformation{%
+ \ifx\pgf@nlt@list\pgfutil@empty%
+ \else%
+ \pgfpointtransformednonlinear{\pgfpoint{1pt}{0pt}}%
+ \pgf@xa\pgf@x
+ \pgf@ya\pgf@y
+ \pgfpointtransformednonlinear{\pgfpoint{0pt}{1pt}}%
+ \pgf@xb\pgf@x
+ \pgf@yb\pgf@y
+ \pgfpointtransformednonlinear{\pgfpointorigin}%
+ \advance\pgf@xa by-\pgf@x
+ \advance\pgf@xb by-\pgf@x
+ \advance\pgf@ya by-\pgf@y
+ \advance\pgf@yb by-\pgf@y
+ \pgfsettransformentries{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@yb}{\pgf@x}{\pgf@y}%
+ \let\pgf@nlt@list\pgfutil@empty%
+ \let\pgf@nlt@moveto\pgf@lt@moveto%
+ \let\pgf@nlt@lineto\pgf@lt@lineto%
+ \let\pgf@nlt@curveto\pgf@lt@curveto%
+ \let\pgf@nlt@closepath\pgf@lt@closepath%
+ \fi%
+}%
+
+
+
+% Adds a non-linear transformation to the current list of
+% transformations.
+%
+% #1 = code
+%
+% Description:
+%
+% When the code #1 is called, \pgf@x and \pgf@y will be set to some
+% values, let us call this the point p. The nonlinear transformation
+% will now map this point to a new point f(p). The coordinates of this
+% point should be returned in \pgf@x and \pgf@y. Furthermore, consider
+% the two "unit tangents" (going in $x$-direction and in
+% $y$-direction) at point p. The nonlinear transformation will map
+% these to new tangents, t_x and t_y. The (not necessarily normalized)
+% vectors t_x and t_y should be returned in pgf@xa and -ya and pgf@xb
+% and pgf@yb. The macro should not do any global assignments except to
+% \pgf@x and \pgf@y, but may do arbitrary local assignments.
+%
+% The effect of installing a new transformation is the following: As
+% long as there is at least one nonlinear transformation installed,
+% whenever the path construction commands add a curve or line to the
+% softpath, the line or curve will be "bend" by applying all of the
+% nonlinear transformation installed. In particular, straight lines
+% will be replaced by curves.
+%
+% Note that the normal linear transformation are always applied before
+% any nonlinear transformations are applied.
+
+\def\pgftransformnonlinear#1{%
+ \expandafter\def\expandafter\pgf@nlt@list\expandafter{\pgf@nlt@list#1}%
+ \let\pgf@nlt@moveto\pgf@nlt@moveto@nlt
+ \let\pgf@nlt@lineto\pgf@nlt@lineto@nlt
+ \let\pgf@nlt@curveto\pgf@nlt@curveto@nlt
+ \let\pgf@nlt@closepath\pgf@nlt@closepath@nlt
+}%
+
+\def\pgf@nlt@moveto@nlt#1#2{%
+ {%
+ \pgfutil@tempdima#1%
+ \pgfutil@tempdimb#2%
+ \pgf@x\pgfutil@tempdima%
+ \pgf@y\pgfutil@tempdimb%
+ \xdef\pgf@nlt@last@moveto@orig{{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@nlt@list%
+ \xdef\pgf@nlt@last@moveto@trans{{\the\pgf@x}{\the\pgf@y}}%
+ \xdef\pgf@nlt@last@moveto@xaxis{{\the\pgf@xa}{\the\pgf@ya}}%
+ \xdef\pgf@nlt@last@moveto@yaxis{{\the\pgf@xb}{\the\pgf@yb}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}%
+ \global\let\pgf@nlt@last@coord@orig\pgf@nlt@last@moveto@orig%
+ \global\let\pgf@nlt@last@coord@trans\pgf@nlt@last@moveto@trans%
+ \global\let\pgf@nlt@last@coord@xaxis\pgf@nlt@last@moveto@xaxis%
+ \global\let\pgf@nlt@last@coord@yaxis\pgf@nlt@last@moveto@yaxis%
+ }%
+}%
+
+
+\def\pgf@nlt@lineto@nlt#1#2{%
+ {%
+ \edef\pgf@temp{\pgf@xc\the#1\pgf@yc\the#2}%
+ \pgf@temp%
+ \expandafter\pgfqpoint\pgf@nlt@last@coord@orig%
+ \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@trans%
+ % Test, whether the points are quite near:
+ \pgf@xa\pgf@x\advance\pgf@xa by-\pgf@xc%
+ \pgf@ya\pgf@y\advance\pgf@ya by-\pgf@yc%
+ \pgfutil@tempswafalse%
+ \ifdim\pgf@xa<0.1pt\relax\ifdim\pgf@xa>-0.1pt\relax\ifdim\pgf@ya<0.1pt\relax\ifdim\pgf@ya>-0.1pt\relax\pgfutil@tempswatrue\fi\fi\fi\fi%
+ \ifpgfutil@tempswa%
+ \pgf@x\pgf@xc\pgf@y\pgf@yc%
+ \xdef\pgf@nlt@last@coord@orig{{\the\pgf@x}{\the\pgf@y}}%
+ \pgf@process{\pgf@nlt@list}%
+ \xdef\pgf@nlt@last@coord@trans{{\the\pgf@x}{\the\pgf@y}}%
+ \xdef\pgf@nlt@last@coord@xaxis{{\the\pgf@xa}{\the\pgf@ya}}%
+ \xdef\pgf@nlt@last@coord@yaxis{{\the\pgf@xb}{\the\pgf@yb}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}%
+ \else%
+ % Compute support points
+ \pgf@xb=.333333\pgf@x%
+ \advance\pgf@xb by.666666\pgf@xc%
+ \pgf@yb=.333333\pgf@y%
+ \advance\pgf@yb by.666666\pgf@yc%
+ \pgf@xa=.333333\pgf@xc%
+ \advance\pgf@xa by.666666\pgf@x%
+ \pgf@ya=.333333\pgf@yc%
+ \advance\pgf@ya by.666666\pgf@y%
+ \pgf@nlt@inner@curve%
+ \fi%
+ }%
+}%
+
+\def\pgf@nlt@set@temps#1#2{%
+ \pgfutil@tempdima#1\pgfutil@tempdimb#2%
+}%
+
+\def\pgf@nlt@curveto@nlt#1#2#3#4#5#6{%
+ {%
+ \edef\pgf@temp{\pgf@xa\the#1\pgf@ya\the#2\pgf@xb\the#3\pgf@yb\the#4\pgf@xc\the#5\pgf@yc\the#6}%
+ \pgf@temp%
+ \pgf@nlt@inner@curve%
+ }%
+}%
+
+\newdimen\pgftransformnonlinearflatness
+\pgftransformnonlinearflatness=5pt
+\def\pgfsettransformnonlinearflatness#1{\pgfmathsetlength\pgftransformnonlinearflatness{#1}}%
+
+
+
+% Compute a curve from \pgf@nlt@last@coord@orig to \pgf@xc/\pgf@yc via the
+% controls \pgf@xa/\pgf@ya and \pgf@xb/\pgf@yb.
+\def\pgf@nlt@inner@curve{%
+ \expandafter\pgfqpoint\pgf@nlt@last@coord@orig%
+ % Save delta of supports:
+ \pgfutil@tempdima\pgf@xa\advance\pgfutil@tempdima by-\pgf@xb
+ \pgfutil@tempdimb\pgf@ya\advance\pgfutil@tempdimb by-\pgf@yb
+ \begingroup
+ % Replace supports by relative supports
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \advance\pgf@xb by-\pgf@xc%
+ \advance\pgf@yb by-\pgf@yc%
+ %
+ % Now, test whether the flatness is satisfied:
+ %
+ \pgfutil@tempswafalse
+ \ifdim\pgfutil@tempdima>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgfutil@tempdima<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgfutil@tempdimb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgfutil@tempdimb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@xa>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@xa<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@ya>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@ya<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@xb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@xb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@yb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifdim\pgf@yb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi%
+ \ifpgfutil@tempswa%
+ \endgroup% Undo the adjustments...
+ {%
+ \edef\pgf@orig@xya{\pgf@xa\the\pgf@xa\pgf@ya\the\pgf@ya}
+ \edef\pgf@orig@xyb{\pgf@xb\the\pgf@xb\pgf@yb\the\pgf@yb}
+ \edef\pgf@orig@xyc{\pgf@xc\the\pgf@xc\pgf@yc\the\pgf@yc}
+ \pgfpointcurveattime{.5}%
+ {\expandafter\pgfqpoint\pgf@nlt@last@coord@orig}%
+ {\pgf@x\pgf@xa\pgf@y\pgf@ya}%
+ {\pgf@x\pgf@xb\pgf@y\pgf@yb}%
+ {\pgf@x\pgf@xc\pgf@y\pgf@yc}%
+ % First new curve:
+ % Start is at last@coord@orig,
+ % first support is at last@coord@orig*t + s*(original xa/ya)
+ % second support is at xb/yb
+ % target is at x/y
+ {%
+ % Target:
+ \pgf@xc\pgf@x\pgf@yc\pgf@y
+ % First support:
+ \expandafter\pgfqpoint\pgf@nlt@last@coord@orig%
+ \pgf@orig@xya%
+ \pgf@xa\pgf@time@s\pgf@xa\advance\pgf@xa by\pgf@time@t\pgf@x%
+ \pgf@ya\pgf@time@s\pgf@ya\advance\pgf@ya by\pgf@time@t\pgf@y%
+ \pgf@nlt@inner@curve%
+ }%
+ % Second new curve:
+ % Start is at (new) last@coord@orig
+ % first support is at xa/ya
+ % second support is at t*(original xb/yb) + s*(original xc/yc)
+ % target is at original xc/yc
+ {%
+ \pgf@orig@xyb%
+ \pgf@orig@xyc%
+ \pgf@xb\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc%
+ \pgf@yb\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc%
+ \pgf@nlt@inner@curve%
+ }%
+ }%
+ \else%
+ \endgroup% Snap back...
+ \pgf@nlt@do@inner@curve%
+ \fi%
+}%
+
+\def\pgf@nlt@do@inner@curve{%
+ \pgf@process{\pgf@x\pgf@xa\pgf@y\pgf@ya\pgf@nlt@list}%
+ \pgf@xa\pgf@x\pgf@ya\pgf@y%
+ \pgf@process{\pgf@x\pgf@xb\pgf@y\pgf@yb\pgf@nlt@list}%
+ \pgf@xb\pgf@x\pgf@yb\pgf@y%
+ \xdef\pgf@nlt@last@coord@orig{{\the\pgf@xc}{\the\pgf@yc}}%
+ \pgf@process{\pgf@x\pgf@xc\pgf@y\pgf@yc\pgf@nlt@list}%
+ \pgf@xc\pgf@x\pgf@yc\pgf@y%
+ \xdef\pgf@nlt@last@coord@trans{{\the\pgf@xc}{\the\pgf@yc}}%
+ \pgf@protocolsizes{\pgf@xa}{\pgf@ya}%
+ \pgf@protocolsizes{\pgf@xb}{\pgf@yb}%
+ \pgf@protocolsizes{\pgf@xc}{\pgf@yc}%
+ \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}%
+}%
+
+
+\def\pgf@nlt@closepath@nlt{%
+ {%
+ \expandafter\pgfqpoint\pgf@nlt@last@moveto@orig%
+ \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@orig%
+ \advance\pgfutil@tempdima by-\pgf@x%
+ \advance\pgfutil@tempdimb by-\pgf@y%
+ \pgfutil@tempswatrue%
+ \ifdim\pgfutil@tempdima<0.01pt\relax\ifdim\pgfutil@tempdima>-0.01pt\relax\ifdim\pgfutil@tempdimb<0.01pt\relax\ifdim\pgfutil@tempdimb>-0.01pt\relax\pgfutil@tempswafalse\fi\fi\fi\fi%
+ \ifpgfutil@tempswa%
+ \pgf@nlt@lineto@nlt{\pgf@x}{\pgf@y}%
+ \fi%
+ \pgfsyssoftpath@closepath%
+ }%
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmoduleoo.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmoduleoo.code.tex
new file mode 100644
index 0000000000..86c1e8e996
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmoduleoo.code.tex
@@ -0,0 +1,844 @@
+% Copyright 2019 by Till Tantau
+% Copyright 2019 by Saso Zivanovic
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% Based on pgfmoduleoo.code.tex v1.8 by Till Tantau. This version adds inheritance.
+
+
+
+% Support of object-oriented programming in TeX, with inheritance.
+
+
+% The oo support works as follows:
+%
+% The main supported concepts are classes, objects, methods,
+% attributes and signal/slots. A class defines a set of methods, which are,
+% in the end, just normal TeX macros. Once a class has been created,
+% it can be instantiated by calling the \pgfoonew command, resulting
+% in a new object. Objects are local to their group. Given an object,
+% you can send it a message, resulting in the method code of the
+% object's method to be executed. While an object exists, it has a set
+% of attributes whose values can change over time. Attributes values
+% are not local to TeX groups, rather their life-cycle is the same as
+% the object's (which, however, is local to the group in which the
+% object was declared).
+%
+% The implementation is as follows: There is an ID counter that is
+% increased each time an object is created. This counter is local to
+% the group, which means that when a group ends the counter will
+% revert to the previous value, allowing objects to the reused in
+% subsequent groups.
+%
+% A method is just a normal \TeX macro, but to call it you write
+% \objecthandle.methodname(parameters). The \objecthandle is a macro
+% that is created when you say \pgfoonew. The special object
+% \pgfoothis is the current object.
+%
+% Attributes are stored globally in internal TeX macros whose name is
+% composed of the object number and the attribute name.
+
+
+
+
+% Declares a class
+%
+% #1 = class name
+% #2 = methods
+%
+% Description:
+%
+% This command declares a class for future use. Inside #2, the macro
+% \method can be used to declare a method. The \method macro takes a
+% method name, parameters (methods are normal TeX macros, after all)
+% and body.
+
+% base classes are put in parenthesis before the new class name, but
+% are optional.
+\def\pgfooclass{%
+ \pgfutil@ifnextchar ({%
+ \pgfooclass@
+ }{%
+ \pgfooclass@()
+ }%
+}%
+\long\def\pgfooclass@(#1)#2#3{%
+ \def\pgfoo@classname{#2}%
+ \expandafter\ifx\csname pgfooY\pgfoo@classname.@pgfooinit\endcsname\relax\else
+ \pgferror{class #2 is already defined}%
+ \fi
+ \pgfoo@ciii{#2}{#1}%
+ \expandafter\let\csname pgfooY#2@pgfoo@mro\endcsname\pgfoo@mro
+ \let\pgfoo@origmethod=\method%
+ \let\pgfoo@origattribute=\attribute%
+ \let\method=\pgfoo@declaremethod%
+ \let\attribute=\pgfoo@declareattribute%
+ \let\pgfoo@attributes=\pgfutil@empty%
+ \let\pgfoo@methods=\pgfutil@empty%
+ #3%
+ % inherit
+ \def\pgfoo@temp@baseclasses{#1}%
+ \pgfoo@inherit@methods
+ \pgfoo@inherit@attributes
+ % Always present (and never inherited) methods:
+ \expandafter\let\csname pgfooY\pgfoo@classname.get handle\endcsname\pgfoo@obj%
+ \expandafter\let\csname pgfooY\pgfoo@classname.get id\endcsname\pgfoo@id%
+ % for compatibility with previous versions of pgfoo, define method
+ % with the same name as the class as a synonym for init
+ \expandafter\let\expandafter\pgfoo@init\csname pgfooY\pgfoo@classname.init\endcsname
+ \expandafter\let\csname pgfooY\pgfoo@classname.\pgfoo@classname\endcsname\pgfoo@init
+ % Cleanup
+ \let\method=\pgfoo@origmethod%
+ \let\attribute=\pgfoo@origattribute%
+}%
+
+\def\pgfoo@emptyinit(){}%
+\def\pgfoo@escapeif#1#2\fi{\fi#1}% a little helper
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Compute MRO using C3 algorithm
+% The sequences are enclosed in brackets; elements of sequences and
+% the big list are terminated by a comma and a dot, respectively. (Why
+% comma *and* a dot: TeX's parset---brackets don't form groups! Soooo,
+% why not braces? Because I don't know how do delete excess "{},"s...)
+
+% #1 = current class, #2 = list of base classes
+\def\pgfoo@ciii#1#2{%
+ % \pgfoo@seq will hold a list of sequences.
+ % (i) the first sequence has just one element: the current class
+ \def\pgfoo@seq{[#1,].}%
+ % (ii) every subclass has a sequence (in the order as they were
+ % given): the class' sequence is its mro.
+ \pgfutil@for\pgfoo@baseclass:={#2}\do{%
+ \edef\pgfoo@baseclass@mro{\csname pgfooY\pgfoo@baseclass @pgfoo@mro\endcsname}%
+ \expandafter\ifx\expandafter\relax\pgfoo@baseclass@mro\relax\else
+ \edef\pgfoo@seq{\pgfoo@seq[\pgfoo@baseclass@mro,].}%
+ \fi
+ }%
+ % The final sequence is a sequence of base classes, in the order as
+ % they were given.
+ \ifx\relax#2\relax\else
+ \edef\pgfoo@seq{\pgfoo@seq[#2,].}%
+ \fi
+ \edef\pgfoo@temp{()(\pgfoo@seq)}%
+ \expandafter\pgfoo@ciii@merge\pgfoo@temp
+}%
+
+% #1 = MRO so far
+% #2 = remaining sequences
+% no empty sequences [] should arrive here: they should be removed
+% before calling this macro
+\def\pgfoo@ciii@merge(#1)(#2){%
+ \ifx\relax#2\relax
+ \pgfoo@ciii@done(#1)%
+ \else\pgfoo@escapeif{% split #2
+ \pgfoo@ciii@merge@A(#1)(#2)%
+ }\fi%
+}%
+% a splitter: to be only called from \pgfoo@ciii@merge
+\def\pgfoo@ciii@merge@A(#1)(#2.#3){%
+ \ifx\relax#3\relax % if #3 is empty, we can take the shortcut
+ \pgfoo@ciii@mergeA@done(#1)(#2)%
+ \else\pgfoo@escapeif{%
+ \pgfoo@ciii@merge@checkHead(#1)()(#2)()(#3)%
+ }\fi
+}%
+
+\def\pgfoo@ciii@mergeA@done(#1)([#2]){%
+ \pgfoo@ciii@done(#1#2)%
+}%
+
+% #1 = MRO so far
+% #2 = sequences with bad heads (dot after each sequence)
+% [#3,#4] = the sequence whose head we're testing right
+% now---obviously, it should not be empty! (#3 has no comma,
+% #4 has a comma after each class name)
+% #5 = #3 does not occur in the tail of these sequences (dot after
+% each sequence)
+% #6 = the remaining sequences (dot after each sequence)
+\def\pgfoo@ciii@merge@checkHead(#1)(#2)([#3,#4])(#5)(#6){%
+ \pgfutil@in@{[#3,}{#2}%
+ \ifpgfutil@in@\pgfoo@escapeif{% #3 is already blacklisted
+ \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5#6)}%
+ }\else\pgfoo@escapeif{%
+ \ifx\relax#6\relax\pgfoo@escapeif{% no more sequences to test the head against!
+ % so, #3 is a good head, and we can recurse
+ \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5)%
+ }\else\pgfoo@escapeif{% split #6 and get to work
+ \pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6)%
+ }\fi
+ }\fi
+}%
+% splitter: to be only called from \pgfoo@ciii@merge@checkHead
+% we will check if #3 occurs in the tail of #6
+\def\pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6.#7){%
+ \pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)(#6)(#7)%
+}%
+% splitter: to be only called from \pgfoo@ciii@merge@checkHead@A
+% &worker: we will check if #3 occurs in #7. If it does, #3 is a bad head.
+\def\pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)([#6,#7])(#8){%
+% \def\pgfoo@ciii@tempA{#3}\def\pgfoo@ciii@tempB{#5}%
+% \ifx\pgfoo@ciii@tempA\pgfoo@ciii@tempB
+% \pgferror{An attempt to derive from the same class twice}%
+% \else\pgfoo@escapeif{%
+ \pgfutil@in@{,#3,}{,#7}%
+ \ifpgfutil@in@\pgfoo@escapeif{% bad head! get next head and restart
+ % but: need to clean up first!
+ \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5[#6,#7].#8)}%
+ }\else\pgfoo@escapeif{% so far, so good
+ \ifx\relax#8\relax\pgfoo@escapeif{% if #8 is empty, we won:
+ % #3 is a good head! we will move it to MRO
+ % but clean-up first!
+ \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5[#6,#7].)%
+ }\else\pgfoo@escapeif{% proceed to the first seq in #8
+ \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead{(#1)(#2)([#3,#4])(#5[#6,#7].)(#8)}%
+ }\fi
+ }\fi
+% }\fi
+}%
+
+% #1 = MRO
+% #2 = good head
+% #3 = the remaining sequences (in need of removing the good head from
+% them, and then also some general cleanup)
+\def\pgfoo@ciii@goodHeadFound(#1)(#2)(#3){%
+ \pgfutil@in@{,#2,}{#3}%
+ \ifpgfutil@in@\pgfoo@escapeif{%
+ \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3,#2,##4){%
+ \pgfoo@ciii@goodHeadFound(##1)(##2)(##3,##4)}%
+ \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)%
+ }\else\pgfoo@escapeif{%
+ \pgfutil@in@{[#2,}{#3}%
+ \ifpgfutil@in@\pgfoo@escapeif{%
+ \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3[#2,##4){%
+ \pgfoo@ciii@goodHeadFound(##1)(##2)(##3[##4)}%
+ \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)%
+ }\else\pgfoo@escapeif{%
+ \pgfoo@ciii@clean\pgfoo@ciii@merge{(#1#2,)(#3)}%
+ }\fi
+ }\fi
+}%
+
+% mediates between the bad head exit of \pgfoo@ciii@merge@checkHead@B
+% and \pgfoo@ciii@merge@checkHead; we need the mediator because #3
+% below might have been affected by cleaning.
+\def\pgfoo@ciii@merge@checkHead@P(#1)(#2)(#3){%
+ \if\relax#3\relax % no more good head candidates!
+ \pgferror{Bad MRO: There is no good (monotonic etc.)
+ Method Resolution Order for your class hierarchy}%
+ \else\pgfoo@escapeif{%
+ \pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3)%
+ }\fi
+}%
+% splitter for \pgfoo@ciii@merge@checkHead@P
+% #3 = the sequence containing the newest good head candidate
+\def\pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3.#4){%
+ \pgfoo@ciii@merge@checkHead(#1)(#2)(#3)()(#4)%
+}%
+
+% cyclically removes all occurrences of "[]," and "[]." (i.e., empty
+% sequences) in #2. When done, calls #1 with whatever remains.
+\def\pgfoo@ciii@clean#1#2{% clean commas
+ \pgfutil@in@{[].}{#2}% clean dots
+ \ifpgfutil@in@\pgfoo@escapeif{%
+ \pgfoo@ciii@clean@dot#1#2\pgfoo@ciii@clean@END
+ }\else\pgfoo@escapeif{%
+ #1#2%
+ }\fi
+}%
+\def\pgfoo@ciii@clean@dot#1#2[].#3\pgfoo@ciii@clean@END{%
+ \pgfoo@ciii@clean#1{#2#3}%
+}%
+
+\def\pgfoo@ciii@done(#1,){%
+ \def\pgfoo@mro{#1}%
+}%
+
+% end of C3
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+% Declare a method
+%
+% Description:
+%
+% Defines a method. To use/invoke this method for an object \object,
+% you write \object.methodname(parameters). This will cause the method
+% body to be invoked with the argument "(parameters)".
+%
+% To define the method \method should be directly followed by the
+% method name and, then, by (, followed by a parameter pattern,
+% followed by ), followed by the message body. Spaces are allowed only
+% after "\method" and after the closing ).
+%
+% Example:
+%
+% \pgfooclass{MyPlot}{
+%
+% \attribute x=0;
+% \attribute y=0;
+%
+% \method MyPlot() {
+% }
+%
+% \method getX(#1) {
+% \pgfooget{x}{#1}
+% }
+%
+% \method setPoint(#1,#2) {
+% \pgfooset{x}{#1}
+% \pgfooset{y}{#2}
+% }
+% }
+
+% define the method macro and append the method to the method collection
+\long\def\pgfoo@declaremethod#1(#2)#3{%
+ \def\pgfoo@method{#1}%
+ \ifx\pgfoo@classname\pgfoo@method
+ \def\pgfoo@method{init}%
+ \fi
+ \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname(#2){#3}%
+ \edef\pgfoo@methods{\pgfoo@methods,\pgfoo@method}%
+}%
+
+\def\pgfoo@inherit@methods{%
+ % for non-derived classes:
+ \expandafter\ifx\expandafter\relax\pgfoo@temp@baseclasses\relax
+ % if init is not defined, define an empty one
+ \expandafter\ifx\csname pgfooY\pgfoo@classname.init\endcsname\relax
+ \expandafter\let\csname pgfooY\pgfoo@classname.init\endcsname\pgfoo@emptyinit%
+ \edef\pgfoo@methods{,init\pgfoo@methods}%
+ \fi
+ \fi
+ \if\relax\pgfoo@methods\relax\else
+ % gobble the initial comma
+ \edef\pgfoo@methods{\expandafter\pgfutil@gobble\pgfoo@methods}%
+ \fi
+ % remember the list of collected methods
+ \expandafter\let\csname pgfooY\pgfoo@classname @pgfoo@methods\endcsname\pgfoo@methods
+ % get MRO
+ \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname
+ % loop throough base classes in MRO
+ \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{%
+ \ifx\pgfoo@baseclass\pgfoo@classname % skip self
+ \else\pgfoo@escapeif{%
+ % get methods defined in this base class
+ \expandafter\let\expandafter\pgfoo@methods\csname pgfooY\pgfoo@baseclass @pgfoo@methods\endcsname
+ \pgfutil@for\pgfoo@method:=\pgfoo@methods\do{% for each method
+ % check if it is already defined in our class
+ \expandafter\ifx\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname\relax
+ % if not, link the method name from our class to base class
+ \edef\pgfoo@temp{\noexpand\let
+ \expandafter\noexpand\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname
+ \expandafter\noexpand\csname pgfooY\pgfoo@baseclass.\pgfoo@method\endcsname}%
+ \pgfoo@temp
+ \fi
+ }%
+ }\fi
+ }%
+}%
+
+\def\pgfoosuper(#1,#2).#3({%
+ #2.get id(\pgfoo@temp@id)%
+ \edef\pgfoo@classname{\csname pgfooX\pgfoo@temp@id @class\endcsname}%
+ \def\pgfoo@super@A##1,#1,##2.##3({%
+ \pgfoo@super@B##2.##3(%
+ }%
+ \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname
+ \expandafter\pgfoo@super@A\expandafter,\pgfoo@mro,.#3(%
+}%
+\def\pgfoo@super@B#1,#2.#3({%
+ \expandafter\ifx\csname pgfooY#1.#3\endcsname\relax
+ \pgfoo@escapeif{\pgfoo@super@B#2.#3(}%
+ \else
+ \pgfoo@escapeif{\expandafter\pgfoo@caller\pgfoo@temp@id.#1.#3(}%
+ \fi
+}%
+
+
+
+% Declare an attribute
+%
+% #1 = attribute name
+% #2 = optional default value
+%
+% Description:
+%
+% Declares the attribute #1 for the current class. If the attribute
+% name is followed by =, the text following the equal sign is the
+% default value.
+
+\def\pgfoo@declareattribute#1;{%
+ \pgfutil@in@{ =}{#1}%
+ \ifpgfutil@in@%
+ \pgfoo@declareunpackspace#1;%
+ \else%
+ \pgfutil@in@={#1}%
+ \ifpgfutil@in@%
+ \pgfoo@declareunpack#1;%
+ \else%
+ \pgfoo@declareattribute@\let{#1}\pgfutil@empty
+ \fi%
+ \fi%
+}%
+\def\pgfoo@declareunpack#1=#2;{\pgfoo@declareattribute@\def{#1}{{#2}}}%
+\def\pgfoo@declareunpackspace#1 =#2;{\pgfoo@declareattribute@\def{#1}{{#2}}}%
+
+% put the initial value in the class's namespace
+% put the attr name in a list
+\def\pgfoo@declareattribute@#1#2#3{%
+ \expandafter#1\csname pgfooY\pgfoo@classname @#2\endcsname#3%
+ \expandafter\def\expandafter\pgfoo@attributes\expandafter{\pgfoo@attributes,#2}%
+}%
+
+% for each base class:
+% for each attribute declared in that class:
+% add the attr on a list if it's not there yet
+% convert the list of (attr,class which it comes from) into an
+% efficient sequence of triples \op{attrname}\pointer-to-initial-value
+% (\op is then set differently in init and garbage collection)
+\def\pgfoo@inherit@attributes{%
+ % store the list of attributes declared in this class for use in
+ % derived classes
+ \if\relax\pgfoo@attributes\relax\else
+ \edef\pgfoo@attributes{\expandafter\pgfutil@gobble\pgfoo@attributes}% gobble comma
+ \fi
+ \expandafter\let\csname pgfooY\pgfoo@classname.@pgfoo@attributes\endcsname\pgfoo@attributes%
+ % get MRO
+ \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname
+ \def\pgfoo@allattributes{}% here we will store the attrs declared in base classes
+ \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{% for each base class in MRO order
+ % the attributes declared in this base class
+ \expandafter\let\expandafter\pgfoo@attributes\csname pgfooY\pgfoo@baseclass.@pgfoo@attributes\endcsname
+ \pgfutil@for\pgfoo@attribute:=\pgfoo@attributes\do{% for each attribute
+ % check if we have already found it in some previous base class
+ \edef\pgfoo@temp{{,\pgfoo@attribute=}{\pgfoo@allattributes,}}%
+ \expandafter\pgfutil@in@\pgfoo@temp
+ \ifpgfutil@in@\else % don't overwrite
+ % append to the list
+ \edef\pgfoo@allattributes{\pgfoo@allattributes,\pgfoo@attribute=\pgfoo@baseclass}%
+ \fi
+ }%
+ }%
+ \if\relax\pgfoo@allattributes\relax\else
+ \edef\pgfoo@allattributes{\expandafter\pgfutil@gobble\pgfoo@allattributes}% gobble comma
+ \fi
+ % this macro will hold a list of attributes from all base classes
+ % we run this macro at init and gc
+ \def\pgfoo@process@attributes{}%
+ \pgfutil@for\pgfoo@attributeclass:=\pgfoo@allattributes\do{% for each (attribute, class) pair
+ % append to the attribute processor
+ \expandafter\pgfoo@inherit@attributes@appendattribute\pgfoo@attributeclass.%
+ }%
+ \expandafter\let\csname pgfooY\pgfoo@classname .@pgfoo@process@attributes\endcsname\pgfoo@process@attributes
+}%
+
+
+% #1=attr, #2=class which the attr comes from
+\def\pgfoo@inherit@attributes@appendattribute#1=#2.{%
+ \def\pgfoo@tempA{\pgfoo@attribute@op{#1}}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@tempB\expandafter\expandafter\expandafter{\expandafter\pgfoo@tempA\csname pgfooY#2@#1\endcsname}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@process@attributes\expandafter\expandafter\expandafter{\expandafter\pgfoo@process@attributes\pgfoo@tempB}%
+ % above is just this:
+ % \def\pgfoo@process@attributes{\pgfoo@process@attributes\pgfoo@attribute@op{#1}%
+ % \csname pgfooY#2@#1\endcsname}
+ % with \pgfoo@process@attributes and \csname expanded exactly once:
+}%
+
+% \pgfoo@attribute@op for garbage collection
+\def\pgfoo@gc@attribute#1#2{\pgfoolet{#1}\relax}%
+
+
+\newcount\pgfoo@objectcount
+\newcount\pgfoothis@count
+
+% The attribute value method
+%
+% #1 = attr
+%
+% This method inserts the current value of the given attribute for the
+% current object.
+
+\def\pgfoovalueof#1{%
+ \csname pgfooX\the\pgfoothis@count @#1\endcsname%
+}%
+
+
+% The attribute get method
+%
+% #1 = attr
+% #2 = macro
+%
+% This method makes the macro equal to the current value of the
+% attribute for the current object.
+
+\def\pgfooget#1#2{%
+ \expandafter\let\expandafter#2\csname pgfooX\the\pgfoothis@count @#1\endcsname%
+}%
+
+
+% The attribute set method
+%
+% #1 = attr
+% #2 = value
+%
+% This method sets the given attribute for the current object to the
+% given value.
+
+\long\def\pgfooset#1#2{%
+ \expandafter\gdef\csname pgfooX\the\pgfoothis@count @#1\endcsname{#2}%
+}%
+
+
+% The attribute set method (expanded version)
+%
+% #1 = attr
+% #2 = value
+%
+% This method sets the given attribute for the current object to the
+% expanded version of the given value.
+
+\long\def\pgfooeset#1#2{%
+ \expandafter\xdef\csname pgfooX\the\pgfoothis@count @#1\endcsname{#2}%
+}%
+
+
+% The attribute let method
+%
+% #1 = attr
+% #2 = value
+%
+% This method sets the given attribute for the current object to the
+% given value using \let.
+
+\def\pgfoolet#1#2{%
+ \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @#1\endcsname#2%
+}%
+
+
+% Add something to an attribute at the end
+%
+% #1 = attr
+% #2 = code
+%
+% This method adds the give code to the attr at the end.
+
+\def\pgfooappend#1#2{%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@oo@temp\expandafter\expandafter\expandafter{\csname pgfooX\the\pgfoothis@count @#1\endcsname#2}%
+ \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @#1\endcsname\pgf@oo@temp%
+}%
+
+
+% Add something to an attribute at the beginning
+%
+% #1 = attr
+% #2 = code
+%
+% This method adds the give code to the attr at the beginning.
+
+\def\pgfooprefix#1#2{%
+ \pgfooget{#1}\pgf@oo@temp%
+ \def\pgf@oo@@temp{#2}%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@oo@temp%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@oo@@temp\pgf@oo@temp}%
+ \pgfoolet{#1}\pgf@oo@temp%
+}%
+
+
+
+% Help macro for scanning arguments
+\newtoks\pgfoo@toks
+
+\def\pgfoo@collect@args{%
+ \pgfutil@ifnextchar\bgroup\pgfoo@collect@args@group\pgfoo@collect@args@nogroup%
+}%
+\def\pgfoo@collect@args@nogroup#1){%
+ \pgfoo@toks{#1}%
+ \pgfoo@continue%
+}%
+\def\pgfoo@collect@args@group#1{%
+ \pgfutil@ifnextchar){\pgfoo@toks{{#1}}\expandafter\pgfoo@continue\pgfutil@gobble}{\pgfoo@collect@args@nogroup{#1}}%
+}%
+
+
+% Instantiate an object
+%
+% Possible syntax:
+%
+% 1) \pgfoonew new <class name>(<constructor parameters)
+% 2) \pgfoonew \<objectname>=new <class name>(<constructor parameters)
+% 3) \pgfoonew{attribute}=new <class name>(<constructor parameters)
+%
+% Description:
+%
+% Creates an object. After the object has been created, the method
+% called <class name> (the constructor) is invoked. If the
+% \<objectname>= part is present, the macro is assigned to the newly
+% created object.
+
+\def\pgfoonew{%
+ \pgfutil@ifnextchar n{%
+ \pgfoo@new\pgfoo@dummy=%
+ }{%
+ \pgfutil@ifnextchar\bgroup{%
+ \pgfoo@new@attribute%
+ }{%
+ \pgfoo@new%
+ }%
+ }%
+}%
+\def\pgfoo@new#1={%
+ \def\pgfutil@reserved@a{#1}%
+ \let\pgfutil@next\pgfoo@@new
+ \futurelet\pgfutil@let@token\pgfutil@ignorespaces}%
+\def\pgfoo@@new new #1({%
+ \expandafter\ifx\csname pgfooY#1.get id\endcsname\relax%
+ \pgferror{Unknown class '#1'}%
+ \else%
+ \expandafter\pgfoo@new@create\pgfutil@reserved@a{#1}%
+ {%
+ \pgfoothis@count\pgfoo@objectcount%
+ \let\pgfoo@attribute@op\pgfoolet
+ \csname pgfooY#1.@pgfoo@process@attributes\endcsname%
+ }%
+ \let\pgfoo@continue=\pgf@oo@new@cont%
+ \expandafter\pgfoo@collect@args%
+ \fi%
+}%
+
+\def\pgf@oo@new@cont{%
+ \expandafter\pgfoolastobj\expandafter.\expandafter i\expandafter n\expandafter i\expandafter t\expandafter(\the\pgfoo@toks)%
+ \aftergroup\pgfoogc% cleanup after group
+}%
+
+\def\pgfoo@new@attribute#1={%
+ \def\pgfutil@reserved@a{#1}%
+ \let\pgfutil@next\pgfoo@@new@attribute
+ \futurelet\pgfutil@let@token\pgfutil@ignorespaces}%
+\def\pgfoo@@new@attribute new #1({%
+ \expandafter\ifx\csname pgfooY#1.get id\endcsname\relax%
+ \pgferror{Unknown class '#1'}%
+ \else%
+ \pgfoo@new@create\pgfoo@temp{#1}%
+ {%
+ \pgfoothis@count\pgfoo@objectcount%
+ \let\pgfoo@attribute@op\pgfoolet%
+ \csname pgfooY#1.@pgfoo@process@attributes\endcsname%
+ }%
+ \expandafter\pgfoolet\expandafter{\pgfutil@reserved@a}\pgfoo@temp%
+ \let\pgfoo@continue=\pgf@oo@new@cont%
+ \expandafter\pgfoo@collect@args%
+ \fi%
+}%
+
+\def\pgfoo@new@create#1#2{%
+ \advance\pgfoo@objectcount by 1\relax%
+ \edef\pgfoolastobj{\noexpand\pgfoo@caller{\the\pgfoo@objectcount}}%
+ \expandafter\gdef\csname pgfooX\the\pgfoo@objectcount @class\endcsname{#2}%
+ \let#1\pgfoolastobj%
+}%
+
+\def\pgfoo@caller#1.#2({%
+ \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX#1@class\endcsname.#2\endcsname%
+ \ifx\pgfoo@caller@temp\relax%
+ % assume that #2 is of form "superclass.method"
+ \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#2\endcsname%
+ \ifx\pgfoo@caller@temp\relax%
+ \pgferror{Object #1 has no method '#2'}%
+ \fi%
+ \fi%
+ \def\pgf@marshal{%
+ \pgfoothis@count=#1\relax%
+ }%
+ \let\pgfoo@continue\pgfoo@caller@cont%
+ \pgfoo@collect@args%
+}%
+\def\pgfoo@caller@cont{%
+ \edef\pgf@marshal{%
+ \pgf@marshal%
+ \noexpand\pgfoo@caller@temp(\the\pgfoo@toks)%
+ }%
+ \expandafter\pgf@marshal\expandafter\pgfoothis@count\the\pgfoothis@count\relax%
+}%
+\let\pgfoo@orig@caller=\pgfoo@caller
+
+% The special "this" object
+
+\def\pgfoothis.#1({%
+ \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname%
+ \ifx\pgfoo@caller@temp\relax%
+ % assume that #1 is of form "superclass.method"
+ \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#1\endcsname%
+ \fi%
+ \let\pgfoo@continue\pgfoothis@cont%
+ \pgfoo@collect@args%
+}%
+\def\pgfoothis@cont{%
+ \expandafter\pgfoo@caller@temp\expandafter(\the\pgfoo@toks)%
+}%
+
+
+
+% Get the object id
+%
+% #1 = macro to store the id
+%
+% Description:
+%
+% This special method allows you to access the object id. You can then
+% use \pgfoocall to call a method using this id. This is mainly useful
+% when you wish to store the id for a longer time.
+
+\def\pgfoo@id(#1){%
+ \edef#1{\the\pgfoothis@count}%
+}%
+
+% Yields the object with the given id
+%
+% #1 = id
+%
+% Description:
+%
+% Given an object id, \pgfooobj{<id>} will yield the object having
+% this id.
+
+\def\pgfooobj#1{%
+ \pgfoo@caller{#1}%
+}%
+
+
+% Get the object
+%
+% #1 = macro to store the object
+%
+% Description:
+%
+% This special method allows you to get a new handle to a given
+% object. If \obj is an object, you could normally just say
+% \let#1=\obj. However, if \obj happens to be \pgfoothis, then you may
+% wish to get a handle to the object itself, not to the special macro
+% \pgfoothis. In this case you can say \obj.get handle(#1).
+
+\def\pgfoo@obj(#1){%
+ \edef#1{\noexpand\pgfoo@caller{\the\pgfoothis@count}}%
+}%
+
+
+
+% The garbage collector
+%
+% Description:
+%
+% This method frees space occupied by unused objects. Garbage are
+% objects that have been destroyed because of the end of the scope in
+% which they were created. In this case, however, the memory used by
+% this object is not immediately reused because the attributes of the
+% object are actually stored in global variables. When the garbage
+% collector is called, it will set all these global variables to
+% \relax, thereby ensuring that no memory is needed for them.
+
+\def\pgfoogc{%
+ {%
+ % We do this in a group...
+ \pgfoothis@count\pgfoo@objectcount% this is temporary...
+ \let\pgfoo@next=\pgfoo@dogc%
+ \pgfoo@next%
+ }%
+}%
+\def\pgfoo@dogc{%
+ \advance\pgfoothis@count by 1\relax%
+ \expandafter\ifx\csname pgfooX\the\pgfoothis@count @class\endcsname\relax%
+ \let\pgfoo@next=\relax%
+ \else%
+ % Cleanup this object:
+ % The following is the fast version of \pgfooobj{\the\pgfoo@objectcount}.@pgfoogc:
+ \let\pgfoo@attribute@op\pgfoo@gc@attribute
+ \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfoo@process@attributes\endcsname%
+ \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @class\endcsname\relax%
+ \fi%
+ \pgfoo@next%
+}%
+
+
+
+%
+%
+% Object class
+% defines method "copy"
+%
+%
+
+\pgfooclass{object}{%
+ \method copy(#1) {%
+ % create a new object
+ \edef\pgfoo@temp@classname{\csname pgfooX\the\pgfoothis@count @class\endcsname}%
+ \expandafter\pgfoo@new@create\expandafter#1\expandafter{\pgfoo@temp@classname}%
+ \def\pgfoo@copy@attributes##1##2{%
+ \pgfooget{##1}\pgfoo@attrvalue
+ \expandafter\let\csname pgfooX\the\pgfoo@objectcount @##1\endcsname\pgfoo@attrvalue
+ }%
+ \let\pgfoo@attribute@op\pgfoo@copy@attributes
+ \csname pgfooY\pgfoo@temp@classname .@pgfoo@process@attributes\endcsname
+ \aftergroup\pgfoogc% cleanup after group
+ }%
+}%
+
+
+%
+%
+% Signal class
+%
+%
+
+\pgfooclass{signal}
+{%
+ %
+ % This class implements signals.
+ %
+ % After you have created a signal object, you can call
+ % connect to connect a slot. Then, whenever the emit method is
+ % called, all connected methods get called.
+
+ % Attribute
+ \attribute emitter;%
+ % Collects the objects that should be called.
+
+ % Constructor
+ \method signal() {}%
+
+ % Connect a slot (method) #2 of object #1
+ \method connect(#1,#2) {%
+ {%
+ #1.get id(\pgf@tempid)%
+ % Save in emitter
+ \pgfooget{emitter}\pgf@temp%
+ \let\pgfoo@signal@call=\relax% avoid expansion
+ \edef\pgf@temp{\pgf@temp\pgfoo@signal@call{\pgf@tempid}{#2}}%
+ \pgfoolet{emitter}\pgf@temp%
+ }%
+ }%
+
+ \def\pgfoo@signal@call#1#2{%
+ \def\pgf@temp{\pgfooobj{#1}.#2}%
+ \expandafter\pgf@temp\expandafter(\pgfoo@signal@args)%
+ }%
+
+ % Emit a signal
+ \method emit(#1) {%
+ \def\pgfoo@signal@args{#1}%
+ \pgfoovalueof{emitter}
+ }%
+}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmoduleparser.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmoduleparser.code.tex
new file mode 100644
index 0000000000..ca2a597560
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmoduleparser.code.tex
@@ -0,0 +1,697 @@
+% Copyright 2019 by Till Tantau
+% Copyright 2019 by Jonathan P. Spratte
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmoduleparser.code.tex}
+
+%
+% This file defines commands for defining a letter-by-letter parser
+% based on a dfa. The idea is inspired by the pgf module parser, but extends it
+% and eventually replaced it.
+%
+
+% options
+\long\def\pgfparserset#1%
+ {%
+ \pgfqkeys{/pgfparser}{#1}%
+ }
+\pgfparserset
+ {%
+ ,silent/.is if=\pgfparser@ifname{every parser silent}%
+ ,status/.is if=\pgfparser@ifname{pgfparser status}%
+ }
+
+% logic helpers
+\long\def\pgfparser@fi@Bn\fi#1{\fi}
+\long\def\pgfparser@fi@Bg\fi#1#2{\fi}
+\long\def\pgfparser@fi@BTb\fi#1#2#3{\fi#2}
+\long\def\pgfparser@fi@BTc\fi#1#2#3{\fi#3}
+
+% opt arg parsing
+\long\def\pgfparserifmark#1%
+ {%
+ \ifx\pgfparser@mark#1%
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ }
+\pgfutil@protected\long\def\pgfparser@oarg@oarg#1%
+ {%
+ \pgfutil@ifnextchar[{\pgfparser@oarg@oarg@{#1}}{#1{\pgfparser@mark}}%
+ }
+\long\def\pgfparser@oarg@oarg@#1[#2]%
+ {%
+ #1{#2}%
+ }
+\pgfutil@protected\long\def\pgfparser@oarg@Oarg#1#2%
+ {%
+ \pgfutil@ifnextchar[{\pgfparser@oarg@oarg@{#2}}{#2{#1}}%
+ }
+\pgfutil@protected\long\def\pgfparser@oarg@darg#1#2#3%
+ {%
+ \long\def\pgfparser@oarg@darg@##1#1##2#2{##1{##2}}%
+ \pgfutil@ifnextchar#1{\pgfparser@oarg@darg@{#3}}{#3{\pgfparser@mark}}%
+ }
+\pgfutil@protected\long\def\pgfparser@oarg@Darg#1#2#3#4%
+ {%
+ \long\def\pgfparser@oarg@darg@##1#1##2#2{##1{##2}}%
+ \pgfutil@ifnextchar#1{\pgfparser@oarg@darg@{#4}}{#4{#3}}%
+ }
+\pgfutil@protected\long\def\pgfparser@oarg@targ@#1%
+ {%
+ \def\pgfparser@oarg@targ@next{#1}%
+ \afterassignment\pgfparser@oarg@targ@next
+ \let\pgfparser@ignored@token=%
+ }
+\pgfutil@protected\long\def\pgfparser@oarg@targ#1#2%
+ {%
+ \pgfutil@ifnextchar#1%
+ {\pgfparser@oarg@targ@{#2{\pgfparser@mark}}}{#2{\pgfparser@stop}}%
+ }
+
+% status messages
+\pgfutil@protected\def\pgfparser@msg#1%
+ {%
+ \immediate\write0{(pgfparser) #1}%
+ }
+\pgfutil@protected\def\pgfparser@status@start#1%
+ {%
+ \pgfparser@if{pgfparser status}{\pgfparser@msg{parser '#1' started}}{}%
+ }
+\pgfutil@protected\def\pgfparser@status@state#1%
+ {%
+ \pgfparser@if{pgfparser status}
+ {\pgfparser@msg{|= switched to state '#1'}}
+ {}%
+ }
+\pgfutil@protected\def\pgfparser@status@rule
+ {%
+ \pgfparser@if{pgfparser status}
+ {\pgfparser@msg{| \space|= rule '\meaning\pgfparsertoken' executed}}
+ {}%
+ }
+\pgfutil@protected\def\pgfparser@status@rule@all
+ {%
+ \pgfparser@if{pgfparser status}
+ {%
+ \pgfparser@msg
+ {| \space|= (all) rule '\meaning\pgfparsertoken' executed}%
+ }
+ {}%
+ }
+\pgfutil@protected\def\pgfparser@status@rule@undefined
+ {%
+ \pgfparser@if{pgfparser status}
+ {%
+ \pgfparser@msg
+ {| \space|= unknown for '\meaning\pgfparsertoken' executed}%
+ }
+ {}%
+ }
+\pgfutil@protected\def\pgfparser@status@rule@undefined@all
+ {%
+ \pgfparser@if{pgfparser status}
+ {%
+ \pgfparser@msg
+ {| \space|= (all) unknown for '\meaning\pgfparsertoken' executed}%
+ }
+ {}%
+ }
+
+% macros for string comparison
+\begingroup
+\lccode`\P=`\P \lccode`\G=`\G \lccode`\F=`\F
+\lccode`\:=`\X \lccode`\;=`\r \lccode`\A=`\-
+\lowercase
+ {%
+ \endgroup
+ \def\pgfparser@mark{APGFparse;:mark-}%
+ \def\pgfparser@stop{APGFparse;:stop-}%
+ }%
+\def\pgfparser@final{final}
+\def\pgfparser@noarg{noarg}
+\def\pgfparser@blankspace{blank space}
+
+% counters
+\newcount\pgfparserdef@arg@count
+
+% shortcuts for special names
+\def\pgfparser@name#1%
+ {%
+ pgfparser #1%
+ }
+\def\pgfparser@rule#1%
+ {%
+ \pgfparser@current\space #1\space \meaning\pgfparsertoken
+ }
+\def\pgfparser@type#1%
+ {%
+ \pgfparser@rule{#1} type%
+ }
+\def\pgfparser@code#1%
+ {%
+ \pgfparser@rule{#1} code%
+ }
+\def\pgfparser@undefined#1%
+ {%
+ \pgfparser@current\space #1\space unknown%
+ }
+\def\pgfparser@ifname#1%
+ {%
+ pgfparserconditional #1%
+ }
+
+% conditionals
+\def\pgfparser@if#1%
+ {%
+ \pgfutil@ifundefined{if\pgfparser@ifname{#1}}
+ {%
+ \pgferror{Undefined conditional '#1'. Falling back to false}%
+ \iffalse
+ }
+ {\csname if\pgfparser@ifname{#1}\endcsname}%
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ }
+\def\pgfparser@newif#1%
+ {%
+ \csname newif\expandafter\endcsname
+ \csname if\pgfparser@ifname{#1}\endcsname
+ }
+\pgfparser@newif{every parser silent}
+\pgfparser@newif{pgfparserdef abort}
+\pgfparser@newif{pgfparser status}
+
+% pgfparserdef
+\pgfutil@protected\def\pgfparserdef#1#2%
+ {%
+ \def\pgfparserdef@twoargs{{#1}{#2}}%
+ \pgfparserdef@a
+ }
+\pgfutil@protected\def\pgfparserdef@a
+ {%
+ \futurelet\pgfparserdef@arg\pgfparserdef@b
+ }
+\def\pgfparserdef@b
+ {%
+ \ifx\pgfparserdef@arg\pgfutil@sptoken
+ % will also gobble the \pgfparserdef@c after \fi
+ \pgfparserdef@gobble@space
+ \fi
+ \pgfparserdef@c
+ }
+\pgfutil@protected\def\pgfparserdef@gobble@space\fi#1%
+ {%
+ \fi
+ \afterassignment\pgfparserdef@a
+ \let\pgfparser@ignored@token= % space after = to get spaces, too
+ }
+\pgfutil@protected\def\pgfparserdef@c#1%
+ {%
+ \ifx\pgfparserdef@arg\bgroup
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ {%
+ \def\pgfparserdef@arg{#1}%
+ \ifx\pgfparser@blankspace\pgfparserdef@arg
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ {\expandafter\pgfparserdef@d\pgfparserdef@twoargs{blank space \space}}
+ {\expandafter\pgfparserdef@d\pgfparserdef@twoargs{#1}}%
+ }
+ {%
+ \expandafter\pgfparserdef@d\pgfparserdef@twoargs
+ {\meaning\pgfparserdef@arg}%
+ }%
+ }
+\long\def\pgfparserdef@d#1#2#3%
+ {%
+ \pgfparser@oarg@Oarg{}{\pgfparserdef@e{#1}{#2}{#3}}%
+ }
+\pgfutil@protected\long\def\pgfparserdef@e#1#2#3#4#5%
+ {%
+ \pgfparser@initiate@parser{#1}%
+ \csname\pgfparser@ifname{pgfparserdef abort}false\endcsname
+ % check how many arguments are used, also parses whether the argument string
+ % is valid
+ \pgfparserdef@arg@count=0
+ \pgfparserdef@argcount#4\pgfparser@mark
+ \ifnum\pgfparserdef@arg@count>9
+ \pgferror
+ {%
+ Too many arguments for parser rule. A maximum of 9 parameters is
+ supported.%
+ }%
+ \csname\pgfparser@ifname{pgfparserdef abort}true\endcsname
+ \fi
+ % define what the code does
+ \pgfparser@if{pgfparserdef abort}{}
+ {%
+ % use a macro as flag that there is a rule for the specified state and
+ % hold information how to parse it
+ \ifnum\pgfparserdef@arg@count=0
+ \pgfutil@namedef{\pgfparser@name{#1} #2 #3 type}{noarg}%
+ \pgfutil@namedef{\pgfparser@name{#1} #2 #3 code}%
+ {#5\pgfparser@getnexttoken}%
+ \else
+ \pgfutil@namedef{\pgfparser@name{#1} #2 #3 type}{#4}%
+ \expandafter\pgfparserdef@argstring@def\the\pgfparserdef@arg@count
+ \pgfutil@namedef{\pgfparser@name{#1} #2 #3 code\expandafter}%
+ \pgfparserdef@argstring##1##2##3##4##5##6##7##8##9%
+ {#5\pgfparser@getnexttoken}%
+ \fi
+ }%
+ }
+\def\pgfparserdef@argstring@def#1%
+ {%
+ \def\pgfparserdef@argstring##1#1##2##{##1#1}%
+ }
+\def\pgfparserdef@argcount#1%
+ {%
+ \ifx\pgfparser@mark#1%
+ \pgfparser@fi@Bg
+ \fi
+ \pgfutil@firstofone
+ {%
+ \pgfutil@IfUndefined{pgfparserdef@argcount@#1}
+ {%
+ \pgferror{Unknown argument type '#1'. Aborting rule definition}%
+ \pgfparserdef@argcount@abort
+ }
+ {\csname pgfparserdef@argcount@#1\endcsname}%
+ }%
+ }
+\pgfutil@protected\long\def\pgfparserdef@argcount@abort#1\pgfparser@mark
+ {%
+ \csname\pgfparser@ifname{pgfparserdef abort}true\endcsname
+ }
+\def\pgfparserdef@argcount@m
+ {%
+ \advance\pgfparserdef@arg@count1
+ \pgfparserdef@argcount
+ }
+\let\pgfparserdef@argcount@o\pgfparserdef@argcount@m
+\def\pgfparserdef@argcount@O#1%
+ {%
+ \advance\pgfparserdef@arg@count1
+ \pgfparserdef@argcount
+ }
+\let\pgfparserdef@argcount@r\pgfparserdef@argcount@O
+\let\pgfparserdef@argcount@t\pgfparserdef@argcount@O
+\def\pgfparserdef@argcount@d#1#2%
+ {%
+ \advance\pgfparserdef@arg@count1
+ \pgfparserdef@argcount
+ }
+\def\pgfparserdef@argcount@D#1#2#3%
+ {%
+ \advance\pgfparserdef@arg@count1
+ \pgfparserdef@argcount
+ }
+
+\pgfutil@protected\def\pgfparser@initiate@parser#1%
+ {%
+ % if that is the first rule for the parser
+ \pgfutil@IfUndefined{if\pgfparser@ifname{#1 silent}}%
+ {%
+ % define space to be a no-op
+ \pgfutil@namedef
+ {\pgfparser@name{#1} all blank space \space\space type}{noarg}%
+ \pgfutil@namedef
+ {\pgfparser@name{#1} all blank space \space\space code}%
+ {\pgfparser@getnexttoken}%
+ % define a new conditional whether the parser silently ignores unknown
+ % tokens
+ \pgfparser@newif{#1 silent}%
+ \pgfparserset
+ {%
+ #1/silent/.is if=\pgfparser@ifname{#1 silent}%
+ }%
+ }
+ {}%
+ }
+
+% pgfparserlet
+\pgfutil@protected\def\pgfparserlet#1#2%
+ {%
+ \def\pgfparserlet@parser@a{#1}%
+ \def\pgfparserlet@state@a{#2}%
+ \pgfparserlet@a
+ }
+\pgfutil@protected\def\pgfparserlet@a
+ {%
+ \futurelet\pgfparserlet@arga\pgfparserlet@b
+ }
+\def\pgfparserlet@b
+ {%
+ \ifx\pgfparserlet@arga\pgfutil@sptoken
+ % will also gobble the \pgfparserlet@c after \fi
+ \pgfparserlet@gobble@space\pgfparserlet@a
+ \fi
+ \pgfparserlet@c
+ }
+\pgfutil@protected\def\pgfparserlet@gobble@space#1\fi#2%
+ {%
+ \fi
+ \afterassignment#1%
+ \let\pgfparser@ignored@token= % space after = to get spaces, too
+ }
+\pgfutil@protected\def\pgfparserlet@c#1%
+ {%
+ \ifx\pgfparserlet@arga\bgroup
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ {%
+ \def\pgfparserlet@arga{#1}%
+ \ifx\pgfparser@blankspace\pgfparserlet@arga
+ \def\pgfparserlet@arga{blank space \space}%
+ \fi
+ }
+ {\edef\pgfparserlet@arga{\meaning\pgfparserlet@arga}}%
+ \pgfparser@oarg@oarg\pgfparserlet@d
+ }
+\pgfutil@protected\def\pgfparserlet@d#1%
+ {%
+ \pgfparserifmark{#1}
+ {%
+ \let\pgfparserlet@parser@b\pgfparserlet@parser@a
+ \let\pgfparserlet@state@b\pgfparserlet@state@a
+ \pgfparserlet@f
+ }
+ {\pgfparser@oarg@oarg{\pgfparserlet@e{#1}}}%
+ }
+\pgfutil@protected\def\pgfparserlet@e#1#2%
+ {%
+ \pgfparserifmark{#2}
+ {%
+ \let\pgfparserlet@parser@b\pgfparserlet@parser@a
+ \def\pgfparserlet@state@b{#1}%
+ }
+ {%
+ \def\pgfparserlet@parser@b{#1}%
+ \def\pgfparserlet@state@b{#2}%
+ }
+ \pgfparserlet@f
+ }
+\pgfutil@protected\def\pgfparserlet@f
+ {%
+ \futurelet\pgfparserlet@argb\pgfparserlet@g
+ }
+\def\pgfparserlet@g
+ {%
+ \ifx\pgfparserlet@argb\pgfutil@sptoken
+ % will also gobble the \pgfparserlet@h after \fi
+ \pgfparserlet@gobble@space\pgfparserlet@f
+ \fi
+ \pgfparserlet@h
+ }
+\pgfutil@protected\def\pgfparserlet@h#1%
+ {%
+ \ifx\pgfparserlet@argb\bgroup
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ {%
+ \def\pgfparserlet@argb{#1}%
+ \ifx\pgfparser@blankspace\pgfparserlet@argb
+ \def\pgfparserlet@argb{blank space \space}%
+ \fi
+ }
+ {\edef\pgfparserlet@argb{\meaning\pgfparserlet@argb}}%
+ \pgfparserlet@i
+ \pgfparserlet@parser@a
+ \pgfparserlet@state@a
+ \pgfparserlet@arga
+ \pgfparserlet@parser@b
+ \pgfparserlet@state@b
+ \pgfparserlet@argb
+ }
+\def\pgfparserlet@i#1#2#3#4#5#6%
+ {%
+ \pgfutil@IfUndefined{\pgfparser@name{#4} #5 #6 type}
+ {%
+ \pgferror
+ {%
+ There is no rule defined for parser '#4' in state '#5' for '#6'.
+ Aborting \string\pgfparserlet
+ }%
+ }
+ {%
+ \pgfparser@initiate@parser{#1}%
+ \pgfparserlet@let{#1}{#2}{#3}{#4}{#5}{#6}{type}%
+ \pgfparserlet@let{#1}{#2}{#3}{#4}{#5}{#6}{code}%
+ }%
+ }
+\def\pgfparserlet@let#1#2#3#4#5#6#7%
+ {%
+ \expandafter\let\csname\pgfparser@name{#1} #2 #3 #7\expandafter\endcsname
+ \csname\pgfparser@name{#4} #5 #6 #7\endcsname
+ }
+
+\pgfutil@protected\long\def\pgfparserdefunknown#1#2#3%
+ {%
+ \pgfparser@initiate@parser{#1}%
+ \pgfutil@namedef{\pgfparser@name{#1} #2 unknown}{#3}%
+ }
+\pgfutil@protected\long\def\pgfparserdeffinal#1#2%
+ {%
+ \pgfutil@namedef{\pgfparser@name{#1} final action}{#2}%
+ }
+\pgfutil@protected\def\pgfparserswitch#1%
+ {%
+ \pgfparser@status@state{#1}%
+ \def\pgfparserstate{#1}%
+ }
+\pgfutil@protected\def\pgfparserparse#1%
+ {%
+ \pgfutil@IfUndefined{if\pgfparser@ifname{#1 silent}}
+ {\pgferror{No parser named '#1' defined}}
+ {%
+ \edef\pgfparser@current{\pgfparser@name{#1}}%
+ \def\pgfparser@usersname{#1}%
+ \pgfparser@status@start{#1}%
+ \pgfparserswitch{initial}%
+ \pgfparser@getnexttoken
+ }%
+ }
+% get next token
+\pgfutil@protected\def\pgfparser@getnexttoken
+ {%
+ \ifx\pgfparserstate\pgfparser@final
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ {%
+ \pgfutil@IfUndefined{\pgfparser@current\space final action}
+ {}
+ {\csname \pgfparser@current\space final action\endcsname}%
+ }
+ {\futurelet\pgfparsertoken\pgfparser@getnexttoken@a}%
+ }
+\pgfutil@protected\def\pgfparser@getnexttoken@a
+ {%
+ % check the problematic categories based on the meaning of the token
+ \edef\pgfparser@tokencategory{\pgfparser@extractmeaning\pgfparsertoken}%
+ \pgfparser@getnexttoken@ifcategory\pgfparser@category@i\bgroup
+ {%
+ \pgfparser@getnexttoken@ifcategory\pgfparser@category@ii\egroup
+ {%
+ \pgfparser@getnexttoken@ifcategory\pgfparser@category@x{ }%
+ {%
+ \pgfparser@getnexttoken@ifcategory\pgfparser@category@vi{####}%
+ {\pgfparser@getnexttoken@defchar}%
+ }%
+ }%
+ }%
+ }
+\begingroup
+\def\pgfparser@extractmeaning#1%
+ {%
+ \endgroup
+ \def\pgfparser@extractmeaning##1%
+ {\expandafter\pgfparser@extractmeaning@\meaning##1#1#1\pgfparser@mark}%
+ \def\pgfparser@extractmeaning@##1#1##2#1##3\pgfparser@mark{##1#1##2}%
+ }
+\catcode`\ =12\pgfparser@extractmeaning{ } % ends the group
+\edef\pgfparser@category@i{\pgfparser@extractmeaning\bgroup}
+\edef\pgfparser@category@ii{\pgfparser@extractmeaning\egroup}
+\edef\pgfparser@category@vi{\pgfparser@extractmeaning#}
+\edef\pgfparser@category@x{\pgfparser@extractmeaning\pgfutil@sptoken}
+\pgfutil@protected\def\pgfparser@getnexttoken@ifcategory#1#2%
+ {%
+ \ifx\pgfparser@tokencategory#1%
+ \def\pgfparserletter{#2}%
+ \pgfparser@getnexttoken@gobble
+ \fi
+ \pgfutil@firstofone
+ }
+\pgfutil@protected\def\pgfparser@getnexttoken@gobble\fi#1#2%
+ {%
+ \fi
+ \afterassignment\pgfparser@getnexttoken@b
+ \let\pgfparser@ignored@token= % gobble should gobble a space
+ }
+\pgfutil@protected\long\def\pgfparser@getnexttoken@defchar#1%
+ {%
+ \def\pgfparserletter{#1}%
+ \pgfparser@getnexttoken@b
+ }
+\pgfutil@protected\def\pgfparser@getnexttoken@b
+ {%
+ \pgfutil@IfUndefined{\pgfparser@type{\pgfparserstate}}
+ {%
+ \pgfutil@IfUndefined{\pgfparser@type{all}}
+ {%
+ \pgfparser@if{every parser silent}{}
+ {%
+ \pgfparser@if{\pgfparser@usersname\space silent}{}
+ {%
+ \pgferror
+ {%
+ No rule for parser '\pgfparser@usersname' in state
+ '\pgfparserstate' for '\meaning\pgfparsertoken'.
+ Ignoring token%
+ }%
+ }%
+ }%
+ \pgfutil@IfUndefined{\pgfparser@undefined{\pgfparserstate}}
+ {%
+ \pgfutil@IfUndefined{\pgfparser@undefined{all}}
+ {}
+ {%
+ \pgfparser@status@rule@undefined@all
+ \csname\pgfparser@undefined{all}\endcsname
+ }%
+ }
+ {%
+ \pgfparser@status@rule@undefined
+ \csname\pgfparser@undefined{\pgfparserstate}\endcsname
+ }%
+ \pgfparser@getnexttoken
+ }
+ {%
+ \pgfparser@status@rule@all
+ \pgfparser@handle{all}%
+ }%
+ }
+ {%
+ \pgfparser@status@rule
+ \pgfparser@handle{\pgfparserstate}%
+ }%
+ }
+
+% handle arguments
+\pgfutil@protected\def\pgfparser@handle#1%
+ {%
+ \expandafter\ifx\csname\pgfparser@type{#1}\endcsname\pgfparser@noarg
+ \pgfparser@fi@BTb
+ \fi
+ \pgfutil@secondoftwo
+ {\csname\pgfparser@code{#1}\endcsname}
+ {\pgfparser@handle@args{#1}}%
+ }
+\pgfutil@protected\def\pgfparser@handle@args#1%
+ {%
+ \def\pgfparser@stateorall{#1}%
+ \expandafter\expandafter\expandafter\pgfparser@handle@args@a
+ \csname\pgfparser@type{#1}\endcsname\pgfparser@mark\pgfparser@stop
+ }
+\def\pgfparser@handle@args@a
+ {%
+ \pgfparser@handle@args@b{}%
+ }
+\pgfutil@protected\long\def\pgfparser@handle@args@b#1#2#3\pgfparser@stop
+ {%
+ \pgfparserifmark{#2}
+ {\csname\pgfparser@code{\pgfparser@stateorall}\endcsname#1}
+ {%
+ \pgfutil@IfUndefined{pgfparser@handle@args@#2}
+ {\pgferror{Unknown argument type '#2'}}
+ {\csname pgfparser@handle@args@#2\endcsname{#1}{#3}}%
+ }%
+ }
+\long\def\pgfparser@handle@args@c#1#2%
+ {%
+ \pgfparserifmark{#2}
+ {\csname\pgfparser@code{\pgfparser@stateorall}\endcsname#1}
+ {\pgfparser@handle@args@b{#1}#2\pgfparser@stop}%
+ }
+\long\def\pgfparser@handle@args@m#1#2#3%
+ {%
+ \pgfparser@handle@args@c{#1{#3}}{#2}%
+ }
+\pgfutil@protected\long\def\pgfparser@handle@args@o#1#2%
+ {%
+ \pgfparser@oarg@oarg{\pgfparser@handle@args@m{#1}{#2}}%
+ }
+\long\def\pgfparser@handle@args@O#1#2%
+ {%
+ \pgfparser@handle@args@O@{#1}#2\pgfparser@stop
+ }
+\pgfutil@protected\long\def\pgfparser@handle@args@O@#1#2#3\pgfparser@stop
+ {%
+ \pgfparser@oarg@Oarg{#2}{\pgfparser@handle@args@m{#1}{#3}}%
+ }
+\long\def\pgfparser@handle@args@d#1#2%
+ {%
+ \pgfparser@handle@args@d@{#1}#2\pgfparser@stop
+ }
+\pgfutil@protected\long\def\pgfparser@handle@args@d@#1#2#3#4\pgfparser@stop
+ {%
+ \pgfparser@oarg@darg{#2}{#3}{\pgfparser@handle@args@m{#1}{#4}}%
+ }
+\long\def\pgfparser@handle@args@D#1#2%
+ {%
+ \pgfparser@handle@args@D@{#1}#2\pgfparser@stop
+ }
+\pgfutil@protected\long\def\pgfparser@handle@args@D@#1#2#3#4#5\pgfparser@stop
+ {%
+ \pgfparser@oarg@Darg{#2}{#3}{#4}{\pgfparser@handle@args@m{#1}{#5}}%
+ }
+\long\def\pgfparser@handle@args@r#1#2%
+ {%
+ \pgfparser@handle@args@r@a{#1}#2\pgfparser@stop
+ }
+\pgfutil@protected\long\def\pgfparser@handle@args@r@a#1#2#3\pgfparser@stop
+ {%
+ \def\pgfparser@handle@args@r@b##1#2%
+ {\pgfparser@handle@args@c{#1{##1}}{#3}}%
+ \pgfparser@handle@args@r@b
+ }
+\long\def\pgfparser@handle@args@t#1#2%
+ {%
+ \pgfparser@handle@args@t@{#1}#2\pgfparser@stop
+ }
+\pgfutil@protected\long\def\pgfparser@handle@args@t@#1#2#3\pgfparser@stop
+ {%
+ \pgfparser@oarg@targ{#2}{\pgfparser@handle@args@m{#1}{#3}}%
+ }
+
+\pgfutil@protected\long\def\pgfparserreinsert#1%
+ {%
+ \ifx\pgfparser@getnexttoken#1%
+ \pgfparser@fi@BTb
+ \fi
+ \@secondoftwo
+ {\expandafter\pgfparser@getnexttoken\pgfparserletter}
+ {%
+ \pgferror
+ {%
+ Misuse of \string\pgfparserreinsert\space detected. You should only
+ use it at the the end of an action code%
+ }%
+ #1%
+ }%
+ }
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmoduleplot.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmoduleplot.code.tex
new file mode 100644
index 0000000000..0afea0ae34
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmoduleplot.code.tex
@@ -0,0 +1,561 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmoduleplot.code.tex}
+
+
+% PGF's plotting interface works as follows:
+%
+% In order to plot something, two things need to be done. First, you
+% need to provide the coordinates (obviously) of the points that
+% should be plotted. The coordinates are given via a long stream of
+% commands. These commands are \pgfplotstreamstart, which is
+% given exactly once at the beginning, the commands
+% \pgfplotstreampoint, \pgfplotstreampointoutlier,
+% \pgfplotstreampointundefined, \pgfplotstreamnewdataset, of which
+% there are numerous in the middle, the special \pgfplotstreamspecial,
+% of which there may be numerous in the middle, and \pgfplotstreamend,
+% which must be given at the end. Between these commands arbitrary
+% other commands may be given. Here is an example:
+%
+% ...
+% \pgfplotstreamstart
+% \pgfplotstreampoint{\pgfpointxy{0}{0}}
+% \pgfplotstreampoint{\pgfpointxy{1}{1}}
+% \pgfplotstreamnewdataset
+% \pgfplotstreampoint{\pgfpointxy{2}{4}}
+% \relax
+% \pgfplotstreampointoutlier{\pgfpointxy{3}{9}}
+% \pgfplotstreamspecial{some handler-dependent special stuff}
+% \pgfplotstreamend
+%
+% By themselves, the \pgfplotstreamxxxx commands do not do anything by
+% default. Rather, to ``use'' such a stream, you must first install a
+% stream handler. For example, the ``lineto'' handler will simply
+% basically every \pgfplotstreampoint into a \pgfpathlineto.
+%
+% One special things is the handling of "jumps" in a stream. For
+% instance, when a lineto handler encounters an "outlier" or a new
+% data set, the current line should end and a new subpath should start
+% (unless configured otherwise). For this, the special jump handler is
+% important.
+%
+% Example:
+%
+% \pgfpathmoveto{\pgfpointorigin}
+%
+% \pgfplothandlerlineto
+% \pgfplotstreamstart
+% \pgfplotstreampoint{\pgfpointxy{0}{0}}
+% \pgfplotstreampoint{\pgfpointxy{1}{1}}
+% \pgfplotstreampoint{\pgfpointxy{2}{4}}
+% \relax
+% \pgfplotstreampoint{\pgfpointxy{3}{9}}
+% \pgfplotstreamend
+
+
+% The stream commands actually call their ``internal'' versions, which
+% are set by the handlers:
+\def\pgfplotstreamstart{\pgf@plotstreamstart}%
+\def\pgfplotstreampoint#1{\gdef\pgfplotlastpoint{#1}\pgf@plotstreampoint{#1}}%
+\def\pgfplotstreampointoutlier#1{\pgfplot@outliers{}{\pgf@plotstreamjump}{\pgfplotstreampoint{#1}}}%
+\def\pgfplotstreampointundefined{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}%
+\def\pgfplotstreamnewdataset{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}%
+\def\pgfplotstreamspecial{\pgf@plotstreamspecial}%
+\def\pgfplotstreamend{\pgf@plotstreamend}%
+
+\def\pgfplot@ignorer#1#2#3{#1}%
+\def\pgfplot@jumper#1#2#3{#2}%
+\def\pgfplot@plotter#1#2#3{#3}%
+
+\let\pgfplot@outliers\pgfplot@jumper
+\let\pgfplot@undefined\pgfplot@jumper
+\let\pgfplot@newdata\pgfplot@jumper
+
+\pgfset{
+ handle outlier points in plots/.is choice,
+ handle outlier points in plots/ignore/.code=\let\pgfplot@outliers\pgfplot@ignorer,
+ handle outlier points in plots/jump/.code=\let\pgfplot@outliers\pgfplot@jumper,
+ handle outlier points in plots/plot/.code=\let\pgfplot@outliers\pgfplot@plotter,
+ handle undefined points in plots/.is choice,
+ handle undefined points in plots/ignore/.code=\let\pgfplot@undefined\pgfplot@ignorer,
+ handle undefined points in plots/jump/.code=\let\pgfplot@undefined\pgfplot@jumper,
+ handle new data sets in plots/.is choice,
+ handle new data sets in plots/ignore/.code=\let\pgfplot@newdata\pgfplot@ignorer,
+ handle new data sets in plots/jump/.code=\let\pgfplot@newdata\pgfplot@jumper,
+}%
+
+
+% Declares a new plot handler
+%
+% #1 = macro that should install the stream handler subsequently
+% #2 = parameter list of said macro.
+% #3 = keys as described below
+%
+% Description:
+%
+% When you declare a new plot handler, you provide, through keys,
+% different "actions" that should be taken when the different stream
+% commands are used:
+%
+% start = some code to be executed when \pgfplotstreamstart is called
+% for this plothandler
+% end = same for the end of the stream
+% point = code to be executed for a point of the stream
+% jump = code to be executed for a "jump" in the stream
+% special = code to be executed for \pgfplotstreamspecial
+% start macro = here and for the following keys, the to-be-executed
+% code is stored in the given macro
+% end macro = see above
+% jump macro = see above
+% point macro = see above
+% special macro = see above
+%
+% Example:
+%
+% \pgfdeclareplothandler{\ultrasimplehandler}{}{
+% point=\pgfpathlineto{##1}
+% }
+
+\def\pgfdeclareplothandler#1#2#3{%
+ \def#1#2{%
+ \pgfkeys{%
+ /pgf/plots/@handler options/.cd,
+ start=\relax,
+ end macro=\relax,
+ point macro=\pgfutil@gobble,
+ jump macro=\relax,
+ special macro=\pgfutil@gobble,%
+ #3%
+ }%
+ }%
+}%
+
+\pgfkeys{%
+ /pgf/plots/@handler options/.cd,
+ start/.code=%
+ \gdef\pgf@plotstreamstart{%
+ \global\pgf@plot@startedfalse%
+ \global\let\pgf@plotstreamend\pgf@plotstreamend@init%
+ \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init%
+ \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init%
+ \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init%
+ #1%
+ },%
+ start macro/.code=%
+ \gdef\pgf@plotstreamstart{%
+ \global\pgf@plot@startedfalse%
+ \global\let\pgf@plotstreamend\pgf@plotstreamend@init%
+ \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init%
+ \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init%
+ \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init%
+ #1%
+ },%
+ end/.code=\gdef\pgf@plotstreamend@init{#1},
+ end macro/.code=\global\let\pgf@plotstreamend@init#1,
+ point/.code=\gdef\pgf@plotstreampoint@init##1{#1},
+ point macro/.code=\global\let\pgf@plotstreampoint@init#1,
+ jump/.code=\gdef\pgf@plotstreamjump@init{#1},
+ jump macro/.code=\global\let\pgf@plotstreamjump@init#1,
+ special/.code=\gdef\pgf@plotstreamspecial@init##1{#1},
+ special macro/.code=\global\let\pgf@plotstreamspecial@init#1,
+}%
+
+\newif\ifpgf@plot@started
+
+
+
+
+% Sets the action taken for the first point of a plot to a lineto.
+%
+% Description:
+%
+% For certain handlers it makes sense either the start a plot by
+% moving to the first point of the plot or to do a lineto to that
+% first point. Using this command this action can be set to a lineto.
+%
+% Example:
+%
+% \pgfsetlinetofirstplotpoint
+
+\def\pgfsetlinetofirstplotpoint{\let\pgf@plot@first@action=\pgfpathlineto}%
+
+
+% Sets the action taken for the first point of a plot to a moveto.
+%
+% Example:
+%
+% \pgfsetmovetofirstplotpoint
+
+\def\pgfsetmovetofirstplotpoint{\let\pgf@plot@first@action=\pgfpathmoveto}%
+
+\let\pgf@plot@first@action=\pgfpathmoveto
+
+
+
+
+%
+% Handlers
+%
+
+
+% This handler converts each plot stream command into a lineto
+% command, except for the first, which is converted to the action that
+% has previously been specified using \pgfsetlinetofirstplotpoint or
+% \pgfsetmovetofirstplotpoint.
+%
+% Example:
+%
+% \pgfplothandlerlineto
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerlineto}{}{
+ point macro=\pgf@plot@line@handler,
+ jump=\global\let\pgf@plotstreampoint\pgf@plot@line@handler@move%
+}%
+
+\def\pgf@plot@line@handler#1{%
+ \pgf@plot@first@action{#1}%
+ \global\let\pgf@plotstreampoint=\pgfpathlineto%
+}%
+
+\def\pgf@plot@line@handler@move#1{%
+ \pgfpathmoveto{#1}%
+ \global\let\pgf@plotstreampoint=\pgfpathlineto%
+}%
+
+
+
+% This handler turns creates a series of lineto commands, with the
+% last command being a closepath, resulting in a closed path. If a
+% jump is encountered, the current subpath is closed and a new subpath
+% is started.
+%
+% Example:
+%
+% \pgfplothandlerpolygon
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerpolygon}{}{%
+ point macro=\pgf@plot@line@handler@close,
+ jump macro=\pgf@plot@next@close@and@moveto,
+ end macro=\pgf@plot@polygon@stop
+}%
+
+\def\pgf@plot@line@handler@close#1{%
+ \pgfpathmoveto{#1}%
+ \global\pgf@plot@startedtrue%
+ \global\let\pgf@plotstreampoint=\pgfpathlineto%
+}%
+
+\def\pgf@plot@polygon@stop{%
+ \ifpgf@plot@started%
+ \pgfpathclose%
+ \fi%
+ \global\pgf@plot@startedfalse%
+}%
+
+\def\pgf@plot@next@close@and@moveto{%
+ \ifpgf@plot@started%
+ \pgfpathclose%
+ \fi%
+ \global\let\pgf@plotstreampoint\pgf@plot@line@handler@close%
+}%
+
+
+% More handlers are defined in pgflibraryplothandlers
+
+
+
+
+
+% This handler discards the plot.
+%
+% Example:
+%
+% \pgfplothandlerdiscard
+% \pgfplotxyfile{mytable}
+
+\pgfdeclareplothandler{\pgfplothandlerdiscard}{}{}%
+
+
+
+% This handler records each plot stream command to a macro. This is
+% useful if plot commands are difficult to generate and need to be
+% ``recycled'' later on.
+%
+% Example:
+%
+% \pgfplothandlerrecord{\myplot}
+% \pgfplotxyfile{mytable} % stored in \myplot now
+% \pgfplothandlerline
+% \myplot
+% \pgftransformxshift{1cm}
+% \myplot
+
+\pgfdeclareplothandler{\pgfplothandlerrecord}{#1}{%
+ start=\gdef#1{\pgfplotstreamstart},
+ point=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreampoint{##1}},
+ jump=\expandafter\gdef\expandafter#1\expandafter{#1\pgf@plotstreamjump},
+ special=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamspecial{##1}},
+ end=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend},
+}%
+
+
+
+% Read a plot stream from a file and plot it.
+%
+% #1 = file from which to read things
+%
+% File format:
+%
+% Each line of the file should begin with two numbers separated by a
+% space. Such a line with number #1 and #2 is converted to a
+% \pgfplotstreampoint{\pgfpointxy{#1}{#2}}. Extra characters following
+% on the line are ignored.
+%
+% Lines starting with ``%'' and ``#'' are ignored.
+%
+% Example:
+%
+% \pgfplotxyfile{tableformgnuplot.dat}
+
+\def\pgfplotxyfile#1{%
+ \begingroup%
+ \def\b@pgfplotsxyfile@scanning@for@first{1}%
+ \pgfplotstreamstart%
+ \openin\r@pgf@reada=#1
+ \ifeof\r@pgf@reada
+ \pgfwarning{Plot data file `#1' not found.}
+ \else
+ \catcode`\#=14
+ \catcode`\^^M=5
+ \pgf@readxyfile%
+ \fi
+ \pgfplotstreamend%
+ \endgroup%
+}%
+
+\let\pgf@savedpar=\par
+\def\pgf@partext{\par}%
+\def\pgf@readxyfile{%
+ \pgfutil@read\r@pgf@reada to \pgf@temp%
+ \let\par=\pgf@savedpar%
+ \edef\pgf@temp{\pgf@temp}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \if1\b@pgfplotsxyfile@scanning@for@first
+ \else
+ \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi%
+ \fi
+ \else\ifx\pgf@temp\pgf@partext%
+ \if1\b@pgfplotsxyfile@scanning@for@first
+ \else
+ \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi%
+ \fi
+ \else%
+ \expandafter\pgf@parsexyline\pgf@temp\pgf@stop%
+ \fi\fi%
+ \ifeof\r@pgf@reada\else\expandafter\pgf@readxyfile\fi%
+}%
+
+\def\pgf@parsexyline#1 #2 #3\pgf@stop{%
+ \def\b@pgfplotsxyfile@scanning@for@first{0}%
+ \edef\pgf@xyline@flag@val{#3}%
+ \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef%
+ \pgfplotstreampointundefined%
+ \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out%
+ \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}%
+ \else%
+ \pgfplotstreampoint{\pgfpointxy{#1}{#2}}%
+ \fi\fi%
+}%
+
+\edef\pgf@xyline@flag@out{o\space}%
+\edef\pgf@xyline@flag@undef{u\space}%
+
+
+
+
+% Read a plot stream from a file and plot it.
+%
+% #1 = file from which to read things
+%
+% File format:
+%
+% Like xy, except that each line contains three numbers, which are
+% converted to xyz coordinates.
+%
+% Example:
+%
+% \pgfplotxyfile{tableformgnuplot.dat}
+
+\def\pgfplotxyzfile#1{%
+ \begingroup%
+ \pgfplotstreamstart%
+ \openin\r@pgf@reada=#1
+ \ifeof\r@pgf@reada
+ \pgfwarning{Plot data file `#1' not found.}
+ \else
+ \catcode`\#=14
+ \catcode`\^^M=5
+ \pgf@readxyzfile%
+ \fi
+ \pgfplotstreamend%
+ \endgroup%
+}%
+
+\def\pgf@readxyzfile{%
+ \pgfutil@read\r@pgf@reada to \pgf@temp%
+ \ifx\pgf@temp\pgfutil@empty%
+ \if1\b@pgfplotsxyfile@scanning@for@first
+ \else
+ \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi%
+ \fi
+ \else\ifx\pgf@temp\pgf@partext%
+ \if1\b@pgfplotsxyfile@scanning@for@first
+ \else
+ \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi%
+ \fi
+ \else%
+ \expandafter\pgf@parsexyzline\pgf@temp\pgf@stop%
+ \fi\fi%
+ \ifeof\r@pgf@reada\else\expandafter\pgf@readxyzfile\fi%
+}%
+
+\def\pgf@parsexyzline#1 #2 #3 #4\pgf@stop{%
+ \def\b@pgfplotsxyfile@scanning@for@first{0}%
+ \edef\pgf@xyline@flag@val{#4}%
+ \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef%
+ \pgfplotstreampointundefined%
+ \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out%
+ \pgfplotstreampointoutlier{\pgfpointxyz{#1}{#2}{#3}}%
+ \else%
+ \pgfplotstreampoint{\pgfpointxyz{#1}{#2}{#3}}%
+ \fi\fi%
+}%
+
+
+
+
+% Render a function using gnuplot.
+%
+% #1 = filename prefix for .gnuplot and .table files (optional,
+% default is \jobname)
+% #2 = gnuplot function text
+%
+% Description:
+%
+% This command will write a file called #1.gnuplot that sets up
+% some gnuplot commands to write output to a file called
+% #1.table. Then it calls gnuplot (using the \write18 mechanism)
+% to execute the file. Then it reads #2.table using \pgfplotxyfile.
+%
+% Example:
+%
+% \pgfplothandlerlineto
+% \pgfplotgnuplot[\jobname]{plot [x=0:5] x*sin(x)}
+
+{%
+ \catcode`\%=12
+ \catcode`\"=12
+ \xdef\pgf@gnuplot@head{set table \noexpand\pgf@plottablefile@quoted; set format "%.5f"}
+}%
+
+\let\pgf@plotwrite=\w@pgf@writea
+\newif\ifpgf@resample@plot
+
+\pgfkeys{%
+ /pgf/plot/gnuplot call/.initial={gnuplot}}%
+
+\def\pgfplotgnuplot{\pgfutil@ifnextchar[{\pgf@plotgnuplot}{\pgf@plotgnuplot[\jobname]}}%}%
+\def\pgf@plotgnuplot[#1]#2{%
+ \pgf@resample@plottrue%
+ \pgfutilpreparefilename{#1.gnuplot}%
+ \let\pgf@plotgnuplotfile=\pgfretval
+ \pgfutilpreparefilename{#1.table}%
+ \let\pgf@plottablefile=\pgfretval
+ \let\pgf@plottablefile@quoted=\pgfretvalquoted
+ % Check, whether it is up-to-date
+ \openin\pgfutil@inputcheck=\pgf@plotgnuplotfile\relax
+ \ifeof\pgfutil@inputcheck%
+ \else%
+ \pgfutil@read\pgfutil@inputcheck to\pgf@temp% ignored
+ \pgfutil@read\pgfutil@inputcheck to\pgf@plot@line%
+ \closein\pgfutil@inputcheck
+ \edef\pgf@plot@code{#2\space}%
+ \ifx\pgf@plot@code\pgf@plot@line%
+ \openin\pgfutil@inputcheck=\pgfretval\relax
+ \ifeof\pgfutil@inputcheck%
+ \else%
+ \closein\pgfutil@inputcheck
+ \pgf@resample@plotfalse%
+ \fi%
+ \fi%
+ \fi
+ \ifpgf@resample@plot%
+ \immediate\openout\pgf@plotwrite=\pgf@plotgnuplotfile\relax
+ \immediate\pgfutil@write\pgf@plotwrite{\pgf@gnuplot@head}%
+ \immediate\pgfutil@write\pgf@plotwrite{#2}%
+ \immediate\closeout\pgf@plotwrite%
+ \pgfutil@shellescape{%
+ \pgfkeysvalueof{/pgf/plot/gnuplot call} \pgf@plotgnuplotfile}%
+ \fi%
+% \let\pgf@savedparsexyline=\pgf@parsexyline%
+% \let\pgf@parsexyline=\pgf@parsegnuplotxyline%
+ \pgfplotxyfile{\pgf@plottablefile}%
+% \let\pgf@parsexyline=\pgf@savedparsexyline%
+}%
+
+% \def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{%
+% \edef\pgf@xyline@flag@val{#3}%
+% \edef\pgf@xyline@flag@out{o\space}%
+% \edef\pgf@xyline@flag@undef{u\space}%
+% \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef%
+% \pgfplotstreampointundefined%
+% \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out%
+% \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}%
+% \else%
+% \pgfplotstreampoint{\pgfpointxy{#1}{#2}}%
+% \fi\fi%
+% }%
+
+% This producer handler plots a function using pgf's mathematical engine.
+%
+% #1 = variable
+% #2 = domain for the variable
+% #3 = point, typically defined in terms of the value of the variable
+%
+% Description:
+%
+% This producer will iterate the variable #1 over all variables in #2
+% (using the \foreach statement). For each value, a plot coordinate
+% #3 is created.
+%
+% Note that this command is pretty slow.
+%
+% Example:
+%
+% \pgfplothandlerlineto
+% \pgfplotfunction{\x}{0,0.1,...,3.141}{\pgfpointxy{\x}{sin(\x)}}
+
+\def\pgfplotfunction#1#2#3{%
+ \pgfplotstreamstart%
+ \foreach#1in{#2}%
+ {%
+ \pgf@process{#3}%
+ \edef\pgf@marshal{\noexpand\pgfplotstreampoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \pgf@marshal%
+ }
+ \pgfplotstreamend%
+}%
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmoduleshapes.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmoduleshapes.code.tex
new file mode 100644
index 0000000000..6be10d1464
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmoduleshapes.code.tex
@@ -0,0 +1,1334 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmoduleshapes.code.tex}
+
+
+
+\newbox\pgfnodeparttextbox
+
+
+% Creates a node
+%
+% #1 = shape type
+% #2 = anchor
+% #3 = name for later reference
+% #4 = path usage command
+%
+% Description:
+%
+% This command draws a shape that has previously been defined using
+% \pgfdeclareshape. The shape is shifted such that the anchor is at
+% the origin. In order to transform the whole shape, you should setup
+% pgf's transformation matrix prior to calling this command.
+%
+% When this command is called, the shape-specific TeX boxes of the
+% node must have been setup correctly.
+%
+% Example:
+%
+% \pgftransformshift{\pgfpoint{1cm}{1cm}}
+% \pgfmultipartnode{rectangle}{center}{hellonode}{\pgfusepath{stroke}}
+
+\def\pgfmultipartnode#1#2#3#4{%
+ \pgfutil@ifundefined{pgf@sh@s@#1}%
+ {\pgferror{Unknown shape ``#1''}}%
+ {%
+ {%
+ \ifpgflatenodepositioning%
+ \pgfsys@beginscope%
+ \fi%
+ \pgf@outer@adjust@hook%
+ \let\pgf@sh@savedmacros=\pgfutil@empty% MW
+ \let\pgf@sh@savedpoints=\pgfutil@empty%
+ \def\pgf@sm@shape@name{#1}% CJ % TT added prefix!
+ \csname pgf@sh@s@#1\endcsname%
+ \pgf@sh@savedpoints%
+ \pgf@sh@savedmacros% MW
+ \pgftransformshift{%
+ \pgf@sh@reanchor{#1}{#2}%
+ \pgf@x=-\pgf@x%
+ \pgf@y=-\pgf@y%
+ }%
+ \expandafter\pgfsavepgf@process\csname pgf@sh@sa@#3\endcsname{%
+ \pgf@sh@reanchor{#1}{#2}% FIXME : this is double work!
+ }%
+ % Save the saved points and the transformation matrix
+ \edef\pgf@node@name{#3}%
+ \ifpgflatenodepositioning%
+ \pgf@shapes@late@pos@begin%
+ \fi%
+ \ifx\pgf@node@name\pgfutil@empty%
+ \else%
+ \expandafter\xdef\csname pgf@sh@ns@\pgf@node@name\endcsname{#1}%
+ \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@np@\pgf@node@name\endcsname}%
+ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedpoints}%
+ \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@ma@\pgf@node@name\endcsname}% MW
+ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW
+ \pgfgettransform\pgf@temp%
+ \expandafter\xdef\csname pgf@sh@nt@\pgf@node@name\endcsname{\pgf@temp}%
+ \expandafter\xdef\csname pgf@sh@pi@\pgf@node@name\endcsname{\pgfpictureid}%
+ \fi%
+ \pgfutil@ifundefined{pgf@sh@bbg@#1}{}
+ {{\pgfusetype{.behind background}\pgfidscope\pgfscope\csname pgf@sh@bbg@#1\endcsname\endpgfscope\endpgfidscope}}%
+ \pgfutil@ifundefined{pgf@sh@bg@#1}{%
+ \global\let\pgfpositionnodelaterpath\pgfutil@empty%
+ }%
+ {\pgfpushtype%
+ \pgfusetype{.background}\csname pgf@sh@bg@#1\endcsname%
+ \ifpgflatenodepositioning%
+ \pgfsyssoftpath@getcurrentpath\pgfpositionnodelaterpath%
+ \pgfprocessround{\pgfpositionnodelaterpath}{\pgfpositionnodelaterpath}%
+ \global\let\pgfpositionnodelaterpath\pgfpositionnodelaterpath%
+ \fi%
+ #4\pgfpoptype}%
+ \pgfutil@ifundefined{pgf@sh@fbg@#1}{}
+ {{\pgfusetype{.before background}\pgfidscope\pgfscope\csname pgf@sh@fbg@#1\endcsname\endpgfscope\endpgfidscope}}%
+ {%
+ \expandafter\pgfutil@for\expandafter\pgf@shape@com\expandafter:\expandafter=\csname pgf@sh@boxes@#1\endcsname\do{%
+ {%
+ \pgfusetype{.\pgf@shape@com}%
+ \pgftransformshift{\pgf@sh@reanchor{#1}{\pgf@shape@com}}%
+ \pgfapproximatenonlineartransformation%
+ \expandafter\pgfqboxsynced\expandafter{\csname pgfnodepart\pgf@shape@com box\endcsname}%
+ }%
+ }%
+ }%
+ \pgfutil@ifundefined{pgf@sh@bfg@#1}{}%
+ {{\pgfusetype{.behind foreground}\pgfidscope\pgfscope\csname pgf@sh@bfg@#1\endcsname\endpgfscope\endpgfidscope}}%
+ \pgfutil@ifundefined{pgf@sh@fg@#1}{}%
+ {\pgfpushtype\pgfusetype{.foreground}\csname pgf@sh@fg@#1\endcsname#4\pgfpoptype}%
+ \pgfutil@ifundefined{pgf@sh@ffg@#1}{}%
+ {{\pgfusetype{.before foreground}\pgfidscope\pgfscope\csname pgf@sh@ffg@#1\endcsname\endpgfscope\endpgfidscope}}%
+ \ifpgflatenodepositioning%
+ \pgf@shapes@late@pos@end%
+ \pgfsys@endscope%
+ \else%
+ \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}%
+ \fi%
+ }%
+ }%
+}%
+\let\pgf@outer@adjust@hook\relax
+
+\def\pgf@shapes@late@pos@begin{%
+ % Rename node
+ \edef\pgf@node@name{not yet positionedPGFINTERNAL\pgf@node@name}%
+ % Interrupt bounding box!
+ \pgfinterruptboundingbox%
+ % Put everything in our box:
+ \pgf@relevantforpicturesizetrue%
+ \setbox\pgfpositionnodelaterbox=\hbox%
+ \bgroup%
+ \pgfsys@beginscope%
+}%
+
+\def\pgf@shapes@late@pos@end{%
+ \pgfsys@endscope%
+ \egroup% Close box
+ \ifdim\pgf@picminx>\pgf@picmaxx\relax% happens for empty nodes
+ \def\pgfpositionnodelaterminx{0.0pt}%
+ \let\pgfpositionnodelaterminy\pgfpositionnodelaterminx%
+ \let\pgfpositionnodelatermaxx\pgfpositionnodelaterminx%
+ \let\pgfpositionnodelatermaxy\pgfpositionnodelaterminx%
+ \else%
+ \edef\pgfpositionnodelaterminx{\the\pgf@picminx}%
+ \edef\pgfpositionnodelaterminy{\the\pgf@picminy}%
+ \edef\pgfpositionnodelatermaxx{\the\pgf@picmaxx}%
+ \edef\pgfpositionnodelatermaxy{\the\pgf@picmaxy}%
+ \fi%
+ \let\pgfpositionnodelatername=\pgf@node@name%
+ \pgf@positionnodelater@macro%
+ \endpgfinterruptboundingbox%
+}%
+
+\def\pgf@shift@node#1#2{%
+ % This internal command shifts the recorded coordinates for node #1
+ % by the vector #2. It is used to
+ % correct the position of the node if the recorded coordinate
+ % happens to be wrong
+ {%
+ \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
+ \pgf@process{#2}%
+ \advance\pgf@pt@x by\pgf@x%
+ \advance\pgf@pt@y by\pgf@y%
+ \pgfgettransform{\pgf@temp}%
+ \expandafter\xdef\csname pgf@sh@nt@#1\endcsname{\pgf@temp}%
+ }%
+}%
+
+
+
+% Creates a node
+%
+% #1 = shape type
+% #2 = anchor
+% #3 = normal TeX text
+% #4 = name for later reference
+% #5 = path usage command
+%
+% Description:
+%
+% This command draws a shape that has previously been defined using
+% \pgfdeclareshape. The shape is shifted such that the anchor is at
+% the origin. In order to transform the whole shape, you should setup
+% pgf's transformation matrix prior to calling this command.
+%
+% Example:
+%
+% \pgftransformshift{\pgfpoint{1cm}{1cm}}
+% \pgfnode{rectangle}{center}{Hello}{hellonode}{\pgfusepath{stroke}}
+
+\def\pgfnode#1#2#3#4#5{%
+ {%
+ \setbox\pgfnodeparttextbox=\hbox%
+ {%
+ \pgfinterruptpicture%
+ {#3}%
+ \endpgfinterruptpicture%
+ }%
+ \pgfmultipartnode{#1}{#2}{#4}{#5}%
+ }
+}%
+
+
+
+% Create a node that is positioned later
+%
+% #1 = macro to be called after the next node has been created
+%
+% Description:
+%
+% You can use this command to create a node that is "positioned
+% later". The idea is the following: Normally, when a node is created
+% using a command like \pgfnode, the node is immediately inserted into
+% the current picture. In particular, you have no chance to change the
+% position of a created node after it has been create.
+%
+% Using \pgfpositionnodelater, you can change the default
+% behaviour. This command is not a replacement for \pgfnode, but is
+% called before such a command and will cause the following to happen:
+% The node is created, but not inserted into the picture. Instead, it
+% is stored in the box \pgfpositionnodelaterbox. Furthermore, the node
+% is not relevant for the picture's bounding box, but a bounding box
+% for the node is computed and stored in the macros
+% \pgfpositionnodelaterboundboxminx to
+% \pgfpositionnodelaterboundboxmaxy. Finally, the
+% macro #1 is called with the following macros setup:
+%
+% \pgfpositionnodelaterbox
+% A box register (box 0 by default) that stores the node's paths and
+% texts. You should move the contents of this box to a box of your
+% choice.
+%
+% \pgfpositionnodelatername
+% The name of the just-created-node. This name will be the
+% originally "desired" name of the box plus the prefix "not yet
+% positioned boxPGFINTERNAL".
+%
+% \pgfpositionnodelaterminx
+% \pgfpositionnodelatermaxx
+% \pgfpositionnodelaterminy
+% \pgfpositionnodelatermaxy
+% These four macros store the bounding box as dimensions that are
+% guarenteed to end with "pt".
+%
+% By setting #1 to \relax (which is the default), you can switch off
+% the whole mechanism
+%
+% Once a late node has been created, you can add arbitrary code in the
+% same picture. Then, at some later point, you call
+% \pgfpositionnodenow to finally position the node at a given position.
+%
+% When \pgfpositionnodenow is called, the macros mentioned above
+% should have the exact same values they had when #1 is called.
+
+\def\pgfpositionnodelater#1{%
+ \let\pgf@positionnodelater@macro=#1%
+ \ifx\pgf@positionnodelater@macro\relax%
+ \pgflatenodepositioningfalse%
+ \else%
+ \pgflatenodepositioningtrue%
+ \fi%
+}%
+\newif\ifpgflatenodepositioning
+\pgfpositionnodelater{\relax}%
+\def\pgfpositionnodelaterbox{0}%
+
+
+
+
+% Position a node that has been scheduled for later insertion
+%
+% #1 = position in the picture, where the original anchor should go,
+% now
+%
+% Description:
+%
+% This command works in concert with \pgfpositionnodelater, see the
+% description there. When \pgfpositionnodenow is called, the macros
+% \pgfpositionnodelaterbox and so on should be set to the values they
+% had when the macro given to \pgfpositionnodelater was called. Then,
+% the box described by these macros will be inserted into the picture
+% at the position given #1. More precisely, the original node will
+% have been positioned such that the anchor given upon invocation is
+% at (0,0) and the node is now shifted by #1 before being inserted
+% into the actual picture.
+
+\def\pgfpositionnodenow#1{%
+ \pgfinterruptpath%
+ {%
+ \pgfpointtransformed{#1}%
+ \edef\pgf@temp@shift{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}
+ \pgftransformreset%
+ \pgftransformshift{\pgf@temp@shift}%
+ \pgfsys@pictureboxsynced\pgfpositionnodelaterbox%
+ \pgf@shift@node{\pgfpositionnodelatername}{\pgf@temp@shift}%
+ % Bounding box update...
+ \pgfpointtransformed{\pgfqpoint{\pgfpositionnodelaterminx}{\pgfpositionnodelaterminy}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}
+ \pgfpointtransformed{\pgfqpoint{\pgfpositionnodelatermaxx}{\pgfpositionnodelatermaxy}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}
+ % Naming and callbacks
+ \expandafter\pgfpositionnodenow@rename\pgfpositionnodelatername\relax%
+ }%
+ % Late setup%
+ {%
+ \csname pgf@lns@\pgfpositionnodelatername\endcsname%
+ \expandafter\global\expandafter\let\csname pgf@lns@\pgfpositionnodelatername\endcsname\relax%
+ }%
+ \endpgfinterruptpath%
+}%
+
+\def\pgfpositionnodenow@rename not yet positionedPGFINTERNAL#1\relax{%
+ \pgfnoderename{#1}{not yet positionedPGFINTERNAL#1}
+}%
+
+
+
+% "Fake" a node
+%
+% #1 = node name
+%
+% Description:
+%
+% This command will setup things so that it "looks like" a node named
+% #1 has been created, but, in reality, no node is created. The idea
+% is that a node created in this way can be referenced by systems
+% using the late positioning, which will only create the node later
+% on.
+%
+\def\pgffakenode#1{%
+ \edef\pgf@temp{\ifpgflatenodepositioning not yet positionedPGFINTERNAL\fi#1}%
+ \expandafter\gdef\csname pgf@sh@ns@\pgf@temp\endcsname{coordinate}%
+ \expandafter\gdef\csname pgf@sh@np@\pgf@temp\endcsname{\def\centerpoint{\pgfpointorigin}}%
+ \expandafter\gdef\csname pgf@sh@nt@\pgf@temp\endcsname{{1}{0}{0}{1}{0pt}{0pt}}%
+ \expandafter\global\expandafter\let\csname pgf@sh@ma@\pgf@temp\endcsname\pgfutil@empty%
+ \expandafter\xdef\csname pgf@sh@pi@\pgf@temp\endcsname{\pgfpictureid}%
+}%
+
+
+
+% Specify code that should be executed after a node has been created
+%
+% #1 = node name
+% #2 = later code
+%
+% Description:
+%
+% This macro allows you to provide some code #2 that will be executed
+% right after a node has been positioned using \pgfpositionnodenow. If
+% the node has already been positioned (if the late positioning is not
+% switched on), nothing happens.
+
+\def\pgfnodepostsetupcode#1#2{%
+ \ifpgflatenodepositioning%
+ \expandafter\ifx\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname\relax%
+ \expandafter\gdef\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}%
+ \else%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}%
+ \fi%
+ \fi%
+}%
+
+
+
+% Alias a node
+%
+% #1 = new node name
+% #2 = existing node name
+%
+% Description:
+%
+% This command allows you to subsequently access the node #2 using the
+% name #1.
+%
+% Example:
+%
+% \pgfnode{rectangle}{center}{Hallo}{hellonode}{}
+% \pgfnodealias{mynode}{hellonode}
+
+\def\pgfnodealias#1#2{%
+ \pgf@node@gnamelet{pgf@sh@ns@#1}{pgf@sh@ns@#2}%
+ \pgf@node@gnamelet{pgf@sh@np@#1}{pgf@sh@np@#2}%
+ \pgf@node@gnamelet{pgf@sh@nt@#1}{pgf@sh@nt@#2}%
+ \pgf@node@gnamelet{pgf@sh@pi@#1}{pgf@sh@pi@#2}%
+ \pgf@node@gnamelet{pgf@sh@ma@#1}{pgf@sh@ma@#2}%
+ \pgf@nodecallback{#1}%
+}%
+\def\pgf@node@gnamelet#1#2{%
+ \expandafter\let\expandafter\pgf@temp\csname #2\endcsname%
+ \expandafter\global\expandafter\let\csname #1\endcsname=\pgf@temp%
+}%
+
+% Rename a node
+%
+% #1 = new name
+% #2 = old name
+%
+% Description:
+%
+% Renames a node. This is like an alias, only the memory used for the
+% old name is freed.
+
+\def\pgfnoderename#1#2{%
+ \pgfnodealias{#1}{#2}%
+ \expandafter\global\expandafter\let\csname pgf@sh@ns@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@np@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@nt@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@pi@#2\endcsname\relax
+ \expandafter\global\expandafter\let\csname pgf@sh@ma@#2\endcsname\relax
+}%
+
+
+
+
+% Quickly create a coordinate node
+%
+% #1 = name
+% #2 = coordinate
+%
+% Description:
+%
+% Creates a node of shape coordinate. The following have the same
+% effect, only the second is much faster:
+%
+% { \pgftransformshift{\pgfpoint{1cm}{2cm} \pgfnode{coordinate}{center}{}{foo}{} }
+% \pgfcoordinate{foo}{\pgfpoint{1cm}{2cm}}
+
+\def\pgfcoordinate#1#2{%
+ \edef\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty% do nothing
+ \else%
+ \ifpgflatenodepositioning%
+ {\pgftransformshift{#2}\pgfnode{coordinate}{center}{}{#1}{}}%
+ \else%
+ \pgf@process{\pgfpointtransformed{#2}}%
+ \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}%
+ \expandafter\xdef\csname pgf@sh@np@#1\endcsname{%
+ \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ }
+ \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}%
+ \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty%
+ \expandafter\xdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}%
+ \fi%
+ \fi%
+}%
+
+\def\pgf@sh@redeferredanchor#1#2{% CJ
+ \expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}}% CJ
+
+
+
+
+
+
+\def\pgf@sh@resavedanchor#1#2{%
+ \pgf@process{#2}%
+ \edef\pgf@sh@marshal{%
+ \noexpand\pgfutil@g@addto@macro\noexpand\pgf@sh@savedpoints{%
+ \noexpand\def\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ }}%
+ \pgf@sh@marshal%
+}%
+
+
+\def\pgf@sh@resaveddimen#1#2{%
+ {#2\global\pgf@x=\pgf@x}%
+ \edef\pgf@sh@marshal{%
+ \noexpand\pgfutil@g@addto@macro\noexpand\pgf@sh@savedpoints{%
+ \noexpand\def\noexpand#1{\the\pgf@x}%
+ }}%
+ \pgf@sh@marshal%
+}%
+
+\def\pgf@sh@resavedmacro#1#2{%
+ \let#1\pgfutil@empty%
+ \def\addtosavedmacro##1{%
+ \expandafter\def\expandafter\pgf@sh@addtomacro@temp\expandafter{#1\noexpand\def\noexpand##1{##1}}%
+ {\expandafter\pgfutil@toks@\expandafter{\pgf@sh@addtomacro@temp}\expandafter}%
+ \expandafter\def\expandafter#1\expandafter{\the\pgfutil@toks@}%
+ }%
+ #2\relax%
+ \edef\pgf@sh@marshal{%
+ \noexpand\pgfutil@g@addto@macro\noexpand\pgf@sh@savedmacros{%
+ \noexpand\def\noexpand#1{#1}%
+ }}%
+ \pgf@sh@marshal%
+}%
+
+% Invoke an anchor
+\def\pgf@sh@reanchor#1#2{%
+ \pgfutil@ifundefined{pgf@anchor@#1@#2}%
+ {%
+ \pgfutil@ifundefined{pgf@anchor@generic@#2}{%
+ \pgfmathsetcounter{pgf@counta}{#2}%
+ \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\the\c@pgf@counta}{1pt}}%
+ }{%
+ \csname pgf@anchor@generic@#2\endcsname{#1}%
+ }%
+ }%
+ {\csname pgf@anchor@#1@#2\endcsname}%
+}%
+
+% Defines a generic anchor, i.e. one which gets the associated shape
+% as first argument.
+%
+% #1: the anchor name.
+% #2: the code of the anchor. It may depend upon '##1', the shape's
+% name.
+%
+% The anchor will be defined locally in the current TeX scope.
+%
+% If the anchor will be referenced later by \pgfpointanchor, the macro \pgfreferencednodename
+% can be used to query the referenced node's name.
+% This macro is not defined during node creation.
+\def\pgfdeclaregenericanchor#1#2{%
+ \expandafter\def\csname pgf@anchor@generic@#1\endcsname##1{#2}%
+}%
+
+
+% Retrieves an anchor of a shape
+%
+% #1 = name
+% #2 = anchor or a number (corresponding to a degree)
+%
+% Description:
+%
+% This command yields a point at the anchor of the given named shape.
+%
+% Example:
+%
+% \pgfshape{rectangle}{center}{Hello}{hellonode}{\pgfusepath[stroke]}
+% \pgfpathmoveto{\pgfpointanchor{hellonode}{center}}
+
+\def\pgfpointanchor#1#2{%
+ % Ok, check whether #1 is known!
+ \pgfutil@ifundefined{pgf@sh@ns@#1}
+ {\pgfutil@ifundefined{pgf@sh@ns@not yet positionedPGFINTERNAL#1}{%
+ \pgferror{No shape named `#1' is known}}{
+ % else, fail silently
+ }%
+ \pgfpointorigin}%
+ {%
+ \pgf@process{%
+ \edef\pgfreferencednodename{#1}% for use inside of anchors.
+ % MW install special macros
+ \csname pgf@sh@ma@#1\endcsname% MW
+ % install special coordinates
+ \csname pgf@sh@np@#1\endcsname
+ \pgf@sh@reanchor{\csname pgf@sh@ns@#1\endcsname}{#2}%
+ {%
+ \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
+ \pgf@pos@transform@glob%
+ }%
+ % Add inter picture transformation
+ \pgf@shape@interpictureshift{#1}%
+ % Undo current transformation
+ \pgftransforminvert%
+ \pgf@pos@transform@glob%
+ }%
+ }%
+}%
+
+\def\pgf@shape@interpictureshift#1{%
+ \expandafter\ifx\csname pgf@sh@pi@#1\endcsname\pgfpictureid%
+ \else%
+ \pgfsys@getposition{\csname pgf@sh@pi@#1\endcsname}\pgf@shape@original@pos%
+ \pgfsys@getposition{\pgfpictureid}\pgf@shape@current@pos%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointorigin\pgf@shape@current@pos}%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \pgf@process{\pgfpointorigin\pgf@shape@original@pos}%
+ \advance\pgf@xa by\pgf@x%
+ \advance\pgf@ya by\pgf@y%
+ \pgf@x=\pgf@xa%
+ \pgf@y=\pgf@ya%
+ \fi%
+}%
+
+
+
+% Retrieves a border point of a shape
+%
+% #1 = name
+% #2 = another point
+%
+% Description:
+%
+% This command yields a point on the border of the shape that is on a
+% straight line from the center to the point #2.
+%
+% Example:
+%
+% \pgfshape{rectangle}{center}{Hello}{hellonode}{\pgfusepath[stroke]}
+% \pgfpathmoveto{\pgfpointshapeborder{hellonode}{\pgfpoint{2cm}{1cm}}
+% \pgfpathlineto{\pgfpoint{2cm}{1cm}}
+% \pgfusepath{stroke}
+
+\def\pgfpointshapeborder#1#2{%
+ % Ok, check whether #1 is known!
+ \pgfutil@ifundefined{pgf@sh@ns@#1}
+ {\pgferror{No shape named `#1' is known}%
+ \pgfpointorigin}%
+ {%
+ \pgf@process{%
+ \edef\pgfreferencednodename{#1}% for use inside of anchors.
+ % MW install special macros
+ \csname pgf@sh@ma@#1\endcsname% MW
+ % install special coordinates
+ \csname pgf@sh@np@#1\endcsname%
+ {%
+ \pgf@process{\pgfpointtransformed{#2}}%
+ \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
+ \pgftransforminvert%
+ \pgf@pos@transform@glob%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\csname pgf@anchor@\csname pgf@sh@ns@#1\endcsname @center\endcsname}%
+ \pgf@process{\pgf@shape@interpictureshift{#1}}%%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ % Now (\pgf@xa, \pgf@ya) is a coord in shape's coord system, and
+ % relative to the anchor "center". If (xa, ya) is almost identical to
+ % the node center, which is determined by sqrt(xa^2+ya^2) < 0.02pt,
+ % just return the node center.
+ %
+ % \pgf@xb = 10*\pgf@xa if -1pt<\pgf@xa<1pt else 10pt
+ % - "10*\pgf@xa": reduce ruonding errors when \pgf@xa is small
+ % - "-1pt<\pgf@xa<1pt": guard against error "Dimension too large"
+ \pgf@xb=10pt
+ \ifdim\pgf@xa<1pt\ifdim\pgf@xa>-1pt
+ \pgf@xb=10\pgf@xa
+ \fi\fi
+ % \pgf@yb = 10*\pgf@ya if -1pt<\pgf@ya<1pt else 10pt
+ \pgf@yb=10pt
+ \ifdim\pgf@ya<1pt\ifdim\pgf@ya>-1pt
+ \pgf@yb=10\pgf@ya
+ \fi\fi
+ % if xb^2+yb^2 < 0.04pt, which means sqrt(xa^2+ya^2) < 0.02pt,
+ % return node center
+ \ifdim\dimexpr\expandafter\Pgf@geT\the\pgf@xb\pgf@xb
+ +\expandafter\Pgf@geT\the\pgf@yb\pgf@yb\relax<0.04pt
+ \expandafter\pgfutil@firstoftwo
+ \else
+ \expandafter\pgfutil@secondoftwo
+ \fi
+ {% return coord of "center"
+ \pgfwarning
+ {Returning node center instead of a point on node border. Did you
+ specify a point identical to the center of node
+ ``\pgfreferencednodename''?}%
+ \pgf@sh@reanchor{\csname pgf@sh@ns@#1\endcsname}{center}%
+ }
+ {% this calls the corresponding \anchorborder in shape declaration
+ \csname pgf@anchor@\csname pgf@sh@ns@#1\endcsname @border\endcsname
+ {\pgfqpoint{\pgf@xa}{\pgf@ya}}%
+ }%
+ \pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
+ \pgf@pos@transform@glob%
+ \global\pgf@x=\pgf@x%
+ \global\pgf@y=\pgf@y%
+ }%
+ % Add inter picture transformation
+ \pgf@shape@interpictureshift{#1}%
+ % Undo current transformation
+ \pgftransforminvert%
+ \pgf@pos@transform@glob%
+ }%
+ }%
+}%
+
+
+% Retrieve the list of node parts of a shape
+%
+% #1 = a macro
+% #2 = a shape name
+%
+% Description:
+%
+% Stores the list of node parts of a shape #2 in the macro #1.
+%
+% Example:
+%
+% \pgfgetnodeparts\mylist{circle split}
+%
+% This will set \mylist\ to "text,lower"
+
+\def\pgfgetnodeparts#1#2{%
+ \expandafter\let\expandafter#1\csname pgf@sh@boxes@#2\endcsname%
+}%
+
+
+% Declares a shape type
+%
+% #1 = shape type
+% #2 = shape specification
+%
+% Description:
+%
+% This command declares a new shape type. The shape specification
+% should contain the following commands:
+%
+% - \savedanchor
+% This command takes two arguments: a name and some code. The point
+% specified by the code (the \pgf@x and \pgf@y values resulting from
+% executing the code, to be precise), will be stored under the given
+% name. Whenever, later on, an anchor is invoked these stored points
+% will be available. The \saveddimen works like \savedanchor, only a
+% single dimension is stored (taken from \pgf@x).
+% When a savedanchor is calculated, the height/width/depth of the
+% boxes mentioned in \nodeparts can be used.
+%
+% - \anchor
+% Specifies an anchor. This command takes two arguments: an anchor
+% name and some code for computing the anchor. When the anchor
+% computation starts, all shape points and shape dimension will be
+% setup.
+%
+% - \anchorborder
+% This command should compute a point on the border of the
+% shape. When the code is called, \pgf@x and \pgf@y will have been
+% preinitialised with a direction.
+%
+% - \behindbackgroundpath
+% Some things to be draw behind everything.
+%
+% - \backgroundpath
+% A path that is drawn behind the main box. How this path is used
+% depends on how \pgfshape is called.
+%
+% - \beforebackgroundpath
+% Some things to be draw before the background path, but behind the
+% main box.
+%
+% - \behindforegroundpath
+% Some things to be draw on top of the main box.
+%
+% - \foregroundpath
+% A path that is drawn on top of all of the above. How this path is
+% used depends on how \pgfshape is called.
+%
+% - \beforeforegroundpath
+% Some things to be draw before everything.
+%
+% - \nodeparts
+% List of node parts that make up the shape. For each entry XYZ in
+% the list there must be a box named \pgfnodepartXYZbox (possibly
+% ``redirected'' to some different box using \let). Each such box
+% will be placed at the anchor XYZ.
+% By default, \nodeparts is just {text}. Thus, there will be one
+% node part box named \pgfnodeparttextbox and this node will be
+% placed at the anchor text.
+%
+%
+% Example:
+%
+% See the definition of rectangle, below.
+
+\long\def\pgfdeclareshape#1#2{%
+ {%
+ \def\pgf@sm@shape@name{#1}%
+ \let\savedanchor=\pgf@sh@savedanchor
+ \let\saveddimen=\pgf@sh@saveddimen
+ \let\savedmacro=\pgf@sh@savedmacro% MW
+ \let\deferredanchor=\pgf@sh@deferredanchor% CJ
+ \let\anchor=\pgf@sh@anchor
+ \let\anchorborder=\pgf@sh@anchorborder
+ \let\behindbackgroundpath=\pgf@sh@behindbgpath
+ \let\backgroundpath=\pgf@sh@bgpath
+ \let\beforebackgroundpath=\pgf@sh@beforebgpath
+ \let\behindforegroundpath=\pgf@sh@behindfgpath
+ \let\foregroundpath=\pgf@sh@fgpath
+ \let\beforeforegroundpath=\pgf@sh@beforefgpath
+ \let\nodeparts=\pgf@sh@boxes
+ \let\inheritsavedanchors=\pgf@sh@inheritsavedanchors
+ \let\inheritanchor=\pgf@sh@inheritanchor
+ \let\inheritanchorborder=\pgf@sh@inheritanchorborder
+ \let\inheritbehindbackgroundpath=\pgf@sh@inheritbehindbgpath
+ \let\inheritbackgroundpath=\pgf@sh@inheritbgpath
+ \let\inheritbeforebackgroundpath=\pgf@sh@inheritbeforebgpath
+ \let\inheritbehindforegroundpath=\pgf@sh@inheritbehindfgpath
+ \let\inheritforegroundpath=\pgf@sh@inheritfgpath
+ \let\inheritbeforeforegroundpath=\pgf@sh@inheritbeforefgpath
+ \let\inheritnodeparts=\pgf@sh@inheritboxes
+ \anchorborder{\csname pgf@anchor@#1@center\endcsname}%
+ \anchor{text}{\pgfpointorigin}%
+ \nodeparts{text}%
+ \expandafter\global\expandafter\let\csname pgf@sh@s@\pgf@sm@shape@name\endcsname=\pgfutil@empty%
+ #2%
+ }%
+}%
+
+\def\pgf@sh@savedanchor#1#2{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}}%
+\def\pgf@sh@saveddimen#1#2{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}}%
+ \def\pgf@sh@savedmacro#1#2{% MW
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW
+\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}}%
+\def\pgf@sh@deferredanchor#1#2{% CJ
+ \expandafter\pgfutil@g@addto@macro
+ \csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@redeferredanchor{#1}{#2}}}% CJ
+\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @border\endcsname##1{\pgf@process{##1}#1}}%
+\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\pgf@sm@shape@name\endcsname{#1}}%
+\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\pgf@sm@shape@name\endcsname{#1}}%
+\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\pgf@sm@shape@name\endcsname{#1}}%
+\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\pgf@sm@shape@name\endcsname{#1}}%
+\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\pgf@sm@shape@name\endcsname{#1}}%
+\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sh@ffg@\pgf@sm@shape@name\endcsname{#1}}%
+\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\pgf@sm@shape@name\endcsname{#1}}%
+
+\def\pgf@sh@inheritsavedanchors[from=#1]{%
+ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}}%
+
+\def\pgf@sh@inheritanchor[from=#1]#2{%
+ \edef\pgf@marshal{\global\let\expandafter\noexpand\csname
+ pgf@anchor@\pgf@sm@shape@name @#2\endcsname=\expandafter\noexpand\csname
+ pgf@anchor@#1@#2\endcsname}%
+ \pgf@marshal%
+}%
+\def\pgf@sh@inheritanchorborder[from=#1]{%
+ \edef\pgf@marshal{\global\let\expandafter\noexpand\csname
+ pgf@anchor@\pgf@sm@shape@name @border\endcsname=\expandafter\noexpand\csname
+ pgf@anchor@#1@border\endcsname}%
+ \pgf@marshal%
+}%
+\def\pgf@sh@inheritor#1#2{%
+ \edef\pgf@marshal{\global\let\expandafter\noexpand\csname
+ pgf@sh@#1@\pgf@sm@shape@name\endcsname=\expandafter\noexpand\csname
+ pgf@sh@#1@#2\endcsname}%
+ \pgf@marshal%
+}%
+\def\pgf@sh@inheritbehindbgpath[from=#1]{\pgf@sh@inheritor{bbg}{#1}}%
+\def\pgf@sh@inheritbgpath[from=#1]{\pgf@sh@inheritor{bg}{#1}}%
+\def\pgf@sh@inheritbeforebgpath[from=#1]{\pgf@sh@inheritor{fbg}{#1}}%
+\def\pgf@sh@inheritbehindfgpath[from=#1]{\pgf@sh@inheritor{bfg}{#1}}%
+\def\pgf@sh@inheritfgpath[from=#1]{\pgf@sh@inheritor{fg}{#1}}%
+\def\pgf@sh@inheritbeforefgpath[from=#1]{\pgf@sh@inheritor{ffg}{#1}}%
+\def\pgf@sh@inheritboxes[from=#1]{\pgf@sh@inheritor{boxes}{#1}}%
+
+
+
+%
+% Coordinate. This shape is special: It is only used to reference a
+% point for later usage. Nothing is drawn, all anchors are identical
+% to the center.
+%
+
+\pgfdeclareshape{coordinate}
+{%
+ \savedanchor\centerpoint{%
+ % x
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ % y
+ \pgf@y=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by -.5\dp\pgfnodeparttextbox%
+ }%
+
+ \anchor{center}{\centerpoint}%
+ \anchor{north}{\centerpoint}%
+ \anchor{north west}{\centerpoint}%
+ \anchor{north east}{\centerpoint}%
+ \anchor{west}{\centerpoint}%
+ \anchor{east}{\centerpoint}%
+ \anchor{mid}{\centerpoint}%
+ \anchor{mid west}{\centerpoint}%
+ \anchor{mid east}{\centerpoint}%
+ \anchor{base}{\centerpoint}%
+ \anchor{base west}{\centerpoint}%
+ \anchor{base east}{\centerpoint}%
+ \anchor{south}{\centerpoint}%
+ \anchor{south west}{\centerpoint}%
+ \anchor{south east}{\centerpoint}%
+ \anchorborder{\centerpoint}%
+
+ \nodeparts{}% no text
+}%
+
+
+% Value keys for shapes:
+%
+% /pgf/inner xsep : recommended inner x separation
+% /pgf/inner ysep : recommended inner y separation
+% /pgf/outer xsep : recommended outer x separation
+% /pgf/outer ysep : recommended outer y separation
+% /pgf/minimum width : recommended minimum width
+% /pgf/minimum height : recommended minimum height
+
+\pgfset{
+ inner xsep/.initial =.3333em,
+ inner ysep/.initial =.3333em,
+ inner sep/.style ={/pgf/inner xsep={#1},/pgf/inner ysep={#1}},
+ outer xsep/.initial =.5\pgflinewidth,
+ outer ysep/.initial =.5\pgflinewidth,
+ outer sep/.code =\pgf@handle@outer@sep{#1},
+ minimum width/.initial =1pt,
+ minimum height/.initial =1pt,
+ minimum size/.style ={/pgf/minimum width={#1},/pgf/minimum height={#1}},
+}%
+
+
+
+\def\pgf@handle@outer@sep#1{%
+ \def\pgf@temp{#1}%
+ \ifx\pgf@temp\pgf@auto@text%
+ \def\pgf@outer@adjust@hook{%
+ \pgftransformationadjustments%
+ \pgfkeyssetvalue{/pgf/outer xsep}{.5\pgflinewidth*\pgfhorizontaltransformationadjustment}%
+ \pgfkeyssetvalue{/pgf/outer ysep}{.5\pgflinewidth*\pgfverticaltransformationadjustment}%
+ \pgf@outer@auto@adjust@hook%
+ }%
+ \else%
+ \pgfkeyssetvalue{/pgf/outer xsep}{#1}%
+ \pgfkeyssetvalue{/pgf/outer ysep}{#1}%
+ \fi%
+}%
+\def\pgf@auto@text{auto}%
+
+\let\pgf@outer@auto@adjust@hook\relax
+
+
+% Keys for rotating the shape border.
+% (may not be supported by all shapes)
+%
+% /pgf/shape border uses incircle : Calculate the shape border using the incircle
+% around the node contents (+inner sep).
+%
+% /pgf/shape border rotate : Angle of independent border rotation.
+
+\newif\ifpgfshapeborderusesincircle
+\pgfkeys{/pgf/shape border uses incircle/.is if=pgfshapeborderusesincircle}%
+\pgfkeys{/pgf/shape border rotate/.initial=0}%
+
+%
+% Rectangle
+%
+
+\pgfdeclareshape{rectangle}
+{%
+ \savedanchor\northeast{%
+ % Calculate x
+ %
+ % First, is width < minimum width?
+ \pgf@x=\the\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x by 2\pgf@xc%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<\pgf@xb%
+ % yes, too small. Enlarge...
+ \pgf@x=\pgf@xb%
+ \fi%
+ % Now, calculate right border: .5\wd\pgfnodeparttextbox + .5 \pgf@x + outer sep
+ \pgf@x=.5\pgf@x%
+ \advance\pgf@x by.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \advance\pgf@x by\pgf@xa%
+ % Calculate y
+ %
+ % First, is height+depth < minimum height?
+ \pgf@y=\ht\pgfnodeparttextbox%
+ \advance\pgf@y by\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y by 2\pgf@yc%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<\pgf@yb%
+ % yes, too small. Enlarge...
+ \pgf@y=\pgf@yb%
+ \fi%
+ % Now, calculate upper border: .5\ht-.5\dp + .5 \pgf@y + outer sep
+ \pgf@y=.5\pgf@y%
+ \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
+ \advance\pgf@y by.5\ht\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \advance\pgf@y by\pgf@ya%
+ }%
+
+ \savedanchor\southwest{%
+ % Calculate x
+ %
+ % First, is width < minimum width?
+ \pgf@x=\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x by 2\pgf@xc%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<\pgf@xb%
+ % yes, too small. Enlarge...
+ \pgf@x=\pgf@xb%
+ \fi%
+ % Now, calculate left border: .5\wd\pgfnodeparttextbox - .5 \pgf@x - outer sep
+ \pgf@x=-.5\pgf@x%
+ \advance\pgf@x by.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \advance\pgf@x by-\pgf@xa%
+ % Calculate y
+ %
+ % First, is height+depth < minimum height?
+ \pgf@y=\ht\pgfnodeparttextbox%
+ \advance\pgf@y by\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y by 2\pgf@yc%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<\pgf@yb%
+ % yes, too small. Enlarge...
+ \pgf@y=\pgf@yb%
+ \fi%
+ % Now, calculate upper border: .5\ht-.5\dp - .5 \pgf@y - outer sep
+ \pgf@y=-.5\pgf@y%
+ \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
+ \advance\pgf@y by.5\ht\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \advance\pgf@y by-\pgf@ya%
+ }%
+
+ %
+ % Anchors
+ %
+ \anchor{center}{
+ \pgf@process{\northeast}%
+ \pgf@xa=.5\pgf@x%
+ \pgf@ya=.5\pgf@y%
+ \pgf@process{\southwest}%
+ \pgf@x=.5\pgf@x%
+ \pgf@y=.5\pgf@y%
+ \advance\pgf@x by \pgf@xa%
+ \advance\pgf@y by \pgf@ya%
+ }%
+ \anchor{mid}{\pgf@anchor@rectangle@center\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{base}{\pgf@anchor@rectangle@center\pgf@y=0pt}%
+ \anchor{north}{
+ \pgf@process{\southwest}%
+ \pgf@xa=.5\pgf@x%
+ \pgf@process{\northeast}%
+ \pgf@x=.5\pgf@x%
+ \advance\pgf@x by \pgf@xa%
+ }%
+ \anchor{south}{
+ \pgf@process{\northeast}%
+ \pgf@xa=.5\pgf@x%
+ \pgf@process{\southwest}%
+ \pgf@x=.5\pgf@x%
+ \advance\pgf@x by \pgf@xa%
+ }%
+ \anchor{west}{
+ \pgf@process{\northeast}%
+ \pgf@ya=.5\pgf@y%
+ \pgf@process{\southwest}%
+ \pgf@y=.5\pgf@y%
+ \advance\pgf@y by \pgf@ya%
+ }%
+ \anchor{mid west}{\southwest\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{base west}{\southwest\pgf@y=0pt}%
+ \anchor{north west}{
+ \southwest
+ \pgf@xa=\pgf@x
+ \northeast
+ \pgf@x=\pgf@xa}%
+ \anchor{south west}{\southwest}%
+ \anchor{east}{%
+ \pgf@process{\southwest}%
+ \pgf@ya=.5\pgf@y%
+ \pgf@process{\northeast}%
+ \pgf@y=.5\pgf@y%
+ \advance\pgf@y by \pgf@ya%
+ }%
+ \anchor{mid east}{\northeast\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{base east}{\northeast\pgf@y=0pt}%
+ \anchor{north east}{\northeast}%
+ \anchor{south east}{
+ \northeast
+ \pgf@xa=\pgf@x
+ \southwest
+ \pgf@x=\pgf@xa
+ }%
+ \anchorborder{%
+ \pgf@xb=\pgf@x% xb/yb is target
+ \pgf@yb=\pgf@y%
+ \southwest%
+ \pgf@xa=\pgf@x% xa/ya is se
+ \pgf@ya=\pgf@y%
+ \northeast%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \pgf@xc=.5\pgf@x% x/y is half width/height
+ \pgf@yc=.5\pgf@y%
+ \advance\pgf@xa by\pgf@xc% xa/ya becomes center
+ \advance\pgf@ya by\pgf@yc%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpointborderrectangle
+ {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}
+ {\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
+ }%
+ \pgf@process{\pgf@marshal}%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ }%
+
+ %
+ % Background path
+ %
+ \backgroundpath{
+ \pgfpathrectanglecorners
+ {\pgfpointadd{\southwest}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}
+ {\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfkeysvalueof{/pgf/outer xsep}}{\pgfkeysvalueof{/pgf/outer ysep}}}}}
+ }%
+}%
+
+
+% Special current path start coordinate:
+\expandafter\def\csname pgf@sh@ns@current subpath start\endcsname{coordinate}%
+\expandafter\def\csname pgf@sh@np@current subpath start\endcsname{%
+ \def\centerpoint{\expandafter\pgfqpoint\pgfsyssoftpath@lastmoveto}%
+}%
+\expandafter\def\csname pgf@sh@nt@current subpath start\endcsname{{1}{0}{0}{1}{0pt}{0pt}}%
+\expandafter\def\csname pgf@sh@pi@current subpath start\endcsname{\pgfpictureid}%
+
+
+
+% Special current bounding box rectangle:
+\expandafter\def\csname pgf@sh@ns@current bounding box\endcsname{rectangle}%
+\expandafter\def\csname pgf@sh@np@current bounding box\endcsname{%
+ \def\southwest{\pgfqpoint{\pgf@picminx}{\pgf@picminy}}%
+ \def\northeast{\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}%
+}%
+\expandafter\def\csname pgf@sh@nt@current bounding box\endcsname{{1}{0}{0}{1}{0pt}{0pt}}%
+\expandafter\def\csname pgf@sh@pi@current bounding box\endcsname{\pgfpictureid}%
+
+
+% Special current path bounding box rectangle:
+\expandafter\def\csname pgf@sh@ns@current path bounding box\endcsname{rectangle}%
+\expandafter\def\csname pgf@sh@np@current path bounding box\endcsname{%
+ \def\southwest{\pgfqpoint{\pgf@pathminx}{\pgf@pathminy}}%
+ \def\northeast{\pgfqpoint{\pgf@pathmaxx}{\pgf@pathmaxy}}%
+}%
+\expandafter\def\csname pgf@sh@nt@current path bounding box\endcsname{{1}{0}{0}{1}{0pt}{0pt}}%
+\expandafter\def\csname pgf@sh@pi@current path bounding box\endcsname{\pgfpictureid}%
+
+
+% Special current page bounding box rectangle:
+\expandafter\def\csname pgf@sh@ns@current page\endcsname{rectangle}%
+\expandafter\def\csname pgf@sh@np@current page\endcsname{%
+ \def\southwest{\pgfpointorigin}%
+ \def\northeast{\pgfpoint{\pgfsys@thepagewidth}{\pgfsys@thepageheight}}%
+}%
+\expandafter\def\csname pgf@sh@nt@current page\endcsname{{1}{0}{0}{1}{0pt}{0pt}}%
+\expandafter\def\csname pgf@sh@pi@current page\endcsname{pgfpageorigin}%
+
+
+% Special scope bounding box rectangle:
+\pgfkeys{/pgf/local bounding box/.code={%
+ \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{rectangle}
+ \expandafter\gdef\csname pgf@sh@np@#1\endcsname{%
+ \def\southwest{\pgfqpoint{\csname pgf@lbb@minx@#1\endcsname}{\csname pgf@lbb@miny@#1\endcsname}}%
+ \def\northeast{\pgfqpoint{\csname pgf@lbb@maxx@#1\endcsname}{\csname pgf@lbb@maxy@#1\endcsname}}%
+ }
+ \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
+ \expandafter\gdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}
+ \expandafter\gdef\csname pgf@lbb@maxx@#1\endcsname{-16000pt}%
+ \expandafter\gdef\csname pgf@lbb@minx@#1\endcsname{16000pt}%
+ \expandafter\gdef\csname pgf@lbb@maxy@#1\endcsname{-16000pt}%
+ \expandafter\gdef\csname pgf@lbb@miny@#1\endcsname{16000pt}%
+ \pgf@size@hookedtrue%
+ \expandafter\def\expandafter\pgf@path@size@hook\expandafter{\pgf@path@size@hook\pgf@lbb@do{#1}}
+ },
+ /pgf/freeze local bounding box/.code={%
+ {%
+ \csname pgf@sh@np@#1\endcsname%
+ \southwest%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \northeast%
+ \expandafter\xdef\csname pgf@sh@np@#1\endcsname{%
+ \noexpand\def\noexpand\southwest{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
+ \noexpand\def\noexpand\northeast{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}%
+ }%
+ }%
+ },
+}%
+\def\pgf@lbb@do#1{%
+ \ifdim\pgf@size@hook@x<\csname pgf@lbb@minx@#1\endcsname\expandafter\xdef\csname pgf@lbb@minx@#1\endcsname{\the\pgf@size@hook@x}\fi%
+ \ifdim\pgf@size@hook@x>\csname pgf@lbb@maxx@#1\endcsname\expandafter\xdef\csname pgf@lbb@maxx@#1\endcsname{\the\pgf@size@hook@x}\fi%
+ \ifdim\pgf@size@hook@y<\csname pgf@lbb@miny@#1\endcsname\expandafter\xdef\csname pgf@lbb@miny@#1\endcsname{\the\pgf@size@hook@y}\fi%
+ \ifdim\pgf@size@hook@y>\csname pgf@lbb@maxy@#1\endcsname\expandafter\xdef\csname pgf@lbb@maxy@#1\endcsname{\the\pgf@size@hook@y}\fi%
+}%
+
+%
+% Circle
+%
+
+\pgfdeclareshape{circle}
+%
+% Draws a circle around the text
+%
+{%
+ \savedanchor\centerpoint{%
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgf@y=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
+ }%
+
+ \saveddimen\radius{%
+ %
+ % Calculate ``height radius''
+ %
+ \pgf@ya=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya by\pgf@yb%
+ %
+ % Calculate ``width radius''
+ %
+ \pgf@xa=.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa by\pgf@xb%
+ %
+ % Calculate length of radius vector:
+ %
+ \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
+ \ifdim\pgf@x>\pgf@y%
+ \c@pgf@counta=\pgf@x%
+ \ifnum\c@pgf@counta=0\relax%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@xa=16\pgf@xa\relax%
+ \divide\pgf@xa by\c@pgf@counta%
+ \pgf@xa=16\pgf@xa\relax%
+ \fi%
+ \else%
+ \c@pgf@counta=\pgf@y%
+ \ifnum\c@pgf@counta=0\relax%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@ya=16\pgf@ya\relax%
+ \divide\pgf@ya by\c@pgf@counta%
+ \pgf@xa=16\pgf@ya\relax%
+ \fi%
+ \fi%
+ \pgf@x=\pgf@xa%
+ %
+ % If necessary, adjust radius so that the size requirements are
+ % met:
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<.5\pgf@xb%
+ \pgf@x=.5\pgf@xb%
+ \fi%
+ \ifdim\pgf@x<.5\pgf@yb%
+ \pgf@x=.5\pgf@yb%
+ \fi%
+ %
+ % Now, add larger of outer separations.
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgf@x by\pgf@yb%
+ \else%
+ \advance\pgf@x by\pgf@xb%
+ \fi%
+ }%
+
+ %
+ % Anchors
+ %
+ \anchor{center}{\centerpoint}%
+ \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{base}{\centerpoint\pgf@y=0pt}%
+ \anchor{north}{\centerpoint\advance\pgf@y by\radius}%
+ \anchor{south}{\centerpoint\advance\pgf@y by-\radius}%
+ \anchor{west}{\centerpoint\advance\pgf@x by-\radius}%
+ \anchor{east}{\centerpoint\advance\pgf@x by\radius}%
+ \anchor{mid west}{\centerpoint\advance\pgf@x by-\radius\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{mid east}{\centerpoint\advance\pgf@x by\radius\pgfmathsetlength\pgf@y{.5ex}}%
+ \anchor{base west}{\centerpoint\advance\pgf@x by-\radius\pgf@y=0pt}%
+ \anchor{base east}{\centerpoint\advance\pgf@x by\radius\pgf@y=0pt}%
+ \anchor{north west}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by-0.707107\pgf@xa
+ \advance\pgf@y by0.707107\pgf@xa
+ }%
+ \anchor{south west}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by-0.707107\pgf@xa
+ \advance\pgf@y by-0.707107\pgf@xa
+ }%
+ \anchor{north east}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by0.707107\pgf@xa
+ \advance\pgf@y by0.707107\pgf@xa
+ }%
+ \anchor{south east}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by0.707107\pgf@xa
+ \advance\pgf@y by-0.707107\pgf@xa
+ }%
+ \anchorborder{%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpointborderellipse
+ {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}
+ {\noexpand\pgfqpoint{\radius}{\radius}}%
+ }%
+ \pgf@marshal%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \centerpoint%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ }%
+
+ %
+ % Background path
+ %
+ \backgroundpath{%
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \pgfpathcircle{\centerpoint}{\pgfutil@tempdima}%
+ }%
+}%
+
+
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmodulesnakes.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmodulesnakes.code.tex
new file mode 100644
index 0000000000..9b692b1340
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmodulesnakes.code.tex
@@ -0,0 +1,369 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmodulesnakes.code.tex}
+
+\pgfwarning{Snakes have been superseded by decorations. Use the module decorations instead of snakes}
+
+\usepgfmodule{decorations}%
+
+\endinput
+
+
+
+\newdimen\pgfsnakeremainingdistance
+\newdimen\pgfsnakecompleteddistance
+
+
+% Creates a new pgf snake
+%
+% #1 = snake name
+% #1 = initial state
+% #3 = states of the snake
+%
+%
+% This command declares a new snake for later use. The second
+% parameter specifies the states of the snake, see also the
+% description of pgfpathsnake.
+%
+% Inside the code of #3 the command \state may be used. This command
+% will only be defined while #3 is executed.
+%
+% Example:
+%
+% \pgfdeclaresnake{zig zag}{one zig zag}
+% {
+% \state{one zig zag}[width=10pt]
+% {
+% \pgfpathlineto{\pgfpoint{2.5pt}{2.5pt}}
+% \pgfpathlineto{\pgfpoint{7.5pt}{-2.5pt}}
+% \pgfpathlineto{\pgfpoint{10pt}{0pt}}
+% }
+% \state{final}
+% {
+% \pgfpathlineto{\pgfpoint{\pgfsnakeremainingdistance}{0pt}}
+% }
+% }
+
+\long\def\pgfdeclaresnake#1#2#3{%
+ \def\pgf@snake@name{#1}%
+ \pgfutil@namedef{pgf@snake@@#1@initial}{#2}%
+ \let\pgf@orig@state=\state%
+ \let\state=\pgf@snake@state
+ #3
+ \let\state=\pgf@orig@state%
+}%
+
+
+% Sets the additional transformation applied to every segment of a snake
+%
+% #1 = transformation
+%
+% Example:
+%
+% \pgfsetsnakesegmenttransformation{\pgftransformyshift{5pt}}
+
+\def\pgfsetsnakesegmenttransformation#1{\def\pgf@snakeadditionaltransform{#1}}%
+\pgfsetsnakesegmenttransformation{}%
+
+
+% Declares a new state
+%
+% #1 = state name
+% #2 = options
+% #3 = path element
+%
+% Description:
+%
+% When a snake is drawn and the current state is #1, the following
+% happens. First, the options are executed, which will possible change
+% the state. If that does not happen, the path element is added to the
+% path and the coordinate system is translated by the path element's
+% width (which is specified using the width option).
+%
+% Example:
+%
+% \state{initial}[width=10pt]
+% {
+% \pgfpathlineto{\pgfpoint{2.5pt}{2.5pt}}
+% \pgfpathlineto{\pgfpoint{7.5pt}{-2.5pt}}
+% \pgfpathlineto{\pgfpoint{10pt}{0pt}}
+% }
+
+\def\pgf@snake@state#1{\pgfutil@ifnextchar[{\pgf@@snake@start#1}{\pgf@@snake@start#1[]}}%}%
+\def\pgf@@snake@start#1[#2]#3{%
+ \pgfutil@namedef{pgf@snake@@\pgf@snake@name @#1@options}{#2}%
+ \pgfutil@namedef{pgf@snake@@\pgf@snake@name @#1@code}{#3}%
+}%
+
+
+
+% Use multiple snakes
+%
+% #1 = list of snake names/length pairs
+% #2 = point to which the snake leads
+%
+% This operation uses the snakes in parameter #1 to get to the point
+% #4. The parameter #1 should contain pairs consisting of a snake name
+% and a length for which this snake should be used. When the length is
+% computed, the dimensions \pgfsnakeremainingdistance and
+% \pgfsnakecompleteddistance will have been set to the length of the
+% total distance to #2 that has already been covered/that still needs
+% to be covered.
+%
+% Example:
+%
+% \pgfpathsnakesto{{lineto}{1cm},{zig zag}{\pgfsnakeremainingdistance}}{\pgfpoint{2cm}{3cm}}
+
+\def\pgfpathsnakesto#1#2{%
+ \begingroup%
+ % compute target vector
+ \pgfpointtransformed{#2}%
+ \advance\pgf@x by-\pgf@path@lastx%
+ \advance\pgf@y by-\pgf@path@lasty%
+ %
+ % MW: Calculate the angle of the snake.
+ %
+ \edef\pgf@marshal{%
+ \noexpand\pgfmathanglebetweenpoints{\noexpand\pgfpointorigin}{%
+ \noexpand\pgf@x\the\pgf@x\noexpand\pgf@y\the\pgf@y}%
+ }%
+ \pgf@marshal%
+ \let\pgfsnakeangle\pgfmathresult%
+ %
+ % MW: Use this instead for length (?). More accurate and only a few operations slower.
+ %
+ \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}%
+ \pgfsnakeremainingdistance\pgfmathresult pt\relax%
+ %
+ % Ok, now normalize the vector...
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpointnormalised{}}%
+ % ok, now computer length (arghh...)
+ % In theory that's easy: divide the larger of the values x or y by
+ % the normalized x or y. Well...
+ %
+ % First, make xa and ya positive:
+ % \ifdim\pgf@xa<0pt%
+% \pgf@xa=-\pgf@xa%
+% \fi%
+% \ifdim\pgf@ya<0pt%
+% \pgf@ya=-\pgf@ya%
+% \fi%
+% % Now do division:
+% \ifdim\pgf@xa>\pgf@ya%
+% \c@pgf@counta=\pgf@x%
+% \ifnum\c@pgf@counta=0\relax%
+% \else%
+% \divide\c@pgf@counta by 255\relax%
+% \pgf@xa=16\pgf@xa\relax%
+% \divide\pgf@xa by\c@pgf@counta%
+% \pgf@xa=16\pgf@xa\relax%
+% \fi%
+% \else%
+% \c@pgf@counta=\pgf@y%
+% \ifnum\c@pgf@counta=0\relax%
+% \else%
+% \divide\c@pgf@counta by 255\relax%
+% \pgf@ya=16\pgf@ya\relax%
+% \divide\pgf@ya by\c@pgf@counta%
+% \pgf@xa=16\pgf@ya\relax%
+% \fi%
+% \fi%
+% % Make positive:
+% \ifdim\pgf@xa<0pt%
+% \pgf@xa=-\pgf@xa%
+% \fi%
+% % Ok, now we draw things...
+ \edef\pgf@list{#1}%
+% \pgfsnakeremainingdistance=\pgf@xa%
+ \pgfsnakecompleteddistance=0pt%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \pgfutil@for\pgf@temp:=\pgf@list\do{%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \expandafter\pgf@snake@invoke\pgf@temp%
+ \fi%
+ }%
+ \endgroup%
+}%
+
+\def\pgf@snake@invoke#1#2{%
+ \pgfmathsetlength\pgf@xa{#2}%
+ {%
+ \edef\pgf@marshal{\noexpand\pgfpathsnakealongvector{#1}{\the\pgf@xa}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}}%
+ \pgf@marshal%
+ }%
+ \advance\pgfsnakecompleteddistance by\pgf@xa%
+ \advance\pgfsnakeremainingdistance by-\pgf@xa%
+}%
+
+% Use a snake
+%
+% #1 = snake name
+% #2 = point to which the snake leads
+%
+% This operation mainly computes \pgfpathsnakealongvector for a vector
+% appropriately chosen. See \pgfpathsnakealongvector for details.
+%
+% Example:
+%
+% \pgfpathsnaketo{zig zag}{\pgfpoint{2cm}{3cm}}
+
+\def\pgfpathsnaketo#1#2{\pgfpathsnakesto{{#1}{\pgfsnakeremainingdistance}}{#2}}%
+
+
+
+% Use a snake
+%
+% #1 = snake name
+% #2 = length of the snake
+% #3 = vector along which the snake grows, should have unit length.
+%
+% This command draws a snake (more precisely, it adds a snake to the
+% path). This works as follows:
+%
+% First, the coordinate system is transformed such that the vector #3
+% points to the right.
+%
+% Next, the state `initial' of the snake is entered. Unless the
+% options of this state cause it to switch to another state, the path
+% element is added to the path. Then, the coordinate system is
+% translated by the width of the path element as specified in the
+% width option of the path element. The dimensions
+% \pgfsnakeremainingdistance and \pgfsnakecompleteddistance are
+% updated.
+%
+% The process ends when the state `final' is entered. The code of the
+% final state is executed and the process stops.
+%
+% Example:
+%
+% \pgfpathsnakealongvector{zig zag}{100pt}{\pgfpolar{30}{1pt}}
+
+\def\pgfpathsnakealongvector#1#2#3{%
+ \pgfutil@ifundefined{pgf@snake@@#1@initial}{\pgferror{Undefined snake ``#1''}}
+ {
+ \begingroup% keep things local
+ \pgftransformreset%
+ \pgf@pt@x=\pgf@path@lastx% evil trickery to transform to the last point
+ \pgf@pt@y=\pgf@path@lasty%
+ \pgf@process{#3}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@xb=-\pgf@y%
+ \pgf@yb=\pgf@x%
+ \pgftransformcm
+ {\pgf@sys@tonumber{\pgf@xa}}{\pgf@sys@tonumber{\pgf@ya}}
+ {\pgf@sys@tonumber{\pgf@xb}}{\pgf@sys@tonumber{\pgf@yb}}
+ {\pgfpointorigin}%
+ % Now, setup the automaton
+ \expandafter\let\expandafter\pgf@snake@current@state\expandafter=\csname pgf@snake@@#1@initial\endcsname%
+ \def\pgf@snake@name{#1}%
+ \pgfsnakecompleteddistance=0pt%
+ \pgfmathsetlength\pgfsnakeremainingdistance{#2}%
+ \pgf@snake@run%
+ % Last step:
+ {%
+ \pgftransformxshift{\pgfsnakecompleteddistance}%
+ \pgf@snakeadditionaltransform%
+ \csname pgf@snake@@#1@final@code\endcsname%
+ }%
+ \endgroup%
+ }%
+}%
+
+\def\pgf@final@text{final}%
+
+\def\pgf@snake@run{%
+ \let\pgf@snake@next=\pgf@snake@do@state%
+ \ifx\pgf@snake@current@state\pgf@final@text%
+ \let\pgf@snake@next=\relax%
+ \fi%
+ \pgf@snake@next%
+}%
+
+\def\pgf@snake@do@state{%
+ \let\pgf@snake@next=\relax%
+ \let\pgf@snake@next@state=\pgf@snake@current@state%
+ % execute options
+ \expandafter\expandafter\expandafter\pgf@snakes@setter
+ \expandafter\expandafter\expandafter{\csname pgf@snake@@\pgf@snake@name @\pgf@snake@current@state @options\endcsname}%
+ \ifx\pgf@snake@next\relax%
+ \let\pgf@snake@next=\pgf@snake@do@code%
+ \fi%
+ \pgf@snake@next%
+}%
+\def\pgf@snakes@setter{%
+ \pgfqkeys{/pgf/snakes}%
+}%
+
+\def\pgf@snake@do@code{%
+ % Ok, execute code:
+ {%
+ \pgftransformxshift{\pgfsnakecompleteddistance}%
+ \pgf@snakeadditionaltransform%
+ \csname pgf@snake@@\pgf@snake@name @\pgf@snake@current@state @code\endcsname%
+ }%
+ % next, do transformation and update
+ \pgfmathsetlength{\pgf@xa}{\pgf@snake@width}%
+ \advance\pgfsnakeremainingdistance by-\pgf@xa%
+ \advance\pgfsnakecompleteddistance by\pgf@xa%
+ % Next iteration:
+ \let\pgf@snake@current@state=\pgf@snake@next@state%
+ \pgf@snake@run%
+}%
+
+\pgfkeys{
+ /pgf/snakes/width/.code=\def\pgf@snake@width{#1}\pgf@snake@switch@if#1 to final\pgf@stop,%
+ /pgf/snakes/switch if less than/.code=\pgf@snake@switch@if#1\pgf@stop,%
+ /pgf/snakes/next state/.store in=\pgf@snake@next@state%
+}%
+
+\def\pgf@snake@switch@if#1to #2\pgf@stop{%
+ \ifx\pgf@snake@next\relax%
+ \pgfmathsetlength\pgf@x{#1}%
+ \ifdim\pgfsnakeremainingdistance<\pgf@x%
+ \def\pgf@snake@current@state{#2}%
+ \let\pgf@snake@next=\pgf@snake@run%
+ \fi%
+ \fi%
+}%
+
+
+
+% lineto snake
+%
+% This snake simply adds a straight line. This snake is mainly useful
+% in conjunction with other snakes.
+
+\pgfdeclaresnake{lineto}{final}
+{%
+ \state{final}
+ { \pgfpathlineto{\pgfqpoint{\pgfsnakeremainingdistance}{0pt}} }
+}%
+
+
+
+% moveto snake
+%
+% This snake simply jumps to the end. This snake, too, is mainly
+% useful in conjunction with other snakes.
+
+\pgfdeclaresnake{moveto}{final}
+{%
+ \state{final}
+ { \pgfpathmoveto{\pgfqpoint{\pgfsnakeremainingdistance}{0pt}} }
+}%
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/modules/pgfmodulesorting.code.tex b/graphics/pgf/base/tex/generic/modules/pgfmodulesorting.code.tex
new file mode 100644
index 0000000000..9aa1df9fef
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/modules/pgfmodulesorting.code.tex
@@ -0,0 +1,69 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfmodulesorting.code.tex}
+
+%
+% This file defines commands for sorting data. This is useful for 3d plots,
+% but also for drawing things in the correct order.
+%
+
+
+\newcount\pgfsortingbuckets
+
+
+% Init the sorting
+%
+% #1 = number of buckets
+%
+% Description:
+%
+% This macro inits a sorting. At any time there can be only one active
+% sorting. When you init the sorting, #1 should be a number of
+% buckets. You can then call \pgfsortinginsert to insert code into the
+% buckets. Once you are done, calling \pgfsortingexecute will execute
+% first the code in buckets 0, then the code in bucket 1, and so on to
+% bucket number #1-1.
+%
+\def\pgfsortinginit#1{
+ \pgfsortingbuckets#1\relax%
+ \c@pgf@counta=0\relax
+ \pgfutil@loop
+ \ifnum\c@pgf@counta<\c@pgf@countb\relax%
+ \expandafter\global\expandafter\let\csname pgf@sort@\the\c@pgf@counta\endcsname\pgfutil@empty%
+ \advance\c@pgf@counta by1\relax%
+ \pgfutil@repeat
+}%
+
+% Insert code into some bucket
+%
+% #1 = the bucket
+% #2 = the code
+%
+\def\pgfsortinginsert#1#2{
+ \expandafter\let\expandafter\pgf@temp\csname pgf@lib@sort@#1\endcsname%
+ \expandafter\def\expandafter\pgf@temp\expandafter{\pgf@temp#2}%
+ \expandafter\global\expandafter\let\csname pgf@lib@sort@\the\c@pgf@counta\endcsname\pgf@temp%
+}%
+
+
+% After all code has been inserted into the buckets, you can call
+% this method to execute the code in the order of the buckets.
+\def\pgfsortingexecute{
+ \c@pgf@countb=\pgfoovalueof{buckets}\relax
+ \c@pgf@counta=0\relax
+ \pgfutil@loop
+ \ifnum\c@pgf@counta<\c@pgf@countb\relax%
+ \csname pgf@lib@sort@\the\c@pgf@counta\endcsname%
+ \advance\c@pgf@counta by1\relax%
+ \pgfutil@repeat
+}%
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/pgf.revision.tex b/graphics/pgf/base/tex/generic/pgf.revision.tex
new file mode 100644
index 0000000000..12b28e2045
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/pgf.revision.tex
@@ -0,0 +1,4 @@
+\def\pgfrevision{3.1.10}
+\def\pgfversion{3.1.10}
+\def\pgfrevisiondate{2023-01-15}
+\def\pgfversiondate{2023-01-15}
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgf.cfg b/graphics/pgf/base/tex/generic/systemlayer/pgf.cfg
new file mode 100644
index 0000000000..2580bad9d1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgf.cfg
@@ -0,0 +1,33 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgf.cfg}
+
+% Copy this file to somewhere local and uncomment one of the following
+% if you do not trust/use/like the automatic driver selection
+% algorithms:
+
+% \def\pgfsysdriver{pgfsys-dvi.def}
+% \def\pgfsysdriver{pgfsys-dvipdfm.def}
+% \def\pgfsysdriver{pgfsys-dvipdfmx.def}
+% \def\pgfsysdriver{pgfsys-dvips.def}
+% \def\pgfsysdriver{pgfsys-pdftex.def}
+% \def\pgfsysdriver{pgfsys-luatex.def}
+% \def\pgfsysdriver{pgfsys-tex4ht.def}
+% \def\pgfsysdriver{pgfsys-textures.def}
+% \def\pgfsysdriver{pgfsys-vtex.def}
+% \def\pgfsysdriver{pgfsys-xetex.def}
+
+% Alternatively, use one of the above commands in your own files.
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf-via-dvi.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf-via-dvi.def
new file mode 100644
index 0000000000..0678b18820
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf-via-dvi.def
@@ -0,0 +1,172 @@
+% Copyright 2019 by Till Tantau
+% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-common-pdf-via-dvi.def}
+
+% Common driver commands for all drivers that produce pdf via the
+% detour of a dvi file
+
+% For unique object name:
+\newcount\pgfsys@objnum\pgfsys@objnum\@ne
+
+% Hboxes
+
+\def\pgfsys@beginpurepicture{\special{pdf: content q}}
+
+
+\def\pgfsys@imagesuffixlist{.pdf:.jpg:.jpeg:.png:}
+\def\pgfsys@horishading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@process{\pgfpoint{\pgf@max}{#2}}%
+ \edef\@temp{\noexpand\pgfutil@insertatbegincurrentpage{\special{pdf: beginxobj @pgfshade\the\pgfsys@objnum\space width \the\pgf@max\space height \the\pgf@y}}}\@temp%
+ \edef\@temp{\noexpand\pgfutil@insertatbegincurrentpage{\special{pdf: put @resources <<
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@doma\space0 \pgf@domb\space0]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >> >>}}}\@temp% <<
+ \pgfutil@insertatbegincurrentpage{\special{pdf: content /Sh sh}%
+ \special{pdf: endxobj}}%
+ \xdef\pgfutil@tempa{%
+ \hbox to\the\pgf@max{\vbox to#2{\vfil\special{pdf: usexobj @pgfshade\the\pgfsys@objnum}}\hfil}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+ \global\advance\pgfsys@objnum\@ne
+}
+\def\pgfsys@vertshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@process{\pgfpoint{\pgf@max}{#2}}%
+ \edef\@temp{\noexpand\pgfutil@insertatbegincurrentpage{\special{pdf: beginxobj @pgfshade\the\pgfsys@objnum\space width \the\pgf@y\space height \the\pgf@max\space}}}\@temp%
+ \edef\@temp{\noexpand\pgfutil@insertatbegincurrentpage{\special{pdf: put @resources <<
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [0 \pgf@doma\space0 \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >> >>}}}\@temp% <<
+ \pgfutil@insertatbegincurrentpage{\special{pdf: content /Sh sh}%
+ \special{pdf: endxobj}}%
+ \xdef\pgfutil@tempa{%
+ \hbox to#2{\vbox to\the\pgf@max{\vfil\special{pdf: usexobj @pgfshade\the\pgfsys@objnum}}\hfil}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+ \global\advance\pgfsys@objnum\@ne
+}
+\def\pgfsys@radialshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpoint{\pgf@max}{\pgf@max}}%
+ \advance\pgf@xa by \pgf@x\relax%
+ \advance\pgf@ya by \pgf@y\relax%
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgfutil@tempdima=2\pgf@max\relax%
+ \edef\@temp{\noexpand\pgfutil@insertatbegincurrentpage{\special{pdf: beginxobj @pgfshade\the\pgfsys@objnum\space width \the\pgfutil@tempdima\space height \the\pgfutil@tempdima}}}\@temp%
+ \edef\@temp{\noexpand\pgfutil@insertatbegincurrentpage{\special{pdf: put @resources <<
+ /Shading << /Sh << /ShadingType 3
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@sys@tonumber{\pgf@xa} \pgf@sys@tonumber{\pgf@ya} \pgf@doma\space \pgf@sys@tonumber{\pgf@x} \pgf@sys@tonumber{\pgf@y} \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [true false] >> >> >>}}}\@temp% <<
+ \pgfutil@insertatbegincurrentpage{\special{pdf: content /Sh sh}%
+ \special{pdf: endxobj}}%
+ \xdef\pgfutil@tempa{%
+ \hbox to\the\pgfutil@tempdima{\vbox to\the\pgfutil@tempdima{\vfil\special{pdf: usexobj @pgfshade\the\pgfsys@objnum}}\hfil}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+ \global\advance\pgfsys@objnum\@ne
+}%
+
+\def\pgf@sys@pdf@dvi@tracker{
+ \def\pgfsys@markposition##1{%
+ \pdfsavepos%
+ \edef\pgf@temp{##1}%
+ \expandafter\write\expandafter\pgfutil@auxout\expandafter{%
+ \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}%
+ }
+ \def\pgfsyspdfmark##1##2##3{%
+ \expandafter\gdef\csname pgf@sys@pdf@mark@pos@##1\endcsname{\pgfqpoint{##2sp}{##3sp}}%
+ }
+ \def\pgfsys@getposition##1##2{%
+ \edef\pgf@marshal{\let\noexpand##2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@##1\endcsname}%
+ \pgf@marshal%
+ }
+ \def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfpointorigin}
+}
+
+
+
+%
+% Resource management
+%
+
+\newif\ifpgf@sys@pdf@colorspaces@exists
+\newif\ifpgf@sys@pdf@patterns@exists
+\newif\ifpgf@sys@pdf@extgs@exists
+\newif\ifpgf@sys@pdf@colorspaces@created
+\newif\ifpgf@sys@pdf@patterns@created
+\newif\ifpgf@sys@pdf@extgs@created
+\newif\ifpgf@sys@pdf@any@resources
+
+\def\pgf@sys@setuppdfresources@plain{%
+ % This command will setup pdf resource in plain and in latex
+ % mode. ConTeXt has its own handler
+ \pgfutil@insertatbegineverypage{%
+ \pgf@sys@pdf@any@resourcesfalse%
+ \ifpgf@sys@pdf@extgs@exists%
+ \pgf@sys@pdf@any@resourcestrue%
+ \ifpgf@sys@pdf@extgs@created \else \special{pdf: obj @pgfextgs <<>>} \global\pgf@sys@pdf@extgs@createdtrue \fi% <<
+ \fi%
+ \ifpgf@sys@pdf@colorspaces@exists%
+ \pgf@sys@pdf@any@resourcestrue%
+ \ifpgf@sys@pdf@colorspaces@created \else \special{pdf: obj @pgfcolorspaces <<>>} \global\pgf@sys@pdf@colorspaces@createdtrue \fi% <<
+ \fi%
+ \ifpgf@sys@pdf@patterns@exists%
+ \pgf@sys@pdf@any@resourcestrue%
+ \ifpgf@sys@pdf@patterns@created \else \special{pdf: obj @pgfpatterns <<>>} \global\pgf@sys@pdf@patterns@createdtrue \fi% <<
+ \fi%
+ \ifpgf@sys@pdf@any@resources%
+ \special{pdf: put @resources <<
+ \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi
+ \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpattern \fi
+ \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi
+ >>}% <<
+ \fi%
+ }
+ \def\pgf@sys@addpdfresource@extgs@plain##1{%
+ \global\pgf@sys@pdf@extgs@existstrue%
+ \pgfutil@insertatbegincurrentpage{\special{pdf: put @pgfextgs << ##1 >>}}% <<
+ }
+ \def\pgf@sys@addpdfresource@colorspaces@plain##1{%
+ \global\pgf@sys@pdf@colorspaces@existstrue%
+ \pgfutil@insertatbegincurrentpage{\special{pdf: put @pgfcolorspaces << ##1 >>}}% <<
+ }
+ \def\pgf@sys@addpdfresource@patterns@plain##1{%
+ \global\pgf@sys@pdf@patterns@existstrue%
+ \pgfutil@insertatbegincurrentpage{\special{pdf: put @pgfpatterns << ##1 >>}}% <<
+ }
+}
+\pgfutil@setuppdfresources % possibly call the above
+
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf.def
new file mode 100644
index 0000000000..e1ad4e7021
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-pdf.def
@@ -0,0 +1,119 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-common-pdf.def}
+
+
+% Common driver commands for all drivers that produce pdf
+
+
+% Path construction:
+\def\pgfsys@lineto#1#2{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{l}}
+\def\pgfsys@moveto#1#2{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{m}}
+\def\pgfsys@curveto#1#2#3#4#5#6{%
+ \pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgf@sys@bp{#3}\pgf@sys@bp{#4}\pgf@sys@bp{#5}\pgf@sys@bp{#6}\pgfsysprotocol@literal{c}}
+\def\pgfsys@rect#1#2#3#4{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgf@sys@bp{#3}\pgf@sys@bp{#4}\pgfsysprotocol@literal{re}}
+\def\pgfsys@closepath{\pgfsysprotocol@literal{h}}
+
+% Path usage:
+\def\pgfsys@stroke{\pgfsysprotocol@literal{S}}
+\def\pgfsys@closestroke{\pgfsysprotocol@literal{s}}
+\def\pgfsys@fill{\ifpgfsys@eorule\pgfsysprotocol@literal{f*}\else\pgfsysprotocol@literal{f}\fi}
+\def\pgfsys@fillstroke{\ifpgfsys@eorule\pgfsysprotocol@literal{B*}\else\pgfsysprotocol@literal{B}\fi}
+\def\pgfsys@clipnext{\ifpgfsys@eorule\pgfsysprotocol@literal{W*}\else\pgfsysprotocol@literal{W}\fi}
+\def\pgfsys@discardpath{\pgfsysprotocol@literal{n}}
+
+% Transformation:
+\def\pgfsys@transformcm#1#2#3#4#5#6{%
+ \pgfsysprotocol@literalbuffered{#1 #2 #3 #4}\pgf@sys@bp{#5}\pgf@sys@bp{#6}\pgfsysprotocol@literal{cm}}
+
+% Scopes
+\def\pgfsys@beginscope{\pgfsysprotocol@literal{q}}
+\def\pgfsys@endscope{\pgfsysprotocol@literal{Q}}
+
+% Graphics state
+\def\pgfsys@setdash#1#2{%
+ \pgfsysprotocol@literalbuffered{[}%
+ \pgfutil@for\pgf@sys@temp:={#1}\do{\pgf@sys@bp{\pgf@sys@temp}}%
+ \pgfsysprotocol@literalbuffered{]}%
+ \pgf@sys@bp{#2}\pgfsysprotocol@literal{d}}
+\def\pgfsys@setlinewidth#1{\pgf@sys@bp{#1}\pgfsysprotocol@literal{w}}
+\def\pgfsys@setmiterlimit#1{\pgfsysprotocol@literal{#1 M}}
+\def\pgfsys@buttcap{\pgfsysprotocol@literal{0 J}}
+\def\pgfsys@roundcap{\pgfsysprotocol@literal{1 J}}
+\def\pgfsys@rectcap{\pgfsysprotocol@literal{2 J}}
+\def\pgfsys@miterjoin{\pgfsysprotocol@literal{0 j}}
+\def\pgfsys@roundjoin{\pgfsysprotocol@literal{1 j}}
+\def\pgfsys@beveljoin{\pgfsysprotocol@literal{2 j}}
+\def\pgfsys@color@rgb@stroke#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 RG}}
+\def\pgfsys@color@rgb@fill#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 rg}}
+\def\pgfsys@color@cmyk@stroke#1#2#3#4{\pgfsysprotocol@literal{#1 #2 #3 #4 K}}
+\def\pgfsys@color@cmyk@fill#1#2#3#4{\pgfsysprotocol@literal{#1 #2 #3 #4 k}}
+\def\pgfsys@color@cmy@stroke#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 0 K}}
+\def\pgfsys@color@cmy@fill#1#2#3{\pgfsysprotocol@literal{#1 #2 #3 0 k}}
+\def\pgfsys@color@gray@stroke#1{\pgfsysprotocol@literal{#1 G}}
+\def\pgfsys@color@gray@fill#1{\pgfsysprotocol@literal{#1 g}}
+
+% Visibility
+\def\pgfsys@begininvisiblescope{\pgfsys@beginscope{\pgfsys@discardpath\pgfsys@clipnext\pgfsys@moveto{0pt}{0pt}\pgfsys@discardpath}}
+\def\pgfsys@endinvisiblescope{\pgfsys@endscope}
+
+% Opacity
+\def\pgfsys@stroke@opacity#1{%
+ \expandafter\ifx\csname pgf@sys@pdf@so@#1\endcsname\relax%
+ \expandafter\gdef\csname pgf@sys@pdf@so@#1\endcsname{/pgf@CA#1}%
+ \pgfutil@addpdfresource@extgs{/pgf@CA#1 << /CA #1 >>}%<<
+ \fi%
+ \pgfsysprotocol@literal{\csname pgf@sys@pdf@so@#1\endcsname\space gs}%
+}
+\def\pgfsys@fill@opacity#1{%
+ \expandafter\ifx\csname pgf@sys@pdf@fo@#1\endcsname\relax%
+ \expandafter\gdef\csname pgf@sys@pdf@fo@#1\endcsname{/pgf@ca#1}%
+ \pgfutil@addpdfresource@extgs{/pgf@ca#1 << /ca #1 >>}%<<
+ \fi%
+ \pgfsysprotocol@literal{\csname pgf@sys@pdf@fo@#1\endcsname\space gs}%
+}
+
+% Blending
+\def\pgfsys@blend@mode#1{%
+ \expandafter\ifx\csname pgf@sys@pdf@bm@#1\endcsname\relax%
+ \expandafter\let\expandafter\pgf@temp\csname pgf@sys@pdf@blend@mode@map@#1\endcsname%
+ \expandafter\xdef\csname pgf@sys@pdf@bm@#1\endcsname{/pgf@bm\pgf@temp}%
+ \ifx\pgf@temp\relax%
+ \pgferror{Unknown blend mode '#1'}%
+ \def\pgf@temp{Normal}%
+ \fi%
+ \edef\pgf@temp{/pgf@bm\pgf@temp << /BM /\pgf@temp >>}%<<
+ \expandafter\pgfutil@addpdfresource@extgs\expandafter{\pgf@temp}%
+ \fi%
+ \pgfsysprotocol@literal{\csname pgf@sys@pdf@bm@#1\endcsname\space gs}%
+}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@normal\endcsname{Normal}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@multiply\endcsname{Multiply}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@screen\endcsname{Screen}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@overlay\endcsname{Overlay}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@darken\endcsname{Darken}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@lighten\endcsname{Lighten}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color dodge\endcsname{ColorDodge}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color burn\endcsname{ColorBurn}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hard light\endcsname{HardLight}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@soft light\endcsname{SoftLight}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@difference\endcsname{Difference}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@exclusion\endcsname{Exclusion}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@saturation\endcsname{Saturation}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color\endcsname{Color}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hue\endcsname{Hue}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@luminosity\endcsname{Luminosity}
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-postscript.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-postscript.def
new file mode 100644
index 0000000000..004b8e38f4
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-postscript.def
@@ -0,0 +1,600 @@
+% Copyright 2019 by Till Tantau
+% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-common-postscript.def}
+
+
+% Driver commands for postscript
+
+\newif\ifpgf@fillcolor
+\newif\ifpgf@strokecolor
+\newif\ifpgfsys@@clipnext
+
+% Path construction:
+\def\pgfsys@lineto#1#2{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{lineto}}
+\def\pgfsys@moveto#1#2{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{moveto}}
+\def\pgfsys@curveto#1#2#3#4#5#6{%
+ \pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgf@sys@bp{#3}\pgf@sys@bp{#4}\pgf@sys@bp{#5}\pgf@sys@bp{#6}\pgfsysprotocol@literal{curveto}}
+\def\pgfsys@rect#1#2#3#4{\pgf@sys@bp{#4}\pgf@sys@bp{#3}\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{pgfe}}
+\def\pgfsys@closepath{\pgfsysprotocol@literal{closepath}}
+
+% Path usage:
+\def\pgfsys@stroke{%
+ \ifpgfsys@@clipnext%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{gsave pgfsc pgfstr grestore eoclip newpath}%
+ \else%
+ \pgfsysprotocol@literal{gsave pgfsc pgfstr grestore clip newpath}%
+ \fi%
+ \pgfsys@@clipnextfalse%
+ \else%
+ \ifpgf@strokecolor%
+ \pgfsysprotocol@literal{gsave pgfsc pgfstr grestore newpath}%
+ \else%
+ \pgfsysprotocol@literal{pgfstr}%
+ \fi%
+ \fi}
+\def\pgfsys@fill{%
+ \ifpgfsys@@clipnext%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{gsave pgffc pgfeofill grestore eoclip newpath}%
+ \else%
+ \pgfsysprotocol@literal{gsave pgffc pgffill grestore clip newpath}%
+ \fi%
+ \pgfsys@@clipnextfalse%
+ \else%
+ \ifpgf@fillcolor%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{gsave pgffc pgfeofill grestore newpath}%
+ \else%
+ \pgfsysprotocol@literal{gsave pgffc pgffill grestore newpath}%
+ \fi%
+ \else%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{pgfeofill}%
+ \else%
+ \pgfsysprotocol@literal{pgffill}%
+ \fi%
+ \fi%
+ \fi}
+\def\pgfsys@fillstroke{%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{gsave pgffc pgfeofill grestore gsave pgfsc pgfstr grestore}%
+ \else%
+ \pgfsysprotocol@literal{gsave pgffc pgffill grestore gsave pgfsc pgfstr grestore}%
+ \fi%
+ \ifpgfsys@@clipnext%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{eoclip}%
+ \else%
+ \pgfsysprotocol@literal{clip}%
+ \fi%
+ \pgfsys@@clipnextfalse%
+ \fi%
+ \pgfsysprotocol@literal{newpath}}
+\def\pgfsys@clipnext{\pgfsys@@clipnexttrue}
+\def\pgfsys@discardpath{%
+ \ifpgfsys@@clipnext%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{eoclip}%
+ \else%
+ \pgfsysprotocol@literal{clip}%
+ \fi%
+ \pgfsys@@clipnextfalse%
+ \fi%
+ \pgfsysprotocol@literal{newpath}}
+
+% Transformation:
+\def\pgfsys@transformshift#1#2{\pgf@sys@bp{#1}\pgf@sys@bp{#2}\pgfsysprotocol@literal{translate}}
+\def\pgfsys@transformxyscale#1#2{\pgfsysprotocol@literal{#1 #2 scale}}
+\def\pgfsys@transformcm#1#2#3#4#5#6{%
+ \pgfsysprotocol@literalbuffered{[#1 #2 #3 #4}\pgf@sys@bp{#5}\pgf@sys@bp{#6}\pgfsysprotocol@literal{] concat}}
+
+% Scopes
+\def\pgfsys@beginscope{\pgfsysprotocol@literal{save}}
+\def\pgfsys@endscope{\pgfsysprotocol@literal{restore}}
+
+\newif\ifpgfsys@ps@boxmode
+\def\pgfsys@begin@text{\pgfsys@ps@boxmodetrue}
+\def\pgfsys@end@text{}
+
+
+% Graphics state
+\def\pgfsys@setdash#1#2{%
+ \pgfsysprotocol@literalbuffered{[}%
+ \pgfutil@for\pgf@sys@temp:={#1}\do{\pgf@sys@bp{\pgf@sys@temp}}%
+ \pgfsysprotocol@literalbuffered{]}%
+ \pgf@sys@bp{#2}\pgfsysprotocol@literal{setdash}}
+\def\pgfsys@setlinewidth#1{\pgf@sys@bp{#1}\pgfsysprotocol@literal{pgfw}}
+\def\pgfsys@setmiterlimit#1{\pgfsysprotocol@literal{#1 setmiterlimit}}
+\def\pgfsys@buttcap{\pgfsysprotocol@literal{0 setlinecap}}
+\def\pgfsys@roundcap{\pgfsysprotocol@literal{1 setlinecap}}
+\def\pgfsys@rectcap{\pgfsysprotocol@literal{2 setlinecap}}
+\def\pgfsys@miterjoin{\pgfsysprotocol@literal{0 setlinejoin}}
+\def\pgfsys@roundjoin{\pgfsysprotocol@literal{1 setlinejoin}}
+\def\pgfsys@beveljoin{\pgfsysprotocol@literal{2 setlinejoin}}
+\def\pgfsys@color@rgb@stroke#1#2#3{\pgfsysprotocol@literal{/pgfsc{#1 #2 #3 setrgbcolor}def}\pgf@strokecolortrue}
+\def\pgfsys@color@rgb@fill#1#2#3{\pgfsysprotocol@literal{/pgffc{#1 #2 #3 setrgbcolor}def}\pgf@fillcolortrue}
+\def\pgfsys@color@rgb#1#2#3{\pgfsys@color@reset\pgfsysprotocol@literal{#1 #2 #3 setrgbcolor}}
+\def\pgfsys@color@cmyk@stroke#1#2#3#4{\pgfsysprotocol@literal{/pgfsc{#1 #2 #3 #4 setcmykcolor}def}\pgf@strokecolortrue}
+\def\pgfsys@color@cmyk@fill#1#2#3#4{\pgfsysprotocol@literal{/pgffc{#1 #2 #3 #4 setcmykcolor}def}\pgf@fillcolortrue}
+\def\pgfsys@color@cmyk#1#2#3#4{\pgfsys@color@reset\pgfsysprotocol@literal{#1 #2 #3 #4 setcmykcolor}}
+\def\pgfsys@color@cmy@stroke#1#2#3{\pgfsysprotocol@literal{/pgfsc{#1 #2 #3 0 setcmykcolor}def}\pgf@strokecolortrue}
+\def\pgfsys@color@cmy@fill#1#2#3{\pgfsysprotocol@literal{/pgffc{#1 #2 #3 0 setcmykcolor}def}\pgf@fillcolortrue}
+\def\pgfsys@color@cmy#1#2#3{\pgfsys@color@reset\pgfsysprotocol@literal{#1 #2 #3 0 setcmykcolor}}
+\def\pgfsys@color@gray@stroke#1{\pgfsysprotocol@literal{/pgfsc{#1 setgray}def}\pgf@strokecolortrue}
+\def\pgfsys@color@gray@fill#1{\pgfsysprotocol@literal{/pgffc{#1 setgray}def}\pgf@fillcolortrue}
+\def\pgfsys@color@gray#1{\pgfsys@color@reset\pgfsysprotocol@literal{#1 setgray}}
+\def\pgfsysps@color@resetnow{\pgfsysprotocol@literal{/pgfsc{}def/pgffc{}def}\pgf@strokecolorfalse\pgf@fillcolorfalse}%
+\def\pgfsys@color@reset{%
+ \ifpgfsys@color@reset@inorder%
+ \ifpgf@strokecolor%
+ \pgfsysps@color@resetnow%
+ \else%
+ \ifpgf@fillcolor%
+ \pgfsysps@color@resetnow%
+ \fi%
+ \fi%
+ \else%
+ \pgfsysps@color@resetnow%
+ \fi}
+
+
+% Opacity
+
+\def\pgfsys@fill@opacity#1{%
+ \pgfsysprotocol@literal{#1 .pgfsetfillopacityalpha}%
+}
+\def\pgfsys@stroke@opacity#1{%
+ \pgfsysprotocol@literal{#1 .pgfsetstrokeopacityalpha}%
+}
+
+% Objects
+\newcount\pgf@objectcount
+\def\pgfsys@defobject#1#2#3#4{%
+ \global\advance\pgf@objectcount by 1%
+ \expandafter\xdef\csname#1\endcsname{\the\pgf@objectcount}%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@temp%
+ {%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ #4%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@@temp%
+ \pgf@sys@postscript@object{/pgf\csname#1\endcsname{gsave exec \pgfsys@@temp\space grestore} bind def}%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfsys@temp%
+}
+\def\pgfsys@useobject#1#2{%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@temp%
+ {%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedfalse%
+ #2%
+ \pgfsysprotocol@invokecurrentprotocol%
+ \pgfsys@invoke{pgf\csname#1\endcsname}%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfsys@temp}
+
+% Shadings
+
+\def\pgfsys@horishading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathsetlength\pgf@x{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@y=\pgf@max%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \xdef\pgfutil@tempa{\hbox to \the\pgf@max{%
+ \noexpand\vrule width0pt height\the\pgf@xa%
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@rect{0pt}{0pt}{\the\pgf@max}{\the\pgf@xa}%
+ \noexpand\pgfsys@clipnext%
+ \noexpand\pgfsys@discardpath%
+ \noexpand\pgfsys@invoke{\pgf@domb\space \pgf@sys@tonumber{\pgf@x} pgfH\pgf@shading@model\space \pgf@psfuncs\space pop}%
+ \hss%
+ \noexpand\pgfsys@endpurepicture}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+\def\pgfsys@vertshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathsetlength\pgf@x{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@y=\pgf@max%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \xdef\pgfutil@tempa{\hbox to \the\pgf@xa{%
+ \noexpand\vrule width0pt height\the\pgf@max%
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@rect{0pt}{0pt}{\the\pgf@xa}{\the\pgf@max}%
+ \noexpand\pgfsys@clipnext%
+ \noexpand\pgfsys@discardpath%
+ \noexpand\pgfsys@invoke{\pgf@domb\space \pgf@sys@tonumber{\pgf@x} pgfV\pgf@shading@model\space \pgf@psfuncs\space pop}%
+ \hss%
+ \noexpand\pgfsys@endpurepicture}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+\def\pgfsys@radialshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@process{#2}%
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \pgf@xa=2\pgf@max%
+ \pgf@sys@bp@correct{\pgf@max}%
+ \advance\pgf@x by \pgf@max%
+ \advance\pgf@y by \pgf@max%
+ \xdef\pgfutil@tempa{\hbox to \the\pgf@xa{%
+ \noexpand\vrule width0pt height\the\pgf@xa%
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@invoke{%
+ \pgf@domb\space \pgf@sys@tonumber{\pgf@y} \pgf@sys@tonumber{\pgf@x} \pgf@sys@tonumber{\pgf@max} pgfR1\pgf@shading@model\space
+ \pgf@psfuncs\space \pgf@firstcolor\space \pgf@doma\space pgfR2\pgf@shading@model}%
+ \hss%
+ \noexpand\pgfsys@endpurepicture}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+\def\pgfsys@functionalshading#1#2#3#4{%
+ {%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgf@sys@bp@correct{\pgf@xb}%
+ \pgf@sys@bp@correct{\pgf@yb}%
+ \pgf@xc=-\pgf@xa%
+ \pgf@yc=-\pgf@ya%
+ \xdef\pgfutil@tempa{%
+ \hbox to\the\pgf@x{\vbox to\the\pgf@y{\vfil
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@invoke{%
+ \pgf@sys@tonumber{\pgf@xc} \pgf@sys@tonumber{\pgf@yc} translate
+ 1.1 setlinewidth [] 0 setdash 0 setlinecap
+ /pgfproc {#4} bind def
+ \pgf@sys@tonumber{\pgf@ya} 1 \pgf@sys@tonumber{\pgf@yb}
+ {
+ \pgf@sys@tonumber{\pgf@xa} 1 \pgf@sys@tonumber{\pgf@xb}
+ { 1 index 2 copy pgfproc \pgf@shading@ps@device\space moveto 1.1 0 rlineto stroke }
+ for
+ pop
+ }
+ for
+ }%
+ \noexpand\pgfsys@endpurepicture
+ }\hfil}%
+ }%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+
+%
+% Patterns
+%
+
+
+\def\pgfsys@declarepattern#1#2#3#4#5#6#7{%
+ % Start building the pattern dictionary:
+ \pgf@xa=#2\relax%
+ \pgf@ya=#3\relax%
+ \pgf@xb=#4\relax%
+ \pgf@yb=#5\relax%
+ \pgf@xc=#6\relax%
+ \pgf@yc=#7\relax%
+ \pgf@sys@bp@correct\pgf@xa%
+ \pgf@sys@bp@correct\pgf@ya%
+ \pgf@sys@bp@correct\pgf@xb%
+ \pgf@sys@bp@correct\pgf@yb%
+ \pgf@sys@bp@correct\pgf@xc%
+ \pgf@sys@bp@correct\pgf@yc%
+ \pgfsys@@declarepattern{#1}%
+}
+
+\def\pgfsys@@declarepattern#1#2#3#4#5#6#7#8#9{%
+ \pgfutil@tempdima=#6\relax%
+ \pgfutil@tempdimb=#7\relax%
+ \pgf@sys@bp@correct\pgfutil@tempdima%
+ \pgf@sys@bp@correct\pgfutil@tempdimb%
+ \edef\pgf@sys@marshal{%
+ \noexpand\pgfutil@insertatbegincurrentpage{\noexpand\pgfsys@outerinvoke{
+ save true setglobal globaldict begin /pgfpat#1
+ {
+ \ifnum#9=0 [/Pattern /DeviceRGB] \else /Pattern \fi\space
+ setcolorspace
+ gsave
+ initgraphics
+ <<
+ /Type /Pattern
+ /PatternType 1
+ /PaintType \ifnum#9=0 2 \else 1 \fi
+ /TilingType 1
+ /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb]
+ /XStep \pgf@sys@tonumber\pgf@xc\space
+ /YStep \pgf@sys@tonumber\pgf@yc\space
+ /Matrix [#2\space#3\space#4\space#5\space\pgf@sys@tonumber\pgfutil@tempdima\space\pgf@sys@tonumber\pgfutil@tempdimb]
+ /PaintProc
+ { begin 2 dict begin #8\space end end } bind
+ >>
+ matrix
+ makepattern
+ %/pgfpat#1\space exch def
+ grestore
+ setcolor
+ } bind def end restore
+ }}% <<
+ }%
+ \pgf@sys@marshal%
+}
+
+\def\pgfsys@setpatternuncolored#1#2#3#4{%
+ \pgfsysprotocol@literal{/pgffc{#2 #3 #4 pgfpat#1}def}%
+% [/Pattern /DeviceRGB] setcolorspace
+% #2 #3 #4 pgfpat#1\space setcolor
+% }def}%
+ \pgf@fillcolortrue%
+}
+
+\def\pgfsys@setpatterncolored#1{%
+ \pgfsysprotocol@literal{/pgffc{pgfpat#1}def}%/Pattern setcolorspace
+% pgfpat#1\space setcolor}def}%
+ \pgf@fillcolortrue%
+}
+
+
+
+\def\pgfsys@atbegindocument{%
+ % Parameters to horizontal pre axishade: \pgf@domb x
+ \pgf@sys@postscript@header{/pgfHrgb{%
+ /pgfheight exch def 0.75 setlinewidth [] 0 setdash
+ /pgfshade {pgfArgb} def /pgfdir { dup 0 moveto
+ dup 5 index lineto } bind def} bind def}%
+
+ % Parameters to vertical pre axishade: \pgf@domb x
+ \pgf@sys@postscript@header{/pgfVrgb{%
+ /pgfheight exch def 0.75 setlinewidth [] 0 setdash
+ /pgfshade {pgfArgb} def /pgfdir { dup 0 exch moveto dup 5 index
+ exch lineto } bind def} bind def}%
+
+ % Parameters to axishade: end x, start x, r-, g-, b- of first color, r-, g-, b- of second color
+ % Stack afterwards: end x
+ \pgf@sys@postscript@header{/pgfArgb{
+ /pgfdiff 8 index round cvi 8 index round cvi sub 2 mul 1 add def
+ 2 index 6 index sub pgfdiff div % put red-step on stack
+ 2 index 6 index sub pgfdiff div % put green-step on stack
+ 2 index 6 index sub pgfdiff div % put blue-step on stack
+ pgfheight 9 index 9 index 9 index 14 index
+ pgfdiff {
+ 3 index 3 index 3 index setrgbcolor % Set color
+ pgfdir
+ stroke
+ 4 -1 roll 7 index add % red += incred
+ 4 -1 roll 6 index add % green += incgreen
+ 4 -1 roll 5 index add % blue += incblue
+ 4 -1 roll .5 sub % x += 0.5
+ } repeat
+ mark 15 1 roll cleartomark exch pop % leave only start x on stack
+ }bind def }
+
+ % Parameters to radialshade pre: \pgf@domb y x max
+ \pgf@sys@postscript@header{/pgfR1rgb{
+ newpath dup dup dup 0 360 arc clip newpath
+ dup /pgfendx exch def
+ /pgfendy exch def
+ 0.875 setlinewidth
+ [] 0 setdash
+ /pgfshade {pgfRrgb} def
+ /pgfstartx exch def
+ /pgfstarty exch def
+ /pgfdiffx pgfendx pgfstartx sub def
+ /pgfdiffy pgfendy pgfstarty sub def
+ dup /pgfdomb exch def
+ }bind def }
+
+ % Parameters to radialshade post: \pgf@firstcolor \pgf@doma
+ \pgf@sys@postscript@header{/pgfR2rgb{
+ newpath 0.5 add pgfcircx pgfcircy 3 2 roll 0 360 arc
+ setrgbcolor fill pop}bind def }%
+
+ % Parameters to radialshade: end x, start x, r-, g-, b- of first color, r-, g-, b- of second color
+ % Stack afterwards: end x
+ \pgf@sys@postscript@header{/pgfRrgb{
+ /pgfdiff 8 index round cvi 8 index round cvi sub 4 mul 1 add def
+ /pgfcircx pgfstartx 9 index pgfdiffx pgfdomb div mul add def
+ /pgfcircy pgfstarty 9 index pgfdiffy pgfdomb div mul add def
+ /pgfcircxe pgfstartx 8 index pgfdiffx pgfdomb div mul add def
+ /pgfcircye pgfstarty 8 index pgfdiffy pgfdomb div mul add def
+ /pgfxstep pgfcircxe pgfcircx sub pgfdiff div def
+ /pgfystep pgfcircye pgfcircy sub pgfdiff div def
+ 2 index 6 index sub pgfdiff div % put red-step on stack
+ 2 index 6 index sub pgfdiff div % put green-step on stack
+ 2 index 6 index sub pgfdiff div % put green-step on stack
+ 8 index 8 index 8 index 13 index
+ pgfdiff {
+ 3 index 3 index 3 index setrgbcolor % Set color
+ pgfcircx pgfcircy 2 index 0 360 arc closepath
+ stroke
+ 4 -1 roll 6 index add % red += incred
+ 4 -1 roll 5 index add % green += incgreen
+ 4 -1 roll 4 index add % blue += incblue
+ 4 -1 roll .25 sub % x += 0.25
+ /pgfcircx pgfcircx pgfxstep add def
+ /pgfcircy pgfcircy pgfystep add def
+ } repeat
+ mark 14 1 roll cleartomark exch pop % leave only start x on stack
+ }bind def}
+
+ % Parameters to horizontal pre axishade: \pgf@domb x
+ \pgf@sys@postscript@header{/pgfHcmyk{
+ /pgfheight exch def 0.75 setlinewidth [] 0 setdash
+ /pgfshade {pgfAcmyk} def /pgfdir { dup 0 moveto
+ dup 6 index lineto } bind def} bind def}%
+
+ % Parameters to vertical pre axishade: \pgf@domb x
+ \pgf@sys@postscript@header{/pgfVcmyk{
+ /pgfheight exch def 0.75 setlinewidth [] 0 setdash
+ /pgfshade {pgfAcmyk} def /pgfdir { dup 0 exch moveto dup 6 index
+ exch lineto } bind def} bind def}%
+
+ % Parameters to axishade: end x, start x, c-, m-, y-, k- of first color, c-, m-, y-, k- of second color
+ \pgf@sys@postscript@header{/pgfAcmyk{
+ /pgfdiff 10 index round cvi 10 index round cvi sub 2 mul 1 add def
+ 3 index 8 index sub pgfdiff div % put cyan-step on stack
+ 3 index 8 index sub pgfdiff div % put magenta-step on stack
+ 3 index 8 index sub pgfdiff div % put yellow-step on stack
+ 3 index 8 index sub pgfdiff div % put black-step on stack
+ pgfheight 12 index 12 index 12 index 12 index 18 index
+ pgfdiff {
+ 4 index 4 index 4 index 4 index setcmykcolor % Set color
+ pgfdir
+ stroke
+ 5 -1 roll 9 index add % cyan += inccyan
+ 5 -1 roll 8 index add % magenta += incmagenta
+ 5 -1 roll 7 index add % yellow += incyellow
+ 5 -1 roll 6 index add % black += incblack
+ 5 -1 roll .5 sub % x += 0.5
+ } repeat
+ mark 19 1 roll cleartomark exch pop % leave only start x on stack
+ }bind def }%
+
+ % Parameters to radialshade pre: \pgf@domb y x max
+ \pgf@sys@postscript@header{/pgfR1cmyk{
+ newpath dup dup dup 0 360 arc clip newpath
+ dup /pgfendx exch def
+ /pgfendy exch def
+ 0.875 setlinewidth
+ [] 0 setdash
+ /pgfshade {pgfRcmyk} def
+ /pgfstartx exch def
+ /pgfstarty exch def
+ /pgfdiffx pgfendx pgfstartx sub def
+ /pgfdiffy pgfendy pgfstarty sub def
+ dup /pgfdomb exch def
+ }bind def }%
+
+ % Parameters to radialshade post: \pgf@firstcolor \pgf@doma
+ \pgf@sys@postscript@header{/pgfR2cmyk{
+ newpath 0.5 add pgfcircx pgfcircy 3 2 roll 0 360 arc
+ setcmykcolor fill pop}bind def }%
+
+ % Parameters to radialshade: end x, start x, c-, m-, y-, k- of first color, c-, m-, y-, k- of second color
+ \pgf@sys@postscript@header{/pgfRcmyk{
+ /pgfdiff 10 index round cvi 10 index round cvi sub 4 mul 1 add def
+ /pgfcircx pgfstartx 11 index pgfdiffx pgfdomb div mul add def
+ /pgfcircy pgfstarty 11 index pgfdiffy pgfdomb div mul add def
+ /pgfcircxe pgfstartx 10 index pgfdiffx pgfdomb div mul add def
+ /pgfcircye pgfstarty 10 index pgfdiffy pgfdomb div mul add def
+ /pgfxstep pgfcircxe pgfcircx sub pgfdiff div def
+ /pgfystep pgfcircye pgfcircy sub pgfdiff div def
+ 3 index 8 index sub pgfdiff div % put cyan-step on stack
+ 3 index 8 index sub pgfdiff div % put magenta-step on stack
+ 3 index 8 index sub pgfdiff div % put yellow-step on stack
+ 3 index 8 index sub pgfdiff div % put black-step on stack
+ 11 index 11 index 11 index 11 index 17 index
+ pgfdiff {
+ 4 index 4 index 4 index 4 index setcmykcolor % Set color
+ pgfcircx pgfcircy 2 index 0 360 arc closepath
+ stroke
+ 5 -1 roll 8 index add % cyan += inccyan
+ 5 -1 roll 7 index add % magenta += incmagenta
+ 5 -1 roll 6 index add % yellow += incyellow
+ 5 -1 roll 5 index add % black += incblack
+ 5 -1 roll .25 sub % x += 0.25
+ /pgfcircx pgfcircx pgfxstep add def
+ /pgfcircy pgfcircy pgfystep add def
+ } repeat
+ mark 18 1 roll cleartomark exch pop % leave only start x on stack
+ }bind def}%
+
+ % Parameters to horizontal pre axishade: \pgf@domb x
+ \pgf@sys@postscript@header{/pgfHgray{
+ /pgfheight exch def 0.75 setlinewidth [] 0 setdash
+ /pgfshade {pgfAgray} def /pgfdir { dup 0 moveto
+ dup 3 index lineto } bind def} bind def}%
+
+ % Parameters to vertical pre axishade: \pgf@domb x
+ \pgf@sys@postscript@header{/pgfVgray{
+ /pgfheight exch def 0.75 setlinewidth [] 0 setdash
+ /pgfshade {pgfAgray} def /pgfdir { dup 0 exch moveto dup 3 index
+ exch lineto } bind def} bind def}%
+
+ % Parameters to axishade: end x, start x, g of first color, g of second color
+ \pgf@sys@postscript@header{/pgfAgray{
+ /pgfdiff 4 index round cvi 4 index round cvi sub 2 mul 1 add def
+ dup 2 index sub pgfdiff div % put gray-step on stack
+ pgfheight 3 index 6 index
+ pgfdiff {
+ 1 index setgray % Set color
+ pgfdir
+ stroke
+ exch 3 index add % gray += incgray
+ exch .5 sub % x += 0.5
+ } repeat
+ mark 7 1 roll cleartomark exch pop % leave only start x on stack
+ }bind def }%
+
+ % Parameters to radialshade pre: \pgf@domb y x max
+ \pgf@sys@postscript@header{/pgfR1gray{
+ newpath dup dup dup 0 360 arc clip newpath
+ dup /pgfendx exch def
+ /pgfendy exch def
+ 0.875 setlinewidth
+ [] 0 setdash
+ /pgfshade {pgfRgray} def
+ /pgfstartx exch def
+ /pgfstarty exch def
+ /pgfdiffx pgfendx pgfstartx sub def
+ /pgfdiffy pgfendy pgfstarty sub def
+ dup /pgfdomb exch def
+ }bind def }%
+
+ % Parameters to radialshade post: \pgf@firstcolor \pgf@doma
+ \pgf@sys@postscript@header{/pgfR2gray{
+ newpath 0.5 add pgfcircx pgfcircy 3 2 roll 0 360 arc
+ setgray fill pop}bind def }%
+
+ % Parameters to radialshade: end x, start x, g of first color, g of second color
+ \pgf@sys@postscript@header{/pgfRgray{
+ /pgfdiff 4 index round cvi 4 index round cvi sub 4 mul 1 add def
+ /pgfcircx pgfstartx 5 index pgfdiffx pgfdomb div mul add def
+ /pgfcircy pgfstarty 5 index pgfdiffy pgfdomb div mul add def
+ /pgfcircxe pgfstartx 4 index pgfdiffx pgfdomb div mul add def
+ /pgfcircye pgfstarty 4 index pgfdiffy pgfdomb div mul add def
+ /pgfxstep pgfcircxe pgfcircx sub pgfdiff div def
+ /pgfystep pgfcircye pgfcircy sub pgfdiff div def
+ dup 2 index sub pgfdiff div % put gray-step on stack
+ 2 index 5 index
+ pgfdiff {
+ 1 index setgray % Set color
+ pgfcircx pgfcircy 2 index 0 360 arc closepath
+ stroke
+ exch 2 index add % gray += incgray
+ exch .25 sub % x += 0.25
+ /pgfcircx pgfcircx pgfxstep add def
+ /pgfcircy pgfcircy pgfystep add def
+ } repeat
+ mark 6 1 roll cleartomark exch pop % leave only start x on stack
+ }bind def}%
+}
+
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-svg.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-svg.def
new file mode 100644
index 0000000000..f1d2729023
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-common-svg.def
@@ -0,0 +1,1613 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-common-svg.def}
+
+
+% Driver commands for svg
+
+
+
+% Helping functions:
+\def\pgf@sys@svg@make@defs#1{\pgf@sys@fail{svg defs}}
+\def\pgf@sys@svg@ref@defs#1{\pgf@sys@fail{svg defs}}
+\let\pgf@sys@svgpath=\pgfutil@empty
+\def\pgf@sys@svgnum#1{%
+ {%
+ \pgf@x=#1\relax%
+ \edef\temp{\expandafter\Pgf@geT\the\pgf@x\space}%
+ \pgfutil@toks@\expandafter\expandafter\expandafter{\expandafter\pgf@sys@svgpath\temp}%
+ \xdef\pgf@sys@svgpath{\the\pgfutil@toks@}%
+ }%
+}
+\def\pgf@sys@addtosvgpath#1{\pgfutil@g@addto@macro\pgf@sys@svgpath{#1\space}}
+\def\pgf@sys@flushsvgpath{\pgfsysprotocol@literal{\pgf@sys@svgpath}\global\let\pgf@sys@svgpath=\pgfutil@empty}
+\def\pgf@sys@svg@gs#1{%
+ {%
+ \pgfsysprotocol@literal{<g #1>\pgfsys@svg@newline}%
+ }%
+ \global\advance\pgf@sys@svg@scopecount by1\relax%
+}
+\newcount\pgf@sys@svg@objectcount
+
+{\catcode`\%=12
+\gdef\pgf@sys@svg@percentchar{%}
+}
+{\catcode`\#=11
+\gdef\pgf@sys@svg@hash{#}
+}
+
+% Path construction:
+\def\pgfsys@lineto#1#2{\pgf@sys@addtosvgpath{L}\pgf@sys@svgnum{#1}\pgf@sys@svgnum{#2}}
+\def\pgfsys@moveto#1#2{\pgf@sys@addtosvgpath{M}\pgf@sys@svgnum{#1}\pgf@sys@svgnum{#2}}
+\def\pgfsys@curveto#1#2#3#4#5#6{%
+ \pgf@sys@addtosvgpath{C}%
+ \pgf@sys@svgnum{#1}\pgf@sys@svgnum{#2}%
+ \pgf@sys@svgnum{#3}\pgf@sys@svgnum{#4}%
+ \pgf@sys@svgnum{#5}\pgf@sys@svgnum{#6}}
+\def\pgfsys@rect#1#2#3#4{%
+ \pgfsys@moveto{#1}{#2}%
+ \pgf@sys@addtosvgpath{h}\pgf@sys@svgnum{#3}%
+ \pgf@sys@addtosvgpath{v}\pgf@sys@svgnum{#4}%
+ \pgf@sys@addtosvgpath{h}{\pgf@x=#3\pgf@x=-\pgf@x\pgf@sys@svgnum{\pgf@x}}%
+ \pgfsys@closepath}
+\def\pgfsys@closepath{\pgf@sys@addtosvgpath{Z}}
+
+% Path usage:
+\newif\ifpgf@sys@svg@clipnext
+\def\pgf@sys@svg@possiblyclippedpath#1{%
+ \edef\pgf@sys@cacheref{\pgfsys@id@refcurrent}%
+ \pgfsys@if@fresh@currentid{\csname pgf@sys@svg@path@\pgf@sys@cacheref\endcsname}{}%
+ \let\pgfsys@anim@ba@d\pgfutil@empty
+ \csname pgfsys@anim@ba@\pgf@sys@cacheref\endcsname%
+ \ifpgf@sys@svg@clipnext%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \pgfsysprotocol@literal{%
+ <clipPath id="\pgfsys@if@fresh@currentid{\pgf@sys@cacheref}{pgfcp\the\pgf@sys@svg@objectcount}clip">
+ <path id="\pgfsys@if@fresh@currentid{\pgf@sys@cacheref}{pgfcp\the\pgf@sys@svg@objectcount}" d="}%
+ \ifx\pgfsys@anim@ba@d\pgfutil@empty\pgf@sys@flushsvgpath\else\pgfsysprotocol@literal{\pgfsys@anim@ba@d}\fi%
+ \pgfsysprotocol@literal{"/> </clipPath>\pgfsys@svg@newline }
+ \pgfsysprotocol@literal{<use xlink:href="\#\pgfsys@if@fresh@currentid{\pgf@sys@cacheref}{pgfcp\the\pgf@sys@svg@objectcount}" %
+ \ifx\pgfsys@anim@ba@d\pgfutil@empty\else%
+ \ifx\pgfsys@anim@ba@markerstart\pgfutil@empty\else%
+ marker-start="url(\#\pgfsys@anim@ba@markerstart)" %
+ \fi%
+ \ifx\pgfsys@anim@ba@markerend\pgfutil@empty\else%
+ marker-end="url(\#\pgfsys@anim@ba@markerend)" %
+ \fi%
+ \fi%
+ #1/>\pgfsys@svg@newline }%
+ \pgf@sys@svg@gs{clip-path="url(\#\pgfsys@if@fresh@currentid{\pgfsys@id@refcurrent}{pgfcp\the\pgf@sys@svg@objectcount}clip)"}
+ \pgf@sys@svg@clipnextfalse%
+ \else%
+ \pgfsysprotocol@literal{<path\pgfsys@if@fresh@currentid{ id="\pgfsys@id@refcurrent"}{} d="}%
+ \ifx\pgfsys@anim@ba@d\pgfutil@empty\pgf@sys@flushsvgpath\else\pgfsysprotocol@literal{\pgfsys@anim@ba@d}\fi%
+ \pgfsysprotocol@literal{" %
+ \ifx\pgfsys@anim@ba@d\pgfutil@empty\else%
+ \ifx\pgfsys@anim@ba@markerstart\pgfutil@empty\else%
+ marker-start="url(\#\pgfsys@anim@ba@markerstart)" %
+ \fi%
+ \ifx\pgfsys@anim@ba@markerend\pgfutil@empty\else%
+ marker-end="url(\#\pgfsys@anim@ba@markerend)" %
+ \fi%
+ \fi%
+ #1/>\pgfsys@svg@newline }%
+ \fi%
+ \pgfsys@invalidate@currentid%
+}
+\def\pgfsys@stroke{\pgf@sys@svg@possiblyclippedpath{fill="none"}}
+\def\pgfsys@fill{\pgf@sys@svg@possiblyclippedpath{stroke="none"}}
+\def\pgfsys@fillstroke{\pgf@sys@svg@possiblyclippedpath{}}
+\def\pgfsys@clipnext{\pgf@sys@svg@clipnexttrue}
+\def\pgfsys@discardpath{%
+ \ifpgf@sys@svg@clipnext%
+ \edef\pgf@sys@cacheref{\pgfsys@id@refcurrent}%
+ \let\pgfsys@anim@ba@d\pgfutil@empty
+ \csname pgfsys@anim@ba@\pgf@sys@cacheref\endcsname%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \pgfsysprotocol@literal{%
+ <clipPath id="pgfcp\the\pgf@sys@svg@objectcount">%
+ <path\pgfsys@if@fresh@currentid{ id="\pgfsys@id@refcurrent"}{} d="}%
+ \ifx\pgfsys@anim@ba@d\pgfutil@empty\pgf@sys@flushsvgpath\else\pgfsysprotocol@literal{\pgfsys@anim@ba@d}\fi%
+ \pgfsysprotocol@literal{"/> </clipPath>\pgfsys@svg@newline }
+ \pgf@sys@svg@gs{clip-path="url(\#pgfcp\the\pgf@sys@svg@objectcount)"}
+ \pgf@sys@svg@clipnextfalse%
+ \else%
+ \global\let\pgf@sys@svgpath=\pgfutil@empty
+ \fi%
+ \pgfsys@invalidate@currentid%
+}
+
+% Fill rules:
+\def\pgfsys@eoruletrue{\pgf@sys@svg@gs{fill-rule="evenodd"}}
+\def\pgfsys@eorulefalse{\pgf@sys@svg@gs{fill-rule="nonzero"}}
+
+% Transparency:
+\def\pgfsys@opacity#1{\pgf@sys@svg@gs{opacity="#1"}}
+\def\pgfsys@stroke@opacity#1{\pgf@sys@svg@gs{stroke-opacity="#1"}}
+\def\pgfsys@fill@opacity#1{\pgf@sys@svg@gs{fill-opacity="#1"}\def\pgf@sys@svg@opacity{#1}}
+\def\pgf@sys@svg@opacity{1}
+\def\pgfsys@transparencygroupfrombox#1{%
+ \setbox#1=\hbox{%
+ \pgfsys@invoke{<g opacity="\pgf@sys@svg@opacity" stroke-opacity="1" fill-opacity="1">\pgfsys@svg@newline }%
+ \box#1%
+ \pgfsys@invoke{</g>\pgfsys@svg@newline }%
+ }%
+}
+
+% Transformation:
+\def\pgfsys@transformcm#1#2#3#4#5#6{%
+ {\pgf@x=#5\pgf@y=#6%
+ \edef\pgf@temp{#1,#2,#3,#4}%
+ \ifx\pgf@temp\pgf@sys@svg@idtrans@text%
+ \ifdim\pgf@x=0pt\relax%
+ \ifdim\pgf@y=0pt%
+ \else%
+ \pgf@sys@svg@gs{transform="translate(\pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})"}%
+ \fi%
+ \else%
+ \pgf@sys@svg@gs{transform="translate(\pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})"}%
+ \fi%
+ \else%
+ \pgf@sys@svg@gs{transform="matrix(#1,#2,#3,#4,\pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})"}%
+ \fi}}
+\def\pgfsys@transformshift#1#2{%
+ {\pgf@x=#1\pgf@y=#2%
+ \ifdim\pgf@x=0pt\relax%
+ \ifdim\pgf@y=0pt%
+ \else%
+ \pgf@sys@svg@gs{transform="translate(\pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})"}%
+ \fi%
+ \else%
+ \pgf@sys@svg@gs{transform="translate(\pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})"}%
+ \fi}}
+\def\pgfsys@transformxyscale#1#2{%
+ {\pgf@x=#1pt\pgf@y=#2pt%
+ \pgf@sys@svg@gs{transform="scale(\pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})"}}}
+\def\pgfsys@viewboxmeet{\pgf@sys@svg@viewbox{meet}}
+\def\pgfsys@viewboxslice{\pgf@sys@svg@viewbox{slice}}
+\def\pgf@sys@svg@viewbox#1#2#3#4#5#6#7#8#9{%
+ {%
+ \edef\pgf@sys@cacheref{\pgfsys@id@refcurrent}%
+ \csname pgfsys@anim@ba@\pgf@sys@cacheref\endcsname%
+ \pgf@x#2%
+ \pgf@y#3%
+ \pgf@xa#4%
+ \pgf@ya#5%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \pgf@xb#6%
+ \pgf@yb#7%
+ \pgf@xc#8%
+ \pgf@yc#9%
+ \advance\pgf@xc by-\pgf@xb%
+ \advance\pgf@yc by-\pgf@yb%
+ \pgfsysprotocol@literal{<svg
+ overflow="visible"
+ preserveAspectRatio="xMidYMid #1"
+ \pgfsys@if@fresh@currentid{ id="\pgf@sys@cacheref"}{}
+ x="\pgf@sys@tonumber{\pgf@x}"
+ y="\pgf@sys@tonumber{\pgf@y}"
+ width="\pgf@sys@tonumber{\pgf@xa}"
+ height="\pgf@sys@tonumber{\pgf@ya}"
+ viewBox="%
+ \ifx\pgfsys@anim@ba@viewBox\pgfutil@empty%
+ \pgf@sys@tonumber{\pgf@xb} \pgf@sys@tonumber{\pgf@yb} \pgf@sys@tonumber{\pgf@xc} \pgf@sys@tonumber{\pgf@yc}%
+ \else%
+ \pgfsys@anim@ba@viewBox%
+ \fi%
+ ">}%
+ \pgfsys@invalidate@currentid%
+ }%
+}
+\def\pgfsys@endviewbox{\pgfsysprotocol@literal{</svg>}}
+
+
+% Scopes
+\newcount\pgf@sys@svg@scopecount
+
+\newif\ifpgfsys@svg@boxmode
+\def\pgfsys@begin@text{\pgfsys@beginscope\pgfsys@svg@boxmodetrue}
+\def\pgfsys@end@text{\pgfsys@endscope}
+
+\def\pgfsys@beginscope{%
+ \edef\pgf@sys@svg@thescopecount{\the\pgf@sys@svg@scopecount}%
+ \begingroup%
+ \pgf@sys@svg@scopecount=0\relax%
+}
+\def\pgfsys@beginscope@#1{%
+ \edef\pgf@sys@svg@thescopecount{\the\pgf@sys@svg@scopecount}%
+ \begingroup%
+ \pgf@sys@svg@scopecount=1\relax%
+ \pgfsysprotocol@literal{<g#1>\pgfsys@svg@newline }%
+}
+\def\pgfsys@endscope{%
+ \loop%
+ \ifnum\pgf@sys@svg@scopecount>0\relax%
+ \pgfsysprotocol@literal{</g>\pgfsys@svg@newline }%
+ \advance\pgf@sys@svg@scopecount by-1\relax%
+ \repeat%
+ \endgroup%
+ \global\pgf@sys@svg@scopecount=\pgf@sys@svg@thescopecount\relax%
+}
+\newif\ifpgfsys@svg@close@strokenone
+\def\pgfsys@begin@idscope{%
+ \begingroup%
+ \pgfsys@if@fresh@currentid{%
+ \edef\pgf@sys@cacheref{\pgfsys@id@refcurrent}%
+ \let\pgf@sys@svg@ba@gs\pgfutil@empty%
+ \csname pgfsys@anim@ba@\pgf@sys@cacheref\endcsname%
+ \pgfsys@beginscope@{ id="\pgf@sys@cacheref" \pgf@sys@svg@ba@gs\pgfsys@svg@rdf}%
+ \expandafter\let\expandafter\pgf@sys@svg@end@id@scope@code\csname pgf@sys@att@end@\pgfsys@id@refcurrent\endcsname%
+ \let\pgf@sys@svg@end@id@scope\pgfsys@endscope%
+ \csname pgf@sys@att@beg@\pgfsys@id@refcurrent\endcsname%
+ }{%
+ \ifx\pgfsys@svg@rdf\pgfutil@empty%
+ \let\pgf@sys@svg@end@id@scope@code\relax%
+ \let\pgf@sys@svg@end@id@scope\relax%
+ \else%
+ \pgfsys@beginscope@{\pgfsys@svg@rdf}%
+ \let\pgf@sys@svg@end@id@scope@code\relax%
+ \let\pgf@sys@svg@end@id@scope\pgfsys@endscope%
+ \fi%
+ }%
+ \expandafter\global\expandafter\let\csname pgf@sys@att@beg@\pgfsys@id@refcurrent\endcsname\relax%
+ \expandafter\global\expandafter\let\csname pgf@sys@att@end@\pgfsys@id@refcurrent\endcsname\relax%
+ \ifpgfsys@svg@boxmode\pgfsysprotocol@literal{<g stroke="none">}\pgfsys@svg@close@strokenonetrue\fi%
+ \pgfsys@invalidate@currentid%
+ \begingroup%
+ \global\let\pgfsys@svg@rdf\pgfutil@empty%
+}
+\def\pgfsys@end@idscope{%
+ \endgroup%
+ \ifpgfsys@svg@close@strokenone\pgfsysprotocol@literal{</g>}\fi%
+ \pgf@sys@svg@end@id@scope@code%
+ \pgf@sys@svg@end@id@scope%
+ \endgroup%
+}
+\let\pgfsys@svg@rdf\pgfutil@empty%
+
+% IDs
+
+\newcount\pgf@sys@svg@type@count
+
+\def\pgfsys@clean@type#1#2{%
+ \expandafter\let\expandafter#1\csname pgf@sys@svg@lookup@#2\endcsname%
+ \if#1\relax%
+ \global\advance\pgf@sys@svg@type@count by1\relax%
+ \expandafter\xdef\csname pgf@sys@svg@lookup@#2\endcsname{t\the\pgf@sys@svg@type@count}%
+ \expandafter\let\expandafter#1\csname pgf@sys@svg@lookup@#2\endcsname%
+ \fi%
+}
+
+
+
+% Graphics state
+\def\pgfsys@setdash#1#2{%
+ {%
+ \pgf@xa#2\relax%
+ \edef\pgf@test@dashpattern{#1}%
+ \ifx\pgf@test@dashpattern\pgfutil@empty%
+ \pgf@sys@svg@gs{stroke-dasharray="none" stroke-dashoffset="\pgf@sys@tonumber\pgf@xa"}%
+ \else%
+ \let\pgf@sys@svg@parsed@dash\pgfutil@empty%
+ \expandafter\pgf@sys@svg@parse@dash\pgf@test@dashpattern,\relax%
+ \pgf@sys@svg@gs{stroke-dasharray="\pgf@sys@svg@parsed@dash" stroke-dashoffset="\pgf@sys@tonumber\pgf@xa"}%
+ \fi%
+ }%
+}
+\def\pgf@sys@svg@parse@dash#1,{%
+ \pgf@x#1\relax%
+ \pgfutil@ifnextchar\relax{%
+ \edef\pgf@sys@svg@parsed@dash{\pgf@sys@svg@parsed@dash\pgf@sys@tonumber\pgf@x}%
+ }{%
+ \edef\pgf@sys@svg@parsed@dash{\pgf@sys@svg@parsed@dash\pgf@sys@tonumber\pgf@x,}%
+ \pgf@sys@svg@parse@dash%
+ }%
+}
+\def\pgfsys@setlinewidth#1{{\pgf@x=#1\pgf@sys@svg@gs{stroke-width="\pgf@sys@tonumber{\pgf@x}"}}}
+\def\pgfsys@setmiterlimit#1{\pgf@sys@svg@gs{stroke-miterlimit="#1"}}
+\def\pgfsys@buttcap{\pgf@sys@svg@gs{stroke-linecap="butt"}}
+\def\pgfsys@roundcap{\pgf@sys@svg@gs{stroke-linecap="round"}}
+\def\pgfsys@rectcap{\pgf@sys@svg@gs{stroke-linecap="square"}}
+\def\pgfsys@miterjoin{\pgf@sys@svg@gs{stroke-linejoin="miter"}}
+\def\pgfsys@roundjoin{\pgf@sys@svg@gs{stroke-linejoin="round"}}
+\def\pgfsys@beveljoin{\pgf@sys@svg@gs{stroke-linejoin="bevel"}}
+
+% Invisibility
+\def\pgfsys@begininvisible{\pgfsysprotocol@literal{<g visibility="hidden">\pgfsys@svg@newline }}
+\def\pgfsys@endinvisible{\pgfsysprotocol@literal{</g>}}
+\def\pgfsys@begininvisiblescope{\pgfsys@beginscope@{ visibility="hidden"}}
+\def\pgfsys@endinvisiblescope{\pgfsys@endscope}
+
+
+%
+% Color management
+%
+
+\def\pgf@sys@svg@rgb@to@hash#1#2#3{%
+ {%
+ \pgf@sys@svg@do@color{#1}%
+ \let\pgf@sys@svg@ra\pgf@sys@svg@hex@first%
+ \let\pgf@sys@svg@rb\pgf@sys@svg@hex@second%
+ \pgf@sys@svg@do@color{#2}%
+ \let\pgf@sys@svg@ga\pgf@sys@svg@hex@first%
+ \let\pgf@sys@svg@gb\pgf@sys@svg@hex@second%
+ \pgf@sys@svg@do@color{#3}%
+ \let\pgf@sys@svg@ba\pgf@sys@svg@hex@first%
+ \let\pgf@sys@svg@bb\pgf@sys@svg@hex@second%
+ \xdef\pgf@sys@svg@prepared{\pgf@sys@svg@hash\pgf@sys@svg@ra\pgf@sys@svg@rb\pgf@sys@svg@ga\pgf@sys@svg@gb\pgf@sys@svg@ba\pgf@sys@svg@bb}%
+ \ifx\pgf@sys@svg@ra\pgf@sys@svg@rb%
+ \ifx\pgf@sys@svg@ga\pgf@sys@svg@gb%
+ \ifx\pgf@sys@svg@ba\pgf@sys@svg@bb%
+ \xdef\pgf@sys@svg@prepared{\pgf@sys@svg@hash\pgf@sys@svg@ra\pgf@sys@svg@ga\pgf@sys@svg@ba}%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}
+
+\expandafter\def\csname pgf@svg@0\endcsname{0}
+\expandafter\def\csname pgf@svg@1\endcsname{1}
+\expandafter\def\csname pgf@svg@2\endcsname{2}
+\expandafter\def\csname pgf@svg@3\endcsname{3}
+\expandafter\def\csname pgf@svg@4\endcsname{4}
+\expandafter\def\csname pgf@svg@5\endcsname{5}
+\expandafter\def\csname pgf@svg@6\endcsname{6}
+\expandafter\def\csname pgf@svg@7\endcsname{7}
+\expandafter\def\csname pgf@svg@8\endcsname{8}
+\expandafter\def\csname pgf@svg@9\endcsname{9}
+\expandafter\def\csname pgf@svg@10\endcsname{a}
+\expandafter\def\csname pgf@svg@11\endcsname{b}
+\expandafter\def\csname pgf@svg@12\endcsname{c}
+\expandafter\def\csname pgf@svg@13\endcsname{d}
+\expandafter\def\csname pgf@svg@14\endcsname{e}
+\expandafter\def\csname pgf@svg@15\endcsname{f}
+
+\def\pgf@sys@svg@do@color#1{%
+ \pgf@x#1\relax%
+ \c@pgf@counta\pgf@x%
+ \divide\c@pgf@counta by256\relax%
+ \ifnum\c@pgf@counta>255\relax%
+ \c@pgf@counta=255\relax%
+ \fi%
+ \ifnum\c@pgf@counta<0\relax%
+ \c@pgf@counta=0\relax%
+ \fi%
+ \c@pgf@countb\c@pgf@counta\relax%
+ \divide\c@pgf@countb by16\relax%
+ \expandafter\let\expandafter\pgf@sys@svg@hex@first\csname pgf@svg@\the\c@pgf@countb\endcsname%
+ \multiply\c@pgf@countb by16\relax%
+ \advance\c@pgf@counta by-\c@pgf@countb\relax%
+ \expandafter\let\expandafter\pgf@sys@svg@hex@second\csname pgf@svg@\the\c@pgf@counta\endcsname%
+}
+
+\def\pgf@sys@svg@color@rgb#1,#2,#3\relax{%
+ {%
+ \pgf@sys@svg@rgb@to@hash{#1pt}{#2pt}{#3pt}%
+ }%
+}
+\def\pgf@sys@svg@color@cmy#1,#2,#3\relax{%
+ {%
+ \pgf@xa=1pt%
+ \advance\pgf@xa by-#1pt%
+ \pgf@xb=1pt%
+ \advance\pgf@xb by-#2pt%
+ \pgf@xc=1pt%
+ \advance\pgf@xc by-#3pt%
+ \pgf@sys@svg@rgb@to@hash{\pgf@xa}{\pgf@xb}{\pgf@xc}%
+ }%
+}
+\def\pgf@sys@svg@color@cmyk#1,#2,#3,#4\relax{%
+ {%
+ \pgf@xa=1pt%
+ \advance\pgf@xa by-#4pt%
+ \pgf@xa=#1\pgf@xa%
+ \advance\pgf@xa by#4pt%
+ \advance\pgf@xa by-1pt%
+ \pgf@xa=-\pgf@xa%
+ \pgf@xb=1pt%
+ \advance\pgf@xb by-#4pt%
+ \pgf@xb=#2\pgf@xb%
+ \advance\pgf@xb by#4pt%
+ \advance\pgf@xb by-1pt%
+ \pgf@xb=-\pgf@xb%
+ \pgf@xc=1pt%
+ \advance\pgf@xc by-#4pt%
+ \pgf@xc=#3\pgf@xc%
+ \advance\pgf@xc by#4pt%
+ \advance\pgf@xc by-1pt%
+ \pgf@xc=-\pgf@xc%
+ \pgf@sys@svg@rgb@to@hash{\pgf@xa}{\pgf@xb}{\pgf@xc}%
+ }%
+}
+\def\pgf@sys@svg@color@gray#1\relax{%
+ {%
+ \pgf@xa=#1pt%
+ \pgf@sys@svg@rgb@to@hash{\pgf@xa}{\pgf@xa}{\pgf@xa}%
+ }%
+}
+
+\def\pgf@sys@svg@gs@color#1{%
+ \ifpgfpicture\pgf@sys@svg@gs{#1}\fi%
+}
+
+\def\pgf@sys@svg@colorpop{\special{color pop}}
+
+
+% RGB
+\def\pgfsys@color@rgb@stroke#1#2#3{%
+ \pgf@sys@svg@color@rgb#1,#2,#3\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{stroke="\pgf@sys@svg@prepared"}}
+\def\pgfsys@color@rgb@fill#1#2#3{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@rgb#1,#2,#3\relax%
+ \pgf@sys@svg@gs@color{fill="\pgf@sys@svg@prepared"}%
+ \else%
+ \special{color push rgb #1 #2 #3}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+\def\pgfsys@color@rgb#1#2#3{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@rgb#1,#2,#3\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{\ifpgfsys@svg@boxmode\else stroke="\pgf@sys@svg@prepared" \fi fill="\pgf@sys@svg@prepared"}%
+ \else%
+ \special{color push rgb #1 #2 #3}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+
+%CMYK
+\def\pgfsys@color@cmyk@stroke#1#2#3#4{%
+ \pgf@sys@svg@color@cmyk#1,#2,#3,#4\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{stroke="\pgf@sys@svg@prepared"}}
+\def\pgfsys@color@cmyk@fill#1#2#3#4{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@cmyk#1,#2,#3,#4\relax%
+ \pgf@sys@svg@gs@color{fill="\pgf@sys@svg@prepared"}%
+ \else%
+ \special{color push cmyk #1 #2 #3 #4}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+\def\pgfsys@color@cmyk#1#2#3#4{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@cmyk#1,#2,#3,#4\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{\ifpgfsys@svg@boxmode\else stroke="\pgf@sys@svg@prepared" \fi fill="\pgf@sys@svg@prepared"}%
+ \else%
+ \special{color push cmyk #1 #2 #3 #4}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+
+% CMY
+\def\pgfsys@color@cmy@stroke#1#2#3{%
+ \pgf@sys@svg@color@cmy#1,#2,#3\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{stroke="\pgf@sys@svg@prepared"}}
+\def\pgfsys@color@cmy@fill#1#2#3{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@cmy#1,#2,#3\relax%
+ \pgf@sys@svg@gs@color{fill="\pgf@sys@svg@prepared"}
+ \else%
+ \special{color push cmyk #1 #2 #3 0}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+\def\pgfsys@color@cmy#1#2#3{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@cmy#1,#2,#3\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{\ifpgfsys@svg@boxmode\else stroke="\pgf@sys@svg@prepared" \fi fill="\pgf@sys@svg@prepared"}%
+ \else%
+ \special{color push cmyk #1 #2 #3 0}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+
+% gray
+\def\pgfsys@color@gray@stroke#1{%
+ \pgf@sys@svg@color@gray#1\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{stroke="\pgf@sys@svg@prepared"}}
+\def\pgfsys@color@gray@fill#1{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@gray#1\relax%
+ \pgf@sys@svg@gs@color{fill="\pgf@sys@svg@prepared"}%
+ \else%
+ \special{color push gray #1}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+\def\pgfsys@color@gray#1{%
+ \ifpgfpicture%
+ \pgf@sys@svg@color@gray#1\relax%
+ \let\pgf@sys@svg@last@stroke\pgf@sys@svg@prepared%
+ \pgf@sys@svg@gs@color{\ifpgfsys@svg@boxmode\else stroke="\pgf@sys@svg@prepared" \fi fill="\pgf@sys@svg@prepared"}%
+ \else%
+ \special{color push gray #1}%
+ \aftergroup\pgf@sys@svg@colorpop%
+ \fi}
+
+
+% Shadings:
+\def\pgf@sys@svg@shading@stops{%
+ % Step 1: Compute 1/\pgf@sys@shading@end@pos
+ \pgf@x=\pgf@sys@shading@end@pos\relax%
+ \c@pgf@counta=\pgf@x\relax%
+ \divide\c@pgf@counta by4096\relax%
+ % Step 2: Insert stops.
+ \expandafter\pgf@sys@svg@shading@dostops\pgf@sys@shading@ranges%
+ % dummy for end:
+ {{\pgf@sys@shading@end@pos}{\pgf@sys@shading@end@pos}{\pgf@sys@shading@end@rgb}{\pgf@sys@shading@end@rgb}}%
+ {}% end
+}
+\def\pgf@sys@svg@shading@dostops#1{%
+ \edef\pgf@test{#1}%
+ \ifx\pgf@test\pgfutil@empty%
+ \else%
+ \expandafter\pgf@sys@svg@shading@dostop\pgf@test%
+ \expandafter\pgf@sys@svg@shading@dostops%
+ \fi%
+}
+\def\pgf@sys@svg@shading@dostop#1#2#3#4{%
+ % #1 start pos
+ % #2 end pos
+ % #3 start rgb
+ % #4 end rgb
+ \pgf@x=#1%
+ \pgf@x=16\pgf@x%
+ \divide\pgf@x by \c@pgf@counta\relax%
+ \pgf@sys@svg@addtostops{<stop offset="\pgf@sys@tonumber\pgf@x" stop-color="}%
+ \pgf@sys@svg@shading@dorgb#3%
+ \pgf@sys@svg@addtostops{"/>\noexpand\pgfsys@svg@newline}%
+}
+\def\pgf@sys@svg@shading@dorgb#1#2#3{%
+ \pgf@sys@svg@color@rgb#1,#2,#3\relax%
+ \pgf@sys@svg@addtostops{\pgf@sys@svg@prepared}%
+}
+
+\let\pgf@sys@svg@thestops=\pgfutil@empty
+\def\pgf@sys@svg@addtostops#1{%
+ \edef\pgf@temp{#1}%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter\pgf@sys@svg@thestops
+ \expandafter\expandafter\expandafter{\expandafter\pgf@sys@svg@thestops\expandafter\space\pgf@temp}%
+}
+
+
+\def\pgfsys@horishading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \pgf@sys@svg@addtostops{<linearGradient id="pgfsh\the\pgf@sys@svg@objectcount">\noexpand\pgfsys@svg@newline}%
+ \pgf@sys@svg@shading@stops%
+ \pgf@sys@svg@addtostops{</linearGradient>\noexpand\pgfsys@svg@newline}%
+ \pgf@process{\pgfpoint{\pgf@sys@shading@end@pos}{#2}}%
+ \xdef\pgfutil@tempa{%
+ \def\noexpand\pgf@sys@svg@sh@defs{\noexpand\pgfsysprotocol@literal{\pgf@sys@svg@thestops}}%
+ \def\noexpand\pgf@sys@svg@sh{\noexpand\pgfsysprotocol@literal{<rect
+ width="\pgf@sys@tonumber{\pgf@x}"
+ height="\pgf@sys@tonumber{\pgf@y}"
+ style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount);
+ stroke:none"/>\noexpand\pgfsys@svg@newline}}%
+ \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
+ }%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+
+\def\pgfsys@functionalshading#1#2#3#4{%
+ \pgf@sys@fail{functional shadings}%
+ \expandafter\gdef\csname @pgfshading#1!\endcsname{%
+ \let\pgf@sys@svg@sh@defs\relax%
+ \let\pgf@sys@svg@sh\relax%
+ \let\pgf@sys@svg@pos\pgfpointorigin%
+ }%
+}
+
+\def\pgfsys@vertshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \pgf@sys@svg@addtostops{<linearGradient
+ id="pgfsh\the\pgf@sys@svg@objectcount"
+ gradientTransform="rotate(90)">\noexpand\pgfsys@svg@newline}%
+ \pgf@sys@svg@shading@stops%
+ \pgf@sys@svg@addtostops{</linearGradient>\noexpand\pgfsys@svg@newline}%
+ \pgf@process{\pgfpoint{\pgf@sys@shading@end@pos}{#2}}%
+ \xdef\pgfutil@tempa{%
+ \def\noexpand\pgf@sys@svg@sh@defs{\noexpand\pgfsysprotocol@literal{\pgf@sys@svg@thestops}}%
+ \def\noexpand\pgf@sys@svg@sh{\noexpand\pgfsysprotocol@literal{<rect
+ width="\pgf@sys@tonumber{\pgf@y}"
+ height="\pgf@sys@tonumber{\pgf@x}"
+ style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount);
+ stroke:none"/>\noexpand\pgfsys@svg@newline}}%
+ \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@y}{\the\pgf@x}}%
+ }%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+
+\def\pgfsys@radialshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@x=\pgf@sys@shading@end@pos\relax%
+ \c@pgf@counta=\pgf@x\relax%
+ \divide\c@pgf@counta by4096\relax%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \pgf@process{#2}%
+ % Divide by 2\pgf@sys@shading@end@pos%
+ \pgf@x=8\pgf@x%
+ \divide\pgf@x by \c@pgf@counta\relax%
+ \pgf@y=8\pgf@y%
+ \divide\pgf@y by \c@pgf@counta\relax%
+ \advance\pgf@x by.5pt%
+ \advance\pgf@y by.5pt%
+ \pgf@sys@svg@addtostops{<radialGradient
+ id="pgfsh\the\pgf@sys@svg@objectcount"
+ fx="\pgf@sys@tonumber\pgf@x"
+ fy="\pgf@sys@tonumber\pgf@y"
+ >\noexpand\pgfsys@svg@newline}%
+ \pgf@sys@svg@shading@stops%
+ \pgf@sys@svg@addtostops{</radialGradient>\noexpand\pgfsys@svg@newline}%
+ \pgf@xa=\pgf@sys@shading@end@pos%
+ \pgf@xb=2\pgf@xa%
+ \xdef\pgfutil@tempa{%
+ \def\noexpand\pgf@sys@svg@sh@defs{\noexpand\pgfsysprotocol@literal{\pgf@sys@svg@thestops}}%
+ \def\noexpand\pgf@sys@svg@sh{\noexpand\pgfsysprotocol@literal{<circle
+ cx="\pgf@sys@tonumber{\pgf@xa}"
+ cy="\pgf@sys@tonumber{\pgf@xa}"
+ r="\pgf@sys@tonumber{\pgf@xa}"
+ style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount);
+ stroke:none"/>\noexpand\pgfsys@svg@newline}}%
+ \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@xb}{\the\pgf@xb}}%
+ }%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+
+
+% Patterns
+
+\def\pgfsys@declarepattern#1#2#3#4#5#6#7{%
+ % Start building the pattern dictionary:
+ \pgf@xa=#2\relax%
+ \pgf@ya=#3\relax%
+ \pgf@xb=#4\relax%
+ \pgf@yb=#5\relax%
+ \pgf@xc=#6\relax%
+ \pgf@yc=#7\relax%
+ \pgfsys@@declarepattern{#1}%
+}
+
+\def\pgfsys@@declarepattern#1#2#3#4#5#6#7#8#9{%
+ \pgfutil@tempdima=#6\relax%
+ \pgfutil@tempdimb=#7\relax%
+ \ifnum#9=1\relax%
+ % Colored. That's easy:
+ \pgf@sys@svg@make@defs{#1}{
+ <pattern
+ id="pgfpat#1"
+ patternUnits="userSpaceOnUse"
+ width="\pgf@sys@tonumber\pgf@xc"
+ height="\pgf@sys@tonumber\pgf@yc"
+ patternTransform="matrix(#2\space#3\space#4\space#5\space\pgf@sys@tonumber\pgfutil@tempdima\space\pgf@sys@tonumber\pgfutil@tempdimb)">
+ #8
+ </pattern>}%
+ \else%
+ % Uncolored. Yikes!
+ \pgf@sys@svg@make@defs{#1}{
+ <pattern
+ id="pgfpat#1"
+ patternUnits="userSpaceOnUse"
+ width="\pgf@sys@tonumber\pgf@xc"
+ height="\pgf@sys@tonumber\pgf@yc"
+ patternTransform="matrix(#2\space#3\space#4\space#5\space\pgf@sys@tonumber\pgfutil@tempdima\space\pgf@sys@tonumber\pgfutil@tempdimb)"/>
+ <symbol id="pgfsym#1">
+ #8
+ </symbol>}%
+ \fi%
+}
+
+\def\pgfsys@setpatternuncolored#1#2#3#4{%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \pgf@sys@svg@color@rgb#2,#3,#4\relax%
+ \pgfsysprotocol@literal{
+ <pattern id="pgfupat\the\pgf@sys@svg@objectcount" xlink:href="\#pgfpat#1">
+ <g stroke="\pgf@sys@svg@prepared" fill="\pgf@sys@svg@prepared"> <use xlink:href="\#pgfsym#1"/> </g>
+ </pattern>}%
+ \pgf@sys@svg@ref@defs{#1}%
+ \pgf@sys@svg@gs@color{fill="url(\#pgfupat\the\pgf@sys@svg@objectcount)"}%
+}
+
+\def\pgfsys@setpatterncolored#1{%
+ \pgf@sys@svg@ref@defs{#1}%
+ \pgf@sys@svg@gs@color{fill="url(\#pgfpat#1)"}%
+}
+
+
+
+
+
+
+% Animation
+
+\pgfsysanimationsupportedtrue
+
+\let\pgfsys@anim@val@dur\pgfutil@empty
+\let\pgfsys@anim@val@restart\pgfutil@empty
+\let\pgfsys@anim@val@repeatCount\pgfutil@empty
+\let\pgfsys@anim@val@repeatDur\pgfutil@empty
+\let\pgfsys@anim@val@fill\pgfutil@empty
+\let\pgfsys@anim@val@keyTimes\pgfutil@empty
+\let\pgfsys@anim@val@keyPoints\pgfutil@empty
+\let\pgfsys@anim@val@keySplines\pgfutil@empty
+\let\pgfsys@anim@val@begin\pgfutil@empty
+\let\pgfsys@anim@val@end\pgfutil@empty
+\let\pgfsys@anim@val@additive\pgfutil@empty
+\let\pgfsys@anim@val@accumulate\pgfutil@empty
+\def\pgfsys@anim@val@calcMode{spline}
+\let\pgfsys@anim@val@from\pgfutil@empty
+\let\pgfsys@anim@val@to\pgfutil@empty
+\let\pgfsys@anim@val@path\pgfutil@empty
+\let\pgfsys@anim@val@rotate\pgfutil@empty
+\let\pgfsys@anim@val@values\pgfutil@empty
+\def\pgfsys@anim@val@canvas@trans{{}{}}
+\let\pgfsys@anim@val@@id\pgfutil@empty
+\let\pgfsys@anim@val@@type\pgfutil@empty
+\let\pgfsys@anim@val@base\pgfutil@empty
+\let\pgfsys@anim@val@idref\pgfutil@empty
+\expandafter\let\csname pgfsys@anim@val@xlink:href\endcsname\pgfutil@empty
+
+\def\pgf@sys@svg@key#1{%
+ \expandafter\ifx\csname pgfsys@anim@val@#1\endcsname\pgfutil@empty\else%
+ \space#1="\csname pgfsys@anim@val@#1\endcsname"%
+ \fi%
+}
+
+\def\pgf@svg@anim@keys{
+ \pgf@sys@svg@key{dur}%
+ \pgf@sys@svg@key{restart}%
+ \pgf@sys@svg@key{repeatCount}%
+ \pgf@sys@svg@key{repeatDur}%
+ \pgf@sys@svg@key{fill}%
+ \pgf@sys@svg@key{keyTimes}%
+ \pgf@sys@svg@key{keyPoints}%
+ \pgf@sys@svg@key{keySplines}%
+ \pgf@sys@svg@key{begin}%
+ \pgf@sys@svg@key{end}%
+ \pgf@sys@svg@key{additive}%
+ \pgf@sys@svg@key{accumulate}%
+ \pgf@sys@svg@key{calcMode}%
+ \pgf@sys@svg@key{values}%
+ \pgf@sys@svg@key{from}%
+ \pgf@sys@svg@key{to}%
+ \pgf@sys@svg@key{path}%
+ \pgf@sys@svg@key{rotate}%
+ \pgf@sys@svg@key{xlink:href}%
+}
+
+\newif\ifpgf@sys@at@least@one@event
+\def\pgf@sys@svg@do@events#1{%
+ \pgf@sys@at@least@one@eventfalse%
+ \def\pgf@sys@event@target{#1}%
+ \expandafter\expandafter\expandafter\pgf@sys@svg@do@events@now\csname pgf@sys@event@list@#1\endcsname\relax%
+}
+\def\pgf@sys@svg@do@events@now{%
+ \pgfutil@ifnextchar\relax{}{\pgf@sys@svg@do@event}%
+}
+\def\pgf@sys@svg@do@event#1#2#3#4{%
+ \pgf@sys@at@least@one@eventtrue%
+ %
+ {%
+ \edef\pgf@temp{#1}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \else%
+ \pgfsys@register@type{#2}%
+ \def\pgf@temp{\pgfsys@id@ref{#1}{#2}.}%
+ \fi%
+ \edef\pgf@@temp{#4}%
+ \ifx\pgf@@temp\pgfutil@empty%
+ \pgf@x0pt%
+ \else%
+ \pgf@x#4pt%
+ \fi%
+ \ifx\pgf@sys@event@target\pgf@sys@begin@text%
+ \advance\pgf@x by\pgf@xa\relax%
+ \fi\relax%
+ \ifdim\pgf@x<0pt%
+ \edef\pgf@@temp{ \pgf@sys@tonumber\pgf@x s}%
+ \else
+ \edef\pgf@@temp{ +\pgf@sys@tonumber\pgf@x s}%
+ \fi%
+ \xdef\pgf@svg@anim@temp{\pgf@temp#3\pgf@@temp}%
+ }%
+ \pgf@sys@svg@append{\pgf@sys@event@target}{\pgf@svg@anim@temp}%
+ \global\let\pgf@svg@anim@temp\relax%
+ \pgf@sys@svg@do@events@now%
+}
+
+
+\newif\ifpgf@sys@svg@is@sync@base
+\def\pgf@sys@svg@anim#1#2#3{%
+ \ifx\pgfsys@anim@val@@id\pgfutil@empty%
+ \pgferror{Animation misses ``whom''}%
+ \else%
+ {%
+ \ifx\pgfsys@anim@val@base\pgfutil@empty%
+ \else%
+ % Hook into id:
+ \expandafter\let\expandafter\pgf@sys@temp\csname pgfsys@anim@ba@\pgfsys@anim@val@idref\endcsname%
+ \ifx\pgf@sys@temp\relax%
+ \edef\pgf@sys@temp{\global\let\expandafter\noexpand\csname pgfsys@anim@ba@\pgfsys@anim@val@idref\endcsname\relax\noexpand\pgfsys@anim@ba@setup}%
+ \fi%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@temp\expandafter\expandafter\expandafter{\expandafter\pgf@sys@temp\expandafter\def\expandafter#3\expandafter{\pgfsys@anim@val@base}}%
+ \expandafter\global\expandafter\let\csname pgfsys@anim@ba@\pgfsys@anim@val@idref\endcsname\pgf@sys@temp%
+ \fi%
+ \pgf@sys@svg@tl@eval%
+ \pgf@sys@svg@do@events{begin}%
+ \ifpgf@sys@at@least@one@event%
+ \else%
+ \pgf@sys@svg@append{begin}{\ifdim\pgf@xa>0pt+\fi\pgf@sys@tonumber\pgf@xa s}%
+ \fi%
+ \pgf@sys@svg@do@events{end}%
+ #2%
+ % Suppress empty, superfluous animations:
+ \pgfutil@tempswatrue%
+ \pgfsys@if@fresh@currentid{}{%
+ \ifx\pgfsys@anim@val@values\pgfutil@empty%
+ \ifx\pgfsys@anim@val@to\pgfutil@empty%
+ \ifx\pgfsys@anim@val@dur\pgfutil@empty%
+ \pgfutil@tempswafalse%
+ \fi%
+ \fi%
+ \fi}
+ \ifpgfutil@tempswa%
+ \edef\pgf@temp{{<animate #1\pgfsys@if@fresh@currentid{ id="\pgfsys@id@refcurrent"}{}\pgf@svg@anim@keys/>\pgfsys@svg@newline}}%
+ \expandafter\pgfsysprotocol@literal\pgf@temp%
+ \fi%
+ \pgfsys@invalidate@currentid%
+ }%
+ \fi%
+}
+
+\def\pgf@sys@svg@anim@path{%
+ % animate a path...
+ \ifx\pgfsys@anim@val@@id\pgfutil@empty%
+ \pgferror{Animation misses ``whom''}%
+ \else%
+ {%
+ \let\pgf@sys@svg@add@code\pgfutil@empty%
+ %
+ % Setup markers:
+ %
+ % Setup start
+ \ifx\pgf@svg@anim@marker@start\pgfutil@empty%
+ \let\pgf@sys@svg@marker@id@start\pgfutil@empty%
+ \else%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \edef\pgf@sys@svg@marker@id{pgf\the\pgf@sys@svg@objectcount m}%
+ \edef\pgf@sys@svg@add@code{%
+ \noexpand\pgf@sys@svg@ref@defs{pgfs\pgf@svg@anim@marker@start}%
+ \noexpand\pgfsysprotocol@literal{<marker id="\pgf@sys@svg@marker@id" markerUnits="userSpaceOnUse" orient="auto" overflow="visible">
+ <use xlink:href="\#pgfs\pgf@svg@anim@marker@start" transform="scale(-1,-1)"/> </marker>\pgfsys@svg@newline}%
+ }%
+ \let\pgf@sys@svg@marker@id@start\pgf@sys@svg@marker@id%
+ \fi%
+ % Setup end
+ \ifx\pgf@svg@anim@marker@end\pgfutil@empty%
+ \let\pgf@sys@svg@marker@id@end\pgfutil@empty%
+ \else%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \edef\pgf@sys@svg@marker@id{pgf\the\pgf@sys@svg@objectcount m}%
+ \edef\pgf@sys@svg@add@code@{%
+ \noexpand\pgf@sys@svg@ref@defs{pgfs\pgf@svg@anim@marker@end}%
+ \noexpand\pgfsysprotocol@literal{<marker id="\pgf@sys@svg@marker@id" markerUnits="userSpaceOnUse" orient="auto" overflow="visible">
+ <use xlink:href="\#pgfs\pgf@svg@anim@marker@end"/> </marker>\pgfsys@svg@newline}%
+ }%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@svg@add@code\expandafter\expandafter\expandafter{\expandafter\pgf@sys@svg@add@code\pgf@sys@svg@add@code@}%
+ \let\pgf@sys@svg@marker@id@end\pgf@sys@svg@marker@id%
+ \fi%
+ \ifx\pgfsys@anim@val@base\pgfutil@empty%
+ \else%
+ % Hook into id of path:
+ \expandafter\let\expandafter\pgf@sys@temp\csname pgfsys@anim@ba@\pgfsys@anim@val@idref\endcsname%
+ \ifx\pgf@sys@temp\relax%
+ \edef\pgf@sys@temp{\global\let\expandafter\noexpand\csname pgfsys@anim@ba@\pgfsys@anim@val@idref\endcsname\relax\noexpand\pgfsys@anim@ba@setup}%
+ \fi%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@temp\expandafter\expandafter\expandafter{\expandafter\pgf@sys@temp\expandafter\def\expandafter\pgfsys@anim@ba@d\expandafter{\pgfsys@anim@val@base}}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@temp\expandafter\expandafter\expandafter{\expandafter\pgf@sys@temp\expandafter\def\expandafter\pgfsys@anim@ba@markerstart\expandafter{\pgf@sys@svg@marker@id@start}}%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@temp\expandafter\expandafter\expandafter{\expandafter\pgf@sys@temp\expandafter\def\expandafter\pgfsys@anim@ba@markerend\expandafter{\pgf@sys@svg@marker@id@end}}%
+ \expandafter\global\expandafter\let\csname pgfsys@anim@ba@\pgfsys@anim@val@idref\endcsname\pgf@sys@temp%
+ \fi%
+ \pgf@sys@svg@tl@eval%
+ \pgf@sys@svg@do@events{begin}%
+ \ifpgf@sys@at@least@one@event%
+ \else%
+ \pgf@sys@svg@append{begin}{\ifdim\pgf@xa>0pt+\fi\pgf@sys@tonumber\pgf@xa s}%
+ \fi%
+ \pgf@sys@svg@do@events{end}%
+ % Suppress empty, superfluous animations:
+ \pgfutil@tempswatrue%
+ \pgfsys@if@fresh@currentid{}{%
+ \ifx\pgfsys@anim@val@values\pgfutil@empty%
+ \ifx\pgfsys@anim@val@to\pgfutil@empty%
+ \ifx\pgfsys@anim@val@dur\pgfutil@empty%
+ \pgfutil@tempswafalse%
+ \fi%
+ \fi%
+ \fi}
+ \ifpgfutil@tempswa%
+ % Ok, first, animate the path:
+ \edef\pgf@temp{%
+ {%
+ <animate attributeName="d"\pgfsys@if@fresh@currentid{ id="\pgfsys@id@refcurrent"}{}\pgf@svg@anim@keys/>\pgfsys@svg@newline
+ <animate attributeName="marker-start"\pgfsys@if@fresh@currentid{ id="\pgfsys@id@refcurrent-ms"}{}%
+ \pgf@sys@svg@key{dur}%
+ \pgf@sys@svg@key{restart}%
+ \pgf@sys@svg@key{repeatCount}%
+ \pgf@sys@svg@key{repeatDur}%
+ \pgf@sys@svg@key{fill}%
+ \pgf@sys@svg@key{begin}%
+ \pgf@sys@svg@key{end}%
+ \pgf@sys@svg@key{xlink:href}
+ from="\ifx\pgf@svg@anim@marker@start\pgfutil@empty none\else url(\#\pgf@sys@svg@marker@id@start)\fi"
+ to="\ifx\pgf@svg@anim@marker@start\pgfutil@empty none\else url(\#\pgf@sys@svg@marker@id@start)\fi"
+ />\pgfsys@svg@newline%
+ <animate attributeName="marker-end"\pgfsys@if@fresh@currentid{ id="\pgfsys@id@refcurrent-me"}{}%
+ \pgf@sys@svg@key{dur}%
+ \pgf@sys@svg@key{restart}%
+ \pgf@sys@svg@key{repeatCount}%
+ \pgf@sys@svg@key{repeatDur}%
+ \pgf@sys@svg@key{fill}%
+ \pgf@sys@svg@key{begin}%
+ \pgf@sys@svg@key{end}%
+ \pgf@sys@svg@key{xlink:href}
+ from="\ifx\pgf@svg@anim@marker@end\pgfutil@empty none\else url(\#\pgf@sys@svg@marker@id@end)\fi"
+ to="\ifx\pgf@svg@anim@marker@end\pgfutil@empty none\else url(\#\pgf@sys@svg@marker@id@end)\fi"
+ />\pgfsys@svg@newline%
+ }}%
+ \expandafter\pgfsysprotocol@literal\pgf@temp%
+ \fi%
+ \ifx\pgf@sys@svg@add@code\pgfutil@empty%
+ \else%
+ \expandafter\let\expandafter\pgf@sys@svg@add@code@\csname pgf@sys@svg@path@\pgfsys@id@ref{\pgfsys@anim@val@@id}{\pgfsys@anim@val@@type}\endcsname%
+ \ifx\pgf@sys@svg@add@code@\relax%
+ \else%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@svg@add@code\expandafter\expandafter\expandafter{\expandafter\pgf@sys@svg@add@code\pgf@sys@svg@add@code@}%
+ \fi%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@svg@add@code%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@sys@svg@add@code\expandafter\global\expandafter\let\csname pgf@sys@svg@path@\pgfsys@id@ref{\pgfsys@anim@val@@id}{\pgfsys@anim@val@@type}\endcsname\relax}%
+ \expandafter\global\expandafter\let\csname pgf@sys@svg@path@\pgfsys@id@ref{\pgfsys@anim@val@@id}{\pgfsys@anim@val@@type}\endcsname\pgf@sys@svg@add@code%
+ \fi%
+ \pgfsys@invalidate@currentid%
+ }%
+ \fi%
+}
+
+\def\pgfsys@anim@ba@setup{%
+ \let\pgfsys@anim@ba@opacity\pgfutil@empty%
+ \let\pgfsys@anim@ba@fillopacity\pgfutil@empty%
+ \let\pgfsys@anim@ba@strokeopacity\pgfutil@empty%
+ \let\pgfsys@anim@ba@visibility\pgfutil@empty%
+ \let\pgfsys@anim@ba@strokewidth\pgfutil@empty%
+ \let\pgfsys@anim@ba@fill\pgfutil@empty%
+ \let\pgfsys@anim@ba@stroke\pgfutil@empty%
+ \let\pgfsys@anim@ba@strokedasharray\pgfutil@empty%
+ \let\pgfsys@anim@ba@strokedashoffset\pgfutil@empty%
+ \let\pgf@sys@svg@ba@gs\pgf@sys@svg@ba@gs@do@now%
+}
+\let\pgfsys@anim@ba@opacity\pgfutil@empty%
+\let\pgfsys@anim@ba@fillopacity\pgfutil@empty%
+\let\pgfsys@anim@ba@strokeopacity\pgfutil@empty%
+\let\pgfsys@anim@ba@visibility\pgfutil@empty%
+\let\pgfsys@anim@ba@strokewidth\pgfutil@empty%
+\let\pgfsys@anim@ba@fill\pgfutil@empty%
+\let\pgfsys@anim@ba@stroke\pgfutil@empty%
+\let\pgfsys@anim@ba@viewBox\pgfutil@empty%
+\let\pgfsys@anim@ba@d\pgfutil@empty%
+\let\pgfsys@anim@ba@strokedasharray\pgfutil@empty%
+\let\pgfsys@anim@ba@strokedashoffset\pgfutil@empty%
+\let\pgfsys@anim@ba@markerstart\pgfutil@empty%
+\let\pgfsys@anim@ba@markerendd\pgfutil@empty%
+
+\def\pgf@sys@svg@ba@gs@do@now{%
+ \ifx\pgfsys@anim@ba@fill\pgfutil@empty\else fill="\pgfsys@anim@ba@fill" \fi%
+ \ifx\pgfsys@anim@ba@stroke\pgfutil@empty\else stroke="\pgfsys@anim@ba@stroke" \fi%
+ \ifx\pgfsys@anim@ba@opacity\pgfutil@empty\else opacity="\pgfsys@anim@ba@opacity" \fi%
+ \ifx\pgfsys@anim@ba@fillopacity\pgfutil@empty\else fill-opacity="\pgfsys@anim@ba@fillopacity" \fi%
+ \ifx\pgfsys@anim@ba@strokeopacity\pgfutil@empty\else stroke-opacity="\pgfsys@anim@ba@strokeopacity" \fi%
+ \ifx\pgfsys@anim@ba@visibility\pgfutil@empty\else visibility="\pgfsys@anim@ba@visibility" \fi%
+ \ifx\pgfsys@anim@ba@strokewidth\pgfutil@empty\else stroke-width="\pgfsys@anim@ba@strokewidth" \fi%
+ \ifx\pgfsys@anim@ba@strokedasharray\pgfutil@empty\else stroke-dasharray="\pgfsys@anim@ba@strokedasharray" \fi%
+ \ifx\pgfsys@anim@ba@strokedashoffset\pgfutil@empty\else stroke-dashoffset="\pgfsys@anim@ba@strokedashoffset" \fi%
+}
+
+
+
+\newcount\pgf@sys@svg@canvascount
+\def\pgf@sys@svg@anim@trans#1#2#3{%
+ \ifx\pgfsys@anim@val@@id\pgfutil@empty%
+ \pgferror{Animation misses ``whom''}%
+ \else%
+ {%
+ %
+ \global\advance\pgf@sys@svg@canvascount by1\relax%
+ \pgf@sys@svg@tl@eval%
+ \pgf@sys@svg@do@events{begin}%
+ \ifpgf@sys@at@least@one@event%
+ \else%
+ \pgf@sys@svg@append{begin}{\ifdim\pgf@xa>0pt+\fi\pgf@sys@tonumber\pgf@xa s}%
+ \fi%
+ \pgf@sys@svg@do@events{end}%
+ #2%
+ \pgfsys@register@type{\pgfsys@anim@val@@type}%
+ \pgf@sys@svg@replace{xlink:href}{\#\pgfsys@id@ref{\pgfsys@anim@val@@id canvas\the\pgf@sys@svg@canvascount}{\pgfsys@anim@val@@type}}%
+ \ifx\pgfsys@anim@val@base\pgfutil@empty%
+ \let\pgf@sys@svg@base@trans\pgfutil@empty%
+ \else%
+ \edef\pgf@sys@svg@base@trans{ transform="#3(\pgfsys@anim@val@base)"}%
+ \fi%
+ \pgfsysprotocol@literal{<#1\pgfsys@if@fresh@currentid{ id="\pgfsys@id@refcurrent"}{}\pgf@svg@anim@keys/>\pgfsys@svg@newline}%
+ \pgfsys@invalidate@currentid%
+ \edef\pgf@temp{{\pgfsys@id@ref{\pgfsys@anim@val@@id
+ canvas\the\pgf@sys@svg@canvascount}{\pgfsys@anim@val@@type}}}%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgf@sys@svg@attacher%
+ \expandafter\expandafter\expandafter\pgf@temp\expandafter\pgfsys@anim@val@canvas@trans\expandafter{\pgf@sys@svg@base@trans}%
+ }%
+ \fi%
+}
+
+\newif\ifpgf@sys@svg@called
+\def\pgf@sys@svg@attacher#1#2#3#4{%
+ \toks0{%
+ {%
+ \let\pgfsys@transformcm\pgfsys@anim@transformcm%
+ \global\pgf@sys@svg@calledfalse%
+ #2%
+ \ifpgf@sys@svg@called\else\pgfsysprotocol@literal{<g>}\fi%
+ \pgfsysprotocol@literal{<g id="#1"#4>}
+ {%
+ \global\pgf@sys@svg@calledfalse%
+ #3%
+ \ifpgf@sys@svg@called\else\pgfsysprotocol@literal{<g>}\fi%
+ }%
+ }%
+ }%
+ \edef\pgf@sys@svg@beg{\the\toks0}%
+ \def\pgf@sys@svg@end{\pgfsysprotocol@literal{</g></g></g>\noexpand\pgfsys@svg@newline}}%
+ \expandafter\expandafter\expandafter\pgfsys@attach@to@id%
+ \expandafter\expandafter\expandafter\pgfsys@anim@val@@id%
+ \expandafter\expandafter\expandafter\pgfsys@anim@val@@type%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@sys@svg@beg\expandafter}\expandafter{\pgf@sys@svg@end}%
+}
+
+
+\def\pgfsys@anim@transformcm#1#2#3#4#5#6{%
+ \ifpgf@sys@svg@called%
+ \pgferror{Double transformation calls in animation}%
+ \else%
+ {%
+ \pgf@x=#5\pgf@y=#6%
+ \edef\pgf@temp{ transform="matrix(#1,#2,#3,#4,\pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})"}%
+ \ifx\pgf@temp\pgf@sys@svg@idmat@stext%
+ \let\pgf@temp\pgfutil@empty%
+ \fi%
+ \pgfsysprotocol@literal{<g\pgf@temp>}%
+ }%
+ \global\pgf@sys@svg@calledtrue%
+ \fi%
+}
+\def\pgf@sys@svg@idtrans@text{1.0,0.0,0.0,1.0}
+\def\pgf@sys@svg@idmat@text{transform="matrix(1.0,0.0,0.0,1.0,0.0,0.0)"}
+\def\pgf@sys@svg@idmat@stext{ transform="matrix(1.0,0.0,0.0,1.0,0.0,0.0)"}
+
+\def\pgf@sys@svg@replace#1#2{%
+ \expandafter\edef\csname pgfsys@anim@val@#1\endcsname{#2}%
+}
+
+\def\pgf@sys@svg@append#1#2{%
+ \expandafter\let\expandafter\pgf@svg@anim@temp@\csname pgfsys@anim@val@#1\endcsname%
+ \ifx\pgf@svg@anim@temp@\pgfutil@empty%
+ \expandafter\edef\csname pgfsys@anim@val@#1\endcsname{#2}%
+ \else\ifx\pgf@svg@anim@temp@\relax%
+ \pgfutil@packageerror{pgfsys}{Unknown animation key '#1'}{}
+ \else%
+ \edef\pgf@svg@anim@temp@{\pgf@svg@anim@temp@;#2}%
+ \expandafter\let\csname pgfsys@anim@val@#1\endcsname\pgf@svg@anim@temp@%
+ \fi\fi%
+}
+
+% The actual animate command
+\def\pgfsys@animate#1{%
+ \expandafter\let\expandafter\pgf@sys@temp\csname pgfsys@svg@animate#1\endcsname\relax%
+ \ifx\pgf@sys@temp\relax%
+ \pgf@sys@fail{animation attribute #1}%
+ \else%
+ \pgf@sys@temp%
+ \fi%
+}
+
+
+% The non-transforming animations
+\def\pgfsys@svg@animatenone{}
+\def\pgfsys@svg@animateopacity{\pgf@sys@svg@anim{attributeName="opacity"}{}{\pgfsys@anim@ba@opacity}}
+\def\pgfsys@svg@animatefillopacity{\pgf@sys@svg@anim{attributeName="fill-opacity"}{}{\pgfsys@anim@ba@fillopacity}}
+\def\pgfsys@svg@animatestrokeopacity{\pgf@sys@svg@anim{attributeName="stroke-opacity"}{}{\pgfsys@anim@ba@strokeopacity}}
+\def\pgfsys@svg@animatevisibility{\pgf@sys@svg@anim{attributeName="visibility"}{}{\pgfsys@anim@ba@visibility}}
+\def\pgfsys@svg@animatelinewidth{\pgf@sys@svg@anim{attributeName="stroke-width"}{}{\pgfsys@anim@ba@strokewidth}}
+\def\pgfsys@svg@animatecolor{\pgf@sys@svg@anim{attributeName="fill"}{}{\pgfsys@anim@ba@fill}\pgf@sys@svg@anim{attributeName="stroke"}{}{\pgfsys@anim@ba@stroke}}
+\def\pgfsys@svg@animatefillcolor{\pgf@sys@svg@anim{attributeName="fill"}{}{\pgfsys@anim@ba@fill}}
+\def\pgfsys@svg@animatestrokecolor{\pgf@sys@svg@anim{attributeName="stroke"}{}{\pgfsys@anim@ba@stroke}}
+\def\pgfsys@svg@animateviewbox{\pgf@sys@svg@anim{attributeName="viewBox"}{}{\pgfsys@anim@ba@viewBox}}
+\def\pgfsys@svg@animatepath{\pgf@sys@svg@anim@path}
+\def\pgfsys@svg@animatesyncbase{{\pgf@sys@svg@is@sync@basetrue\pgf@sys@svg@anim{}{}{}}}
+\def\pgfsys@svg@animatedash{%
+ \pgf@svg@anim@prep@dash{\pgfsys@anim@val@base}{\pgfsys@anim@val@base@array}{\pgfsys@anim@val@base@offset}%
+ \let\pgfsys@anim@val@base\pgfsys@anim@val@base@array%
+ \pgf@sys@svg@anim{attributeName="stroke-dasharray"}{%
+ \pgf@svg@anim@prep@dash{\pgfsys@anim@val@from}{\pgfsys@anim@val@from@array}{\pgfsys@anim@val@from@offset}%
+ \pgf@svg@anim@prep@dash{\pgfsys@anim@val@to}{\pgfsys@anim@val@to@array}{\pgfsys@anim@val@to@offset}%
+ \pgf@svg@anim@prep@dash{\pgfsys@anim@val@values}{\pgfsys@anim@val@values@array}{\pgfsys@anim@val@values@offset}%
+ \let\pgfsys@anim@val@from\pgfsys@anim@val@from@array%
+ \let\pgfsys@anim@val@to\pgfsys@anim@val@to@array%
+ \let\pgfsys@anim@val@values\pgfsys@anim@val@values@array%
+ }{\pgfsys@anim@ba@strokedasharray}%
+ \let\pgfsys@anim@val@base\pgfsys@anim@val@base@offset%
+ \pgf@sys@svg@anim{attributeName="stroke-dashoffset"}{%
+ \pgf@svg@anim@prep@dash{\pgfsys@anim@val@from}{\pgfsys@anim@val@from@array}{\pgfsys@anim@val@from@offset}%
+ \pgf@svg@anim@prep@dash{\pgfsys@anim@val@to}{\pgfsys@anim@val@to@array}{\pgfsys@anim@val@to@offset}%
+ \pgf@svg@anim@prep@dash{\pgfsys@anim@val@values}{\pgfsys@anim@val@values@array}{\pgfsys@anim@val@values@offset}%
+ \let\pgfsys@anim@val@from\pgfsys@anim@val@from@offset%
+ \let\pgfsys@anim@val@to\pgfsys@anim@val@to@offset%
+ \let\pgfsys@anim@val@values\pgfsys@anim@val@values@offset%
+ }{\pgfsys@anim@ba@strokedashoffset}%
+}
+
+% The transforming animations
+\def\pgfsys@svg@animatetranslate{\pgf@sys@svg@anim@trans{animateTransform attributeName="transform" type="translate"}{}{translate}}
+\def\pgfsys@svg@animatescale{\pgf@sys@svg@anim@trans{animateTransform attributeName="transform" type="scale"}{}{scale}}
+\def\pgfsys@svg@animaterotate{\pgf@sys@svg@anim@trans{animateTransform attributeName="transform" type="rotate"}{}{rotate}}
+\def\pgfsys@svg@animateskewx{\pgf@sys@svg@anim@trans{animateTransform attributeName="transform" type="skewX"}{}{skewX}}
+\def\pgfsys@svg@animateskewy{\pgf@sys@svg@anim@trans{animateTransform attributeName="transform" type="skewY"}{}{skewY}}
+\def\pgfsys@svg@animatemotion{\pgf@sys@svg@anim@trans{animateMotion}{%
+ \let\pgfsys@anim@val@base\pgfutil@empty%
+ \let\pgfsys@anim@val@keyPoints\pgfsys@anim@val@values%
+ \let\pgfsys@anim@val@values\pgfutil@empty%
+ \ifx\pgfsys@anim@val@keyTimes\pgfutil@empty%
+ \let\pgfsys@anim@val@keyPoints\pgfutil@empty%
+ \fi%
+ }{}}
+
+% The keys
+\def\pgfsys@animation@whom#1#2{%
+ % Animations must "look forward"...
+ \pgfsys@if@fresh@id{#1}{#2}{}{\pgferror{Animations must precede the to-be-animated objects (``whom'')}}%
+ \pgf@sys@svg@replace{@id}{#1}%
+ \pgf@sys@svg@replace{@type}{#2}%
+ \pgf@sys@svg@replace{xlink:href}{\#\pgfsys@id@ref{#1}{#2}}%
+ \pgf@sys@svg@replace{idref}{\pgfsys@id@ref{#1}{#2}}%
+}
+\def\pgfsys@animation@restart@always{\pgf@sys@svg@replace{restart}{always}}
+\def\pgfsys@animation@restart@never{\pgf@sys@svg@replace{restart}{never}}
+\def\pgfsys@animation@restart@whennotactive{\pgf@sys@svg@replace{restart}{whenNotActive}}
+\def\pgfsys@animation@repeat@indefinite{\pgf@sys@svg@replace{repeatCount}{indefinite}}
+\def\pgfsys@animation@repeat#1{\pgf@sys@svg@replace{repeatCount}{#1}}
+\def\pgfsys@animation@repeat@dur#1{\pgf@sys@svg@replace{repeatDur}{#1}}
+\def\pgfsys@animation@freezeatend{\pgf@sys@svg@replace{fill}{freeze}}
+\def\pgfsys@animation@removeatend{\pgf@sys@svg@replace{fill}{remove}}
+\def\pgfsys@animation@canvas@transform#1#2{\def\pgfsys@anim@val@canvas@trans{{#1}{#2}}}
+\def\pgfsys@animation@offset#1#2{\pgfsys@animation@event{}{}{}{#1}{#2}}
+\def\pgfsys@animation@event#1#2#3#4#5{%
+ \expandafter\edef\csname pgf@sys@event@list@#5\endcsname{\csname pgf@sys@event@list@#5\endcsname{#1}{#2}{#3}{#4}}%
+}%
+\def\pgf@sys@event@list@begin{}
+\def\pgf@sys@event@list@end{}
+\def\pgfsys@animation@syncbegin#1#2#3#4{\pgfsys@animation@event{#1}{#2}{begin}{#3}{#4}}
+\def\pgfsys@animation@syncend#1#2#3#4{\pgfsys@animation@event{#1}{#2}{end}{#3}{#4}}
+\def\pgfsys@animation@repeat@event#1#2#3#4#5{\pgfsys@animation@event{#1}{#2}{repeat(#3)}{#4}{#5}}
+\def\pgfsys@animation@accesskey#1#2#3{\pgfsys@animation@event{}{}{accessKey(#1)}{#2}{#3}}
+%\def\pgfsys@animation@sum{\pgf@sys@svg@replace{additive}{sum}}
+%\def\pgfsys@animation@replace{\pgf@sys@svg@replace{additive}{replace}}
+\def\pgfsys@animation@accumulate{\pgf@sys@svg@replace{accumulate}{sum}}
+\def\pgfsys@animation@noaccumulate{\pgf@sys@svg@replace{accumulate}{}}
+\def\pgfsys@animation@rotatealong{\pgf@sys@svg@replace{rotate}{auto}}
+\def\pgfsys@animation@norotatealong{\pgf@sys@svg@replace{rotate}{}}
+\def\pgfsys@animation@movealong#1{%
+ {%
+ \let\pgf@sys@save@svgpath=\pgf@sys@svgpath%
+ \global\let\pgf@sys@svgpath=\pgfutil@empty%
+ \pgfsyssoftpath@getcurrentpath\pgf@sys@save@path%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ #1%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfsyssoftpath@setcurrentpath\pgf@sys@save@path%
+ \global\let\pgf@svg@anim@temp\pgf@sys@svgpath%
+ \global\let\pgf@sys@svgpath\pgf@sys@save@svgpath%
+ }%
+ \pgf@sys@svg@replace{path}{\pgf@svg@anim@temp}%
+}
+\def\pgfsys@animation@tip@markers#1#2{%
+ \edef\pgf@svg@anim@marker@start{#1}%
+ \edef\pgf@svg@anim@marker@end{#2}%
+}
+\let\pgf@svg@anim@marker@start\pgfutil@empty
+\let\pgf@svg@anim@marker@end\pgfutil@empty
+
+
+
+% Timelines
+\let\pgf@sys@svg@tl@entries\pgfutil@empty
+\let\pgf@sys@svg@tl@start\pgfutil@empty
+\let\pgf@sys@svg@tl@end\pgfutil@empty
+
+
+\def\pgfsys@animation@time#1#2#3#4#5{%
+ \def\pgf@sys@svg@t{#1}%
+ \let\pgf@sys@last@out@spline\pgf@sys@svg@out@spline%
+ \def\pgf@sys@svg@in@spline{{#2}{#3}}%
+ \def\pgf@sys@svg@out@spline{{#4}{#5}}%
+}
+\def\pgfsys@animation@base{%
+ \let\pgf@sys@svg@t\pgf@sys@svg@base@text%
+}
+\def\pgf@sys@svg@base@text{base}
+
+\def\pgf@sys@svg@entry#1{%
+ \ifx\pgf@sys@svg@t\pgf@sys@svg@base@text%
+ % Ah, base. Save!
+ \edef\pgfsys@anim@val@base{#1}%
+ \else%
+ \ifx\pgf@sys@svg@tl@start\pgfutil@empty%
+ % Ah, first.
+ \let\pgf@sys@svg@tl@start\pgf@sys@svg@t%
+ \edef\pgf@sys@svg@tl@entries{%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@svg@t}%
+ \noexpand\pgf@sys@svg@add@value{#1}%
+ }%
+ \else%
+ \ifx\pgf@sys@last@out@spline\pgfsys@stay@text%
+ \ifx\pgf@sys@svg@in@spline\pgfsys@jump@text%
+ {%
+ \pgf@x\pgf@sys@svg@t pt
+ \pgf@xa\pgf@sys@svg@tl@end pt%
+ \advance\pgf@x by\pgf@xa%
+ \pgf@x.5\pgf@x%
+ \edef\pgf@sys@temp{\pgf@sys@tonumber\pgf@x}
+ \expandafter}\expandafter\def\expandafter\pgf@sys@temp\expandafter{\pgf@sys@temp}%
+ \edef\pgf@sys@svg@temp{%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@temp}%
+ \noexpand\pgf@sys@svg@add@spline{0}{0}{1}{1}%
+ \noexpand\pgf@sys@svg@add@value{\pgf@sys@svg@last@value}%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@temp}%
+ \noexpand\pgf@sys@svg@add@spline{0}{0}{1}{1}%
+ \noexpand\pgf@sys@svg@add@value{#1}%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@svg@t}%
+ \noexpand\pgf@sys@svg@add@spline{0}{0}{1}{1}%
+ \noexpand\pgf@sys@svg@add@value{#1}%
+ }%
+ \else
+ \edef\pgf@sys@svg@temp{%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@svg@t}%
+ \noexpand\pgf@sys@svg@add@spline{0}{0}{1}{1}%
+ \noexpand\pgf@sys@svg@add@value{\pgf@sys@svg@last@value}%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@svg@t}%
+ \noexpand\pgf@sys@svg@add@spline{0}{0}{1}{1}%
+ \noexpand\pgf@sys@svg@add@value{#1}%
+ }%
+ \fi%
+ \else%
+ \ifx\pgf@sys@svg@in@spline\pgfsys@jump@text%
+ \edef\pgf@sys@svg@temp{%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@svg@tl@end}%
+ \noexpand\pgf@sys@svg@add@spline{0}{0}{1}{1}%
+ \noexpand\pgf@sys@svg@add@value{#1}%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@svg@t}%
+ \noexpand\pgf@sys@svg@add@spline{0}{0}{1}{1}%
+ \noexpand\pgf@sys@svg@add@value{#1}%
+ }%
+ \else%
+ \edef\pgf@sys@svg@temp{%
+ \noexpand\pgf@sys@svg@add@time{\pgf@sys@svg@t}%
+ \noexpand\pgf@sys@svg@add@spline\pgf@sys@last@out@spline\pgf@sys@svg@in@spline%
+ \noexpand\pgf@sys@svg@add@value{#1}%
+ }%
+ \fi%
+ \fi%
+ \expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\pgf@sys@svg@tl@entries%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@sys@svg@tl@entries\pgf@sys@svg@temp}%
+ \fi%
+ \let\pgf@sys@svg@tl@end\pgf@sys@svg@t%
+ \edef\pgf@sys@svg@last@value{#1}%
+ \fi%
+}
+\newif\ifpgf@sys@svg@do@times
+\def\pgf@sys@svg@tl@eval{%
+ \pgf@xa=0pt%
+ % Overrulings
+ \pgf@sys@svg@do@timestrue%
+ % Ok, we need to compute the time interval
+ \ifx\pgf@sys@svg@tl@end\pgfutil@empty%
+ \else%
+ \ifx\pgf@sys@svg@tl@start\pgfutil@empty\else\pgf@xa=\pgf@sys@svg@tl@start pt\fi%
+ \pgf@xb=\pgf@sys@svg@tl@end pt%
+ \advance\pgf@xb by -\pgf@xa%
+ % Ok, \pgf@xb is now the duration.
+ \ifdim\pgf@xb>0pt\relax%
+ \pgf@sys@svg@replace{dur}{\pgf@sys@tonumber\pgf@xb}%
+ \else%
+ \pgf@sys@svg@replace{dur}{\pgf@sys@svg@indefinitetext}%
+ \fi%
+ % Now, prepare factors
+ \pgf@xc=8192pt%
+ \ifdim\pgf@xb<0.0001pt\relax
+ \pgf@xc=1pt%
+ \pgf@xb=1sp%
+ \else%
+ \divide\pgf@xc by\pgf@xb%
+ \multiply\pgf@xb by\pgf@xc%
+ \divide\pgf@xb by65536%
+ \fi%
+ % Now, run!
+ \pgf@sys@svg@tl@entries%
+ \ifx\pgfsys@anim@val@dur\pgf@sys@svg@indefinitetext%
+ \let\pgfsys@anim@val@from\pgfsys@anim@val@to%
+ \let\pgfsys@anim@val@keyTimes\pgfutil@empty%
+ \let\pgfsys@anim@val@calcMode\pgfutil@empty%
+ \fi%
+ \fi%
+}
+\def\pgf@sys@svg@indefinitetext{indefinite}
+\def\pgf@sys@svg@add@time#1{%
+ \ifpgf@sys@svg@do@times%
+ % Compute fraction:
+ \pgf@yb=#1pt%
+ \advance\pgf@yb by-\pgf@xa%
+ \multiply\pgf@yb by\pgf@xc%
+ \divide\pgf@yb by\pgf@xb%
+ \ifdim\pgf@yb<0pt\pgf@yb=0pt\fi%
+ \ifdim\pgf@yb>1pt\pgf@yb=1pt\fi%
+ \pgf@sys@svg@append{keyTimes}{\pgf@sys@tonumber\pgf@yb}%
+ \fi%
+}
+\def\pgf@sys@svg@add@spline#1#2#3#4{\ifpgf@sys@svg@do@times\pgf@sys@svg@append{keySplines}{#1 #2 #3 #4}\fi}
+\def\pgf@sys@svg@add@value#1{%
+ \ifx\pgfsys@anim@val@values\pgfutil@empty%
+ \ifx\pgfsys@anim@val@to\pgfutil@empty%
+ \pgf@sys@svg@replace{to}{#1}%
+ \else% move
+ \let\pgfsys@anim@val@values\pgfsys@anim@val@to%
+ \let\pgfsys@anim@val@to\pgfutil@empty%
+ \pgf@sys@svg@append{values}{#1}%
+ \fi%
+ \else%
+ \pgf@sys@svg@append{values}{#1}%
+ \fi%
+}
+\def\pgfsys@animation@val@current{\pgf@sys@svg@entry{}}
+\def\pgfsys@animation@val{\pgf@sys@svg@entry{nil}} % will be ignored anyway
+\def\pgfsys@animation@val@text#1{\pgf@sys@svg@entry{#1}}
+\def\pgfsys@animation@val@scalar#1{\pgf@sys@svg@entry{#1}}
+\def\pgfsys@animation@val@dimension#1{%
+ {%
+ \pgf@x=#1\relax%
+ \xdef\pgf@svg@anim@temp{\expandafter\Pgf@geT\the\pgf@x}%
+ }%
+ \pgf@sys@svg@entry{\pgf@svg@anim@temp}%
+}
+\def\pgfsys@animation@val@color@rgb#1#2#3{\pgf@sys@svg@color@rgb#1,#2,#3\relax\pgf@sys@svg@entry{\pgf@sys@svg@prepared}}
+\def\pgfsys@animation@val@color@cmyk#1#2#3#4{\pgf@sys@svg@color@cmyk#1,#2,#3,#4\relax\pgf@sys@svg@entry{\pgf@sys@svg@prepared}}
+\def\pgfsys@animation@val@color@cmy#1#2#3{\pgf@sys@svg@color@cmy#1,#2,#3\relax\pgf@sys@svg@entry{\pgf@sys@svg@prepared}}
+\def\pgfsys@animation@val@color@gray#1{\pgf@sys@svg@color@gray#1\relax\pgf@sys@svg@entry{\pgf@sys@svg@prepared}}
+\def\pgfsys@animation@val@path#1{%
+ {%
+ \let\pgf@sys@save@svgpath=\pgf@sys@svgpath%
+ \global\let\pgf@sys@svgpath=\pgfutil@empty%
+ \pgfsyssoftpath@getcurrentpath\pgf@sys@save@path%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+ #1%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfsyssoftpath@setcurrentpath\pgf@sys@save@path%
+ \global\let\pgf@svg@anim@temp\pgf@sys@svgpath%
+ \global\let\pgf@sys@svgpath\pgf@sys@save@svgpath%
+ }%
+ \pgf@sys@svg@entry{\pgf@svg@anim@temp}%
+}
+\def\pgfsys@animation@val@translate#1#2{%
+ {%
+ \pgf@x=#1\relax%
+ \pgf@y=#2\relax%
+ \xdef\pgf@svg@anim@temp{\expandafter\Pgf@geT\the\pgf@x,\expandafter\Pgf@geT\the\pgf@y}%
+ }%
+ \pgf@sys@svg@entry{\pgf@svg@anim@temp}%
+}
+\def\pgfsys@animation@val@scale#1#2{\pgf@sys@svg@entry{#1,#2}}
+\def\pgfsys@animation@val@viewbox#1#2#3#4{%
+ {%
+ \pgf@x=#1\relax%
+ \pgf@y=#2\relax%
+ \pgf@xa=#3\relax%
+ \pgf@ya=#4\relax%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \xdef\pgf@svg@anim@temp{\expandafter\Pgf@geT\the\pgf@x\space\expandafter\Pgf@geT\the\pgf@y\space\expandafter\Pgf@geT\the\pgf@xa\space\expandafter\Pgf@geT\the\pgf@ya}%
+ }%
+ \pgf@sys@svg@entry{\pgf@svg@anim@temp}%
+}
+\def\pgfsys@animation@val@dash#1#2{%
+ \edef\pgf@test@dashpattern{#1}%
+ \let\pgf@sys@svg@parsed@dash\pgfutil@empty%
+ \ifx\pgf@test@dashpattern\pgfutil@empty%
+ \else%
+ \expandafter\pgf@sys@svg@parse@dash\pgf@test@dashpattern,\relax%
+ \fi%
+ {%
+ \pgf@x=#2\relax%
+ \xdef\pgf@svg@anim@temp{\expandafter\Pgf@geT\the\pgf@x}%
+ }%
+ \pgf@sys@svg@entry{{\pgf@sys@svg@parsed@dash}{\pgf@svg@anim@temp}}%
+}
+
+
+
+\def\pgf@svg@anim@prep@dash#1#2#3{%
+ \let\pgf@svg@anim@dash@array\pgfutil@empty%
+ \let\pgf@svg@anim@dash@offset\pgfutil@empty%
+ % #1 = \pgfsys@anim@val@from or \pgfsys@anim@val@to or \pgfsys@anim@val@values
+ \ifx#1\pgfutil@empty%
+ \else%
+ \expandafter\pgf@svg@anim@prep@dash@parse#1\pgf@stop%
+ \fi%
+ \let#2\pgf@svg@anim@dash@array%
+ \let#3\pgf@svg@anim@dash@offset%
+}
+
+\def\pgf@svg@anim@prep@dash@parse#1#2{%
+ \expandafter\def\expandafter\pgf@svg@anim@dash@array\expandafter{\pgf@svg@anim@dash@array#1}%
+ \expandafter\def\expandafter\pgf@svg@anim@dash@offset\expandafter{\pgf@svg@anim@dash@offset#2}%
+ \pgfutil@ifnextchar;{%
+ \expandafter\def\expandafter\pgf@svg@anim@dash@array\expandafter{\pgf@svg@anim@dash@array;}%
+ \expandafter\def\expandafter\pgf@svg@anim@dash@offset\expandafter{\pgf@svg@anim@dash@offset;}%
+ \expandafter\pgf@svg@anim@prep@dash@parse\pgfutil@gobble%
+ }{%
+ \pgfutil@gobble% done, gobble \pgf@stop
+ }%
+}
+
+
+%
+% Markers
+%
+
+\def\pgfsys@marker@declare@{%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsys@beginscope@{ id="pgfs\the\pgf@sys@id@count"}%
+ \pgfsysprotocol@literal{\csname pgf@sys@marker@prot@\the\pgf@sys@id@count\endcsname}%
+ \pgfsys@endscope%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@temp%
+ \pgf@sys@svg@make@defs{pgfs\the\pgf@sys@id@count}{\pgfsys@temp}%
+}
+
+\def\pgfsys@marker@use#1{%
+ \pgf@sys@svg@ref@defs{pgfs#1}%
+ \pgfsysprotocol@literal{<use xlink:href="\#pgfs#1"/>}%
+}
+
+\def\pgfsys@marker@at@begin@usedpath#1{\def\pgf@sys@svg@marker@begin{#1}\let\pgf@sys@svg@marker@begin@use\pgfutil@empty}
+\def\pgfsys@marker@at@end@usedpath#1{\def\pgf@sys@svg@marker@end{#1}\let\pgf@sys@svg@marker@begin@use\pgfutil@empty}
+
+\let\pgf@sys@svg@marker@begin\relax
+\let\pgf@sys@svg@marker@end\relax
+
+\let\pgf@sys@svg@marker@begin@use\pgfutil@empty
+\let\pgf@sys@svg@marker@end@use\pgfutil@empty
+
+\def\pgf@sys@svg@prep@marker#1#2#3#4#5{%
+ \pgf@sys@svg@ref@defs{pgfs#1}%
+ \global\advance\pgf@sys@svg@objectcount by1\relax%
+ \edef\pgf@sys@svg@marker@id{pgf\the\pgf@sys@svg@objectcount}%
+ \pgfsysprotocol@literal{<marker id="\pgf@sys@svg@marker@id" markerUnits="userSpaceOnUse" orient="auto" overflow="visible">
+ <use xlink:href="\#pgfs#1"#2/> </marker>\pgfsys@svg@newline}%
+ \edef#3{marker-#4="url(\#\pgf@sys@svg@marker@id)" }%
+}
+
+
+%
+% RDF
+%
+
+\def\pgf@svg@rdf@init{%
+ \ifx\pgfsys@svg@rdf\pgfutil@empty%
+ % Ok, first, so init
+ \global\let\pgf@svg@rdf@vocab\relax%
+ \global\let\pgf@svg@rdf@about\relax%
+ \global\let\pgf@svg@rdf@content\relax%
+ \global\let\pgf@svg@rdf@datatype\relax%
+ \global\let\pgf@svg@rdf@href\relax%
+ \global\let\pgf@svg@rdf@inlist\relax%
+ \global\let\pgf@svg@rdf@prefix\relax%
+ \global\let\pgf@svg@rdf@property\relax%
+ \global\let\pgf@svg@rdf@rel\relax%
+ \global\let\pgf@svg@rdf@resource\relax%
+ \global\let\pgf@svg@rdf@rev\relax%
+ \global\let\pgf@svg@rdf@src\relax%
+ \global\let\pgf@svg@rdf@typeof\relax%
+ \global\let\pgfsys@svg@rdf\pgfsys@svg@rdf@initial%
+ \fi%
+}
+\def\pgfsys@svg@rdf@initial{%
+ \ifx\pgf@svg@rdf@vocab\relax\else\space vocab="\pgf@svg@rdf@vocab"\fi%
+ \ifx\pgf@svg@rdf@about\relax\else\space about="\pgf@svg@rdf@about"\fi%
+ \ifx\pgf@svg@rdf@datatype\relax\else\space datatype="\pgf@svg@rdf@datatype"\fi%
+ \ifx\pgf@svg@rdf@href\relax\else\space href="\pgf@svg@rdf@href"\fi%
+ \ifx\pgf@svg@rdf@inlist\relax\else\space inlist="\pgf@svg@rdf@inlist"\fi%
+ \ifx\pgf@svg@rdf@prefix\relax\else\space prefix="\pgf@svg@rdf@prefix"\fi%
+ \ifx\pgf@svg@rdf@property\relax\else\space property="\pgf@svg@rdf@property"\fi%
+ \ifx\pgf@svg@rdf@rel\relax\else\space rel="\pgf@svg@rdf@rel"\fi%
+ \ifx\pgf@svg@rdf@resource\relax\else\space resource="\pgf@svg@rdf@resource"\fi%
+ \ifx\pgf@svg@rdf@rev\relax\else\space rev="\pgf@svg@rdf@rev"\fi%
+ \ifx\pgf@svg@rdf@src\relax\else\space src="\pgf@svg@rdf@src"\fi%
+ \ifx\pgf@svg@rdf@typeof\relax\else\space typeof="\pgf@svg@rdf@typeof"\fi%
+ \ifx\pgf@svg@rdf@content\relax\else\space content="\pgf@svg@rdf@content"\fi%
+}
+
+\def\pgfsys@rdf@about#1{\pgf@svg@rdf@init\gdef\pgf@svg@rdf@about{#1}}
+\def\pgfsys@rdf@content#1{\pgf@svg@rdf@init\gdef\pgf@svg@rdf@content{#1}}
+\def\pgfsys@rdf@datatype#1{\pgf@svg@rdf@init\gdef\pgf@svg@rdf@datatype{#1}}
+\def\pgfsys@rdf@href#1{\pgf@svg@rdf@init\gdef\pgf@svg@rdf@href{#1}}
+\def\pgfsys@rdf@inlist{\pgf@svg@rdf@init\let\pgf@svg@rdf@inlist\pgfutil@empty}
+\def\pgfsys@rdf@prefix#1{\pgf@svg@rdf@init%
+ \ifx\pgf@svg@rdf@prefix\relax%
+ \gdef\pgf@svg@rdf@prefix{#1}
+ \else%
+ \expandafter\gdef\expandafter\pgf@svg@rdf@prefix\expandafter{\pgf@svg@rdf@prefix\space#1}%
+ \fi}
+\def\pgfsys@rdf@property#1{\pgf@svg@rdf@init%
+ \ifx\pgf@svg@rdf@property\relax%
+ \gdef\pgf@svg@rdf@property{#1}
+ \else%
+ \expandafter\gdef\expandafter\pgf@svg@rdf@property\expandafter{\pgf@svg@rdf@property\space#1}%
+ \fi}
+\def\pgfsys@rdf@rel#1{\pgf@svg@rdf@init%
+ \ifx\pgf@svg@rdf@rel\relax%
+ \gdef\pgf@svg@rdf@rel{#1}
+ \else%
+ \expandafter\gdef\expandafter\pgf@svg@rdf@rel\expandafter{\pgf@svg@rdf@rel\space#1}%
+ \fi}
+\def\pgfsys@rdf@rev#1{\pgf@svg@rdf@init%
+ \ifx\pgf@svg@rdf@rev\relax%
+ \gdef\pgf@svg@rdf@rev{#1}
+ \else%
+ \expandafter\gdef\expandafter\pgf@svg@rdf@rev\expandafter{\pgf@svg@rdf@rev\space#1}%
+ \fi}
+\def\pgfsys@rdf@typeof#1{\pgf@svg@rdf@init%
+ \ifx\pgf@svg@rdf@typeof\relax%
+ \gdef\pgf@svg@rdf@typeof{#1}
+ \else%
+ \expandafter\gdef\expandafter\pgf@svg@rdf@typeof\expandafter{\pgf@svg@rdf@typeof\space#1}%
+ \fi}
+\def\pgfsys@rdf@resource#1{\pgf@svg@rdf@init\gdef\pgf@svg@rdf@resource{#1}}
+\def\pgfsys@rdf@src#1{\pgf@svg@rdf@init\gdef\pgf@svg@rdf@src{#1}}
+\def\pgfsys@rdf@vocab#1{\pgf@svg@rdf@init\gdef\pgf@svg@rdf@vocab{#1}}
+
+
+
+
+
+
+%
+
+\def\pgfutil@color{\pgfsetcolor}
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvi.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvi.def
new file mode 100644
index 0000000000..dbe6fb3130
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvi.def
@@ -0,0 +1,394 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-dvi.def}
+
+% Driver commands for pure, ultra-portable dvi, in the tradition of
+% old-style LaTeX pictures.
+%
+% Do not expect magic from this file
+
+
+\newtoks\pgf@sys@dvi@path
+\def\pgf@sys@dvi@addtopath#1{\pgf@sys@dvi@path\expandafter{\the\pgf@sys@dvi@path#1}}
+
+% Placing an object:
+\def\pgf@sys@dvi@put#1#2#3{%
+ {%
+ \setbox\pgf@hbox=\hbox{\raise#2\hbox to0pt{\kern#1\relax#3\hss}}%
+ \wd\pgf@hbox=0pt%
+ \ht\pgf@hbox=0pt%
+ \dp\pgf@hbox=0pt%
+ \box\pgf@hbox%
+ }%
+}
+
+\def\pgf@sys@dvi@drawrect#1#2#3#4{%
+ {%
+ \pgf@x=#1%
+ \pgf@y=#2%
+ \pgf@xa=#3%
+ \pgf@ya=#4%
+ \ifdim\pgf@xa<0pt%
+ \advance\pgf@x by\pgf@xa%
+ \pgf@xa=-\pgf@xa%
+ \fi%
+ \ifdim\pgf@ya<0pt%
+ \advance\pgf@y by\pgf@ya%
+ \pgf@ya=-\pgf@ya%
+ \fi%
+ \pgf@sys@dvi@put{\pgf@x}{\pgf@y}{\vrule width\pgf@xa height\pgf@ya}%
+ }%
+}
+
+\def\pgf@sys@dvi@bezier{%
+ {%
+ % First iteration:
+ \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya%
+ \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb%
+ \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb%
+ \pgf@xb=\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc%
+ \pgf@yb=\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc%
+ % Second iteration:
+ \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya%
+ \pgf@xa=\pgf@time@t\pgf@xa\advance\pgf@xa by\pgf@time@s\pgf@xb%
+ \pgf@ya=\pgf@time@t\pgf@ya\advance\pgf@ya by\pgf@time@s\pgf@yb%
+ % Third iteration:
+ \pgf@x=\pgf@time@t\pgf@x\advance\pgf@x by\pgf@time@s\pgf@xa%
+ \pgf@y=\pgf@time@t\pgf@y\advance\pgf@y by\pgf@time@s\pgf@ya%
+ %
+ \advance\pgf@x by-.5\pgf@sys@dvi@linewidth%
+ \advance\pgf@y by-.5\pgf@sys@dvi@linewidth%
+ \pgf@sys@dvi@drawrect{\pgf@x}{\pgf@y}{\pgf@sys@dvi@linewidth}{\pgf@sys@dvi@linewidth}%
+ }%
+}
+
+\def\pgf@sys@dvi@drawcurve#1#2#3#4#5#6#7#8{%
+ {%
+ \pgf@x=#1%
+ \pgf@y=#2%
+ \pgf@xa=#3%
+ \pgf@ya=#4%
+ \pgf@xb=#5%
+ \pgf@yb=#6%
+ \pgf@xc=#7%
+ \pgf@yc=#8%
+ % Compute number of steps:
+ \pgfutil@tempdima=\pgf@x%
+ \advance\pgfutil@tempdima by-\pgf@xa%
+ \ifdim\pgfutil@tempdima<0pt%
+ \pgfutil@tempdimb=-\pgfutil@tempdima%
+ \else%
+ \pgfutil@tempdimb=\pgfutil@tempdima%
+ \fi%
+ \pgfutil@tempdima=\pgf@y%
+ \advance\pgfutil@tempdima by-\pgf@ya%
+ \ifdim\pgfutil@tempdima<0pt%
+ \pgfutil@tempdima=-\pgfutil@tempdima%
+ \fi%
+ \ifdim\pgfutil@tempdima>\pgfutil@tempdimb%
+ \pgfutil@tempdimb=\pgfutil@tempdima%
+ \fi%
+ \pgfutil@tempdima=\pgf@xb%
+ \advance\pgfutil@tempdima by-\pgf@xc%
+ \ifdim\pgfutil@tempdima<0pt%
+ \pgfutil@tempdima=-\pgfutil@tempdima%
+ \fi%
+ \ifdim\pgfutil@tempdima>\pgfutil@tempdimb%
+ \pgfutil@tempdimb=\pgfutil@tempdima%
+ \fi%
+ \pgfutil@tempdima=\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yc%
+ \ifdim\pgfutil@tempdima<0pt%
+ \pgfutil@tempdima=-\pgfutil@tempdima%
+ \fi%
+ \ifdim\pgfutil@tempdima>\pgfutil@tempdimb%
+ \pgfutil@tempdimb=\pgfutil@tempdima%
+ \fi%
+ \pgfutil@tempdima=\pgf@x%
+ \advance\pgfutil@tempdima by-\pgf@xc%
+ \ifdim\pgfutil@tempdima<0pt%
+ \pgfutil@tempdima=-\pgfutil@tempdima%
+ \fi%
+ \ifdim\pgfutil@tempdima>\pgfutil@tempdimb%
+ \pgfutil@tempdimb=\pgfutil@tempdima%
+ \fi%
+ \pgfutil@tempdima=\pgf@y%
+ \advance\pgfutil@tempdima by-\pgf@yc%
+ \ifdim\pgfutil@tempdima<0pt%
+ \pgfutil@tempdima=-\pgfutil@tempdima%
+ \fi%
+ \ifdim\pgfutil@tempdima>\pgfutil@tempdimb%
+ \pgfutil@tempdimb=\pgfutil@tempdima%
+ \fi%
+ \pgfutil@tempcnta=\pgfutil@tempdimb%
+ \ifdim\pgf@sys@dvi@linewidth>0.3pt%
+ \pgfutil@tempdimb=0.15pt%
+ \else%
+ \ifdim\pgf@sys@dvi@linewidth<0.05pt%
+ \pgfutil@tempdimb=.025pt%
+ \else%
+ \pgfutil@tempdimb=.5\pgf@sys@dvi@linewidth%
+ \fi%
+ \fi%
+ \pgfutil@tempcntb=\pgfutil@tempdimb%
+ \divide\pgfutil@tempcnta by\pgfutil@tempcntb\relax%
+ \ifnum\pgfutil@tempcnta>0\relax%
+ \pgfutil@tempcntb=0\relax%
+ \loop%
+ {%
+ \pgfutil@tempdima=\the\pgfutil@tempcntb pt%
+ \pgfutil@tempdimb=\the\pgfutil@tempcnta pt%
+ \advance\pgfutil@tempdimb by-\pgfutil@tempdima\relax%
+ \divide\pgfutil@tempdima by\pgfutil@tempcnta\relax%
+ \divide\pgfutil@tempdimb by\pgfutil@tempcnta\relax%
+ \edef\pgf@time@t{\pgf@sys@tonumber{\pgfutil@tempdima}}%
+ \edef\pgf@time@s{\pgf@sys@tonumber{\pgfutil@tempdimb}}%
+ \pgf@sys@dvi@bezier%
+ }%
+ \advance\pgfutil@tempcntb by1\relax
+ \ifnum\pgfutil@tempcntb<\pgfutil@tempcnta%
+ {\def\pgf@time@t{1}\def\pgf@time@s{0}\pgf@sys@dvi@bezier}%
+ \repeat%
+ \fi%
+ }%
+}
+
+% Text:
+\def\pgfsys@hbox#1{%
+ \pgfsys@begin@idscope%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \pgf@sys@dvi@put{\pgf@sys@dvi@pt@x}{\pgf@sys@dvi@pt@y}{\box#1}%
+ \pgfsys@end@idscope%
+}
+
+
+
+% Literals:
+
+\def\pgfsys@invoke#1{#1}
+
+
+% Buffered path construction:
+
+\def\pgfsys@moveto#1#2{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@addtopath{\noexpand\pgf@sys@dvi@moveto{#1}{#2}}}}
+\def\pgfsys@lineto#1#2{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@addtopath{\noexpand\pgf@sys@dvi@lineto{#1}{#2}}}}
+\def\pgfsys@curveto#1#2#3#4#5#6{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@addtopath{\noexpand\pgf@sys@dvi@curveto{#1}{#2}{#3}{#4}{#5}{#6}}}}
+\def\pgfsys@rect#1#2#3#4{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@addtopath{\noexpand\pgf@sys@dvi@rect{#1}{#2}{#3}{#4}}}}
+\def\pgfsys@closepath{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@addtopath{\noexpand\pgf@sys@dvi@closepath}}}
+
+
+% Scoping
+\def\pgfsys@beginscope{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@beginscope}}%
+\def\pgfsys@endscope{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@endscope}}%
+
+\def\pgf@sys@dvi@beginscope{%
+ % Save current stuff...
+ \edef\pgf@sys@dvi@return{%
+ \global\pgf@sys@dvi@linewidth=\the\pgf@sys@dvi@linewidth%
+ \global\pgf@sys@dvi@pt@x=\the\pgf@sys@dvi@pt@x%
+ \global\pgf@sys@dvi@pt@y=\the\pgf@sys@dvi@pt@y%
+ \gdef\noexpand\pgf@sys@dvi@pt@aa{\pgf@sys@dvi@pt@aa}%
+ \gdef\noexpand\pgf@sys@dvi@pt@ab{\pgf@sys@dvi@pt@ab}%
+ \gdef\noexpand\pgf@sys@dvi@pt@ba{\pgf@sys@dvi@pt@ba}%
+ \gdef\noexpand\pgf@sys@dvi@pt@bb{\pgf@sys@dvi@pt@bb}%
+ }%
+ \begingroup%
+ \ignorespaces%
+}
+
+\def\pgf@sys@dvi@endscope{%
+ \endgroup%
+ \pgf@sys@dvi@return%
+}
+
+
+
+% Line width
+
+\newdimen\pgf@sys@dvi@linewidth
+\pgf@sys@dvi@linewidth=0.4pt
+
+\def\pgfsys@setlinewidth#1{\global\pgf@sys@dvi@linewidth=#1\relax}
+
+
+% Transformation matrix
+
+\newdimen\pgf@sys@dvi@pt@x
+\newdimen\pgf@sys@dvi@pt@y
+
+\def\pgf@sys@dvi@pt@aa{1.0} \def\pgf@sys@dvi@pt@ab{0.0}
+\def\pgf@sys@dvi@pt@ba{0.0} \def\pgf@sys@dvi@pt@bb{1.0}
+
+\def\pgf@sys@dvi@pos@transform#1#2{%
+ \pgf@pt@temp=#1%
+ #1=\pgf@sys@dvi@pt@aa#1%
+ \advance#1 by\pgf@sys@dvi@pt@ba#2%
+ #2=\pgf@sys@dvi@pt@bb#2%
+ \advance#2 by\pgf@sys@dvi@pt@ab\pgf@pt@temp%
+ \advance#1 by\pgf@sys@dvi@pt@x%
+ \advance#2 by\pgf@sys@dvi@pt@y%
+}
+
+\def\pgf@sys@dvi@transformcm#1#2#3#4#5#6{%
+ {%
+ \pgf@xc=#5%
+ \pgf@yc=#6%
+ %
+ \pgf@x=#1pt%
+ \pgf@y=#2pt%
+ %
+ \pgf@xa=\pgf@sys@dvi@pt@aa\pgf@x%
+ \advance\pgf@xa by \pgf@sys@dvi@pt@ba\pgf@y%
+ %
+ \pgf@ya=\pgf@sys@dvi@pt@ab\pgf@x%
+ \advance\pgf@ya by \pgf@sys@dvi@pt@bb\pgf@y%
+ %
+ \pgf@x=#3pt%
+ \pgf@y=#4pt%
+ %
+ \pgf@xb=\pgf@sys@dvi@pt@aa\pgf@x%
+ \advance\pgf@xb by \pgf@sys@dvi@pt@ba\pgf@y%
+ %
+ \pgf@yb=\pgf@sys@dvi@pt@ab\pgf@x%
+ \advance\pgf@yb by \pgf@sys@dvi@pt@bb\pgf@y%
+ %
+ \pgf@x=\pgf@sys@dvi@pt@aa\pgf@xc%
+ \advance\pgf@x by\pgf@sys@dvi@pt@ba\pgf@yc%
+ \advance\pgf@x by\pgf@sys@dvi@pt@x%
+ %
+ \pgf@y=\pgf@sys@dvi@pt@ab\pgf@xc%
+ \advance\pgf@y by\pgf@sys@dvi@pt@bb\pgf@yc%
+ \advance\pgf@y by\pgf@sys@dvi@pt@y%
+ %
+ \global\pgf@sys@dvi@pt@x=\pgf@x%
+ \global\pgf@sys@dvi@pt@y=\pgf@y%
+ \xdef\pgf@sys@dvi@pt@aa{\pgf@sys@tonumber{\pgf@xa}}%
+ \xdef\pgf@sys@dvi@pt@ab{\pgf@sys@tonumber{\pgf@ya}}%
+ \xdef\pgf@sys@dvi@pt@ba{\pgf@sys@tonumber{\pgf@xb}}%
+ \xdef\pgf@sys@dvi@pt@bb{\pgf@sys@tonumber{\pgf@yb}}%
+ }%
+}
+
+\def\pgfsys@transformcm#1#2#3#4#5#6{%
+ {%
+ \pgf@x=#5\relax%
+ \pgf@y=#6\relax%
+ \pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@transformcm{#1}{#2}{#3}{#4}{\the\pgf@x}{\the\pgf@y}}%
+ }%
+}
+
+
+% Stroking
+
+\def\pgfsys@stroke{\pgfsysprotocol@literal{\noexpand\pgf@sys@dvi@stroke}}%
+
+
+\def\pgf@sys@dvi@stroke{%
+ \let\pgf@sys@dvi@moveto=\pgf@sys@dvi@moveto@stroke%
+ \let\pgf@sys@dvi@lineto=\pgf@sys@dvi@lineto@stroke%
+ \let\pgf@sys@dvi@curveto=\pgf@sys@dvi@curveto@stroke%
+ \let\pgf@sys@dvi@rect=\pgf@sys@dvi@rect@stroke%
+ \let\pgf@sys@dvi@closepath=\pgf@sys@dvi@closepath@stroke%
+ {\the\pgf@sys@dvi@path}%
+ \pgf@sys@dvi@path{}%
+}
+
+\def\pgf@sys@dvi@moveto@stroke#1#2{%
+ % These two store the current position:
+ \pgf@xc=#1\relax%
+ \pgf@yc=#2\relax%
+ % These two store the last moveto:
+ \pgf@xb=\pgf@xc%
+ \pgf@yb=\pgf@yc%
+}
+
+\def\pgf@sys@dvi@lineto@stroke#1#2{%
+ {%
+ \pgf@xa=#1\relax%
+ \pgf@ya=#2\relax%
+ \pgf@x=\pgf@xc%
+ \pgf@y=\pgf@yc%
+ \pgf@sys@dvi@pos@transform{\pgf@xa}{\pgf@ya}%
+ \pgf@sys@dvi@pos@transform{\pgf@x}{\pgf@y}%
+ % Now, we need to draw a line from (x/y) to (xa/ya)
+ %
+ % Horizontal?
+ \ifdim\pgf@y=\pgf@ya%
+ % Ok, that should be easy...
+ \pgf@xb=\pgf@xa%
+ \advance\pgf@xb by-\pgf@x%
+ \advance\pgf@y by-0.5\pgf@sys@dvi@linewidth%
+ \pgf@sys@dvi@drawrect{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@sys@dvi@linewidth}%
+ \else%
+ \ifdim\pgf@x=\pgf@xa%
+ % Ok, also easy...
+ \pgf@yb=\pgf@ya%
+ \advance\pgf@yb by-\pgf@y%
+ \advance\pgf@x by-0.5\pgf@sys@dvi@linewidth%
+ \pgf@sys@dvi@drawrect{\pgf@x}{\pgf@y}{\pgf@sys@dvi@linewidth}{\pgf@yb}%
+ \else%
+ \edef\pgf@marshal{\noexpand\pgf@sys@dvi@drawcurve{\the\pgf@x}{\the\pgf@y}{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xa}{\the\pgf@ya}}%
+ \pgf@marshal%
+ \fi%
+ \fi%
+ }%
+ % Remember:
+ \pgf@xc=#1\relax%
+ \pgf@yc=#2\relax%
+}
+
+
+\def\pgf@sys@dvi@curveto@stroke#1#2#3#4#5#6{%
+ \pgf@x=\pgf@xc%
+ \pgf@y=\pgf@yc%
+ \pgf@xa=#1%
+ \pgf@ya=#2%
+ \pgf@xb=#3%
+ \pgf@yb=#4%
+ \pgf@xc=#5%
+ \pgf@yc=#6%
+ {%
+ \pgf@sys@dvi@pos@transform{\pgf@x}{\pgf@y}%
+ \pgf@sys@dvi@pos@transform{\pgf@xa}{\pgf@ya}%
+ \pgf@sys@dvi@pos@transform{\pgf@xb}{\pgf@yb}%
+ \pgf@sys@dvi@pos@transform{\pgf@xc}{\pgf@yc}%
+ \pgf@sys@dvi@drawcurve{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}{\pgf@xb}{\pgf@yb}{\pgf@xc}{\pgf@yc}%
+ }%
+}
+
+\def\pgf@sys@dvi@closepath@stroke{%
+ \pgf@sys@dvi@lineto@stroke{\pgf@xc}{\pgf@yc}%
+}
+
+\def\pgf@sys@dvi@rect@stroke#1#2#3#4{%
+ \pgf@x=#1\relax%
+ \pgf@y=#2\relax%
+ \pgf@xa=#3\relax%
+ \pgf@ya=#4\relax%
+ \advance\pgf@xa by\pgf@x%
+ \advance\pgf@ya by\pgf@y%
+ \pgf@sys@dvi@moveto@stroke{\pgf@x}{\pgf@y}%
+ \pgf@sys@dvi@lineto@stroke{\pgf@xa}{\pgf@y}%
+ \pgf@sys@dvi@lineto@stroke{\pgf@xa}{\pgf@ya}%
+ \pgf@sys@dvi@lineto@stroke{\pgf@x}{\pgf@ya}%
+ \pgf@sys@dvi@closepath@stroke%
+}
+
+
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfm.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfm.def
new file mode 100644
index 0000000000..df1209aefb
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfm.def
@@ -0,0 +1,110 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-dvipdfm.def}
+
+% Driver commands for dvipdfm
+
+%
+% Load common pdf and pdf in dvi commands:
+%
+\input pgfsys-common-pdf.def
+\input pgfsys-common-pdf-via-dvi.def
+
+%
+% dvipdfm-specific stuff:
+%
+
+\def\pgfsys@hbox#1{%
+ \pgfsys@begin@idscope%
+ \pgfsys@invoke{q -1 0 0 -1 0 0 cm}%
+ \special{pdf: content -1 0 0 -1 0 0 cm 3 Tr q}% translate to
+ % original coordinate system and do
+ % not show anything
+ {\hbox to 0pt{\pgfutil@font@normalfont\pgfutil@selectfont.\hss}}% enforce font change
+ \pgfsys@invoke{0 Tr}%
+ \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \box#1
+ \pgfsys@invoke{n Q Q}%
+ \pgfsys@end@idscope%
+}
+\def\pgfsys@hboxsynced#1{%
+ {%
+ \pgfsys@begin@idscope%
+ \pgfsys@beginscope%
+ \setbox\pgf@hbox=\hbox{%
+ \hskip\pgf@pt@x%
+ \raise\pgf@pt@y\hbox{%
+ \pgf@pt@x=0pt%
+ \pgf@pt@y=0pt%
+ \special{pdf: content q}%
+ \pgflowlevelsynccm%
+ \pgfsys@invoke{q -1 0 0 -1 0 0 cm}%
+ \special{pdf: content -1 0 0 -1 0 0 cm q}% translate to original coordinate system
+ \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \box#1%
+ \pgfsys@invoke{n Q Q Q}%
+ }%
+ \hss%
+ }%
+ \wd\pgf@hbox=0pt%
+ \ht\pgf@hbox=0pt%
+ \dp\pgf@hbox=0pt%
+ \pgfsys@hbox\pgf@hbox%
+ \pgfsys@endscope%
+ \pgfsys@end@idscope%
+ }%
+}
+
+\def\pgfsys@beginpicture{%
+ \pgfsys@invoke{3 Tr}%
+ \hbox to 0pt{\pgfutil@font@normalfont\pgfutil@selectfont.\hss}% enforce font change
+ \pgfsys@invoke{0 Tr}%
+ \special{pdf: content q}}
+\def\pgfsys@endpicture{%
+ \pgfsys@invoke{n Q}%
+}
+
+\def\pgfsys@invoke#1{\special{pdf: content Q #1 q}} % ugly, but necessary...
+
+\def\pgfsys@papersize#1#2{%
+% \expandafter\gdef\expandafter\pgfsys@atbegindocument%
+% \expandafter{\pgfsys@atbegindocument
+ \special{papersize=#1,#2}%
+% }
+}
+
+\def\pgfsys@prepare@papersize#1#2{%
+ \expandafter\gdef\expandafter\pgfsys@atbegindocument%
+ \expandafter{\pgfsys@atbegindocument
+ \special{papersize=#1,#2}%
+ }
+}
+
+%
+% Position tracking (needs pdftex >= 1.40.0-alpha-20051205 in dvi mode)
+%
+\ifx\pdftexversion\@undefined
+\else
+ \ifnum\pdftexversion>139
+ \pgf@sys@pdf@dvi@tracker
+ \fi
+\fi
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfmx.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfmx.def
new file mode 100644
index 0000000000..7fc1a4e7ed
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvipdfmx.def
@@ -0,0 +1,504 @@
+% Copyright 2019 by Till Tantau
+% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-dvipdfmx.def}
+
+% Driver commands for dvipdfmx
+%
+% Modified by Jin-Hwan Cho <chofchof@ktug.or.kr> on April 18, 2009.
+% This driver requires the version DVIPDFMX-20080605 that is contained
+% in texlive 2008 or later.
+
+%
+% Load common pdf and pdf in dvi commands:
+%
+\input pgfsys-common-pdf.def
+
+
+% For unique object name:
+\newcount\pgfsys@objnum\pgfsys@objnum\@ne
+
+% `pdf:code' is an abbreviation of `pdf:literal direct', the idea of which
+% came from pdfTeX's primitive \pdfliteral direct.
+\def\pgfsys@invoke#1{\special{pdf:code #1}}
+
+% If color is changed by \pgfsys@invoke explicitly, the color
+% optimization routine in dvipdfmx does not work correctly
+% because the routine checks color specials only. For example,
+%
+% \special{color push 0}\pgfsys@invoke{1 g 1 G}\special{color push 0}
+%
+% the last color special will be ignored the optimization routine
+% thinks that the color has changed to the same color.
+% To avoid this problem, we need to change the color temporarily to another.
+%
+% We assume that black is the default color when no color is specified.
+\def\pgfsys@dvipdfmx@start@force@reset@color{%
+ \special{pdf:bcolor [1]}%
+ \special{pdf:bcolor [0]}%
+}
+\def\pgfsys@dvipdfmx@stop@force@reset@color{%
+ \special{pdf:ecolor}%
+ \special{pdf:ecolor}%
+}
+
+
+\def\pgfsys@dvipdfmx@suspendcontent{%
+ \special{pdf:code q -1 0 0 -1 0 0 cm q}%
+ \special{pdf: econtent}%
+ \special{pdf: bcontent}%
+ \special{pdf:code -1 0 0 -1 0 0 cm}%
+ \special{pdf:code q}% translate to original system
+ \special{pdf: econtent}%
+}
+
+\def\pgfsys@dvipdfmx@unsuspendcontent{%
+ \special{pdf: bcontent}%
+ \special{pdf:code Q Q Q}%
+}
+
+\def\pgfsys@hbox#1{%
+ \pgfsys@begin@idscope%
+ \pgfsys@beginscope%
+ \setbox#1=\hbox{\box#1}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \pgfsys@dvipdfmx@suspendcontent%
+ \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash
+ \pgfsys@dvipdfmx@start@force@reset@color%
+ \box#1%
+ \pgfsys@dvipdfmx@stop@force@reset@color%
+ \pgfsys@dvipdfmx@unsuspendcontent%
+ \pgfsys@endscope%
+ \pgfsys@end@idscope%
+}
+
+% We cannot use many codes in pgfsys-common-pdf-via-dvi.def.
+% So it is rewritten here (with some bugs fixed).
+\def\pgfsys@hboxsynced#1{%
+ \pgfsys@begin@idscope%
+ \pgfsys@beginscope%
+ \setbox#1=\hbox{\box#1}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \pgfsys@dvipdfmx@suspendcontent%
+ \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash
+ \pgfsys@dvipdfmx@start@force@reset@color%
+ \pgf@sys@bp@correct\pgf@pt@x%
+ \pgf@sys@bp@correct\pgf@pt@y%
+ \special{pdf:btrans matrix \pgf@pt@aa\space \pgf@pt@ab\space \pgf@pt@ba\space \pgf@pt@bb\space
+ \pgf@sys@tonumber{\pgf@pt@x} \pgf@sys@tonumber{\pgf@pt@y}}%
+ \box#1%
+ \special{pdf:etrans}%
+ \pgfsys@dvipdfmx@stop@force@reset@color%
+ \pgfsys@dvipdfmx@unsuspendcontent%
+ \pgfsys@endscope%
+ \pgfsys@end@idscope%
+}
+
+% All text materials between `pdf:bcontent' and `pdf:econtent' are
+% treated in the relative coordinate.
+\def\pgfsys@beginpicture{\special{pdf:bcontent}}
+\def\pgfsys@endpicture{\special{pdf:econtent}}
+
+\def\pgfsys@imagesuffixlist{.pdf:.jpg:.jpeg:.png:.bmp:}
+
+% Shaidng came from pgfsys-pdftex.def
+\def\pgfsys@horishading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathparse{#2}%
+ \pgf@process{\pgfpoint{\pgf@max}{#2}}%
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ \special{pdf:bxobj @pgfshade\the\pgfsys@objnum\space width \the\pgf@max\space height \pgfmathresult pt}%
+ \special{pdf:put @resources
+ <<
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@doma\space0 \pgf@domb\space0]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >>
+ >>}%
+ \pgfsys@invoke{/Sh sh}%
+ \special{pdf:exobj}}}\@tempa% <<
+ \xdef\pgfutil@tempa{%
+ \hbox to\the\pgf@max{\vbox to\pgfmathresult pt{\vfil\special{pdf:uxobj @pgfshade\the\pgfsys@objnum}}\hfil}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+ \global\advance\pgfsys@objnum\@ne%
+}
+\def\pgfsys@vertshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathparse{#2}%
+ \pgf@process{\pgfpoint{\pgf@max}{#2}}%
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ \special{pdf:bxobj @pgfshade\the\pgfsys@objnum\space width \pgfmathresult pt\space height \the\pgf@max}%
+ \special{pdf:put @resources
+ <<
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [0 \pgf@doma\space0 \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >>
+ >>}%
+ \pgfsys@invoke{/Sh sh}%
+ \special{pdf:exobj}}}\@tempa% <<
+ \xdef\pgfutil@tempa{%
+ \hbox to\pgfmathresult pt{\vbox to\the\pgf@max{\vfil\special{pdf:uxobj @pgfshade\the\pgfsys@objnum}}\hfil}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+ \global\advance\pgfsys@objnum\@ne%
+}
+\def\pgfsys@radialshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpoint{\pgf@max}{\pgf@max}}%
+ \advance\pgf@xa by \pgf@x%
+ \advance\pgf@ya by \pgf@y%
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgfutil@tempdima=2\pgf@max%
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ \special{pdf:bxobj @pgfshade\the\pgfsys@objnum\space width \the\pgfutil@tempdima\space height \the\pgfutil@tempdima}%
+ \special{pdf:put @resources
+ <<
+ /Shading << /Sh << /ShadingType 3
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@sys@tonumber{\pgf@xa} \pgf@sys@tonumber{\pgf@ya} \pgf@doma\space \pgf@sys@tonumber{\pgf@x} \pgf@sys@tonumber{\pgf@y} \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [true false] >> >>
+ >>}%
+ \pgfsys@invoke{/Sh sh}%
+ \special{pdf:exobj}}}\@tempa% <<
+ \xdef\pgfutil@tempa{%
+ \hbox to\the\pgfutil@tempdima{\vbox to\the\pgfutil@tempdima{\vfil\special{pdf:uxobj @pgfshade\the\pgfsys@objnum}}\hfil}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+ \global\advance\pgfsys@objnum\@ne%
+}
+\def\pgfsys@functionalshading#1#2#3#4{%
+ {%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgf@sys@bp@correct{\pgf@xb}%
+ \pgf@sys@bp@correct{\pgf@yb}%
+ \pgf@xc=-\pgf@xa%
+ \pgf@yc=-\pgf@ya%
+ % Now build the function
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ \special{pdf:stream @pgfstream\the\pgfsys@objnum\space({#4}) <</FunctionType 4
+ /Domain [\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@ya}\space\pgf@sys@tonumber{\pgf@yb}]
+ /Range [\pgf@shading@functional@range]>>}}}\@tempa%
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ \special{pdf:bxobj @pgfshade\the\pgfsys@objnum\space width \the\pgf@x\space height \the\pgf@y}%
+ \special{pdf:put @resources <</Shading <</Sh <</ShadingType 1
+ /ColorSpace \pgf@shading@device\space
+ /Matrix [1 0 0 1 \pgf@sys@tonumber{\pgf@xc}\space\pgf@sys@tonumber{\pgf@yc}]
+ /Domain [\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@ya}\space\pgf@sys@tonumber{\pgf@yb}]
+ /Function @pgfstream\the\pgfsys@objnum>> >> >>}%
+ \pgfsys@invoke{/Sh sh}%
+ \special{pdf:exobj}}}\@tempa% <<
+ \xdef\pgfutil@tempa{%
+ \hbox to\the\pgf@x{\vbox to\the\pgf@y{\vfil\special{pdf:uxobj @pgfshade\the\pgfsys@objnum}}\hfil}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+ \global\advance\pgfsys@objnum\@ne%
+}
+
+% \pgf@sys@pdf@dvi@tracker was not touched!
+\def\pgf@sys@pdf@dvi@tracker{
+ \def\pgfsys@markposition##1{%
+ \pdfsavepos%
+ \edef\pgf@temp{##1}%
+ \expandafter\pgfutil@writetoaux\expandafter{%
+ \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}%
+ }
+ \def\pgfsyspdfmark##1##2##3{%
+ \expandafter\gdef\csname pgf@sys@pdf@mark@pos@##1\endcsname{\pgfqpoint{##2sp}{##3sp}}%
+ \pgfutil@check@rerun{##1}{{##2}{##3}}%
+ }
+ \def\pgfsys@getposition##1##2{%
+ \edef\pgf@marshal{\let\noexpand##2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@##1\endcsname}%
+ \pgf@marshal%
+ }
+ \def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfpointorigin}
+}
+
+% Resource management: bugs were fixed.
+\newif\ifpgf@sys@pdf@colorspaces@exists
+\newif\ifpgf@sys@pdf@patterns@exists
+\newif\ifpgf@sys@pdf@extgs@exists
+\newif\ifpgf@sys@pdf@colorspaces@created
+\newif\ifpgf@sys@pdf@patterns@created
+\newif\ifpgf@sys@pdf@extgs@created
+\newif\ifpgf@sys@pdf@any@resources
+
+\def\pgf@sys@setuppdfresources@plain{%
+ % This command will setup pdf resource in plain and in latex
+ % mode. ConTeXt has its own handler
+ \pgfutil@insertatbegineverypage{%
+ \pgf@sys@pdf@any@resourcesfalse%
+ \ifpgf@sys@pdf@extgs@exists%
+ \pgf@sys@pdf@any@resourcestrue%
+ \ifpgf@sys@pdf@extgs@created\else\special{pdf:obj @pgfextgs <<>>}\global\pgf@sys@pdf@extgs@createdtrue\fi% <<
+ \fi%
+ \ifpgf@sys@pdf@colorspaces@exists%
+ \pgf@sys@pdf@any@resourcestrue%
+ \ifpgf@sys@pdf@colorspaces@created\else\special{pdf:obj @pgfcolorspaces <<>>}\global\pgf@sys@pdf@colorspaces@createdtrue\fi% <<
+ \fi%
+ \ifpgf@sys@pdf@patterns@exists%
+ \pgf@sys@pdf@any@resourcestrue%
+ \ifpgf@sys@pdf@patterns@created\else\special{pdf:obj @pgfpatterns <<>>}\global\pgf@sys@pdf@patterns@createdtrue\fi% <<
+ \fi%
+ \ifpgf@sys@pdf@any@resources%
+ \special{pdf:put @resources
+ <<
+ \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi
+ \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \fi
+ \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi
+ >>}% <<
+ \fi%
+ }
+ \def\pgf@sys@addpdfresource@extgs@plain##1{%
+ \global\pgf@sys@pdf@extgs@existstrue%
+ \pgfutil@insertatbegincurrentpage{\special{pdf:put @pgfextgs << ##1 >>}}% <<
+ }
+ \def\pgf@sys@addpdfresource@colorspaces@plain##1{%
+ \global\pgf@sys@pdf@colorspaces@existstrue%
+ \pgfutil@insertatbegincurrentpage{\special{pdf:put @pgfcolorspaces << ##1 >>}}% <<
+ }
+ \def\pgf@sys@addpdfresource@patterns@plain##1{%
+ \global\pgf@sys@pdf@patterns@existstrue%
+ \pgfutil@insertatbegincurrentpage{\special{pdf:put @pgfpatterns << ##1 >>}}% <<
+ }
+}
+\pgfutil@setuppdfresources % possibly call the above
+
+% As pgfsys-pdftex.def, the following code is required
+% to give colors on pattern objects.
+\pgfutil@addpdfresource@colorspaces{ /pgfprgb [/Pattern /DeviceRGB] }
+
+% Image Mask came from pgfsys-pdftex.def
+% generic/pgf/basiclayer/pgfcoreimage.code.tex must be modified!
+\def\pgfsys@defineimage{% width, height, page number
+ \ifx\pgf@imagewidth\pgfutil@empty\edef\pgf@imagewidth{1bp}\fi% width?
+ \ifx\pgf@imageheight\pgfutil@empty\edef\pgf@imageheight{1bp}\fi% height?
+ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage}\fi%
+ \ifx\pgf@imageinterpolate\pgfutil@empty\else\edef\pgf@imageinterpolate{ /Interpolate\space\pgf@imageinterpolate}\fi%
+ \ifx\pgf@imagemask\pgfutil@empty\else\xdef\pgf@imagemask{ /SMask @\pgf@imagemask}\fi%
+ \edef\pgf@image{\noexpand\hbox to \pgf@imagewidth{\vbox to \pgf@imageheight{\vfil\special{pdf:image width \pgf@imagewidth\space height \pgf@imageheight\space\pgf@imagepage\space(\pgf@filename) <<\pgf@imageinterpolate\pgf@imagemask\space>>}}\hfil}}%
+}
+\def\pgfsys@definemask{%
+ \ifx\pgf@maskmatte\pgfutil@empty%
+ \else%
+ \edef\pgf@maskmatte{/Matte [\pgf@maskmatte]}%
+ \fi%
+ \edef\pgf@attr{\pgf@maskmatte\space /Decode [1 0]}%
+ \special{pdf:image @pgfmask\the\pgfsys@objnum\space hide (\pgf@filename) << \pgf@attr >>}%
+ \edef\pgf@mask{pgfmask\the\pgfsys@objnum}%
+ \global\advance\pgfsys@objnum\@ne%
+}
+
+% Patterns came from pgfsys-pdftex.def
+% dvipdfmx provides a new special `pdf:stream' for a stream object.
+\def\pgfsys@declarepattern#1#2#3#4#5#6#7{%
+ % Start building the pattern dictionary:
+ \pgf@xa=#2\relax%
+ \pgf@ya=#3\relax%
+ \pgf@xb=#4\relax%
+ \pgf@yb=#5\relax%
+ \pgf@xc=#6\relax%
+ \pgf@yc=#7\relax%
+ \pgf@sys@bp@correct\pgf@xa%
+ \pgf@sys@bp@correct\pgf@ya%
+ \pgf@sys@bp@correct\pgf@xb%
+ \pgf@sys@bp@correct\pgf@yb%
+ \pgf@sys@bp@correct\pgf@xc%
+ \pgf@sys@bp@correct\pgf@yc%
+ \pgfsys@@declarepattern{#1}%
+}
+
+\def\pgfsys@@declarepattern#1#2#3#4#5#6#7#8#9{%
+ \pgfutil@tempdima=#6\relax%
+ \pgfutil@tempdimb=#7\relax%
+ \pgf@sys@bp@correct\pgfutil@tempdima%
+ \pgf@sys@bp@correct\pgfutil@tempdimb%
+ % Now create the pattern object:
+ \pgfsys@dvipdfmx@patternobj{%
+ \pgfsys@dvipdfmx@stream{@pgfpatternobject#1}{#8}{%
+ /Type /Pattern
+ /PatternType 1
+ /PaintType \ifnum#9=0 2 \else 1 \fi
+ /TilingType 1
+ /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb]
+ /XStep \pgf@sys@tonumber\pgf@xc\space
+ /YStep \pgf@sys@tonumber\pgf@yc\space
+ /Matrix [#2\space#3\space#4\space#5\space\pgf@sys@tonumber\pgfutil@tempdima\space\pgf@sys@tonumber\pgfutil@tempdimb]
+ /Resources <</Pattern<<>>>> %<<
+ }%
+ }%
+ \pgfutil@addpdfresource@patterns{/pgfpat#1\space @pgfpatternobject#1}%
+}
+
+% hook for xdvipdfmx:
+\def\pgfsys@dvipdfmx@patternobj#1{%
+ \pgfutil@insertatbegincurrentpagefrombox{#1}%
+}%
+
+% hook for xdvipdfmx:
+\def\pgfsys@dvipdfmx@stream#1#2#3{%
+ \special{pdf:stream #1 (#2) << #3 >>}%
+}%
+
+
+\def\pgfsys@setpatternuncolored#1#2#3#4{%
+ \pgfsysprotocol@literal{/pgfprgb cs #2 #3 #4 /pgfpat#1\space scn}%
+}
+\def\pgfsys@setpatterncolored#1{%
+ \pgfsysprotocol@literal{/Pattern cs /pgfpat#1\space scn}%
+}
+
+% Opacity masks (fadings) came from pgfsys-pdftex.def
+%
+% One problem was that the second argument of \pgfsys@fadingfrombox
+% is a box so that \pgfutil@insertatbegincurrentpage cannot be used.
+% So, the new command \pgfutil@insertatbegincurrentpagefrombox is written
+% in generic/pgf/utilities/pgfutil-[context,latex,plain].def.
+\def\pgfsys@fadingfrombox#1#2{%
+ \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax%
+ {%
+ \pgf@x=-.5\wd#2%
+ \pgf@y=-.5\ht#2%
+ \advance\pgf@y by.5\dp#2%
+ \expandafter\xdef\csname pgfsmasktrans@#1\endcsname{%
+ \noexpand\pgftransformcm{1}{0}{0}{1}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ \special{pdf:bxobj @pgfsmask\the\pgfsys@objnum\space%
+ width \the\wd#2\space height \the\ht#2\space depth \the\dp#2}%
+ \wd#2=0pt%
+ \ht#2=0pt%
+ \dp#2=0pt%
+ \box#2%
+ \special{pdf:put @resources
+ <<
+ \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi
+ \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \fi
+ \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi
+ >>}% <<
+ \special{pdf:exobj <</Group <</S/Transparency /CS/DeviceGray>> >>}}}\@tempa%
+ \expandafter\xdef\csname pgfsmaskxform@#1\endcsname{\the\pgfsys@objnum}%
+ }%
+ \global\advance\pgfsys@objnum\@ne%
+ \fi%
+}
+\def\pgfsys@usefading#1#2#3#4#5#6#7{%
+ \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax%
+ \pgferror{Undefined fading '#1'}%
+ \else%
+ {%
+ \expandafter\ifx\csname pgfsmask@#1\endcsname\relax%
+ \pgf@sys@pdf@install@mask{#1}%
+ \fi%
+ \pgftransformreset%
+ \pgftransformcm{#2}{#3}{#4}{#5}{\pgfpoint{#6}{#7}}%
+ \csname pgfsmasktrans@#1\endcsname%
+ {%
+ \pgflowlevelsynccm%
+ \pgfsys@invoke{/pgfsmask\csname pgfsmaskxform@#1\endcsname\space gs}%
+ }%
+ \pgftransforminvert%
+ \pgflowlevelsynccm%
+ }%
+ \fi
+}
+\def\pgf@sys@pdf@install@mask#1{%
+ \pgfutil@addpdfresource@extgs{%
+ /pgfsmask\csname pgfsmaskxform@#1\endcsname\space <<
+ /SMask <<
+ /S /Luminosity
+ /G @pgfsmask\csname pgfsmaskxform@#1\endcsname
+ >> >>}%<<
+ \expandafter\let\csname pgfsmask@#1\expandafter\endcsname\csname pgfsmaskxform@#1\endcsname%
+}
+
+% Transparency groups came from pgfsys-pdftex.def
+\def\pgfsys@transparencygroupfrombox#1{%
+ {%
+ \pgfutil@tempdima=\pgf@picminx
+ \pgf@sys@bp@correct\pgf@picminx%
+ \pgf@sys@bp@correct\pgf@picmaxx%
+ \pgf@sys@bp@correct\pgf@picminy%
+ \pgf@sys@bp@correct\pgf@picmaxy%
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ \special{pdf:bxobj @pgftransgroup\the\pgfsys@objnum\space bbox \pgf@sys@tonumber\pgf@picminx\space\pgf@sys@tonumber\pgf@picminy\space\pgf@sys@tonumber\pgf@picmaxx\space\pgf@sys@tonumber\pgf@picmaxy}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \hskip\pgfutil@tempdima\box#1\hskip-\pgfutil@tempdima%
+ \special{pdf:put @resources
+ <<
+ \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi
+ \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \fi
+ \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi
+ >>}% <<
+ \special{pdf:exobj <</Group << /S /Transparency
+ /I \ifpgfsys@transparency@group@isolated true \else false \fi
+ /K \ifpgfsys@transparency@group@knockout true \else false \fi>> >>}%
+ }}\@tempa%
+ \special{pdf:uxobj @pgftransgroup\the\pgfsys@objnum}%
+ }%
+ \global\advance\pgfsys@objnum\@ne%
+}
+
+%
+% Position tracking (needs pdftex >= 1.40.0-alpha-20051205 in dvi mode)
+%
+\ifx\pdfsavepos\@undefined
+\else
+ \pgf@sys@pdf@dvi@tracker
+\fi
+
+\def\pgfsys@papersize#1#2{%
+% \expandafter\gdef\expandafter\pgfsys@atbegindocument%%
+% \expandafter{\pgfsys@atbegindocument
+ \special{papersize=#1,#2}%
+% }
+}
+\def\pgfsys@prepare@papersize#1#2{%
+ \expandafter\gdef\expandafter\pgfsys@atbegindocument%%
+ \expandafter{\pgfsys@atbegindocument
+ \special{papersize=#1,#2}%
+ }
+}
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvips.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvips.def
new file mode 100644
index 0000000000..8a791ff5ad
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvips.def
@@ -0,0 +1,644 @@
+% Copyright 2019 by Till Tantau
+%
+% PS-3 shadings, image and opacity masks (fadings), transparency groups,
+% blend modes copyright 2020 by Alexander Grahn
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-dvips.def}
+
+% Driver commands for dvips
+
+\def\pgfsys@invoke#1{\special{ps\ifpgfsys@ps@boxmode\else:\fi: #1}}
+\def\pgfsys@outerinvoke#1{\special{ps: #1}}
+\def\pgf@sys@postscript@header#1{\pgfutil@insertatbegincurrentpage{\special{! #1}}}
+\def\pgf@sys@postscript@object#1{\special{! #1}}
+
+
+%
+% Load common postscript commands:
+%
+\input pgfsys-common-postscript.def
+
+
+%
+% dvips-specific stuff:
+%
+
+\def\pgfsys@beginpicture{\pgfsys@ps@boxmodefalse\special{ps: }\special{ps::[begin]}\pgfsys@invoke{pgfo}}
+\def\pgfsys@endpicture{\pgfsys@invoke{pgfc}\special{ps::[end]}}
+\def\pgfsys@hbox#1{%
+ \pgfsys@begin@idscope%
+ \pgfsys@invoke{pgfs}%
+ \special{ps::[end]}%
+ \wd#1=0pt
+ \ht#1=0pt
+ \dp#1=0pt
+ \box#1
+ \special{ps::[begin]}%
+ \pgfsys@invoke{pgfr}%
+ \pgfsys@end@idscope%
+}
+\def\pgfsys@begininvisible{%
+ \special{ps::[begin]}%
+ \pgfsys@invoke{gsave nulldevice}%
+ \special{ps::[end]}}
+\def\pgfsys@endinvisible{%
+ \special{ps::[begin]}%
+ \pgfsys@invoke{grestore}%
+ \special{ps::[end]}%
+}
+\def\pgfsys@color@unstacked#1{\special{ps: \XC@usecolor{#1}}}
+\def\pgfsys@imagesuffixlist{.epsi:.eps:.ps:}
+
+\def\pgfsys@papersize#1#2{%
+ \special{papersize=#1,#2}%
+ % \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\special{papersize=#1,#2}}%
+}
+\def\pgfsys@prepare@papersize#1#2{%
+ \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\special{papersize=#1,#2}}%
+}
+
+\expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument%
+ \pgf@sys@postscript@header{
+ /pgfsc{}bind def% stroke color is empty by default
+ /pgffc{}bind def% fill color is empty by default
+ /pgfstr{stroke}bind def%
+ /pgffill{fill}bind def%
+ /pgfeofill{eofill}bind def%
+ /pgfe{a dup 0 rlineto exch 0 exch rlineto neg 0 rlineto closepath}bind def% rectangle
+ /pgfw{setlinewidth}bind def% setlinewidth
+ /pgfs{save pgfpd 72 Resolution div 72 VResolution div neg scale
+ magscale{1 DVImag div dup scale}if
+ pgfx neg pgfy neg translate pgffoa .setopacityalpha}bind def% save
+ /pgfr{pgfsd restore}bind def %restore
+ userdict begin%
+ /pgfo{pgfsd /pgfx currentpoint /pgfy exch def def @beginspecial}bind def %open
+ /pgfc{newpath @endspecial pgfpd}bind def %close
+ /pgfsd{globaldict /pgfdelta /delta where {pop delta} {0} ifelse put}bind def% save delta
+ /pgfpd{/delta globaldict /pgfdelta get def}bind def % put delta
+ /.setblendmode where {pop} {/.setblendmode{pop}def} ifelse % install .setblendmode
+ /.setfillconstantalpha where {%
+ pop /.setopacityalpha {.setfillconstantalpha} def%
+ } {%
+ /.setopacityalpha where {pop} {/.setopacityalpha {pop} def} ifelse% install .setopacityalpha (fallback)
+ } ifelse
+ /.pgfsetfillopacityalpha{/pgffoa exch def
+ /.setfillconstantalpha where {pop pgffoa .setfillconstantalpha} {%
+ /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore newpath}bind def
+ /pgfeofill{gsave pgffoa .setopacityalpha eofill 1 .setopacityalpha newpath eofill grestore newpath}bind def%
+ } ifelse%
+ } bind def
+ /.pgfsetstrokeopacityalpha{/pgfsoa exch def
+ /.setstrokeconstantalpha where {pop pgfsoa .setstrokeconstantalpha} {%
+ /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore newpath}bind def%
+ } ifelse%
+ }bind def
+ /pgffoa 1 def
+ /pgfsoa 1 def
+ % mandatory, transparency-related per-page operations, see
+ % https://www.ghostscript.com/doc/current/Language.htm#Transparency
+ % (bop-hook & eop-hook automatically executed if defined in userdict, see texdoc dvips)
+ /.pushpdf14devicefilter where {pop
+ [userdict /bop-hook known {userdict /bop-hook get aload pop} if
+ {0 .pushpdf14devicefilter} aload pop] cvx userdict exch /bop-hook exch put
+ [userdict /eop-hook known {userdict /eop-hook get aload pop} if
+ {.poppdf14devicefilter} aload pop] cvx userdict exch /eop-hook exch put%
+ } if
+ % keeps printers from choking on pdfmark operator
+ systemdict /pdfmark known not {userdict /pdfmark systemdict /cleartomark get put} if
+ end
+ }%
+}
+
+\AtBeginDocument{ % needed for plain TeX
+ \pgfsys@atbegindocument
+ \let\pgfsys@atbegindocument=\pgfutil@empty
+}
+
+
+
+%
+% Position tracking (needs pdftex or luatex in dvi mode)
+%
+\ifx\savepos\@undefined
+ \ifx\pdfsavepos\@undefined
+ \else
+ \let\pgf@savepos\pdfsavepos
+ \let\pgf@lastxpos\pdflastxpos
+ \let\pgf@lastypos\pdflastypos
+ \fi
+\else
+ \let\pgf@savepos\savepos
+ \let\pgf@lastxpos\lastxpos
+ \let\pgf@lastypos\lastypos
+\fi
+
+
+\ifx\pgf@savepos\@undefined
+\else
+
+\def\pgfsys@markposition#1{%
+ \pgf@savepos%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutil@writetoaux\expandafter{%
+ \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pgf@lastxpos}{\the\pgf@lastypos}}%
+}
+
+\def\pgfsyspdfmark#1#2#3{%
+ \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}%
+ \pgfutil@check@rerun{#1}{{#2}{#3}}%
+}
+
+\def\pgfsys@getposition#1#2{%
+ \edef\pgf@marshal{\let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname}%
+ \pgf@marshal%
+}
+
+\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfpointorigin}
+
+\fi
+
+
+% Path usage:
+\def\pgfsys@discardpath{%
+ \ifpgfsys@@clipnext%
+ \ifpgfsys@eorule%
+ \pgfsysprotocol@literal{%
+ /pgfsmaskinplace dup where {exch get}{pop false} ifelse not {eoclip} if}%
+ \else%
+ \pgfsysprotocol@literal{%
+ /pgfsmaskinplace dup where {exch get}{pop false} ifelse not {clip} if}%
+ \fi%
+ \pgfsys@@clipnextfalse%
+ \fi%
+ \pgfsysprotocol@literal{newpath}}
+
+
+%
+% Blending
+%
+
+\def\pgfsys@blend@mode#1{%
+ \expandafter\ifx\csname pgf@sys@pdf@bm@#1\endcsname\relax%
+ \expandafter\let\expandafter\pgf@temp\csname pgf@sys@pdf@blend@mode@map@#1\endcsname%
+ \expandafter\xdef\csname pgf@sys@pdf@bm@#1\endcsname{/\pgf@temp}%
+ \ifx\pgf@temp\relax%
+ \pgferror{Unknown blend mode '#1'}%
+ \def\pgf@temp{Normal}%
+ \fi%
+ \fi%
+ \pgfsysprotocol@literal{\csname pgf@sys@pdf@bm@#1\endcsname\space .setblendmode}%
+}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@normal\endcsname{Normal}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@multiply\endcsname{Multiply}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@screen\endcsname{Screen}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@overlay\endcsname{Overlay}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@darken\endcsname{Darken}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@lighten\endcsname{Lighten}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color dodge\endcsname{ColorDodge}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color burn\endcsname{ColorBurn}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hard light\endcsname{HardLight}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@soft light\endcsname{SoftLight}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@difference\endcsname{Difference}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@exclusion\endcsname{Exclusion}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@saturation\endcsname{Saturation}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color\endcsname{Color}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hue\endcsname{Hue}
+\expandafter\def\csname pgf@sys@pdf@blend@mode@map@luminosity\endcsname{Luminosity}
+
+
+%
+% Shadings
+%
+
+\def\pgfsys@horishading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@xb=\pgf@max
+ \pgfmathsetlength\pgf@y{#2}%
+ \pgf@yb=\pgf@y
+ \pgf@sys@bp@correct{\pgf@xb}%
+ \pgf@sys@bp@correct{\pgf@yb}%
+ \xdef\pgfutil@tempa{\hbox to \the\pgf@max{%
+ \noexpand\vrule width0pt height\the\pgf@y%
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@outerinvoke{
+ \pgf@sys@tonumber{\pgf@yb} \pgf@sys@tonumber{\pgf@xb} 0 0 pgfe <<
+ /PatternType 2
+ /Shading <<
+ /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@doma\space0 \pgf@domb\space0]
+ /Function \pgf@pdfparsedfunction
+ >>
+ >> matrix makepattern setpattern fill
+ }%
+ \hss%
+ \noexpand\pgfsys@endpurepicture%
+ }}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname\pgfutil@tempa%
+}
+\def\pgfsys@vertshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathsetlength\pgf@x{#2}%
+ \pgf@xb=\pgf@x
+ \pgf@yb=\pgf@max
+ \pgf@sys@bp@correct{\pgf@xb}%
+ \pgf@sys@bp@correct{\pgf@yb}%
+ \xdef\pgfutil@tempa{\hbox to \the\pgf@x{%
+ \noexpand\vrule width0pt height\the\pgf@max%
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@outerinvoke{
+ \pgf@sys@tonumber{\pgf@yb} \pgf@sys@tonumber{\pgf@xb} 0 0 pgfe <<
+ /PatternType 2
+ /Shading <<
+ /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [0 \pgf@doma\space0 \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ >>
+ >> matrix makepattern setpattern fill
+ }%
+ \hss%
+ \noexpand\pgfsys@endpurepicture%
+ }}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname\pgfutil@tempa%
+}
+\def\pgfsys@radialshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@process{\pgfpoint{\pgf@max}{\pgf@max}}%
+ \advance\pgf@xa by \pgf@x
+ \advance\pgf@ya by \pgf@y
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgf@max=2\pgf@max
+ \xdef\pgfutil@tempa{\hbox to \the\pgf@max{%
+ \noexpand\vrule width0pt height\the\pgf@max%
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@outerinvoke{
+ <<
+ /ShadingType 3
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@sys@tonumber{\pgf@xa} \pgf@sys@tonumber{\pgf@ya} \pgf@doma\space
+ \pgf@sys@tonumber{\pgf@x} \pgf@sys@tonumber{\pgf@y} \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [true false]
+ >> shfill
+ }%
+ \hss%
+ \noexpand\pgfsys@endpurepicture%
+ }}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname\pgfutil@tempa%
+}
+\def\pgfsys@functionalshading#1#2#3#4{%
+ {%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x
+ \pgf@yb=\pgf@y
+ \advance\pgf@x by-\pgf@xa
+ \advance\pgf@y by-\pgf@ya
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgf@sys@bp@correct{\pgf@xb}%
+ \pgf@sys@bp@correct{\pgf@yb}%
+ \pgf@xc=-\pgf@xa
+ \pgf@yc=-\pgf@ya
+ \xdef\pgfutil@tempa{%
+ \hbox to\the\pgf@x{\vbox to\the\pgf@y{\vfil
+ \noexpand\pgfsys@beginpurepicture%
+ \noexpand\pgfsys@invoke{%
+ % patch coords
+ /pgfpatchllx \pgf@sys@tonumber{\pgf@xa} def
+ /pgfpatchlly \pgf@sys@tonumber{\pgf@ya} def
+ % shading patch width and height
+ /pgfpatchX \pgf@sys@tonumber{\pgf@xb} pgfpatchllx sub def
+ /pgfpatchY \pgf@sys@tonumber{\pgf@yb} pgfpatchlly sub def
+ % number of samples in each direction (with samples spaced by approx. 1bp)
+ /pgfsamplesx pgfpatchX round cvi 1 add def
+ /pgfsamplesy pgfpatchY round cvi 1 add def
+ % exact sample distance in each direction, in bp
+ /pgfpatchdx pgfpatchX pgfsamplesx 1 sub div def
+ /pgfpatchdy pgfpatchY pgfsamplesy 1 sub div def
+ %
+ pgfpatchllx neg pgfpatchlly neg translate
+ /pgfproc {#4} bind def
+ %
+ % sampling procedure; repeatedly called by /ReusableStreamDecode filter;
+ % on each call, /pgfsamplingproc puts one colour sample (rgb, cmyk or gray)
+ % on the operand stack which is then consumed by the filter
+ userdict /pgfsampleidx 0 put % internal index; updated on each call
+ /pgfsamplingproc {
+ pgfsampleidx pgfsamplesx pgfsamplesy mul eq {
+ () % push empty string on the stack to signal end-of-data
+ } {
+ pgfcolorsample\pgf@shading@model\space % -str-
+ pgfsampleidx pgfsamplesx mod pgfpatchdx mul pgfpatchllx add % -str- x
+ pgfsampleidx pgfsamplesx idiv pgfpatchdy mul pgfpatchlly add % -str- x y
+ pgfproc % -str- <colour>
+ pgfwritesample\pgf@shading@model\space % -str-
+ /pgfsampleidx pgfsampleidx 1 add store % (update index)
+ } ifelse
+ } bind def
+ %
+ pgfpatchY pgfpatchX pgfpatchllx pgfpatchlly pgfe <<
+ /PatternType 2
+ /Shading <<
+ /ShadingType 1
+ /Domain [0 1 0 1]
+ /Matrix [pgfpatchX 0 0 pgfpatchY pgfpatchllx pgfpatchlly]
+ /ColorSpace \pgf@shading@device\space
+ /Function <<
+ /FunctionType 0
+ /Order 1
+ /Domain [0 1 0 1]
+ /Range pgfrange\pgf@shading@model
+ /BitsPerSample pgfchanneldepth\pgf@shading@model % bits per channel, actually
+ /Size [pgfsamplesx pgfsamplesy]
+ /DataSource /pgfsamplingproc load /ReusableStreamDecode filter
+ >>
+ >>
+ >> matrix makepattern setpattern fill
+ }%
+ \noexpand\pgfsys@endpurepicture%
+ }\hss}%
+ }%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname\pgfutil@tempa%
+}
+
+% helpers for converting FunctionType-4 to FunctionType-0, i. e. sampled, functions;
+% FunctionType-4 functions are not defined in PostScript-3
+%
+% These are the different colour models we are going to use:
+% +-------+-------------------+-----------+------------------+
+% | model | channel depth/bit | max value | sample size/byte |
+% +-------+-------------------+-----------+------------------+
+% | cmyk | 8 | 255 | 4 |
+% | rgb | 8 | 255 | 3 |
+% | gray | 24 | 16777215 | 3 |
+% +-------+-------------------+-----------+------------------+
+\expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument%
+ \pgf@sys@postscript@header{
+ %
+ % -str- c m y k pgfwritesamplecmyk ==> -str-
+ % -str- r g b pgfwritesamplergb ==> -str-
+ % -str- gray pgfwritesamplegray ==> -str-
+ % writes a single colour sample into the /pgfcolorsample* string;
+ % colour components (c,m,y,k; r,g,b; gray) between 0.0 to 1.0
+ %
+ /pgfwritesamplecmyk {
+ 4 index 0 5 index pgfcheckcolorrange 255 mul round cvi put
+ 4 index 1 4 index pgfcheckcolorrange 255 mul round cvi put
+ 4 index 2 3 index pgfcheckcolorrange 255 mul round cvi put
+ 4 index 3 2 index pgfcheckcolorrange 255 mul round cvi put
+ pop pop pop pop
+ } bind def
+ %
+ /pgfwritesamplergb {
+ 3 index 0 4 index pgfcheckcolorrange 255 mul round cvi put
+ 3 index 1 3 index pgfcheckcolorrange 255 mul round cvi put
+ 3 index 2 2 index pgfcheckcolorrange 255 mul round cvi put
+ pop pop pop
+ } bind def
+ %
+ /pgfwritesamplegray {
+ % grayvalue between 0 and 16777215 (24 bit)
+ pgfcheckcolorrange 16777215 mul round cvi % -str- gray24
+ 1 index 0 2 index -16 bitshift put % high byte
+ 1 index 1 2 index 65535 and -8 bitshift put % middle byte
+ 1 index 2 2 index 255 and put % low byte
+ pop
+ } bind def
+ %
+ % <colour component> pgfcheckcolorrange ==> <something between 0.0 and 1.0>
+ % truncates value to the allowed range (user-defined Type-4 functions may
+ % happen to provide values outside this range)
+ /pgfcheckcolorrange {
+ dup 0.0 lt {pop 0.0} if
+ dup 1.0 gt {pop 1.0} if
+ } bind def
+ %
+ %colour depths per channel (bit)
+ /pgfchanneldepthcmyk 8 def
+ /pgfchanneldepthrgb 8 def
+ /pgfchanneldepthgray 24 def
+ %
+ % allocate strings as buffers for storing a single colour sample
+ /pgfcolorsamplecmyk 4 string def
+ /pgfcolorsamplergb 3 string def
+ /pgfcolorsamplegray 3 string def
+ %
+ %/Range array in the FunctionType 0 dictionary
+ /pgfrangecmyk [0 1 0 1 0 1 0 1] def
+ /pgfrangergb [0 1 0 1 0 1] def
+ /pgfrangegray [0 1] def
+ }%
+}
+
+
+%
+% Opacity masks
+%
+
+\def\pgfsys@fadingfrombox#1#2{%
+ \ifcsname pgfsmaskxform@#1\endcsname
+ \pgfwarning{Fading '#1' already defined.\MessageBreak Going to replace it with new definition}%
+ \fi%
+ \global\advance\pgf@objectcount\@ne%
+ {%
+ \pgf@x=-.5\wd#2%
+ \pgf@y=-.5\ht#2%
+ \advance\pgf@y by.5\dp#2%
+ \expandafter\xdef\csname pgfsmasktrans@#1\endcsname{%
+ \noexpand\pgftransformcm{1}{0}{0}{1}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \edef\@tempa{\noexpand\pgfutil@insertatbegincurrentpagefrombox{%
+ % box coordinates (reference point and top) needed for ps2pdf
+ \pgfsys@outerinvoke{currentpoint /pgf@refy exch def /pgf@refx exch def}%
+ \hbox to 0pt {\hbox to \ifdim\ht#2>\ht\strutbox\ht#2\else\ht\strutbox\fi{\hss\pgfsys@outerinvoke{%
+ /pgf@top pgf@refy currentpoint pop pgf@refx sub VResolution Resolution div mul sub def%
+ }}\hss}%
+ % lower-right box corner coordinates for viewing
+ \hbox to 0pt {\hbox to \wd#2{\hss\pgfsys@outerinvoke{/pgf@right currentpoint pop def}}\hss}%
+ \hbox to 0pt {\hbox to \ifdim\dp#2>\dp\strutbox\dp#2\else\dp\strutbox\fi{\hss\pgfsys@outerinvoke{%
+ /pgf@bot pgf@refy currentpoint pop pgf@refx sub VResolution Resolution div mul add def%
+ }}\hss}%
+ \pgfsys@outerinvoke{gsave
+ clippath pathbbox newpath pop pop translate
+ systemdict /pdfmark known {%
+ % for ps2pdf, translate box to upper-left page corner, so we have the whole clipping
+ % path (i. e. page area) available, as outlying parts get clipped
+ pgf@refx neg pgf@top neg translate%
+ } {%
+ % for viewing, however, we want to hide the box by moving it off-page; we do so by aligning
+ % the lower-right box corner with the upper-left page corner
+ pgf@right neg pgf@bot neg translate%
+ } ifelse
+ % translate origin (0,0) to the reference point
+ gsave pgf@refx pgf@refy translate
+ mark /_objdef {pgfsmaskxform@\the\pgf@objectcount}
+ /BBox [clippath pathbbox newpath] /BP pdfmark grestore%
+ }%
+ \wd#2=0pt
+ \ht#2=0pt
+ \dp#2=0pt
+ \box#2%
+ \pgfsys@outerinvoke{mark /EP pdfmark grestore}%
+ }}\@tempa%
+ \expandafter\xdef\csname pgfsmaskxform@#1\endcsname{\the\pgf@objectcount}%
+ }%
+}
+\def\pgfsys@usefading#1#2#3#4#5#6#7{%
+ \ifcsname pgfsmaskxform@#1\endcsname%
+ {%
+ \pgftransformreset%
+ \pgftransformcm{#2}{#3}{#4}{#5}{\pgfpoint{#6}{#7}}%
+ \csname pgfsmasktrans@#1\endcsname%
+ {%
+ \pgflowlevelsynccm%
+ \pgfsys@outerinvoke{%
+ /.begintransparencymaskgroup where {pop
+ /pgf@sys@currentcolorspace currentcolorspace def
+ /pgf@sys@currentcolor [currentcolor] cvx def
+ /pgf@sys@OverrideICC currentuserparams /OverrideICC get def % Chr. Liddell
+ <</OverrideICC true>> setuserparams % of Artifex
+ /DeviceGray setcolorspace
+ true <</Subtype/Luminosity>> clippath pathbbox newpath .begintransparencymaskgroup
+ gsave
+ 72 Resolution div 72 VResolution div scale
+ 1 DVImag div 1 DVImag div neg scale
+ mark {pgfsmaskxform@\csname pgfsmaskxform@#1\endcsname} /SP pdfmark
+ grestore
+ 0 .endtransparencymask
+ <</OverrideICC pgf@sys@OverrideICC>> setuserparams % restore orig. settings
+ pgf@sys@currentcolorspace setcolorspace
+ pgf@sys@currentcolor setcolor
+ /pgfsmaskinplace true def
+ } if%
+ }%
+ }%
+ \pgftransforminvert%
+ \pgflowlevelsynccm%
+ }%
+ \else
+ \pgferror{Undefined fading '#1'}%
+ \fi%
+}
+\def\pgfsys@clipfading{%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfsys@clipnext%
+ \pgfsys@discardpath%
+}
+
+
+%
+% Transparency groups
+%
+\def\pgfsys@transparencygroupfrombox#1{%
+ \global\advance\pgf@objectcount\@ne%
+ \pgfsys@outerinvoke{%
+ mark /_objdef {pgfxform@\the\pgf@objectcount} /BBox [clippath pathbbox newpath] /BP pdfmark
+ gsave
+ /pgf@sys@foa pgffoa def /pgf@sys@soa pgfsoa def
+ /.setstrokeconstantalpha where
+ {pop 1 .pgfsetfillopacityalpha 1 .pgfsetstrokeopacityalpha} if%
+ }%
+ \wd#1=0pt
+ \ht#1=0pt
+ \dp#1=0pt
+ \hskip\pgf@picminx\box#1\hskip-\pgf@picminx
+ \pgfsys@outerinvoke{%
+ /pgffoa pgf@sys@foa def /pgfsoa pgf@sys@soa def
+ grestore
+ mark /EP pdfmark
+ mark {pgfxform@\the\pgf@objectcount} << /Group << /S /Transparency
+ /I \ifpgfsys@transparency@group@isolated true \else false \fi
+ /K \ifpgfsys@transparency@group@knockout true \else false \fi >> >> /PUT pdfmark%
+ }%
+ \setbox#1=\hbox{\pgfsys@outerinvoke{mark {pgfxform@\the\pgf@objectcount} /SP pdfmark}}%
+}
+
+
+%
+% Image inclusion, adding SMask reference and image interpolation if mandated
+%
+
+\def\pgfsys@defineimage{%
+ \ifx\pgf@imagewidth\pgfutil@empty\else\edef\pgf@imagewidth{width=\pgf@imagewidth,}\fi%
+ \ifx\pgf@imageheight\pgfutil@empty\else\edef\pgf@imageheight{height=\pgf@imageheight,}\fi%
+ \begingroup%
+ \def\pgf@imageaddedkeys{}\def\@tempa{true}%
+ \ifx\pgf@imageinterpolate\@tempa\def\pgf@imageaddedkeys{/Interpolate true}\fi%
+ \ifx\pgf@imagemask\pgfutil@empty\else\edef\pgf@imageaddedkeys{\pgf@imageaddedkeys /SMask {\pgf@imagemask}}\fi%
+ \edef\@tempa{%
+ \ifx\pgf@imageaddedkeys\pgfutil@empty\else%
+ \noexpand\pgfsys@outerinvoke{%
+ save /pgfparent [(img) cvx cvn rand] cvx def %random name for current image
+ mark /_objdef /pgfparent load /NI pdfmark
+ % sometimes, image metadata contain embedded pdfmarks that prevent us from
+ % writing to the image dictionary ourselves, so we disable them temporarily
+ save /pdfmark /cleartomark load def
+ }%
+ \fi%
+ \noexpand\includegraphics[\pgf@imageheight\pgf@imagewidth]{\pgf@filename}%
+ \ifx\pgf@imageaddedkeys\pgfutil@empty\else%
+ \noexpand\pgfsys@outerinvoke{%
+ % empty image dummy, in case the provided file is not a valid raster image
+ 0 0 1 [1 0 0 1 0 0] {} image restore
+ mark /pgfparent load <<\pgf@imageaddedkeys>> /PUT pdfmark restore
+ }%
+ \fi%
+ }%
+ \expandafter\endgroup%
+ \expandafter\def\expandafter\pgf@image\expandafter{\@tempa}%
+}
+
+
+%
+% Image masks
+%
+
+\def\pgfsys@definemask{%
+ \global\advance\pgf@objectcount\@ne%
+ \ifx\pgf@maskmatte\pgfutil@empty%
+ \else%
+ \edef\pgf@maskmatte{/Matte [\pgf@maskmatte]}%
+ \fi%
+ \pgfsys@outerinvoke{%
+ mark /_objdef {pgfmask\the\pgf@objectcount} /NI pdfmark
+ 1 dict begin /pdfmark /cleartomark load def
+ }%
+ \special{psfile=\pgf@filename\space hsize=0 vsize=0}%
+ \pgfsys@outerinvoke{%
+ 0 0 1 [1 0 0 1 0 0] {} image
+ end mark {pgfmask\the\pgf@objectcount} <</Decode [1 0] \pgf@maskmatte>> /PUT pdfmark
+ }%
+ \edef\pgf@mask{pgfmask\the\pgf@objectcount}%
+}
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm.def
new file mode 100644
index 0000000000..a089601182
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm.def
@@ -0,0 +1,217 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-dvisvgm.def}
+
+
+% Driver commands for dvisvgm
+
+%
+% Load common pdf commands:
+%
+\input pgfsys-common-svg.def
+
+\newif\ifpgf@sys@svg@inpicture
+
+\def\pgf@sys@svg@make@defs#1#2{{\let\#\pgf@sys@svg@hash\special{dvisvgm:rawset #1}\special{dvisvgm:rawdef #2}\special{dvisvgm:endrawset}}}
+\def\pgf@sys@svg@ref@defs#1{\special{dvisvgm:rawput #1}}
+\def\pgfsys@invoke#1{{\let\#\pgf@sys@svg@hash\special{dvisvgm:raw #1}}}
+\def\pgfsys@beginpicture{%
+ \special{color push gray 0}% make dvisvgm *not* add anything to text
+ \pgf@sys@svg@inpicturetrue% in a picture
+ \pgfsys@svg@boxmodefalse%
+ \pgfsys@invoke{<g \ifx\pgf@sys@svg@last@stroke\relax\else
+ stroke="\pgf@sys@svg@last@stroke" \fi stroke-miterlimit="10" transform="translate({?x},{?y})scale(0.996264,-0.996264)">}}
+\def\pgfsys@endpicture{\pgfsys@invoke{</g>}\special{color pop}}
+
+\def\pgfsys@svg@newline{{?nl}}
+
+\let\pgf@sys@svg@last@stroke\relax%
+
+
+\def\pgfsys@hbox#1{%
+ {%
+ \setbox#1=\hbox{\box#1}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \pgfsys@begin@idscope%
+ \pgfsys@invoke{<g stroke="none" transform="scale(-1.00375,1.00375)translate({?x},{?y})scale(-1,-1)">}\box#1\pgfsys@invoke{</g>}%
+ \pgfsys@end@idscope%
+ }%
+}
+
+\def\pgfsys@hboxsynced#1{%
+ {%
+ \setbox#1=\hbox{\box#1}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \pgfsys@begin@idscope%
+ \pgfsys@beginscope%
+ \pgflowlevelsynccm%
+ \pgfsys@invoke{<g stroke="none" transform="scale(-1.00375,1.00375)translate({?x},{?y})scale(-1,-1)">}\box#1\pgfsys@invoke{</g>}%
+ \pgfsys@endscope%
+ \pgfsys@end@idscope%
+ }%
+}
+
+
+\def\pgfsys@shadingoutsidepgfpicture#1{%
+ \begingroup%
+ #1%
+ \setbox\pgfpic=\hbox to0pt{%
+ \pgfsys@beginpicture%
+ \pgfsys@beginscope%
+ \pgf@sys@svg@sh@defs%
+ \pgf@sys@svg@sh%
+ \pgfsys@endscope%
+ \pgfsys@endpicture%
+ \hss%
+ }%
+ \pgf@process{\pgf@sys@svg@pos}%
+ \pgf@picminx=0pt%
+ \pgf@picminy=0pt%
+ \pgf@picmaxx=\pgf@x%
+ \pgf@picmaxy=\pgf@y%
+ \def\pgf@trimleft@final{0pt}%
+ \def\pgf@trimright@final{0pt}%
+ \def\pgf@shift@baseline{0pt}%
+ \pgfsys@typesetpicturebox\pgfpic%
+ \endgroup%
+}
+
+\def\pgfsys@shadinginsidepgfpicture#1{%
+ #1%
+ \pgf@sys@svg@sh@defs% hmmm....
+ \pgf@process{\pgf@sys@svg@pos}
+ \pgf@xa=-.5\pgf@x%
+ \pgf@ya=-.5\pgf@y%
+ \pgfsysprotocol@literal{<g transform="translate(\pgf@sys@tonumber{\pgf@xa},\pgf@sys@tonumber{\pgf@ya})">}%
+ \pgf@sys@svg@sh%
+ \pgfsysprotocol@literal{</g>}%
+}
+
+
+
+\def\pgfsys@papersize#1#2{%
+ {%
+ \pgf@x#1\relax%
+ \pgf@y#2\relax%
+ \pgf@xa-1in\relax%
+ \special{dvisvgm:bbox fix \pgf@sys@tonumber\pgf@xa\space \pgf@sys@tonumber\pgf@xa\space \pgf@sys@tonumber\pgf@x\space \pgf@sys@tonumber\pgf@y}%
+ }%
+}
+\def\pgfsys@prepare@papersize#1#2{%
+ \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\pgfsys@papersize{#1}{#2}}%
+}
+
+
+
+\def\pgfsys@typesetpicturebox#1{%
+ \pgf@ya=\pgf@shift@baseline\relax%
+ \advance\pgf@ya by-\pgf@picminy\relax%
+ %
+ %
+ \advance\pgf@picmaxy by-\pgf@picminy\relax% maxy is now the height
+ \advance\pgf@picmaxx by-\pgf@picminx\relax% maxx is now the width
+ \setbox#1=\hbox{\hskip-\pgf@picminx\lower\pgf@picminy\box#1}%
+ \ht#1=\pgf@picmaxy%
+ \wd#1=\pgf@picmaxx%
+ \dp#1=0pt%
+ \leavevmode%
+ \pgf@xa=\pgf@trimleft@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi%
+ \raise-\pgf@ya\hbox{\ifpgf@sys@svg@inpicture\else\special{dvisvgm:bbox \pgf@sys@tonumber\pgf@picmaxx\space\pgf@sys@tonumber\pgf@picmaxy}\fi\box#1}%
+ \pgf@xa=\pgf@trimright@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi%
+}
+
+
+
+\def\pgfsys@text@to@black@hook{%
+ \let\pgfsys@svg@set@color@orig\set@color%
+ \let\pgfsys@svg@reset@color@orig\reset@color%
+ \def\set@color{\special{dvisvgm:raw <g fill="black">}\pgfsys@svg@set@color@orig}%
+ \def\reset@color{\special{dvisvgm:raw </g>}\pgfsys@svg@reset@color@orig}%
+}
+
+
+
+% Fadings
+
+% FIXME: Correct sizes!
+
+%
+% Opacity masks
+%
+% \def\pgfsys@fadingfrombox#1#2{%
+% \setbox#2=\hbox{%
+% \pgfsys@invoke{<mask id="pgfmask#1">}%
+% \box#2%
+% \pgfsys@invoke{</mask>}%
+% }%
+% \wd#2=0pt%
+% \ht#2=0pt%
+% \dp#2=0pt%
+% \unskip\box#2%
+% }
+% \def\pgfsys@usefading#1#2#3#4#5#6#7{%
+% \pgf@sys@svg@gs@color{mask="url(\#pgfmask#1)"}%
+% }
+
+
+
+
+%
+% Position tracking (needs pdftex or luatex in dvi mode)
+%
+\ifx\savepos\@undefined
+ \ifx\pdfsavepos\@undefined
+ \else
+ \let\pgf@savepos\pdfsavepos
+ \let\pgf@lastxpos\pdflastxpos
+ \let\pgf@lastypos\pdflastypos
+ \fi
+\else
+ \let\pgf@savepos\savepos
+ \let\pgf@lastxpos\lastxpos
+ \let\pgf@lastypos\lastypos
+\fi
+
+
+\ifx\pgf@savepos\@undefined
+\else
+
+\def\pgfsys@markposition#1{%
+ \pgf@savepos%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutil@writetoaux\expandafter{%
+ \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pgf@lastxpos}{\the\pgf@lastypos}}%
+}
+
+\def\pgfsyspdfmark#1#2#3{%
+ \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}%
+ \pgfutil@check@rerun{#1}{{#2}{#3}}%
+}
+
+\def\pgfsys@getposition#1#2{%
+ \edef\pgf@marshal{\let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname}%
+ \pgf@marshal%
+}
+
+\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfpointorigin}
+
+\fi
+
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm4ht.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm4ht.def
new file mode 100644
index 0000000000..77e7c9bb7a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-dvisvgm4ht.def
@@ -0,0 +1,86 @@
+% Copyright 2021 by Michal Hoftich
+% Copyright 2006 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-dvisvgm4ht.def}
+
+% Driver commands for tex4ht
+
+%
+% Load common pdf commands:
+%
+
+% we load the dvips driver by default. it doesn't support patterns and some other stuff,
+% but it handles better nested images and some formatting. if you use patterns or if you
+% have other issues with the default method, pass the "tikz-dvisvgm" option to make4ht.
+\ifdefined\ifOption
+\ifOption{tikz+}{\input pgfsys-dvisvgm.def}{\input pgfsys-dvips.def}
+\else
+% load the dvips driver by default
+\input pgfsys-dvips.def
+\fi
+
+
+\def\texfourht@tikz@begin{%
+ \bgroup%
+ \def\run@pict@cmd{}% insert the \Picture hooks only in the top nesting level
+ \def\end@pict@cmd{}%
+ \ifdefined\EndPicture\else% We are already inside command that uses \Picture
+ \ifdefined\inside@pict@cmd\else% handle nested uses
+ \ifdefined\tikzexternalize\else% Support externalize library
+ \def\run@pict@cmd{\Picture*}%
+ \def\end@pict@cmd{\EndPicture}%
+ \fi\fi\fi%
+ % command used to detect nesting
+ \def\inside@pict@cmd{}%
+ \csname a:tikzpicture\endcsname%
+}
+
+\def\texfourht@tikz@end{%
+ \csname b:tikzpicture\endcsname%
+ \egroup%
+}
+
+\AtBeginDocument{%
+ \NewConfigure{tikzpicture}{2}%
+ \catcode`\:=11%
+ \Configure{tikzpicture}{%
+ \protect\csname nested:math\endcsname% support display math
+ \run@pict@cmd{}%
+ }{\end@pict@cmd}
+ % configure the output picture format to svg, as it will require dvisvgm
+ % post processing.
+ \Configure{Picture}{.svg}%
+ % insert tex4ht hooks around TikZ picture box
+ \def\pgfsys@typesetpicturebox#1{%
+ \texfourht@tikz@begin%
+ \orig@pgfsys@typesetpicturebox{#1}%
+ \texfourht@tikz@end%
+ }
+ %
+ \ConfigureEnv{tikzpicture}{\texfourht@tikz@begin}{\texfourht@tikz@end}{}{}%
+ \ConfigureEnv{pgfpicture}{\texfourht@tikz@begin}{\texfourht@tikz@end}{}{}%
+ \catcode`\:=12%
+}
+
+
+% Make the code inserted by tex4ht configurable
+%
+
+
+\let\orig@pgfsys@typesetpicturebox\pgfsys@typesetpicturebox
+%\def\pgf@sys@postscript@header#1{{\special{! #1}}}
+
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-luatex.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-luatex.def
new file mode 100644
index 0000000000..e60b1913a3
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-luatex.def
@@ -0,0 +1,401 @@
+% Copyright 2019 by Till Tantau
+% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-luatex.def}
+
+\ifnum\luatexversion<95
+ \immediate\write-1{luatex driver of PGF: detected lua version \the\luatexversion; falling back to old pdftex driver^^J}%
+ \input pgfsys-pdftex.def
+ \expandafter\endinput
+\fi
+
+% Driver commands for pdf
+
+%
+% Load common pdf commands:
+%
+\input pgfsys-common-pdf.def
+
+%
+% pdftex-specific stuff:
+%
+\def\pgfsys@invoke#1{\pdfextension literal{#1}}
+
+% Synced hboxes
+\def\pgfsys@hboxsynced#1{%
+ {%
+ \pgfsys@beginscope%
+ \setbox\pgf@hbox=\hbox{%
+ \hskip\pgf@pt@x%
+ \raise\pgf@pt@y\hbox{%
+ \pgf@pt@x=0pt%
+ \pgf@pt@y=0pt%
+ \pgflowlevelsynccm%
+ \pgfsys@hbox#1}%
+ \hss%
+ }%
+ \wd\pgf@hbox=0pt%
+ \ht\pgf@hbox=0pt%
+ \dp\pgf@hbox=0pt%
+ \box\pgf@hbox%
+ \pgfsys@endscope%
+ }%
+}
+
+
+
+\def\pgfsys@imagesuffixlist{.pdf:.jpg:.jpeg:.png:}
+\def\pgfsys@defineimage{% width, height, page number
+ \ifx\pgf@imagewidth\pgfutil@empty\else\edef\pgf@imagewidth{ width \pgf@imagewidth }\fi%
+ \ifx\pgf@imageheight\pgfutil@empty\else\edef\pgf@imageheight{ height \pgf@imageheight }\fi%
+ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage }\fi%
+ \ifx\saveimageresource\@undefined% old version of lualatex
+ \ifx\pgf@imagepage\pgfutil@empty\else%
+ \pgfwarning{Page selection not supported. Ignoring page selection}%
+ \fi%
+ \setbox\pgfutil@tempboxa=\hbox{%
+ \pdfimage \pgf@imageheight \pgf@imagewidth {\pgf@filename}}%
+ \pdfform\pgfutil@tempboxa%
+ \edef\pgf@image{\noexpand\pdfrefform\the\pdflastform}%
+ \else% new version
+ {\saveimageresource \pgf@imageheight \pgf@imagewidth attr
+ {/Interpolate \pgf@imageinterpolate\space\pgf@imagemask} \pgf@imagepage
+ {\pgf@filename}}%
+ \edef\pgf@image{\noexpand\useimageresource\the\lastsavedimageresourceindex}%
+ \fi
+}%
+\def\pgfsys@definemask{%
+ \ifx\pgf@maskmatte\pgfutil@empty%
+ \else%
+ \edef\pgf@maskmatte{/Matte [\pgf@maskmatte]}%
+ \fi%
+ \edef\pgf@attr{{\pgf@maskmatte\space /Decode [1 0]}}%
+ \immediate\saveimageresource attr \pgf@attr {\pgf@filename}%
+ \edef\pgf@mask{/SMask \the\lastsavedimageresourceindex\space 0 R}%
+}
+\def\pgfsys@horishading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathparse{#2}%
+ \setbox\pgfutil@tempboxa=\hbox dir TLT to\pgf@max{\vbox to\pgfmathresult pt{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@process{\pgfpoint{\pgf@max}{#2}}%
+ \immediate\saveboxresource resources {%
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@doma\space0 \pgf@domb\space0]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{\noexpand\useboxresource\the\lastsavedboxresourceindex}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+\def\pgfsys@vertshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathparse{#2}%
+ \setbox\pgfutil@tempboxa=\hbox dir TLT to\pgfmathresult pt{\vbox to\pgf@max{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@process{\pgfpoint{#2}{\pgf@max}}%
+ \immediate\saveboxresource resources {%
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [0 \pgf@doma\space0 \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{\noexpand\useboxresource\the\lastsavedboxresourceindex}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+\def\pgfsys@radialshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \setbox\pgfutil@tempboxa=\hbox dir TLT to2\pgf@max{\vbox to2\pgf@max{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpoint{\pgf@max}{\pgf@max}}%
+ \advance\pgf@xa by \pgf@x%
+ \advance\pgf@ya by \pgf@y%
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \immediate\saveboxresource resources {%
+ /Shading << /Sh << /ShadingType 3
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@sys@tonumber{\pgf@xa} \pgf@sys@tonumber{\pgf@ya} \pgf@doma\space \pgf@sys@tonumber{\pgf@x} \pgf@sys@tonumber{\pgf@y} \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [true false] >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{\noexpand\useboxresource\the\lastsavedboxresourceindex}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}%
+\def\pgfsys@functionalshading#1#2#3#4{%
+ {%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \setbox\pgfutil@tempboxa=\hbox dir TLT to\pgf@x{\vbox to\pgf@y{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgf@sys@bp@correct{\pgf@xb}%
+ \pgf@sys@bp@correct{\pgf@yb}%
+ \pgf@xc=-\pgf@xa%
+ \pgf@yc=-\pgf@ya%
+ % Now build the function
+ \pdfextension obj
+ stream
+ attr
+ {
+ /FunctionType 4
+ /Domain [\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@ya}\space\pgf@sys@tonumber{\pgf@yb}]
+ /Range [\pgf@shading@functional@range]
+ }
+ {{#4}}%
+ \edef\pgf@temp@num{\the\numexpr\pdffeedback lastobj\relax}%
+ \saveboxresource resources {%
+ /Shading << /Sh << /ShadingType 1
+ /ColorSpace \pgf@shading@device\space
+ /Matrix [1 0 0 1 \pgf@sys@tonumber{\pgf@xc}\space\pgf@sys@tonumber{\pgf@yc}]
+ /Domain [\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@ya}\space\pgf@sys@tonumber{\pgf@yb}]
+ /Function \pgf@temp@num\space 0 R
+ >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{%
+ \noexpand\useboxresource\the\lastsavedboxresourceindex%
+ \noexpand\pdfextension refobj \pgf@temp@num%
+ }}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+
+
+
+% Patterns
+
+\def\pgfsys@declarepattern#1#2#3#4#5#6#7{%
+ % Start building the pattern dictionary:
+ \pgf@xa=#2\relax%
+ \pgf@ya=#3\relax%
+ \pgf@xb=#4\relax%
+ \pgf@yb=#5\relax%
+ \pgf@xc=#6\relax%
+ \pgf@yc=#7\relax%
+ \pgf@sys@bp@correct\pgf@xa%
+ \pgf@sys@bp@correct\pgf@ya%
+ \pgf@sys@bp@correct\pgf@xb%
+ \pgf@sys@bp@correct\pgf@yb%
+ \pgf@sys@bp@correct\pgf@xc%
+ \pgf@sys@bp@correct\pgf@yc%
+ \pgfsys@@declarepattern{#1}%
+}
+
+\def\pgfsys@@declarepattern#1#2#3#4#5#6#7#8#9{%
+ \pgfutil@tempdima=#6\relax%
+ \pgfutil@tempdimb=#7\relax%
+ \pgf@sys@bp@correct\pgfutil@tempdima%
+ \pgf@sys@bp@correct\pgfutil@tempdimb%
+ % Now create the pattern object:
+ \immediate\pdfextension obj stream
+ attr
+ {
+ /Type /Pattern
+ /PatternType 1
+ /PaintType \ifnum#9=0 2 \else 1 \fi
+ /TilingType 1
+ /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb]
+ /XStep \pgf@sys@tonumber\pgf@xc\space
+ /YStep \pgf@sys@tonumber\pgf@yc\space
+ /Matrix [#2\space#3\space#4\space#5\space\pgf@sys@tonumber\pgfutil@tempdima\space\pgf@sys@tonumber\pgfutil@tempdimb]
+ /Resources <</Pattern<<>>>> %<<
+ }
+ {#8}%
+ \pgfutil@addpdfresource@patterns{/pgfpat#1\space \the\numexpr\pdffeedback lastobj\relax\space 0 R}%
+}
+
+\def\pgfsys@setpatternuncolored#1#2#3#4{%
+ \pgfsysprotocol@literal{/pgfprgb cs #2 #3 #4 /pgfpat#1\space scn}%
+}
+
+\def\pgfsys@setpatterncolored#1{%
+ \pgfsysprotocol@literal{/Pattern cs /pgfpat#1\space scn}%
+}
+
+
+
+\def\pgfsys@papersize#1#2{\pageheight#2\relax\pagewidth#1\relax}
+
+\def\pgfsys@global@papersize#1#2{\global\pageheight#2\relax\global\pagewidth#1\relax}
+
+\ifx\paperheight\@undefined
+ \def\pgfsys@thepageheight{\pageheight}
+ \def\pgfsys@thepagewidth{\pagewidth}
+\fi
+
+
+%
+% Position tracking
+%
+\def\pgfsys@markposition#1{%
+ \savepos%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutil@writetoaux\expandafter{%
+ \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\lastxpos}{\the\lastypos}}%
+}
+
+\def\pgfsyspdfmark#1#2#3{%
+ \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}%
+ \pgfutil@check@rerun{#1}{{#2}{#3}}%
+}
+
+\def\pgfsys@getposition#1#2{%
+ \edef\pgf@marshal{\let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname}%
+ \pgf@marshal%
+}
+
+\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{\hoffset}{\voffset}}
+
+
+%
+% Opacity masks
+%
+\def\pgfsys@fadingfrombox#1#2{%
+ {%
+ \pgf@sys@pdf@check@resources%
+ \pgf@x=-.5\wd#2%
+ \pgf@y=-.5\ht#2%
+ \advance\pgf@y by.5\dp#2%
+ \expandafter\xdef\csname pgfsmasktrans@#1\endcsname{%
+ \noexpand\pgftransformcm{1}{0}{0}{1}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \saveboxresource resources { \pgf@sys@pdf@possible@resources } #2%
+ \expandafter\xdef\csname pgfsmaskxform@#1\endcsname{\the\lastsavedboxresourceindex}%
+ }%
+}
+\def\pgfsys@usefading#1#2#3#4#5#6#7{%
+ \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax%
+ \pgferror{Undefined fading '#1'}%
+ \else%
+ {%
+ \expandafter\ifx\csname pgfsmask@#1\endcsname\relax%
+ \pgf@sys@pdf@install@mask{#1}%
+ \fi%
+ \pgftransformreset%
+ \pgftransformcm{#2}{#3}{#4}{#5}{\pgfpoint{#6}{#7}}%
+ \csname pgfsmasktrans@#1\endcsname%
+ {%
+ \pgflowlevelsynccm%
+ \pgfsys@invoke{/pgfsmask\csname pgfsmask@#1\endcsname\space gs}%
+ }%
+ \pgftransforminvert%
+ \pgflowlevelsynccm%
+ }%
+ \fi
+}
+
+\def\pgf@sys@pdf@install@mask#1{%
+ \setbox\pgfutil@tempboxa=\hbox{\useboxresource\csname pgfsmaskxform@#1\endcsname}
+ \immediate\saveboxresource%
+ attr {
+ /Group
+ <<
+ /S /Transparency
+ /CS /DeviceGray
+ >>
+ }% <<
+ \pgfutil@tempboxa%
+ \pgfutil@addpdfresource@extgs{%
+ /pgfsmask\the\lastsavedboxresourceindex\space
+ <<
+ /SMask
+ <<
+ /S /Luminosity
+ /G \the\lastsavedboxresourceindex\space 0 R
+ >>
+ >> } %<<
+ \expandafter\xdef\csname pgfsmask@#1\endcsname{\the\lastsavedboxresourceindex}%
+}
+
+%
+% Transparency groups
+%
+\def\pgfsys@transparencygroupfrombox#1{%
+ \pgf@sys@pdf@check@resources%
+ \saveboxresource
+ attr { /Group << /S /Transparency
+ /I \ifpgfsys@transparency@group@isolated true \else false \fi
+ /K \ifpgfsys@transparency@group@knockout true \else false \fi >> } %<<
+ resources { \pgf@sys@pdf@possible@resources }
+ #1%
+ \setbox#1=\hbox{\useboxresource\lastsavedboxresourceindex}%
+}
+
+
+
+
+%
+% Resource management
+%
+
+\def\pgf@sys@setuppdfresources@plain{%
+ % This command will setup pdf resource in plain and in latex
+ % mode. ConTeXt has its own handler
+ % Page resources (they are kept in objects and only written at the
+ % very end)
+ \pdfextension obj reserveobjnum \edef\pgf@sys@pdf@extgs@objnum{\the\numexpr\pdffeedback lastobj\relax}
+ \pdfextension obj reserveobjnum \edef\pgf@sys@pdf@pattern@objnum{\the\numexpr\pdffeedback lastobj\relax}
+ \pdfextension obj reserveobjnum \edef\pgf@sys@pdf@colrospaces@objnum{\the\numexpr\pdffeedback lastobj\relax}
+ \def\pgf@sys@pdf@possible@resources{%
+ /ColorSpace \pgf@sys@pdf@colrospaces@objnum\space 0 R
+ /Pattern \pgf@sys@pdf@pattern@objnum\space 0 R
+ /ExtGState \pgf@sys@pdf@extgs@objnum\space 0 R
+ }
+ \let\pgf@sys@pdf@check@resources=\relax%
+ \def\pgf@sys@pdf@install@pageresources{
+ {
+ \edef\temp{
+ \pgf@sys@pdf@possible@resources
+ }
+ \expandafter\global\expandafter\pdfvariable pageresources\expandafter{\temp}
+ }
+ }
+ \pgf@sys@pdf@install@pageresources
+ \expandafter\pgfutil@everybye\expandafter{%
+ \the\pgfutil@everybye%
+ \immediate \pdfextension obj useobjnum \pgf@sys@pdf@extgs@objnum {<<\pgf@sys@pgf@resource@list@extgs>>}%<<
+ \immediate \pdfextension obj useobjnum \pgf@sys@pdf@pattern@objnum {<<\pgf@sys@pgf@resource@list@patterns>>}%<<
+ \immediate \pdfextension obj useobjnum \pgf@sys@pdf@colrospaces@objnum {<<\pgf@sys@pgf@resource@list@colorspaces>>}%<<
+ }
+ \let\pgf@sys@pgf@resource@list@extgs=\pgfutil@empty%
+ \let\pgf@sys@pgf@resource@list@patterns=\pgfutil@empty%
+ \let\pgf@sys@pgf@resource@list@colorspaces=\pgfutil@empty%
+ \def\pgf@sys@addpdfresource@extgs@plain##1{\xdef\pgf@sys@pgf@resource@list@extgs{\pgf@sys@pgf@resource@list@extgs\space##1}}
+ \def\pgf@sys@addpdfresource@patterns@plain##1{\xdef\pgf@sys@pgf@resource@list@patterns{\pgf@sys@pgf@resource@list@patterns\space##1}}
+ \def\pgf@sys@addpdfresource@colorspaces@plain##1{\xdef\pgf@sys@pgf@resource@list@colorspaces{\pgf@sys@pgf@resource@list@colorspaces\space##1}}
+}
+\pgfutil@setuppdfresources % possibly call the above
+
+\pgfutil@addpdfresource@colorspaces{ /pgfprgb [/Pattern /DeviceRGB] }
+
+\def\pgfsys@color@unstacked#1{%
+ \pdfextension literal{\csname\string\color@#1\endcsname}%
+}
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-pdftex.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-pdftex.def
new file mode 100644
index 0000000000..3b9b33006a
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-pdftex.def
@@ -0,0 +1,398 @@
+% Copyright 2019 by Till Tantau
+% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-pdftex.def}
+
+
+% Driver commands for pdf
+
+%
+% Load common pdf commands:
+%
+\input pgfsys-common-pdf.def
+
+%
+% pdftex-specific stuff:
+%
+\def\pgfsys@invoke#1{\pdfliteral{#1}}
+
+% Synced hboxes
+\def\pgfsys@hboxsynced#1{%
+ {%
+ \pgfsys@begin@idscope%
+ \pgfsys@beginscope%
+ \setbox\pgf@hbox=\hbox{%
+ \hskip\pgf@pt@x%
+ \raise\pgf@pt@y\hbox{%
+ \pgf@pt@x=0pt%
+ \pgf@pt@y=0pt%
+ \pgflowlevelsynccm%
+ \pgfsys@hbox#1}%
+ \hss%
+ }%
+ \wd\pgf@hbox=0pt%
+ \ht\pgf@hbox=0pt%
+ \dp\pgf@hbox=0pt%
+ \box\pgf@hbox%
+ \pgfsys@endscope%
+ \pgfsys@end@idscope%
+ }%
+}
+
+
+
+\def\pgfsys@imagesuffixlist{.pdf:.jpg:.jpeg:.png:}
+\def\pgfsys@defineimage{% width, height, page number
+ \ifx\pgf@imagewidth\pgfutil@empty\else\edef\pgf@imagewidth{ width \pgf@imagewidth }\fi%
+ \ifx\pgf@imageheight\pgfutil@empty\else\edef\pgf@imageheight{ height \pgf@imageheight }\fi%
+ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage }\fi%
+ \ifx\pdfximage\@undefined% old version of pdflatex
+ \ifx\pgf@imagepage\pgfutil@empty\else%
+ \pgfwarning{Page selection not supported. Ignoring page selection}%
+ \fi%
+ \setbox\pgfutil@tempboxa=\hbox{%
+ \pdfimage \pgf@imageheight \pgf@imagewidth {\pgf@filename}}%
+ \pdfform\pgfutil@tempboxa%
+ \edef\pgf@image{\noexpand\pdfrefform\the\pdflastform}%
+ \else% new version
+ {\pdfximage \pgf@imageheight \pgf@imagewidth attr
+ {/Interpolate \pgf@imageinterpolate\space\pgf@imagemask} \pgf@imagepage
+ {\pgf@filename}}%
+ \edef\pgf@image{\noexpand\pdfrefximage\the\pdflastximage}%
+ \fi
+}%
+\def\pgfsys@definemask{%
+ \ifx\pgf@maskmatte\pgfutil@empty%
+ \else%
+ \edef\pgf@maskmatte{/Matte [\pgf@maskmatte]}%
+ \fi%
+ \edef\pgf@attr{{\pgf@maskmatte\space /Decode [1 0]}}%
+ \immediate\pdfximage attr \pgf@attr {\pgf@filename}%
+ \edef\pgf@mask{/SMask \the\pdflastximage\space 0 R}%
+}
+\def\pgfsys@horishading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathparse{#2}%
+ \setbox\pgfutil@tempboxa=\hbox to\pgf@max{\vbox to\pgfmathresult pt{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@process{\pgfpoint{\pgf@max}{#2}}%
+ \immediate\pdfxform resources {%
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@doma\space0 \pgf@domb\space0]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{\noexpand\pdfrefxform\the\pdflastxform}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+\def\pgfsys@vertshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \pgfmathparse{#2}%
+ \setbox\pgfutil@tempboxa=\hbox to\pgfmathresult pt{\vbox to\pgf@max{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@process{\pgfpoint{#2}{\pgf@max}}%
+ \immediate\pdfxform resources {%
+ /Shading << /Sh << /ShadingType 2
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [0 \pgf@doma\space0 \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [false false] >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{\noexpand\pdfrefxform\the\pdflastxform}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+\def\pgfsys@radialshading#1#2#3{%
+ {%
+ \pgf@parsefunc{#3}%
+ \setbox\pgfutil@tempboxa=\hbox to2\pgf@max{\vbox to2\pgf@max{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{\pgfpoint{\pgf@max}{\pgf@max}}%
+ \advance\pgf@xa by \pgf@x%
+ \advance\pgf@ya by \pgf@y%
+ \pgf@sys@bp@correct{\pgf@x}%
+ \pgf@sys@bp@correct{\pgf@y}%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \immediate\pdfxform resources {%
+ /Shading << /Sh << /ShadingType 3
+ /ColorSpace \pgf@shading@device\space
+ /Domain [\pgf@pdfparseddomain]
+ /Coords [\pgf@sys@tonumber{\pgf@xa} \pgf@sys@tonumber{\pgf@ya} \pgf@doma\space \pgf@sys@tonumber{\pgf@x} \pgf@sys@tonumber{\pgf@y} \pgf@domb]
+ /Function \pgf@pdfparsedfunction
+ /Extend [true false] >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{\noexpand\pdfrefxform\the\pdflastxform}}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}%
+\def\pgfsys@functionalshading#1#2#3#4{%
+ {%
+ \pgf@process{#2}%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \pgf@process{#3}%
+ \pgf@xb=\pgf@x%
+ \pgf@yb=\pgf@y%
+ \advance\pgf@x by-\pgf@xa%
+ \advance\pgf@y by-\pgf@ya%
+ \setbox\pgfutil@tempboxa=\hbox to\pgf@x{\vbox to\pgf@y{\vfil\pgfsys@invoke{/Sh sh}}\hfil}%
+ \pgf@sys@bp@correct{\pgf@xa}%
+ \pgf@sys@bp@correct{\pgf@ya}%
+ \pgf@sys@bp@correct{\pgf@xb}%
+ \pgf@sys@bp@correct{\pgf@yb}%
+ \pgf@xc=-\pgf@xa%
+ \pgf@yc=-\pgf@ya%
+ % Now build the function
+ \pdfobj
+ stream
+ attr
+ {
+ /FunctionType 4
+ /Domain [\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@ya}\space\pgf@sys@tonumber{\pgf@yb}]
+ /Range [\pgf@shading@functional@range]
+ }
+ {{#4}}%
+ \edef\pgf@temp@num{\the\pdflastobj}%
+ \pdfxform resources {%
+ /Shading << /Sh << /ShadingType 1
+ /ColorSpace \pgf@shading@device\space
+ /Matrix [1 0 0 1 \pgf@sys@tonumber{\pgf@xc}\space\pgf@sys@tonumber{\pgf@yc}]
+ /Domain [\pgf@sys@tonumber{\pgf@xa}\space\pgf@sys@tonumber{\pgf@xb}\space\pgf@sys@tonumber{\pgf@ya}\space\pgf@sys@tonumber{\pgf@yb}]
+ /Function \pgf@temp@num\space 0 R
+ >> >>}\pgfutil@tempboxa% <<
+ \xdef\pgfutil@tempa{\hbox{%
+ \noexpand\pdfrefxform\the\pdflastxform%
+ \noexpand\pdfrefobj\pgf@temp@num%
+ }}%
+ }%
+ \global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@tempa
+}
+
+
+
+% Patterns
+
+\def\pgfsys@declarepattern#1#2#3#4#5#6#7{%
+ % Start building the pattern dictionary:
+ \pgf@xa=#2\relax%
+ \pgf@ya=#3\relax%
+ \pgf@xb=#4\relax%
+ \pgf@yb=#5\relax%
+ \pgf@xc=#6\relax%
+ \pgf@yc=#7\relax%
+ \pgf@sys@bp@correct\pgf@xa%
+ \pgf@sys@bp@correct\pgf@ya%
+ \pgf@sys@bp@correct\pgf@xb%
+ \pgf@sys@bp@correct\pgf@yb%
+ \pgf@sys@bp@correct\pgf@xc%
+ \pgf@sys@bp@correct\pgf@yc%
+ \pgfsys@@declarepattern{#1}%
+}
+
+\def\pgfsys@@declarepattern#1#2#3#4#5#6#7#8#9{%
+ \pgfutil@tempdima=#6\relax%
+ \pgfutil@tempdimb=#7\relax%
+ \pgf@sys@bp@correct\pgfutil@tempdima%
+ \pgf@sys@bp@correct\pgfutil@tempdimb%
+ % Now create the pattern object:
+ \immediate\pdfobj stream
+ attr
+ {
+ /Type /Pattern
+ /PatternType 1
+ /PaintType \ifnum#9=0 2 \else 1 \fi
+ /TilingType 1
+ /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb]
+ /XStep \pgf@sys@tonumber\pgf@xc\space
+ /YStep \pgf@sys@tonumber\pgf@yc\space
+ /Matrix [#2\space#3\space#4\space#5\space\pgf@sys@tonumber\pgfutil@tempdima\space\pgf@sys@tonumber\pgfutil@tempdimb]
+ /Resources <</Pattern<<>>>> %<<
+ }
+ {#8}%
+ \pgfutil@addpdfresource@patterns{/pgfpat#1\space \the\pdflastobj\space 0 R}%
+}
+
+\def\pgfsys@setpatternuncolored#1#2#3#4{%
+ \pgfsysprotocol@literal{/pgfprgb cs #2 #3 #4 /pgfpat#1\space scn}%
+}
+
+\def\pgfsys@setpatterncolored#1{%
+ \pgfsysprotocol@literal{/Pattern cs /pgfpat#1\space scn}%
+}
+
+
+
+\def\pgfsys@papersize#1#2{\pdfpageheight#2\relax\pdfpagewidth#1\relax}
+
+\def\pgfsys@global@papersize#1#2{\global\pdfpageheight#2\relax\global\pdfpagewidth#1\relax}
+
+\ifx\paperheight\@undefined
+ \def\pgfsys@thepageheight{\pdfpageheight}
+ \def\pgfsys@thepagewidth{\pdfpagewidth}
+\fi
+
+
+%
+% Position tracking
+%
+\def\pgfsys@markposition#1{%
+ \pdfsavepos%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutil@writetoaux\expandafter{%
+ \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}%
+}
+
+\def\pgfsyspdfmark#1#2#3{%
+ \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}%
+ \pgfutil@check@rerun{#1}{{#2}{#3}}%
+}
+
+\def\pgfsys@getposition#1#2{%
+ \edef\pgf@marshal{\let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname}%
+ \pgf@marshal%
+}
+
+\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{\hoffset}{\voffset}}
+
+
+%
+% Opacity masks
+%
+\def\pgfsys@fadingfrombox#1#2{%
+ {%
+ \pgf@sys@pdf@check@resources%
+ \pgf@x=-.5\wd#2%
+ \pgf@y=-.5\ht#2%
+ \advance\pgf@y by.5\dp#2%
+ \expandafter\xdef\csname pgfsmasktrans@#1\endcsname{%
+ \noexpand\pgftransformcm{1}{0}{0}{1}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
+ \pdfxform resources { \pgf@sys@pdf@possible@resources } #2%
+ \expandafter\xdef\csname pgfsmaskxform@#1\endcsname{\the\pdflastxform}%
+ }%
+}
+\def\pgfsys@usefading#1#2#3#4#5#6#7{%
+ \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax%
+ \pgferror{Undefined fading '#1'}%
+ \else%
+ {%
+ \expandafter\ifx\csname pgfsmask@#1\endcsname\relax%
+ \pgf@sys@pdf@install@mask{#1}%
+ \fi%
+ \pgftransformreset%
+ \pgftransformcm{#2}{#3}{#4}{#5}{\pgfpoint{#6}{#7}}%
+ \csname pgfsmasktrans@#1\endcsname%
+ {%
+ \pgflowlevelsynccm%
+ \pgfsys@invoke{/pgfsmask\csname pgfsmask@#1\endcsname\space gs}%
+ }%
+ \pgftransforminvert%
+ \pgflowlevelsynccm%
+ }%
+ \fi
+}
+
+\def\pgf@sys@pdf@install@mask#1{%
+ \setbox\pgfutil@tempboxa=\hbox{\pdfrefxform\csname pgfsmaskxform@#1\endcsname}
+ \immediate\pdfxform%
+ attr {
+ /Group
+ <<
+ /S /Transparency
+ /CS /DeviceGray
+ >>
+ }% <<
+ \pgfutil@tempboxa%
+ \pgfutil@addpdfresource@extgs{%
+ /pgfsmask\the\pdflastxform\space
+ <<
+ /SMask
+ <<
+ /S /Luminosity
+ /G \the\pdflastxform\space 0 R
+ >>
+ >> } %<<
+ \expandafter\xdef\csname pgfsmask@#1\endcsname{\the\pdflastxform}%
+}
+
+%
+% Transparency groups
+%
+\def\pgfsys@transparencygroupfrombox#1{%
+ \pgf@sys@pdf@check@resources%
+ \pdfxform
+ attr { /Group << /S /Transparency
+ /I \ifpgfsys@transparency@group@isolated true \else false \fi
+ /K \ifpgfsys@transparency@group@knockout true \else false \fi >> } %<<
+ resources { \pgf@sys@pdf@possible@resources }
+ #1%
+ \setbox#1=\hbox{\pdfrefxform\pdflastxform}%
+}
+
+
+
+
+%
+% Resource management
+%
+
+\def\pgf@sys@setuppdfresources@plain{%
+ % This command will setup pdf resource in plain and in latex
+ % mode. ConTeXt has its own handler
+ % Page resources (they are kept in objects and only written at the
+ % very end)
+ \pdfobj reserveobjnum \edef\pgf@sys@pdf@extgs@objnum{\the\pdflastobj}
+ \pdfobj reserveobjnum \edef\pgf@sys@pdf@pattern@objnum{\the\pdflastobj}
+ \pdfobj reserveobjnum \edef\pgf@sys@pdf@colrospaces@objnum{\the\pdflastobj}
+ \def\pgf@sys@pdf@possible@resources{%
+ /ColorSpace \pgf@sys@pdf@colrospaces@objnum\space 0 R
+ /Pattern \pgf@sys@pdf@pattern@objnum\space 0 R
+ /ExtGState \pgf@sys@pdf@extgs@objnum\space 0 R
+ }
+ \let\pgf@sys@pdf@check@resources=\relax%
+ \def\pgf@sys@pdf@install@pageresources{
+ {
+ \edef\temp{
+ \pgf@sys@pdf@possible@resources
+ }
+ \expandafter\global\expandafter\pdfpageresources\expandafter{\temp}
+ }
+ }
+ \pgf@sys@pdf@install@pageresources
+ \expandafter\pgfutil@everybye\expandafter{%
+ \the\pgfutil@everybye%
+ \immediate \pdfobj useobjnum \pgf@sys@pdf@extgs@objnum {<<\pgf@sys@pgf@resource@list@extgs>>}%<<
+ \immediate \pdfobj useobjnum \pgf@sys@pdf@pattern@objnum {<<\pgf@sys@pgf@resource@list@patterns>>}%<<
+ \immediate \pdfobj useobjnum \pgf@sys@pdf@colrospaces@objnum {<<\pgf@sys@pgf@resource@list@colorspaces>>}%<<
+ }
+ \let\pgf@sys@pgf@resource@list@extgs=\pgfutil@empty%
+ \let\pgf@sys@pgf@resource@list@patterns=\pgfutil@empty%
+ \let\pgf@sys@pgf@resource@list@colorspaces=\pgfutil@empty%
+ \def\pgf@sys@addpdfresource@extgs@plain##1{\xdef\pgf@sys@pgf@resource@list@extgs{\pgf@sys@pgf@resource@list@extgs\space##1}}
+ \def\pgf@sys@addpdfresource@patterns@plain##1{\xdef\pgf@sys@pgf@resource@list@patterns{\pgf@sys@pgf@resource@list@patterns\space##1}}
+ \def\pgf@sys@addpdfresource@colorspaces@plain##1{\xdef\pgf@sys@pgf@resource@list@colorspaces{\pgf@sys@pgf@resource@list@colorspaces\space##1}}
+}
+\pgfutil@setuppdfresources % possibly call the above
+
+\pgfutil@addpdfresource@colorspaces{ /pgfprgb [/Pattern /DeviceRGB] }
+
+\def\pgfsys@color@unstacked#1{%
+ \pdfliteral{\csname\string\color@#1\endcsname}%
+}
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-tex4ht.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-tex4ht.def
new file mode 100644
index 0000000000..44dd1ae5b0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-tex4ht.def
@@ -0,0 +1,487 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-tex4ht.def}
+
+
+
+% Driver commands for tex4ht
+
+%
+% Load common pdf commands:
+%
+\input pgfsys-common-svg.def
+
+%
+% tex4ht-specific stuff:
+%
+\def\pgfsys@invoke#1{\pgf@sys@fail{svg code in preamble}}
+\def\pgfsys@body@invoke#1{\HCode{#1}}
+
+\newcount\pgf@sys@svg@picnum
+
+\def\pgfsys@pictureboxsynced#1{%
+ \pgfsys@beginscope\pgflowlevelsynccm\box#1\pgfsys@endscope%
+}
+
+
+%%
+%% initial support of Mathml and xhtml inside svg through the svg:foreignelement tag
+%%
+%% it'll allow us to have complicated text nodes in the tex4ht driver
+%%
+
+
+%Example (to improve the display, you have to use css)
+%
+%\tikzpicture[svg text only=false]
+%\draw (0,0) node[inner sep=0pt,draw] {tight}
+%(0cm,2em) node[inner sep=5pt,draw] {loose}
+%(0cm,4em) node[fill=red!20] {default};
+%\draw (3,0) node[inner sep=0pt,draw] {TIGHT}
+%(3cm,2em) node[inner sep=5pt,draw] {LOOSE}
+%(3cm,4em) node[fill=red!20] {DEFAULT};
+%\draw (6,0) node[inner sep=0pt,draw] {$tight$}
+%(6cm,2em) node[inner sep=5pt,draw] {$loose$}
+%(6cm,4em) node[fill=red!20] {$default$};
+%\draw (9,0) node[inner sep=0pt,draw] {$TIGHT$}
+%(9cm,2em) node[inner sep=5pt,draw] {$LOOSE$}
+%(9cm,4em) node[fill=red!20] {$Default$};
+%\endtikzpicture
+%
+% you can use the options "svg text css=filename", "svg text id=idname", "svg text class=classname" to customize the display through the use of css
+%
+
+
+
+
+
+
+
+%\def\pgfsys@beginpicture{%
+% % \Configure{[]}{$}{$} these two lines aren't needed for tex4ht and moreother they produce errors with plain tex !
+% % \Configure{()}{$}{$}
+% \Configure{$$}{}{}{}%$$
+% \Configure{$}{}{}{}%$
+% \Configure{SUB}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}
+% \Configure{SUP}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}
+% \Configure{SUBSUP}{}{}{}
+% \Configure{htf}
+% {0}{+}{<tspan font-family="}
+% {\%s}{" font-size="\%s}{}{}
+% {">}{</tspan>}
+%}
+
+
+
+%\def\pgfsys@endpicture{%
+% % undo:
+% \Configure{htf}{0}{+}{<span\Hnewline
+% class="}{\%s}{-\%s}{x-x-\%d}{}{">}{</span>}
+%}
+
+\def\pgfsys@svg@newline{^^J}
+
+% we don't want tex4ht putting <p> and </p> tags automatically in our svg code and causing invalid xhtml in our svg pictures
+\newif\ifpgfsys@CssIncluded@\pgfsys@CssIncluded@false
+\def\pgfsys@beginpicture{%
+ \pgfsys@svg@boxmodefalse%
+ \EndP\HtmlParOff%
+ \pgfkeys{/pgf/tex4ht node/escape=false}%
+ % text only nodes are the default. Advantage : pure svg pictures are
+ % the default, nicer for text only nodes.
+ % Disadvantages : this rendering methods produce more invalid or degraded svg pictures than with the foreignelement tag
+ %% we use css to control the display of foreignelement rendered text nodes
+ \ifpgfsys@CssIncluded@
+ \else
+ \Css{
+ .foreignobject {%
+ line-height:100\%;
+ font-size:120\%; % this is the trick....a font of size 100% in
+ % a box scaled down to half size makes it a
+ % half size font.
+ % you'll have to double the size of things
+ % that you want to have a regular size in
+ % this half-scaled box though
+ font-family:STIXgeneral,Times,Symbol,cmr10,CMSY10,CMEX10;%
+ % can't wait for the stix font...the cmr10, etc font are
+ % available from the mozilla site, times and symbols should be
+ % okey
+ padding:0;
+ margin:0;
+ % background-color:\#12ff55; usefull for debugging positioning
+ text-align:center; % good for centered text nodes...will have to improve that later on...with more integration with pgf options for text nodes
+ }
+ }%
+ \Css{%
+ math {%, math[mode="inline"] {
+ vertical-align:baseline;
+ line-height:100\%;
+ font-size:100\%;
+ font-family:STIXGeneral,Times,Symbol, cmr10,cmsy10,cmex10,cmmi10;
+ font-style: normal;
+ margin:0;
+ % background-color:\#99ff99;
+ padding:0;
+ }%
+ }%
+ \pgfsys@CssIncluded@true
+ \fi
+}%
+
+\def\pgfsys@endpicture{%
+ \HtmlParOn
+ \par% FIXME : was '\Par' but that seems to be undefined!?
+}%
+
+% this is okay for both rendering methods for text nodes (mtext or foreignelement)...
+\def\pgfsys@typesetpicturebox#1{%
+ \global\advance\pgf@sys@svg@picnum by 1\relax%
+ % Ok, compute width/height
+ \pgf@xa=\pgf@picminx%
+ \pgf@ya=\pgf@picminy%
+ \pgf@xb=\pgf@picmaxx%
+ \pgf@yb=\pgf@picmaxy%
+ \pgf@x=\pgf@xb%
+ \advance\pgf@x by-\pgf@xa%
+ \pgf@y=\pgf@yb%
+ \advance\pgf@y by-\pgf@ya%
+ \ifdim\pgf@y<1pt%
+ \pgf@y=1pt%
+ \fi%
+ \pgf@xc=\pgf@x%
+ \pgf@yc=\pgf@y%
+ \pgfsysprotocol@flushcurrentprotocol%
+ \HCode{<object data="\jobname-\the\pgf@sys@svg@picnum.svg" width="}%
+ % Calculate pixel coordinates (this does not really make sense, but
+ % we have to do it anyway). Assume 96dpi.
+ \pgf@x=1.3333333\pgf@x%
+ \pgf@y=1.3333333\pgf@y%
+ % Add one pixel for security:
+ \advance\pgf@x by1pt%
+ \advance\pgf@y by1pt%
+ \pgf@sys@pt\pgf@x%
+ \pgfsysprotocol@flushcurrentprotocol%
+ \pgfsys@invoke{" height="}%
+ \pgf@sys@pt\pgf@y%
+ \pgfsysprotocol@flushcurrentprotocol%
+ \pgfsys@invoke{" type="image/svg+xml"><p>SVG-Viewer needed.</p></object>}%
+ \special{t4ht>\jobname-\the\pgf@sys@svg@picnum.svg}%
+ %%%%%%%% This is necessary to control the svg through css
+ \pgfkeys{%
+ /pgf/tex4ht node/css/.get=\pgfsys@foreignobject@css
+ }%
+ \pgfsys@invoke{<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>\Hnewline% added that
+ <?xml-stylesheet href="\pgfsys@foreignobject@css.css" type="text/css"?>\Hnewline}% added that
+%%%%%%%%%%%%%%% maybee I should add an option to change the css, for the whole picture
+ \pgfsys@invoke{<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink" width="\the\pgf@xc"
+ height="\the\pgf@yc" viewBox="}%
+ \pgf@sys@pt{\pgf@xa}\pgf@sys@pt{\pgf@ya}\pgf@sys@pt{\pgf@xc}\pgf@sys@pt{\pgf@yc}%
+ \pgfsysprotocol@flushcurrentprotocol%
+ \pgf@ya=-\pgf@ya%
+ \pgfsys@invoke{">\Hnewline <g transform="translate(0,}
+ \pgf@sys@pt\pgf@yb\pgfsysprotocol@flushcurrentprotocol%
+ \pgfsys@invoke{) scale(1,-1) translate(0,}%
+ \pgf@sys@pt\pgf@ya\pgfsysprotocol@flushcurrentprotocol%
+ \pgfsys@invoke{)">\Hnewline }%
+ %
+ \pgf@ya=\pgf@shift@baseline\relax%
+ \advance\pgf@ya by-\pgf@picminy\relax%
+ %
+ %
+ \advance\pgf@picmaxy by-\pgf@picminy\relax% maxy is now the height
+ \advance\pgf@picmaxx by-\pgf@picminx\relax% maxx is now the width
+ \setbox#1=\hbox{\hskip-\pgf@picminx\lower\pgf@picminy\box#1}%
+ \ht#1=\pgf@picmaxy%
+ \wd#1=\pgf@picmaxx%
+ \dp#1=0pt%
+ \leavevmode
+ \pgf@xa=\pgf@trimleft@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi
+ \raise-\pgf@ya\box#1%
+ \pgf@xa=\pgf@trimright@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi
+ \pgfsys@invoke{</g>\Hnewline </svg>\Hnewline }%
+ \special{t4ht<\jobname-\the\pgf@sys@svg@picnum.svg}%
+}%
+
+%% we'll use this hbox for the mtext rendering method (the "text only=true" option)
+\def\pgfsys@hbox#1{%
+ \pgf@x=.5\wd#1%
+ \ifx\tikz@textcolor\relax\else\ifx\tikz@textcolor\@undefined\else%
+ \ifx\tikz@textcolor\pgfutil@empty%
+ \pgfsetfillcolor{.}%
+ \else%
+ \pgfsetfillcolor{\tikz@textcolor}%
+ \fi%
+ \fi\fi% tweak for TikZ
+ \HCode{<text
+ style="stroke:none"
+ transform="scale(1,-1) translate(\pgf@sys@tonumber{\pgf@x},0)"
+ text-anchor="middle"
+ }%
+ \ifpgfutil@format@is@latex%
+ \ifx\f@size\pgfutil@empty%
+ \else%
+ \HCode{ font-size="\f@size"}%
+ \fi%
+ \fi%
+ \HCode{>\Hnewline }%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \box#1
+ \HCode{</text>\Hnewline }%
+}%
+
+%% we save this definition
+\let\pgfsys@mtext@hbox\pgfsys@hbox
+
+%% we have to use some "evil" ^^ tex4ht hackery
+% tex4ht hackery
+{% grouping necessary cause we change the catcode of ":"
+ \catcode`:=11\relax
+ %%% this is necessary to calculate the size of text nodes with
+ %%% inline maths
+ % (it is an improvement of tex4ht, got to ask eitan gurary if he
+ % could put it in the tex4ht code)
+ \gdef\DviMathAlt{%
+ \a:DviMath\leavevmode \MathClass
+ \ht:special{t4ht@(}\hbox\bgroup{\expandafter\ifx\csname
+ ht:everypar\endcsname\relax\expandafter\everypar\else
+ \expandafter\ht:everypar\fi{}\leavevmode\ht:special{t4ht@)}}\DviSend
+ }%
+ % these are configures for the foreignelement rendering method of text nodes : we let tex4ht write xhtml and mathml in the svg picture
+ %
+ \gdef\pgfsys@foreignobject@configure{%
+ \Configure{$}{\Configure{@math}{%\a:mathml
+ display="inline" }\DviMathAlt}{\EndDviMath}{}%%% we REALLY need to use \DviMathAlt here instead of \DviMath see above remark
+ \Configure{$$}{\Configure{@math}{%\a:mathml
+ display="block" }\IgnorePar
+ \ifvmode\else \HCode{<!--tex4ht:inline-->}\fi\EndP
+ \DviMath}{\EndDviMath\ShowPar\pgfsys@foreignobject@par{\csname HCondtrue\endcsname\noindent}
+ }{\DisplayMathtrue}%
+ \Configure{SUB}{\Send{BACK}{<\a:mathml msub><\a:mathml mrow\Hnewline>}%
+ \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msub\Hnewline>}%
+ \Configure{SUP}{\Send{BACK}{<\a:mathml msup><\a:mathml mrow\Hnewline>}%
+ \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msup\Hnewline>}%
+ \Configure{SUBSUP}{\Send{BACK}{<\a:mathml msubsup><\a:mathml mrow\Hnewline>}%
+ \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msubsup\Hnewline>}%
+ \Configure{htf}{0}{+}{<span\Hnewline
+ class="}{\%s}{-\%s}{x-x-\%d}{}{">}{</span>}%
+ }%
+ \global\let\pgfsys@foreignobject@par=\par % use this instead of \par
+ % -- \Configure is no \long macro (at
+ % least in one of the older
+ % versions).
+
+ % these are the configures for the mtext rendering method of text
+ % nodes : we turn everything into regular character (don't want math
+ % modes or subsup)
+ % and we hope it works (it doesn't if the text nodes aren't simple)
+ \gdef\pgfsys@mtext@configure{%
+ % no configures for \(\) and \[\] those might be needed for
+ % context or Latex. Let me know !
+ \Configure{$$}{}{}{}% no block maths
+ \Configure{$}{}{}{}%$ no inline maths
+ \Configure{SUB}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}%
+ \Configure{SUP}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}%
+ \Configure{SUBSUP}{}{}{}% not both sub and sup
+ \Configure{htf} {0}{+}{<tspan font-family="}{\%s}{" font-size="\%s}{}{}{">}{</tspan>}%
+ }%
+}%
+
+% a counter to produce unique ids for each text node rendered with foreign element
+\newcount\pgf@sys@svg@nodenum
+
+
+% pgfutil@minipage
+%
+% I had to change it to make it play nice with the way tex4ht puts <p> and <\p> tags
+%
+
+\newif\ifpgfsys@textonly
+\def\pgfutil@minipage[#1]#2{%
+ \hbox to#2\bgroup
+ \hsize=#2\relax
+ \vbox\bgroup
+% though it works, I'm desabling the above-mentioned hack to make tex4ht behave with <p> <\p>, because it blurps the positioning
+% (I''l try to fix that later, it's a css thing)
+%
+% \ifpgfsys@textonly\else\HtmlParOn\fi
+%
+% \noindent is better as it doesn't produce indentation AND it makes you leave vertical mode
+ \noindent%\leavevmode
+}%
+\def\pgfutil@endminipage{%
+% same thing here
+%
+% \ifpgfsys@textonly\else\EndP\HtmlParOff\fi
+ \egroup\egroup
+}%
+
+
+% I'll have to fix those names later
+\newbox\pgfsys@foreignobject@Box
+\newdimen\pgf@s
+\newdimen\pgf@t
+% this is the alternate hbox routine that renders text nodes through the foreignobject tag
+\def\pgfsys@foreignobject@hbox#1{%
+ % Compute box y translation (x translation is correct).
+ \pgf@y=-\ht#1\relax
+ \HCode{<g transform="scale(1,-1) translate(0,\pgf@sys@tonumber{\pgf@y}) % got to translate in y
+ scale(0.5,0.5)">\Hnewline}% scaling work around (damn dumb browsers !)
+ % Compute box size (scaled 2 times)
+ % this is necessary to make the browser scale the font down 50% (the STUPID browsers won't make font-size:50% happen,
+ % so we have to work around this by making svg scale the things down 50%, doubling the size of the text node frame (i.e. no changement there)
+ \pgf@x=2\wd#1\relax
+ \pgf@y=2\ht#1\relax
+ \advance\pgf@y by 2\dp#1\relax
+ % this is to adjust the y translation to compensate for the differences between the TeX and the Html models for lines
+ \setbox\pgfsys@foreignobject@Box=\hbox{abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ $abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZf_1^1\overline D)_1^1\vec i\vec j$}%
+ \pgf@t=\ht#1\relax
+ \advance\pgf@t by -\ht\pgfsys@foreignobject@Box\relax
+ \pgf@s=\pgf@t\relax
+ \advance\pgf@s by \dp#1\relax
+ \advance\pgf@s by -\dp\pgfsys@foreignobject@Box\relax
+ \ifnum\pgf@s>0\relax
+ \pgf@s=0pt
+ \pgf@t=0pt
+ \else
+ \advance \pgf@y by -2\pgf@s\relax
+ \pgf@t=2\pgf@t\relax
+ \fi
+ %
+ \HCode{<foreignObject x="0" y="\pgf@sys@tonumber{\pgf@t}"
+ width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}">}%
+ % this is to make use of the css, class and id options through which you can control the way things display
+ \pgfkeys{%
+ /pgf/tex4ht node/css/.get=\pgfsys@foreignobject@css,%
+ /pgf/tex4ht node/class/.get=\pgfsys@foreignobject@class,%
+ /pgf/tex4ht node/id/.get=\pgfsys@foreignobject@id
+ }%
+ \HCode{<head>\Hnewline
+ <link rel="stylesheet" type="text/css" href="\pgfsys@foreignobject@css.css" />\Hnewline
+ </head>\Hnewline
+ % I'll have to look into this, perhaps there are better
+ % doctype....&nbsp; aren't recognised and produces invalid svg
+ % pictures a workaround (not implemented yet) would be to make
+ % them into entities of the svg picture.
+ <body id="\pgfsys@foreignobject@id" class="\pgfsys@foreignobject@class" xmlns="http://www.w3.org/1999/xhtml" >\Hnewline
+ <div>\Hnewline
+ }%
+ \box#1%
+ \HCode{%
+ </div>\Hnewline
+ </body>\Hnewline
+ </foreignObject>\Hnewline
+ }%
+ % debug positioning not needed but it would be nice to let it there to control things later on
+ % \HCode{<rect x="0" y="0" width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}"
+ % style="fill:yellow;stroke:red; fill-opacity:0.5;stroke-opacity:0.5"/>}
+ \HCode{</g>\Hnewline}%
+ \global\advance\pgf@sys@svg@nodenum by 1\relax
+}%
+
+% the options and the code that controls it all (switches between \pgfsys@mtext@hbox and \pgfsys@foreignelement@hbox)
+
+\pgfkeys{%
+ /pgf/.cd,
+ tex4ht node/escape/.is choice,
+ tex4ht node/escape/false/.code={\let\pgfsys@hbox\pgfsys@mtext@hbox\pgfsys@mtext@configure\pgfsys@textonlytrue},
+ tex4ht node/escape/true/.code={\let\pgfsys@hbox\pgfsys@foreignobject@hbox\pgfsys@foreignobject@configure\pgfsys@textonlyfalse},
+ tex4ht node/css/.initial=\jobname,
+ tex4ht node/class/.initial=foreignobject,
+ tex4ht node/id/.initial=\jobname\the\pgf@sys@svg@picnum-\the\pgf@sys@svg@nodenum
+}%
+
+
+
+
+
+
+% this might be needed
+%\font\SvgText=cmr10\relax
+
+
+
+
+% There is something rellay wrong with the way "%" chars are used in here... you should code "}%" to avoid unnecessary spaces
+% and it is unnecessary to code \cs%
+% got to be carefull with numbers though, cf the texbook...2\relax and 2 % are okey
+
+\def\pgfsys@outerinvoke{\ifpgfpicture\expandafter\pgfsys@invoke\else\expandafter\pgfutil@gobble\fi}
+
+\def\pgfsys@shadingoutsidepgfpicture#1{\pgf@sys@fail{svg code in preamble}}
+\def\pgfsys@shadinginsidepgfpicture#1{\pgf@sys@fail{svg code in preamble}}
+
+\def\pgfsys@body@shadingoutsidepgfpicture#1{%
+ \begingroup%
+ #1%
+ \setbox\pgfpic=\hbox to0pt{%
+ \pgfsys@beginpicture%
+ \pgfsys@beginscope%
+ \pgf@sys@svg@sh@defs%
+ \pgf@sys@svg@sh%
+ \pgfsys@endscope%
+ \pgfsys@endpicture%
+ \hss%
+ }%
+ \pgf@process{\pgf@sys@svg@pos}%
+ \pgf@picminx=0pt%
+ \pgf@picminy=0pt%
+ \pgf@picmaxx=\pgf@x%
+ \pgf@picmaxy=\pgf@y%
+ \def\pgf@trimleft@final{0pt}%
+ \def\pgf@trimright@final{0pt}%
+ \def\pgf@shift@baseline{0pt}%
+ \pgfsys@typesetpicturebox\pgfpic%
+ \endgroup%
+}
+
+\def\pgfsys@body@shadinginsidepgfpicture#1{%
+ #1%
+ \pgf@sys@svg@sh@defs% hmmm....
+ \pgf@process{\pgf@sys@svg@pos}
+ \pgf@xa=-.5\pgf@x%
+ \pgf@ya=-.5\pgf@y%
+ \pgfsysprotocol@literal{<g transform="translate(\pgf@sys@tonumber{\pgf@xa},\pgf@sys@tonumber{\pgf@ya})">\Hnewline}%
+ \pgf@sys@svg@sh%
+ \pgfsysprotocol@literal{</g>\Hnewline}%
+}
+
+
+\ifpgfutil@format@is@latex
+ % Protect against color.4ht evil meddling with xcolor:
+ \RequirePackage{xcolor}
+ \let\pgf@xcolor@declaredcolor=\@declaredcolor
+ \let\pgf@xcolor@undeclaredcolor=\@undeclaredcolor
+\fi
+
+\AtBeginDocument{
+ \let\pgfsys@invoke=\pgfsys@body@invoke
+ \let\pgfsys@shadingoutsidepgfpicture=\pgfsys@body@shadingoutsidepgfpicture
+ \let\pgfsys@shadinginsidepgfpicture=\pgfsys@body@shadinginsidepgfpicture
+ \ifpgfutil@format@is@latex
+ \let\pgf@texht@declaredcolor=\@declaredcolor
+ \let\pgf@texht@undeclaredcolor=\@undeclaredcolor
+ \def\@declaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@declaredcolor\else\expandafter\pgf@texht@declaredcolor\fi}
+ \def\@undeclaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@undeclaredcolor\else\expandafter\pgf@texht@undeclaredcolor\fi}
+ \fi
+ \def\pgfutil@color{\pgfsetcolor}
+ % \ConfigureEnv{pgfpicture}{}{}{}{} there is no environment in plain TeX and this produces errors
+ % this might be needed for context or latex though....let me know !
+}%
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-textures.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-textures.def
new file mode 100644
index 0000000000..6f6163593d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-textures.def
@@ -0,0 +1,95 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-textures.def}
+
+\pgfutil@packagewarning
+ {pgfsys-textures.def}%
+ {This driver is deprecated and will be removed by the end of 2022.
+ Please switch to another TeX engine}
+
+% Driver commands for textures driver
+
+
+\def\pgfsys@invoke#1{\special{rawpostscript #1}}
+\def\pgf@sys@postscript@header#1{\special{prepostscript #1}}
+\def\pgf@sys@postscript@object#1{\special{rawpostscript #1}}
+
+
+%
+% Load common postscript commands:
+%
+\input pgfsys-common-postscript.def
+
+
+%
+% textures-specific stuff:
+%
+
+\def\pgfsys@beginpicture{%
+ \special{rawpostscript save}%
+ \special{rawpostscript save pgfgetcoords}%
+ \special{postscript}% here come the coordinates
+ \special{rawpostscript restore}%
+ \special{rawpostscript pgfbeginpicture}}
+\def\pgfsys@endpicture{\special{rawpostscript restore}}
+\def\pgfsys@hbox#1{%
+ \pgfsys@begin@idscope%
+ \pgfsys@invoke{save pgfbeginhbox}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \box#1%
+ \pgfsys@invoke{restore}%
+ \pgfsys@end@idscope%
+}
+\def\pgfsys@begininvisible{%
+ \special{rawpostscript gsave nulldevice}%
+}
+\def\pgfsys@endinvisible{%
+ \special{rawpostscript grestore}%
+}
+\def\pgfsys@color@unstacked#1{\special{rawpostscript \XC@usecolor{#1}}}
+
+\def\pgfsys@imagesuffixlist{.epsi:.eps:.ps:}
+
+\AtBeginDocument{
+ % Always present specials.
+ \special{prepostscript
+ /pgfsc{}bind def% stroke color is empty by default
+ /pgffc{}bind def% fill color is empty by default
+ /pgfe{moveto dup 0 rlineto exch 0 exch rlineto neg 0 rlineto closepath}bind def% rectangle
+ /pgfstr{stroke}bind def%
+ /pgffill{fill}bind def%
+ /pgfeofill{eofill}bind def%
+ /pgfw{setlinewidth}bind def% setlinewidth
+ /pgfgetcoords{/sps{globaldict begin /pgfgy exch def /pgfgx exch def
+ end pop pop}def/eps{}def userdict begin}bind def
+ /pgfbeginpicture{/pgfx pgfgx def /pgfy pgfgy def pgfx pgfy translate 1 1 72.27 72 div mul2 neg scale}bind def
+ /pgfbeginhbox{1 1 72 72.27 div mul2 neg scale
+ pgfx neg pgfy neg translate
+ pgffoa .setopacityalpha}bind def% save
+ /.setopacityalpha where {pop} {/.setopacityalpha{pop}def} ifelse % install .setopacityalpha
+ /.pgfsetfillopacityalpha{/pgffoa exch def
+ /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha
+ newpath fill grestore newpath}bind def
+ /pgfeofill{gsave pgffoa .setopacityalpha eofill1
+ .setopacityalpha newpath eofill grestore newpath}bind def}bind def
+ /.pgfsetstrokeopacityalpha{/pgfsoa exch def
+ /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore newpath}bind def}bind def
+ /pgffoa 1 def
+ /pgfsoa 1 def
+ }
+}
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-vtex.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-vtex.def
new file mode 100644
index 0000000000..a1b0bea98d
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-vtex.def
@@ -0,0 +1,110 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-vtex.def}
+
+\pgfutil@packagewarning
+ {pgfsys-vtex.def}%
+ {This driver is deprecated and will be removed by the end of 2022.
+ Please switch to another TeX engine}
+
+% Driver commands for vtex
+
+% Invoking things:
+\def\pgfsys@invoke#1{\special{pS: grestore #1 gsave}} % to protect against things happeing in between
+\def\pgfsys@outerinvoke#1{\special{pS: #1}}
+\def\pgf@sys@postscript@header#1{\immediate\special{pS: #1}}
+\def\pgf@sys@postscript@object#1{\immediate\special{pS: #1}}
+
+
+%
+% Load common postscript commands:
+%
+\input pgfsys-common-postscript.def
+
+
+%
+% vtex-specific stuff:
+%
+
+
+% Starting and ending a picture:
+\def\pgfsys@beginpicture{\special{pS:
+ save
+ /pgfx currentpoint /pgfy exch def def
+ currentpoint translate
+ gsave}%
+ \let\set@color=\pgf@sys@vtex@set@color%
+ \let\reset@color=\pgf@sys@vtex@reset@color%
+}
+\def\pgf@sys@vtex@setcolor#1{%
+ \pgfutil@colorlet{pgf@tempcolor}{#1}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}%
+ \expandafter\expandafter\expandafter\pgf@sys@vtex@@setcolor\csname\string\color@pgf@tempcolor\endcsname%
+}
+\def\pgf@sys@vtex@@setcolor#1#2#3#4#5{%
+ \pgfsysps@color@resetnow%
+ \expandafter\ifx\csname pgfsys@color@#4\endcsname\relax%
+ \pgferror{Unsupported color model `#4'. Sorry}%
+ \else%
+ \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4\endcsname}%
+ \pgf@uncomma#5,,%
+ \pgf@colmarshal%
+ \fi}
+\def\pgf@sys@vtex@set@color{\pgf@sys@vtex@setcolor{.}\aftergroup\reset@color}
+\def\pgf@sys@vtex@reset@color{\pgf@sys@vtex@setcolor{.}}
+\def\pgfsys@endpicture{\special{pS:
+ newpath
+ grestore
+ newpath
+ restore}}
+
+% Graphics:
+\def\pgfsys@imagesuffixlist{.epsi:.eps:.ps:.pdf:}
+
+% Starting and ending a box:
+\def\pgfsys@hbox#1{%
+ \pgfsys@invoke{save pgfx neg pgfy neg translate}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \box#1
+ \pgfsys@invoke{restore}%
+}
+
+\def\pgfsys@color@unstacked#1{\special{pS: \XC@usecolor{#1}}}
+
+\def\pgfsys@fill@opacity#1{\pgf@sys@fail{opacity}}
+\def\pgfsys@stroke@opacity#1{\pgf@sys@fail{opacity}}
+
+\AtBeginDocument{
+ % Always present specials.
+ \immediate\special{pS:
+ /pgfsc{} bind def% stroke color is empty by default
+ /pgffc{} bind def% fill color is empty by default
+ /pgfstr{stroke} bind def%
+ /pgffill{fill} bind def%
+ /pgfeofill{eofill} bind def%
+ /pgfe{moveto dup 0 rlineto exch 0 exch rlineto neg 0 rlineto closepath} bind def% rectangle
+ /pgfw{setlinewidth} bind def % setlinewidth
+ }
+}
+
+% vtex commands for changing the paper size
+\def\pgfsys@papersize#1#2{\mediawidth#1\mediaheight#2}
+
+
+
+
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys-xetex.def b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-xetex.def
new file mode 100644
index 0000000000..ce08194ce1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys-xetex.def
@@ -0,0 +1,79 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsys-xetex.def}
+
+\input pgfsys-dvipdfmx.def
+
+\def\pgfsys@dvipdfmx@patternobj#1{%
+ % I have NO idea why this is necessary for xdvipdfmx - but without
+ % it, it crashes.
+ \pgfutil@insertatbegincurrentpagefrombox{#1}%
+}%
+
+% XeTeX supports pdftex commands for paper size
+\def\pgfsys@papersize#1#2{%
+ \pdfpageheight#2\relax%
+ \pdfpagewidth#1\relax}
+
+\def\pgfsys@global@papersize#1#2{%
+ \global\pdfpageheight#2\relax%
+ \global\pdfpagewidth#1\relax}
+
+
+% Xetex does not support interpolate and not mask
+\def\pgfsys@defineimage{% width, height, page number
+ \ifx\includegraphics\undefined
+ \ifx\pgf@imagewidth\pgfutil@empty\edef\pgf@imagewidth{1bp}\fi% width?
+ \ifx\pgf@imageheight\pgfutil@empty\edef\pgf@imageheight{1bp}\fi% height?
+ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage}\fi%
+ \ifx\pgf@imageinterpolate\pgfutil@empty\else\edef\pgf@imageinterpolate{ /Interpolate\space\pgf@imageinterpolate}\fi%
+ \ifx\pgf@imagemask\pgfutil@empty\else\xdef\pgf@imagemask{ /SMask @\pgf@imagemask}\fi%
+ \edef\pgf@image{\noexpand\hbox to \pgf@imagewidth{\vbox to \pgf@imageheight{\vfil\special{pdf:image width \pgf@imagewidth\space height \pgf@imageheight\space\pgf@imagepage\space(\pgf@filename) <<\pgf@imageinterpolate\pgf@imagemask\space>>}}\hfil}}%
+ \else
+ \ifx\pgf@imagewidth\pgfutil@empty\else\edef\pgf@imagewidth{width=\pgf@imagewidth,}\fi%
+ \ifx\pgf@imageheight\pgfutil@empty\else\edef\pgf@imageheight{height=\pgf@imageheight,}\fi%
+ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{page=\pgf@imagepage,}\fi%
+ \edef\pgf@image{\noexpand\includegraphics[\pgf@imageheight\pgf@imagewidth\pgf@imagepage]{\pgf@filename}}%
+ \fi%
+}
+
+% XeTeX supports position tracking, now
+\def\pgfsys@markposition#1{%
+ \pdfsavepos%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutil@writetoaux\expandafter{%
+ \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}%
+}
+
+\def\pgfsyspdfmark#1#2#3{%
+ \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}%
+ \pgfutil@check@rerun{#1}{{#2}{#3}}%
+}
+
+\def\pgfsys@getposition#1#2{%
+ \edef\pgf@marshal{\let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname}%
+ \pgf@marshal%
+}
+
+\ifnum\the\XeTeXversion\expandafter\pgfutil@gobble\XeTeXrevision>0999991\relax
+ \def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{\hoffset}{\voffset}}
+\else
+ \def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{2\hoffset}{0pt}}
+\fi
+
+\ifx\paperheight\@undefined
+\else
+ \pdfpagewidth\paperwidth
+ \pdfpageheight\paperheight % this is to work around a positioning problem in xetex.
+\fi
+
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsys.code.tex b/graphics/pgf/base/tex/generic/systemlayer/pgfsys.code.tex
new file mode 100644
index 0000000000..a673297299
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsys.code.tex
@@ -0,0 +1,1775 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesPackageRCS{pgfsys.code.tex}
+
+
+% Load key mechanism
+\ifdefined\pgfkeysloaded\else
+ \input pgfkeys.code.tex
+\fi
+
+% "pgf" is a family
+\pgfkeys{/pgf/.is family}
+\def\pgfset{\pgfqkeys{/pgf}}
+
+% This if is needed *very* early
+\newif\ifpgfpicture
+
+
+%
+% The following conversion functions are used to convert from TeX
+% dimensions to postscript/pdf points.
+%
+{\catcode`\p=12\catcode`\t=12\gdef\Pgf@geT#1pt{#1}}
+
+\def\pgf@sys@tonumber#1{\expandafter\Pgf@geT\the#1}
+
+\def\pgf@sys@bp@correct#1{#1=0.99627#1}
+
+\def\pgf@sys@bp#1{%
+ {%
+ \pgf@x=#1\relax%
+ \pgf@x=0.99627\pgf@x%
+ \edef\temp{\expandafter\Pgf@geT\the\pgf@x\space}%
+ \pgfutil@toks@\expandafter\expandafter\expandafter{\expandafter\pgfsysprotocol@currentprotocol\temp}%
+ \xdef\pgfsysprotocol@currentprotocol{\the\pgfutil@toks@}%
+ }%
+}
+\def\pgf@sys@pt#1{%
+ {%
+ \pgf@x=#1\relax%
+ \edef\temp{\expandafter\Pgf@geT\the\pgf@x\space}%
+ \pgfutil@toks@\expandafter\expandafter\expandafter{\expandafter\pgfsysprotocol@currentprotocol\temp}%
+ \xdef\pgfsysprotocol@currentprotocol{\the\pgfutil@toks@}%
+ }%
+}
+
+
+% internal dimensions that are always present when pgsys is loaded.
+\newdimen\pgf@x
+\newdimen\pgf@y
+\newdimen\pgf@xa
+\newdimen\pgf@ya
+\newdimen\pgf@xb
+\newdimen\pgf@yb
+\newdimen\pgf@xc
+\newdimen\pgf@yc
+\newdimen\pgf@xd
+\newdimen\pgf@yd
+
+\newwrite\w@pgf@writea
+\newread\r@pgf@reada
+\let\pgfutil@inputcheck=\r@pgf@reada
+
+% internal counters that are always present when pgfsys is loaded
+\newcount\c@pgf@counta
+\newcount\c@pgf@countb
+\newcount\c@pgf@countc
+\newcount\c@pgf@countd
+
+\newtoks\t@pgf@toka
+\newtoks\t@pgf@tokb
+\newtoks\t@pgf@tokc
+
+% Ensure that math registers are the same (math is broken in case it
+% is loaded first)
+\let\pgfmath@x\pgf@x
+\let\pgfmath@xa\pgf@xa
+\let\pgfmath@xb\pgf@xb
+\let\pgfmath@xc\pgf@xc
+
+\let\pgfmath@y\pgf@y
+\let\pgfmath@ya\pgf@ya
+\let\pgfmath@yb\pgf@yb
+\let\pgfmath@yc\pgf@yc
+
+\let\c@pgfmath@counta\c@pgf@counta
+\let\c@pgfmath@countb\c@pgf@countb
+\let\c@pgfmath@countc\c@pgf@countc
+\let\c@pgfmath@countd\c@pgf@countd
+
+
+
+
+
+% In the following dummy definitions of the pgf system commands are
+% given. The individual drivers must overwrite these definitions,
+% preferably all of them. If some system command is used that has not
+% been overwritten, the command fails with a warning.
+%
+% In some cases, some pgf system commands are just shorthands for a
+% series of more complicated commands. In this case, a default
+% implementation is given in this file, but a driver may choose to
+% overwrite this default implementation with a more efficient
+% version. For example, a closestroke is the same as a closepath
+% followed by a stroking, but in pdf there is a special shorthand for
+% this. So, the pdf driver overwrites \pgfsys@closestroke, while the
+% postscript driver does not.
+%
+% The commands for which default implementations are available are
+% given at the end.
+
+\def\pgf@sys@fail#1{%
+ \expandafter\ifx\csname pgf@sys@fail@#1\endcsname\pgfutil@empty%
+ \else%
+ \expandafter\global\expandafter\let\csname pgf@sys@fail@#1\endcsname=\pgfutil@empty%
+ \pgfwarning{Your graphic driver \pgfsysdriver\space does not support #1. This warning is given only once}%
+ \fi%
+}
+
+
+
+%
+% Invocation commands
+%
+
+\def\pgfsys@invoke{\pgf@sys@fail{invoking specials}}
+% This command is used whenever some literal text needs to be inserted
+% into the resulting .pdf, .ps, or .dvi file. Note that most
+% \pgfsys@xxxx commands will not directly call this command, but,
+% rather, use the protocolling mechanism to record their literal
+% text. It is then left to the discretion of the protocolling
+% mechanism to insert the literal text at some appropriate, later
+% time.
+%
+% This command should only be called when \pgfsys@beginpicture has
+% been called previously and when the picture has not been suspended
+% using \pgfsys@beginhbox.
+
+\def\pgfsys@outerinvoke{\pgfsys@invoke}
+% This command can be used to insert protocolled graphic commands
+% outside any picture. This is extremely dangerous, but sometimes
+% useful. By default, this command does the same as inside pictures.
+
+
+
+%
+%
+% Path construction commands
+%
+%
+
+\def\pgfsys@moveto#1#2{\pgf@sys@fail{path constructions}}
+% This command is used to start a path at a specific point (#1,#2)
+% or to move the current point of the current path to (#1,#2)
+% without drawing anything upon stroking (the current path is
+% `interrupted').
+%
+% The arguments must be dimensions (like |10pt|).
+%
+% Example:
+%
+% \pgfsys@moveto{10pt}{10pt}
+% \pgfsys@lineto{0pt}{0pt}
+% \pgfsys@stroke
+%
+% This will draw a line from (10pt,10pt) to the origin of the picture.
+
+\def\pgfsys@lineto#1#2{\pgf@sys@fail{path constructions}}
+% Continue the current path to (#1,#2) with a line.
+
+\def\pgfsys@curveto#1#2#3#4#5#6{\pgf@sys@fail{path constructions}}
+% Continue the current path with a bezier curve to (#5,#6). The
+% control points of the curve are at (#1,#2) and (#3,#4).
+
+\def\pgfsys@rect#1#2#3#4{\pgf@sys@fail{path constructions}}
+% Append a rectangle to the current path whose lower left corner is at
+% (#1,#2) and whose width/height is given by (#3,#4).
+%
+% This command can be `mapped back' to moveto and lineto commands, but
+% it is included since pdf has a special, quick version of this command.
+
+\def\pgfsys@closepath{\pgf@sys@fail{path constructions}}
+% Close the current path. This results in joining the current point of
+% the path with the point specified by the last moveto
+% operation. Typically, this is preferable over using lineto to the
+% last point specified by a moveto, since the line starting at this
+% point and the line ending at this point will be smoothly joined by
+% closepath.
+%
+% Example:
+%
+% \pgfsys@moveto{0}{0}
+% \pgfsys@lineto{10}{10}
+% \pgfsys@lineto{0}{10}
+% \pgfsys@closepath
+% \pgfsys@stroke
+%
+% versus
+%
+% \pgfsys@moveto{0}{0}
+% \pgfsys@lineto{10}{10}
+% \pgfsys@lineto{0}{10}
+% \pgfsys@lineto{0}{0}
+% \pgfsys@stroke
+%
+% The difference between the above will be that in the second triangle
+% the corner at the origin will be wrong; it will just be the overlay
+% of two lines going in different directions, not a sharp pointed
+% corner.
+
+
+
+
+
+
+%
+%
+% Stroking and filling commands
+%
+%
+
+\def\pgfsys@stroke{\pgf@sys@fail{path usage}}
+% Stroke the current path (as if it were drawn with a pen). A number
+% of so-called graphic state parameters influence this, which can be
+% set in different ways:
+%
+% - linewidth
+% The `thickness' of the line. A width of 0 is the thinnest width
+% renderable on the device. On a high-resolution printer this may
+% become invisible and should be avoided. A good choice is 0.4pt,
+% which is the default.
+%
+% - stroke color
+% This special color is used for stroking. If it is not set, the
+% current color is used.
+%
+% - cap
+% The cap describes how the endings of lines a drawn. A round cap
+% adds a little half circle to these endings. A butt cap ends the
+% lines exactly at the end (or start) point without anything
+% added. A rectangular cap ends the lines like the butt cap, but the
+% lines protrude over the endpoint by the line thickness. (See also
+% the pdf or postscript manual). If the path has been closed, no cap
+% is drawn.
+%
+% - join
+% This describes how a bend (a join) in a path is rendered. A round
+% join draws bends using small arcs. A bevel join just draws the two
+% lines and then fills the join minimally so that it becomes
+% convex. A miter join extends the lines so that they form a single
+% sharp corner, but only up to a certain miter limit. (See the pdf
+% or postscript manual once more).
+%
+% - dash
+% The line may be dashed according to a dashing pattern.
+%
+% - clipping area
+% If a clipping area is established, only those parts of the path
+% that are inside the clipping area will be drawn.
+%
+% In addition to stroking a path, the path may also be used for
+% clipping after it has been stroked. This will happen if the
+% \pgfsys@clipnext is used prior to this command, see there for
+% details.
+
+\def\pgfsys@fill{\pgf@sys@fail{path usage}}
+% This command fills the area surrounded by the current path. If the
+% path has not yet been closed, it is closed prior to filling. The
+% path itself is not stroked. For self-intersecting paths or paths
+% consisting of multiple parts, the nonzero winding number rule is
+% used to determine whether a point is inside or outside the
+% path, except if \ifpgfsys@eorule holds -- in which case the even-odd
+% rule should be used. (See the pdf or postscript manual for details.)
+%
+% The following graphic state parameters influence the filling:
+%
+% - fill color
+% If the fill color is not especially set, the current color is
+% used.
+%
+% - clipping area
+% If a clipping area is established, only those parts of the filling
+% area that are inside the clipping area will be drawn.
+%
+% In addition to filling the path, the path will also be used for
+% clipping if \pgfsys@clipnext is used prior to this command.
+
+\def\pgfsys@fillstroke{\pgf@sys@fail{path usage}}
+% First, the path is filled, then the path is stroked. If the fill and
+% stroke colors are the same (or if they are not specified and the
+% current color is used), this yields almost the same as a
+% \pgfsys@fill. However, due to the line thickness of the stroked
+% path, the fillstroked area will be slightly larger.
+%
+% In addition to stroking and filling the path, the path will also be
+% used for clipping if \pgfsys@clipnext is used prior to this command.
+
+\def\pgfsys@clipnext{\pgf@sys@fail{path usage}}
+% This command should be issued after a path has been constructed, but
+% before it has been stroked and/or filled or discarded. When the
+% command is used, the next stroking/filling/discarding command will
+% first be executed normally. Then, afterwards, the just-used path
+% will be used for subsequent clipping. If there has already been a
+% clipping region, this region is intersected with the new clipping
+% path (the clipping cannot get bigger). The nonzero winding number
+% rule is used to determine whether a point is inside or outside the
+% clipping area or the even-odd rule, depending on whether
+% \ifpgfsys@eorule holds.
+
+\def\pgfsys@discardpath{\pgf@sys@fail{path usage}}
+% Normally, this command should `throw away' the current path.
+% However, after \pgfsys@clipnext has been called, the current path
+% should subsequently be used for clipping. See \pgfsys@clipnext for
+% details.
+
+\def\pgfsys@closestroke{\pgfsys@closepath\pgfsys@stroke}
+% This command should have the same effect as first closing the path
+% and then stroking it.
+
+\newif\ifpgfsys@eorule
+% Decides, whether even-odd filling and clipping is
+% to be used or normal the non-zero winding number rule. See the
+% pdf-documentation for details on what these rules are.
+
+
+
+
+%
+%
+% Stroking options
+%
+%
+\def\pgfsys@setlinewidth#1{\pgf@sys@fail{setting the line width}}
+% Sets the width of lines, when stroked, to #1, which must be a TeX
+% dimension (as text).
+
+\def\pgfsys@buttcap{\pgf@sys@fail{setting the line cap}}
+% Sets the cap to a butt cap. See \pgfsys@stroke.
+
+\def\pgfsys@roundcap{\pgf@sys@fail{setting the line cap}}
+% Sets the cap to a round cap. See \pgfsys@stroke.
+
+\def\pgfsys@rectcap{\pgf@sys@fail{setting the line cap}}
+% Sets the cap to a rectangular cap. See \pgfsys@stroke.
+
+\def\pgfsys@miterjoin{\pgf@sys@fail{setting the line join}}
+% Sets the join to a miter join. See \pgfsys@stroke.
+
+\def\pgfsys@setmiterlimit#1{\pgf@sys@fail{setting the line cap}}
+% Sets the miter limit of lines to #1. See the pdf or postscript
+% documentation.
+
+\def\pgfsys@roundjoin{\pgf@sys@fail{setting the line cap}}
+% Sets the join to a round join. See \pgfsys@stroke.
+
+\def\pgfsys@beveljoin{\pgf@sys@fail{setting the line cap}}
+% Sets the join to a bevel join. See \pgfsys@stroke.
+
+\def\pgfsys@setdash#1#2{\pgf@sys@fail{setting the dashing pattern}}
+% Sets the dashing patter. #1 should be a list of lengths separated by
+% commas. #2 should be a single dimension.
+%
+% The list of values in #1 is used to determine the lengths of the
+% `on' phases of the dashing and of the `off' phases. For example, if
+% #1 is `3pt,4pt', then the dashing pattern is `3pt on followed by 4pt
+% off, followed by 3pt on, followed by 4pt off, and so on'. A pattern
+% of `.5pt,4pt,3pt,1.5pt' means `.5pt on, 4pt off, 3pt on, 1.5pt off, .5pt on,
+% ...'. If the number of entries is odd, the last one is used twice,
+% so `3pt' means `3pt on, 3pt off, 3pt on, 3pt off,...'. An empty list
+% means `always on'.
+%
+% The second argument determines the `phase' of the pattern. For
+% example, for a pattern of `3pt,4pt' and a phase of `1pt', the pattern
+% would start: `2pt on, 4pt off, 3pt on, 4pt off, 3pt on, 4pt off...'.
+
+
+
+
+
+%
+%
+% Color stuff
+%
+%
+
+\def\pgfsys@color@rgb@stroke#1#2#3{\pgf@sys@fail{color}}
+% Sets the color used for stroking operations to the given rgb tuple
+% (numbers between 0 and 1).
+%
+% Example: Make stroked text dark red: \pgfsys@color@rgb@stroke{0.5}{0}{0}
+%
+% The special stroking color is only used if the stroking color has
+% been set since the last \pgfutil@color command. Thus, each \pgfutil@color command
+% should reset both the stroking and filling colors.
+
+\def\pgfsys@color@rgb@fill#1#2#3{\pgf@sys@fail{color}}
+% Sets the color used for filling operations to the given rgb tuple
+% (numbers between 0 and 1). This color may be different from the
+% stroking color.
+
+\def\pgfsys@color@rgb#1#2#3{\pgfsys@color@rgb@stroke{#1}{#2}{#3}\pgfsys@color@rgb@fill{#1}{#2}{#3}}
+% Sets the color used for filling and stroking operations. This is a
+% ``low-level'' version of the \pgfutil@color command. It is currently only
+% used by the plain tex version to support colors.
+
+\def\pgfsys@color@cmyk@stroke#1#2#3#4{\pgf@sys@fail{color}}
+% Sets the color used for stroking operations to the given cymk tuple
+% (numbers between 0 and 1).
+
+\def\pgfsys@color@cmyk@fill#1#2#3#4{\pgf@sys@fail{color}}
+% Sets the color used for filling operations to the given cymk tuple
+% (numbers between 0 and 1).
+
+\def\pgfsys@color@cmyk#1#2#3#4{\pgfsys@color@cmyk@stroke{#1}{#2}{#3}{#4}\pgfsys@color@cmyk@fill{#1}{#2}{#3}{#4}}
+% Sets the color used for filling and stroking operations.
+
+\def\pgfsys@color@cmy@stroke#1#2#3{\pgf@sys@fail{color}}
+% Sets the color used for stroking operations to the given cym tuple
+% (numbers between 0 and 1).
+
+\def\pgfsys@color@cmy@fill#1#2#3{\pgf@sys@fail{color}}
+% Sets the color used for filling operations to the given cym tuple
+% (numbers between 0 and 1).
+
+\def\pgfsys@color@cmy#1#2#3{\pgfsys@color@cmy@stroke{#1}{#2}{#3}\pgfsys@color@cmy@fill{#1}{#2}{#3}}
+% Sets the color used for filling and stroking operations.
+
+\def\pgfsys@color@gray@stroke#1{\pgf@sys@fail{color}}
+% Sets the color used for stroking operations to the given gray level
+% (number between 0 and 1).
+
+\def\pgfsys@color@gray@fill#1{\pgf@sys@fail{color}}
+% Sets the color used for filling operations to the given gray level
+% (number between 0 and 1).
+
+\def\pgfsys@color@gray#1{\pgfsys@color@gray@stroke{#1}\pgfsys@color@gray@fill{#1}}
+% Sets the color used for filling and stroking operations.
+
+\newif\ifpgfsys@color@reset@inorder
+% This if decides whether the color resetting of the
+% \pgfsys@color@reset command may assume that all color commands are
+% given ``in order.'' This means that this command will not be called,
+% say, at the beginning of a box that is later inserted at a point
+% where a fill color was actively set. This may allow the command to
+% produce more compact code when it ``knows'' that no special fill or
+% stroke color has been set.
+\pgfsys@color@reset@inordertrue
+
+
+\def\pgfsys@color@reset{}
+% This command will be called when the \pgfutil@color command is used. It
+% should purge any internal settings of stroking and filling
+% color. After this call, till the next use of a command like
+% \pgfsys@color@rgb@fill, the current color installed by the \pgfutil@color
+% command should be used.
+
+\def\pgfsys@color@unstacked#1{}
+% This slightly obscure command causes the color stack to be
+% tricked. When called, this command should set the current color to
+% #1 without causing any change in the color stack.
+
+\def\pgfsys@text@to@black@hook{}
+% Another slightly obscure command that allows tikz to hack into
+% dvisvgm's color management inside text nodes. The problem is that
+% the color "black" is special for dvisvgm.
+
+
+
+%
+%
+% Coordinate system transformations
+%
+%
+
+\def\pgfsys@transformcm#1#2#3#4#5#6{\pgf@sys@fail{transformations}}
+% Perform a concatenation of the low-level current transformation
+% matrix with the matrix given by the values #1 to #6. The
+% transformation matrix is a transformation on a homogeneous
+% 2D-coordinate system. See the pdf or postscript manual for details.
+
+\def\pgfsys@transformshift#1#2{\pgfsys@transformcm{1}{0}{0}{1}{#1}{#2}}
+% This command will change the origin of the low-level coordinate
+% system to (#1,#2).
+
+\def\pgfsys@transformxyscale#1#2{\pgfsys@transformcm{#1}{0}{0}{#2}{0bp}{0bp}}
+% This command will scale the low-level coordinate system (and
+% everything that is drawn) by a factor of #1 in x-directed and #2 in
+% y-direction. Note that this applies to everything, including
+% lines. So a scaled line will have a different width and may even
+% have a different width when going along the x-axis and when going
+% along the y-axis, if the scaling is different in these directions.
+
+\def\pgfsys@viewboxmeet#1#2#3#4#5#6#7#8{\pgfsys@beginscope\pgf@sys@default@viewbox@impl{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{<}}
+% Consider the two rectangles R with lower left corner
+% (#5,#6) and upper right (#7,#8) and S with lower left corner
+% (#1,#2) and upper right (#3,#4). Now, consider the transformation
+% that scales and translates R so that the result T has the same
+% center as S and has maximal size while still being inside S. This
+% transformation gets installed in a new graphics group, which must be
+% ended with a corresponding \pgfsys@endviewbox.
+
+\def\pgfsys@viewboxslice#1#2#3#4#5#6#7#8{\pgfsys@beginscope\pgf@sys@default@viewbox@impl{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{>}}
+% Works like \pgfsys@viewboxmeet, but R3 will have minimal size so
+% that in contains all of R2.
+
+\def\pgfsys@endviewbox{\pgfsys@endscope}
+% Ends a viewbox scope started by either of the previous two commands.
+
+
+\def\pgf@sys@default@viewbox@impl#1#2#3#4#5#6#7#8#9{{%
+ \pgf@x#1%
+ \pgf@y#2%
+ \pgf@xa#3%
+ \pgf@ya#4%
+ \advance\pgf@xa by-\pgf@x%
+ \advance\pgf@ya by-\pgf@y%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@ya}%
+ \let\aspectr\pgfmathresult%
+ \pgf@xb#5%
+ \pgf@yb#6%
+ \pgf@xc#7%
+ \pgf@yc#8%
+ \advance\pgf@xc by-\pgf@xb%
+ \advance\pgf@yc by-\pgf@yb%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@xc}{\pgf@sys@tonumber\pgf@yc}%
+ \let\aspects\pgfmathresult%
+ \ifdim\aspectr pt#9\aspects pt%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xc}%
+ \else%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@yc}%
+ \fi%
+ \advance\pgf@x by.5\pgf@xa%
+ \advance\pgf@xb by.5\pgf@xc%
+ \advance\pgf@y by.5\pgf@ya%
+ \advance\pgf@yb by.5\pgf@yc%
+ \pgfsys@transformcm{\pgfmathresult}{0}{0}{\pgfmathresult}{\pgf@x}{\pgf@y}%
+ \pgfsys@transformcm{1}{0}{0}{1}{-\pgf@xb}{-\pgf@yb}%
+ }%
+}
+
+
+
+
+%
+%
+% Graphic state saving and restoring.
+%
+%
+
+\def\pgfsys@beginscope{\pgf@sys@fail{scoping}}
+% Saves the current graphic state on a graphic state stack. All
+% changes to the graphic state parameters mentioned for \pgfsys@stroke
+% and \pgfsys@fill will be local to the current graphic state and will
+% the old values will be restored after endscope is used.
+%
+% WARNING: pdf and postscript differ with respect to the question of
+% whether the current path is part of the graphic state or not. For
+% this reason, you should never use this command unless the path is
+% currently empty. For example, it might be a good idea to use
+% discardpath prior to calling this command.
+
+\def\pgfsys@endscope{\pgf@sys@fail{scoping}}
+% Restores the last saved graphic state.
+
+\def\pgfsys@begin@idscope{%
+ \begingroup%
+ \edef\pgf@sys@cacheref{\pgfsys@id@refcurrent}%
+ \expandafter\let\expandafter\pgfsys@beg@save\csname pgf@sys@att@beg@\pgf@sys@cacheref\endcsname%
+ \expandafter\let\expandafter\pgfsys@end@save\csname pgf@sys@att@end@\pgf@sys@cacheref\endcsname%
+ \ifx\pgfsys@beg@save\relax%
+ \ifx\pgfsys@end@save\relax%
+ \else%
+ \pgfsys@call@save%
+ \fi%
+ \else%
+ \pgfsys@call@save%
+ \fi%
+ \pgfsys@invalidate@currentid%
+ \begingroup%
+}
+% Starts an "id scope" where the current value of \pgfsys@use@id and
+% \pgfsys@use@type is used. If the combination has been used before,
+% nothing happens. Otherwise, depending of the driver, a graphic
+% scope may or may not be created. To ensure that a graphic scope is
+% created, use \pgfsys@beginscope additionally.
+
+\def\pgfsys@call@save{%
+ \pgfsys@beginscope%
+ \pgfsys@beg@save%
+ \expandafter\global\expandafter\let\csname pgf@sys@att@beg@\pgfsys@id@refcurrent\endcsname\relax%
+ \expandafter\global\expandafter\let\csname pgf@sys@att@end@\pgfsys@id@refcurrent\endcsname\relax%
+}
+
+\def\pgfsys@end@idscope{
+ \endgroup%
+ \ifx\pgfsys@beg@save\relax%
+ \ifx\pgfsys@end@save\relax%
+ \else%
+ \pgfsys@call@end%
+ \fi%
+ \else%
+ \pgfsys@call@end%
+ \fi%
+ \endgroup
+}
+% Ends an id scope.
+
+\def\pgfsys@call@end{%
+ \pgfsys@end@save%
+ \pgfsys@endscope%
+}
+
+
+\def\pgfsys@begin@text{}
+% Inside a text box you should not use graphics command. However, TikZ
+% needs to insert some color commands at the beginnings of text
+% boxes. For most drivers, this is not a problem; except for SVG,
+% where every change of the graphics state opens a scope and needs a
+% closing scope. This command should be used at the beginning of text
+% boxes containing such color commands and the matching
+% \pgfsys@end@text at the end. If the box does not contain commands
+% that change the graphics state, this command is not needed.
+
+\def\pgfsys@end@text{}
+% Closes a \pgfsys@begin@text.
+
+
+
+%
+%
+% Id management (all of these commands have a default implementation
+% any typically need not be redefined by a driver)
+%
+%
+
+% The id count
+\newcount\pgf@sys@id@count
+
+\def\pgfsys@new@id#1{%
+ \edef#1{pgf\the\pgf@sys@id@count}%
+ \global\advance\pgf@sys@id@count by1\relax%
+}
+% Creates a new id and stores it in the macro #1.
+
+\def\pgfsys@use@id#1{%
+ \edef\pgf@sys@id@current@id{#1}%
+ \let\pgfsys@current@type\pgfutil@empty%
+}
+\let\pgf@sys@id@current@id\pgfutil@empty
+% Sets the id to be used for the next graphic object (group, box, or
+% path). The type is reset to be empty. #1 must be a macro name that
+% has previously been set using \pgfsys@new@id.
+%
+% Each combination of id and type can be used only once, on a second
+% use nothing happens.
+
+\def\pgfsys@clear@id{%
+ \let\pgf@sys@id@current@id\pgfutil@empty%
+}
+% Clears the current id, so nothing can be referenced.
+
+\def\pgfsys@use@type#1{%
+ \edef\pgfsys@current@type{#1}%
+ \pgfsys@register@type\pgfsys@current@type%
+}
+\let\pgfsys@current@type\pgfutil@empty
+% Sets the type to be used for the next graphic object.
+
+\def\pgfsys@append@type#1{%
+ \ifx\pgfsys@current@type\pgfutil@empty%
+ \pgfsys@use@type{#1}%
+ \else%
+ \pgfsys@use@type{\pgfsys@current@type.#1}%
+ \fi%
+}
+% Appends something to the current type
+
+\def\pgfsys@register@type#1{%
+ \expandafter\let\expandafter\pgf@sys@temp\csname pgf@sys@reg@type@#1\endcsname%
+ \ifx\pgf@sys@temp\relax%
+ {%
+ \c@pgf@counta\pgf@sys@type@count\relax%
+ \global\advance\c@pgf@counta by1\relax%
+ \edef\pgf@sys@type@count{\the\c@pgf@counta}%
+ \expandafter\xdef\csname pgf@sys@reg@type@#1\endcsname{y\the\c@pgf@counta}%
+ }%
+ \fi%
+}
+% Registers a type with the system. Must be called before any use of
+% the type
+\def\pgf@sys@reg@type@{}
+\def\pgf@sys@reg@type@background{b}
+\def\pgf@sys@reg@type@path{p}
+\def\pgf@sys@reg@type@text{t}
+\expandafter\def\csname pgf@sys@reg@type@background.path\endcsname{bp}
+\def\pgf@sys@type@count{0}
+
+\def\pgfsys@push@type{%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@sys@typestack%
+ \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfsys@current@type%
+ \expandafter\expandafter\expandafter{\expandafter\pgfsys@current@type\expandafter}%
+ \expandafter\def\expandafter\pgf@sys@typestack\expandafter{\pgf@sys@typestack}}%
+}
+\let\pgf@sys@typestack\pgfutil@empty
+% Pushes the current type onto a global stack. This is useful for
+% temporarily changing the type without creating \TeX scopes.
+
+\def\pgfsys@pop@type{\pgf@sys@typestack}
+% Pops the last id from the stack.
+
+\def\pgfsys@id@ref#1#2{#1\csname pgf@sys@reg@type@#2\endcsname}
+% Expands to a text that can be inserted as a reference. #1 must be a
+% reference created \pgfsys@new@id, #2 must be a type that has been
+% registered using \pgfsys@id@register@type.
+
+\def\pgfsys@id@refcurrent{\pgfsys@id@ref{\pgf@sys@id@current@id}{\pgfsys@current@type}}
+% Expands to a text that can be inserted as a reference to the current
+% id-type pair in use.
+
+\def\pgfsys@invalidate@currentid{%
+ \expandafter\global\expandafter\let\csname pgf@sys@id@keylist@\pgfsys@id@refcurrent\endcsname\pgfutil@empty%
+}
+% Mark the current id-type pair as used.
+
+\def\pgfsys@attach@to@id#1#2#3#4{%
+ \pgfsys@register@type{#2}%
+ \expandafter\def\expandafter\pgf@sys@tempbeg\expandafter{\csname pgf@sys@att@beg@\pgfsys@id@ref{#1}{#2}\endcsname}%
+ \expandafter\def\expandafter\pgf@sys@tempend\expandafter{\csname pgf@sys@att@end@\pgfsys@id@ref{#1}{#2}\endcsname}%
+ \expandafter\ifx\pgf@sys@tempbeg\relax%
+ \expandafter\let\pgf@sys@tempbeg\pgfutil@empty%
+ \fi%
+ \expandafter\ifx\pgf@sys@tempend\relax%
+ \expandafter\let\pgf@sys@tempend\pgfutil@empty%
+ \fi%
+ \expandafter\let\expandafter\pgf@sys@tempbeg@cont\pgf@sys@tempbeg%
+ \expandafter\let\expandafter\pgf@sys@tempend@cont\pgf@sys@tempend%
+ \expandafter\expandafter\expandafter\gdef\expandafter\pgf@sys@tempbeg\expandafter{\pgf@sys@tempbeg@cont#3}%
+ \def\pgf@sys@temp{#4}%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\pgf@sys@tempend\expandafter\expandafter\expandafter{\expandafter\pgf@sys@temp\pgf@sys@tempend@cont}%
+}
+% Attaches some code to an id-type pair so that when the id's scope
+% gets created, #3 is added at the beginning and #4 is added at the
+% end.
+
+\def\pgfsys@if@fresh@id#1#2#3#4{%
+ \edef\pgf@sys@temp{#1}%
+ \ifx\pgf@sys@temp\pgfutil@empty% empty id always counts as "has been used"
+ #4%
+ \else%
+ \pgfsys@register@type{#2}%
+ \expandafter\ifx\csname pgf@sys@id@keylist@\pgfsys@id@ref{#1}{#2}\endcsname\pgfutil@empty%
+ % has already been used!
+ #4%
+ \else%
+ #3%
+ \fi%
+ \fi%
+}
+% Checks whether a given id-type pair #1-#2 has not been used, yet. If
+% so, #3 is executed, otherwise #4.
+
+\def\pgfsys@if@fresh@currentid#1#2{%
+ \ifx\pgf@sys@id@current@id\pgfutil@empty% empty id always counts as "has been used"
+ #2%
+ \else%
+ \expandafter\ifx\csname pgf@sys@id@keylist@\pgfsys@id@refcurrent\endcsname\pgfutil@empty%
+ % has already been used!
+ #2%
+ \else%
+ #1%
+ \fi%
+ \fi%
+}
+% Checks whether the current id-type pair in use has not been used,
+% yet. If so, #1 is executed, otherwise #2.
+
+
+
+
+%
+%
+% Special commands
+%
+%
+
+\def\pgfsys@imagesuffixlist{}
+% A list of suffixes, separated by `:', that will be tried when
+% searching for an image.
+
+
+
+%
+%
+% Transparency
+%
+%
+
+\def\pgfsys@opacity#1{\pgfsys@stroke@opacity{#1}\pgfsys@fill@opacity{#1}}
+% Ideally, this should sets the opacity of all operations, treating
+% the group as a transparency group with 1 meaning fully opaque, 0
+% meaning fully transparent. Since most drivers do not support this,
+% the fallback is to set the stroke and fill opacity at the same
+% time. This is not quite the same, however.
+
+\def\pgfsys@stroke@opacity#1{\pgf@sys@fail{opacity}}
+% Sets the opacity of stroking operations. 1 means fully opaque, 0
+% means fully transparent.
+
+\def\pgfsys@fill@opacity#1{\pgf@sys@fail{opacity}}
+% Sets the opacity of filling operations. 1 means fully opaque, 0
+% means fully transparent.
+
+\def\pgfsys@transparencygroupfrombox#1{\pgf@sys@fail{transparency groups}}
+% This takes a TeX box and converts it into a transparency
+% group. This means that any transparency settings apply to the box as
+% a whole. For instance, if a box contains two overlapping black
+% circles and you draw them normally with 50% transparency, then the
+% overlap will be darker than the rest. By comparison, if the circles
+% are part of a transparency group, the overlap will get the same
+% color as the rest.
+%
+% The following settings modify the behaviour of a transparency group:
+
+\newif\ifpgfsys@transparency@group@isolated
+\newif\ifpgfsys@transparency@group@knockout
+
+
+\def\pgfsys@blend@mode#1{\pgf@sys@fail{blend mode}}
+% Sets the current blend mode. See the PDF specification for details
+% on blend modes.
+
+
+\def\pgfsys@definemask{\pgf@sys@fail{image masks}}
+% This command declares a mask for usage with images. It works similar
+% to \pgfsys@defineimage: Certain macros are set when the command is
+% called. The result should be to set the macro \pgf@mask to a pdf
+% object count that can subsequently be used as a soft mask. The
+% following macros will be set when this command is invoked:
+%
+% - \pgf@filename
+% File name of the mask to be defined.
+%
+% - \pgf@maskmatte
+% The so-called matte of the mask (see the pdf documentation for
+% details). The matte is a color specification consisting of 1, 3 or
+% 4 numbers between 0 and 1. The number of numbers depends on the
+% number of color channels in the image (not in the mask!). It will
+% be assumed that the image has been preblended with this color.
+
+\def\pgfsys@fadingfrombox#1#2{\pgf@sys@fail{fadings}}
+% Declares an fading named #1. The parameter #2 must be a
+% box. Its contents luminosity determines the opacity of the resulting
+% mask.
+
+\def\pgfsys@usefading#1#2#3#4#5#6#7{\pgf@sys@fail{fadings}}
+% Installs a previously declared fading #1 in the current graphics
+% state. Parameters #2 to #7 specify a transformation cm that should
+% be applied to the mask before it is used.
+
+\def\pgfsys@clipfading{}
+% This default implementation is a no-op for all drivers except `dvips'
+% where we have to set the clipping path _before_ installing the fading (used in
+% \pgfsetfadingforcurrentpath, \pgfsetfadingforcurrentpathstroked commands of
+% the basic layer)
+
+
+%
+%
+% Shading commands
+%
+%
+
+\def\pgfsys@horishading#1#2#3{\pgf@sys@fail{shadings}\pgf@sys@noshading{#1}}
+% Declares a horizontal shading for later use. The effect of this
+% command should be the definition of a macro called `@pgfshading#1!'
+% (or \csname @pdfshading#1!\endcsname, to be precise). When invoked,
+% this new macro should insert a shading at the current position.
+%
+% #1 is the name of the shading, which is also used in the output
+% macro name. #2 is the height of the shading and must be given as a
+% TeX dimension like `2cm' or `10pt'. #3 is a shading color
+% specification as specified in the pgfuserguide. The shading
+% specification implicitly fixes the width of the shading.
+%
+% When `@pgfshading#1!' is invoked, it should insert a box of height
+% #2 and the width implicit in the shading declaration.
+
+\def\pgfsys@vertshading#1#2#3{\pgf@sys@fail{shadings}\pgf@sys@noshading{#1}}
+% Like horishading, only for vertical shadings. This time, the height
+% of the shading is implicit in #3 and the width is given as #2.
+
+\def\pgfsys@radialshading#1#2#3{\pgf@sys@fail{shadings}\pgf@sys@noshading{#1}}
+% Declares a radial shading. Like the previous macros, this command
+% should setup the macro `@pgfshading#1!', which upon invocation
+% should insert a radial shading whose size is implicit in #3.
+%
+% The parameter #2 is a pgf point specification if the starting point
+% of the shading. See the pgfuserguide for details.
+
+\def\pgfsys@functionalshading#1#2#3#4{\pgf@sys@fail{shadings (functional)}\pgf@sys@noshading{#1}}
+% Declares a shading using a PostScript-like function that provides a
+% color for each point. Like the previous macros, this command
+% should setup the macro `@pgfshading#1!' so that it will produce a
+% box containing the desired shading.
+%
+% Parameter #1 is the name of the shading. Parameter #4 is a
+% Postscript-like function (type 4 function of the PDF specification)
+% as described in Section 3.9.4 of the PDF Specification version 1.7.
+% Parameter #2 and #3 are pgf point specifications that specifies the
+% lower left and upper right coordinate.
+%
+% When function #4 is evaluated, the coordinate of the current
+% point will be on the (virtual) PostScript stack in bp units. After
+% the function has been evaluated, the stack should consist of three
+% numbers (not integers! - the Apple PDF renderer is broken in this
+% regard, so add cvr's at the end if needed) that represent the red,
+% green, and blue components of the color.
+%
+% A buggy #4 will result is *totally unpredictable chaos* during
+% rendering.
+
+\def\pgf@sys@noshading#1{\expandafter\global\expandafter\let\csname @pgfshading#1!\endcsname=\pgfutil@empty}
+
+
+
+
+%
+%
+% Pattern stuff
+%
+%
+
+\def\pgfsys@declarepattern#1#2#3#4#5#6#7#8#9{\pgf@sys@fail{patterns}}
+% This command declares a new colored or uncolored pattern. Uncolored
+% patterns have no inherent color, the color is provided when they are
+% set. Colored patters have an inherent color.
+% #1 = name of the pattern (must be a plain suffix for use in
+% postscript/pdf/etc.)
+% #2 to #5 = four coordinates describing the corners of a bounding box
+% of pattern cells
+% #6 = x-step
+% #7 = y-step
+% #8 = pattern code
+% #9 = 0 if uncolored patter, 1 if colored pattern.
+
+\def\pgfsys@setpatternuncolored#1#2#3#4{\pgf@sys@fail{patterns}}
+% Sets an uncolored pattern #1 as filling color. The numbers #2, #3,
+% #4 must be an rgb-value to be used as the color of the pattern.
+
+\def\pgfsys@setpatterncolored#1{\pgf@sys@fail{patterns}}
+% Sets an colored pattern #1 as filling color.
+
+
+
+
+
+%
+%
+% Animations
+%
+%
+
+
+\newif\ifpgfsysanimationsupported
+% Will be set to true by a driver when animations are supported. Note
+% that snapshots are always supported.
+
+
+\def\pgfsys@animate#1{\pgf@sys@fail{animations}}
+% Adds an animation of the attribute #1 to the current scope.
+% The configuration of the animation (like start times, etc.) is taken
+% from the current values of the animation keys, which are configured
+% using calls to \pgfsys@animation@..., which setup an animation
+% key for the local scope. This means that you typically setup these
+% keys in a scope and at the end of the scope call \pgfsys@animate.
+%
+% Some keys accumulate (like begin or keytime), most do not. In those
+% cases, the last call overrides the previous one.
+%
+% Not all value types make sense or are allowed, it depends on the
+% specific \pgfsys@animate call.
+%
+% Example:
+%
+% {
+% \pgfsys@animation@offset{10}{begin}%
+% \pgfsys@animation@event{}{click}{1}{begin}%
+% \pgfsys@animation@time{5}{1}{1}{0}{0}
+% \pgfsys@animation@val@scalar{1}
+% \pgfsys@animation@time{8}{1}{1}{0}{0}
+% \pgfsys@animation@val@scalar{0.5}
+% \pgfsys@animation@sum%
+% \pgfsys@animate{fillopacity}%
+% }
+%
+% When a driver does not support a specific attribute #1, it should
+% issue a \pgf@sys@fail. Typical attributes are things like "opacity"
+% or "linewidth" or "dash".
+%
+% The following values are permissible for "#1":
+%
+% "opacity" adds an animation of the opacity.
+% Type: scalar
+%
+% "fillopacity" adds an animation of the fill opacity.
+% Type: scalar
+%
+% "strokeopacity" adds an animation of the stroke opacity.
+% Type: scalar
+%
+% "visibility" adds an animation of the visibility.
+% Type: text ("visible" or "hidden")
+%
+% "linewidth" adds an animation of the line width.
+% Type: dimension
+%
+% "dash" adds an animation of the dash.
+% Type: dash
+%
+% "translate" adds an animation of the transformation.
+% Type: translate
+%
+% "scale" adds an animation of the transformation.
+% Type: scale
+%
+% "rotate" adds an animation of the transformation.
+% Type: scalar
+%
+% "skewx" adds an animation of the transformation.
+% Type: scalar
+%
+% "skewy" adds an animation of the transformation.
+% Type: scalar
+%
+% "motion" adds a movement along a path.
+% Type: motion
+%
+% "strokecolor" adds an animation of the stroke color.
+% Type: color
+%
+% "fillcolor" adds an animation of the fill color.
+% Type: color
+%
+% "viewbox" adds an animation of the view box.
+% Type: view box
+%
+% "path" adds an animation of the path to the path specified by
+% \pgfsys@animation@whom
+% Type: path
+%
+% "syncbase" adds a sync base to the animation. A sync base does not animate
+% anything by itself, but other animations can begin and end relative
+% to it.
+%
+% "none" suppresses the animation
+% Type: any
+
+
+
+
+% Animation timing :
+%
+% You specify an animation using a timeline. A timeline consists of a
+% sequence of times together with values for these times. The times
+% must be given in increasing order. You use the command
+% \pgfsys@animation@time to specify a time and
+% \pgfsys@animation@val@... to specify a value. The time must be
+% specified first, the time--value is created when the value command is
+% used.
+%
+% Times are given in seconds (so 0.01 is one hundredth of a second).
+%
+% The animation's timeline will start with the first time mentioned
+% (not necessarily zero and not necessarily a positive value) and ends
+% with the last value. The duration is the difference between these
+% two values.
+
+\def\pgfsys@animation@restart@always{}
+% Specifies that the animation can always restart
+
+\def\pgfsys@animation@restart@never{}
+% Specifies that the animation should never restart
+
+\def\pgfsys@animation@restart@whennotactive{}
+% Specifies that the animation should only restart when it is not active
+
+\def\pgfsys@animation@repeat#1{}
+% #1 must be a number
+
+\def\pgfsys@animation@repeat@indefinite{}
+% Repeats forever
+
+\def\pgfsys@animation@repeat@dur#1{}
+% #1 must be a clock value
+
+\def\pgfsys@animation@freezeatend{}
+% Specifies that the last value of the animation remains in force at
+% the end
+
+\def\pgfsys@animation@removeatend{}
+% Specifies that the effect of the animation is removed at the end
+
+\def\pgfsys@animation@time#1#2#3#4#5{}
+% Specifies a time together with spline control points for the entry
+% and the exit to this time. The value #1 is a time in seconds (so 60
+% means 1 minute, 0.001 means one millisecond). The values #2 and #3
+% specify the control point of the spline *entering* the time point,
+% while the values #4 and #5 specify the control point of the spline
+% *leaving* the time point. They are all dimensionless values between
+% 0 and 1. For a linear animation, set the first two to 1 and the last
+% two to 0.
+%
+% Example:
+% \pgfsys@animation@time{5}{1}{1}{0.25}{0.1}
+% \pgfsys@animation@val@scalar{80}
+% \pgfsys@animation@time{8}{.75}{1}{0}{0}
+% \pgfsys@animation@val@scalar{90}
+%
+% In SVG, this will create the following entries:
+% begin = +5s
+% duration = 3s
+% keyTimes = 0;1
+% values = 80;90
+% keySpline = 0.25 0.1 0.75 1
+%
+% For the key spline, note that the entry spline controls of the first
+% time and the exit spline controls of the last point are dropped.
+%
+%
+% When the exit spline takes the special values #4="stay" and #5="0",
+% the attribute's value "stays" until the next value for the next time
+% (it "jumps" to the next value then). This corresponds, roughly, to
+% an "infinite" #4.
+%
+% Similarly, when the entry spline takes the special value #2="jump"
+% and #3="1", the value immediately jumps from the previous value to
+% the next value when the previous value was "created".
+
+\def\pgfsys@stay@text{{stay}{0}}
+\def\pgfsys@jump@text{{jump}{1}}
+
+\def\pgfsys@animation@base{}
+% Think of this command as setting the value of the attribute in the
+% timeline before the timeline starts. Normally, an animation only
+% influences the timeline while the animation is running (which may be
+% forever) and before and after the animation is running, the
+% attribute's value is not modified by the animation (so, it is just
+% inherited from the surrounding scope). When a base value is set,
+% while the animation is not running, this value is used. For most
+% attributes you can achieve the same effect by surrounding the
+% to-be-animated object by a scope and setting the value there, but
+% using bases is often more convenient and, for instance for the
+% visibility attribute, it is necessary to use a base.
+%
+% Note that when a backend driver does not support animations, base
+% values will not be depicted unless a snapshot is used explicitly.
+
+\def\pgfsys@animation@offset#1#2{}
+% #1 must be a value in seconds, #2 is the target "begin" or "end" to
+% which this offset is appended.
+
+\def\pgfsys@animation@syncbegin#1#2#3#4{}
+% #1 is the id of a sync base (obtained by
+% \pgfsys@new@id), #2 is the id type (or empty), #3 is an optional
+% offset, #4 is the target.
+
+\def\pgfsys@animation@syncend#1#2#3#4{}
+% Like the previous command.
+
+\def\pgfsys@animation@event#1#2#3#4#5{}
+% #1 is the optional id of another element (obtained by
+% \pgfsys@new@id), #2 is the optional type of the id, #3 is an event
+% name, #4 is an optional offset, #5 is the target.
+
+\def\pgfsys@animation@repeat@event#1#2#3#4#5{}
+% #1 is the optional id of another element, #2 is the type, #3 is a
+% repeat count, and #4 is an optional offset, #5 is the target.
+
+\def\pgfsys@animation@accesskey#1#2#3{}
+% #1 is a character, #2 is an optional offset, #3 is the target.
+
+\def\pgf@sys@begin@text{begin}
+
+
+% Accumulation
+
+\def\pgfsys@animation@accumulate{}
+% Corresponds to accumulate="sum" in SVG
+
+\def\pgfsys@animation@noaccumulate{}
+% Corresponds to accumulate="none" in SVG
+
+
+% Targeting
+
+\def\pgfsys@animation@whom#1#2{}
+% Sets the target of the animation. #1 must be an id previously
+% created using \pgfsys@new@id and #2 must be empty or a type
+% previously created using \pgfsys@new@id@type
+
+
+% Attribute definitions
+
+\def\pgfsys@animation@rotatealong{}
+% Applicable only to motion animations. Indicates that the
+% to-be-animated group should be rotated automatically so that it
+% points along the path as time progresses.
+
+\def\pgfsys@animation@norotatealong{}
+% Corresponds to rotate="0"
+
+\def\pgfsys@animation@movealong#1{}
+% Applicable only to motion animations. #1 is a softpath along which
+% the movement will be done.
+
+\def\pgfsys@animation@tip@markers#1#2{}
+% Applicable only to path animations. #1 and #2 are markers (declared
+% using \pgfsys@marker@declare) that store marker symbols to be added
+% at the start and at the end of the to-be-animated path. If empty, no
+% markers are added.
+
+\def\pgfsys@animation@canvas@transform#1#2{}
+% #1 is some code that may call \pgfsys@transformcm at most once. It
+% will be executed when a canvas transformation animation is
+% installed for a scope id. #2 is some further codes that may also
+% call \pgfsys@transformcm at most once. It will be installed right
+% after the animation.
+%
+% Typically, #1 is some pgf coordinate shift followed by
+% {\pgflowlevelsynccm} and #2 is \pgftransforminvert followed by
+% \pgflowlevelsynccm.
+
+
+
+% Values
+
+\def\pgfsys@animation@val@current{}
+% The current value of the attribute. At least with SVG, this can only
+% be used for the first value and, then, only if there is only one
+% other value.
+
+\def\pgfsys@animation@val@text#1{}
+% #1 should be some text.
+
+\def\pgfsys@animation@val@scalar#1{}
+% #1 should be a single value.
+
+\def\pgfsys@animation@val@dimension#1{}
+% #1 must be a dimension.
+
+\def\pgfsys@animation@val@color@rgb#1#2#3{}
+% #1,#2,#3 must be an rgb tuple
+
+\def\pgfsys@animation@val@color@cmyk#1#2#3#4{}
+% #1,#2,#3,#4 must be an cmyk tuple
+
+\def\pgfsys@animation@val@color@cmy#1#2#3{}
+% #1,#2,#3 must be an cmy tuple
+
+\def\pgfsys@animation@val@color@gray#1{}
+% #1 must be a gray value
+
+\def\pgfsys@animation@val@path#1{}
+% #1 must consist of path-construction tokens (as returned by the
+% softpath layer)
+
+\def\pgfsys@animation@val@translate#1#2{}
+% #1,#2 must be dimensions
+
+\def\pgfsys@animation@val@scale#1#2{}
+% #1,#2 must be dimensionless
+
+\def\pgfsys@animation@val@viewbox#1#2#3#4{}
+% #1,#2 describe the lower left, #3,#4 the upper right corner of the
+% view box.
+
+\def\pgfsys@animation@val@dash#1#2{}
+% #1,#2 have the syntax of \pgfsys@setdash.
+
+
+
+%
+%
+% Markers
+%
+%
+
+\def\pgfsys@marker@declare#1#2{%
+ {%
+ \pgfpicturetrue%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@marker@temp%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsys@beginscope%
+ #2%
+ \pgfsys@endscope%
+ \xdef#1{\the\pgf@sys@id@count}%
+ \expandafter\expandafter\expandafter\global\expandafter\pgfsysprotocol@getcurrentprotocol\csname pgf@sys@marker@prot@#1\endcsname%
+ \pgfsys@marker@declare@% curtesy hook
+ \pgfsysprotocol@setcurrentprotocol\pgfsys@marker@temp%
+ \global\advance\pgf@sys@id@count by1\relax%
+ }%
+}
+\let\pgfsys@marker@declare@\relax
+% Declares a new marker symbol whose code is in #2. #1 should be a
+% macro name, which will be set to a unique
+% value by which the marker can be referenced later on. #2 should be
+% code that, when executed, produces recordable code.
+
+\def\pgfsys@marker@use#1{%
+ \pgfsysprotocol@literal{\csname pgf@sys@marker@prot@#1\endcsname}%
+}
+% Draws the marker symbol not at the end of a path, but simply with
+% the current transformation matrix
+
+
+
+
+
+
+%
+%
+% RDF
+%
+%
+
+\def\pgfsys@rdf@about#1{\pgf@sys@fail{rdf}}
+% Adds the rdf attribute "about" with value #1 to the next
+% idscope. The RDF-spec says: "a SafeCURIEorCURIEorIRI, used for
+% stating what the data is about (a 'subject' in RDF terminology);"
+
+\def\pgfsys@rdf@content#1{\pgf@sys@fail{rdf}}
+% Adds the rdf attribute content with value #1 to the next
+% idscope. The RDF-spec says: "a CDATA string, for supplying
+% machine-readable content for a literal (a 'literal object', in RDF
+% terminology);"
+
+\def\pgfsys@rdf@datatype#1{\pgf@sys@fail{rdf}}
+% Adds the rdf attribute datatype with value #1 to the next
+% idscope. The RDF-spec says: "a TERMorCURIEorAbsIRI representing a
+% datatype, to express the datatype of a literal;"
+
+\def\pgfsys@rdf@href#1{\pgf@sys@fail{rdf}}
+% Adds the rdf attribute href with value #1 to the next idscope
+% The RDF-spec says: "a traditionally navigable IRI for
+% expressing the partner resource of a relationship (a 'resource
+% object', in RDF terminology);"
+
+\def\pgfsys@rdf@inlist{\pgf@sys@fail{rdf}}
+% Adds the rdf attribute inlist to the next idscope. The
+% RDF-spec says: "An attribute used to indicate that the object
+% associated with a rel or property attribute on the same element is
+% to be added to the list for that predicate. The value of this
+% attribute must be ignored. Presence of this attribute causes a list
+% to be created if it does not already exist."
+
+\def\pgfsys@rdf@prefix#1{\pgf@sys@fail{rdf}}
+% Adds #1 to the list of the rdf prefix attribute to the next
+% idscope. Can be called several times, in which case all values of #1
+% are concatenated with whitespaces. The RDF-spec says: "a white space
+% separated list of prefix-name IRI pairs of the form NCName ':' ' '+
+% xsd:anyURI"
+
+\def\pgfsys@rdf@property#1{\pgf@sys@fail{rdf}}
+% Adds #1 to the list of the rdf property attribute to the next
+% idscope. Can be called repeatedly. The RDF-spec says: "a white space
+% separated list of TERMorCURIEorAbsIRIs, used for expressing
+% relationships between a subject and either a resource object if
+% given or some literal text (also a 'predicate');"
+
+\def\pgfsys@rdf@rel#1{\pgf@sys@fail{rdf}}
+% Adds #1 to the list of the rdf rel attribute to the next
+% next idscope. Can be called repeatedly. The
+% RDF-spec says: "a white space separated list of
+% TERMorCURIEorAbsIRIs, used for expressing relationships between two
+% resources ('predicates' in RDF terminology);"
+
+\def\pgfsys@rdf@resource#1{\pgf@sys@fail{rdf}}
+% Adds the rdf attribute resource with value #1 to the next idscope. The
+% RDF-spec says: "a SafeCURIEorCURIEorIRI for expressing the partner
+% resource of a relationship that is not intended to be navigable
+% (e.g., a 'clickable' link) (also an 'object');"
+
+\def\pgfsys@rdf@rev#1{\pgf@sys@fail{rdf}}
+% Adds #1 to the list of the rdf rev attribute to the next
+% idscope. Can be called repeatedly. The
+% RDF-spec says: "a white space separated list of
+% TERMorCURIEorAbsIRIs, used for expressing reverse relationships
+% between two resources (also 'predicates');
+
+\def\pgfsys@rdf@src#1{\pgf@sys@fail{rdf}}
+% Adds an rdf attribute src with value #1 to the next idscope. The
+% RDF-spec says: "an IRI for expressing the partner resource of a
+% relationship when the resource is embedded (also a 'resource
+% object');"
+
+\def\pgfsys@rdf@typeof#1{\pgf@sys@fail{rdf}}
+% Adds #1 to the list of the rdf typeof attribute to the next
+% idscope. Can be called repeatedly. The
+% RDF-spec says: "a white space separated list of TERMorCURIEorAbsIRIs
+% that indicate the RDF type(s) to associate with a subject;"
+
+\def\pgfsys@rdf@vocab#1{\pgf@sys@fail{rdf}}
+% Adds an rdf attribute vocab with value #1 to the next idscope. The
+% RDF-spec says: "an IRI that defines the mapping to use when a TERM
+% is referenced in an attribute value. See General Use of Terms in
+% Attributes and the section on Vocabulary Expansion."
+
+
+
+%
+%
+% Page size stuff
+%
+%
+
+\def\pgfsys@papersize#1#2{\pgf@sys@fail{papersize}}
+% This command sets the paper size in a portable way. It tries to do
+% so "locally" for the current page, but what really happens depends
+% strongly on the driver. For instance, dvips will use whatever is
+% used with the first call to this command that is part of the
+% shipped-out document and will ignore all other uses. In contrast,
+% pdftex will use the current value of the papersize for each page
+% and, additionally, setting the papersize is local to the current TeX
+% group.
+% #1 = width
+% #2 = height
+
+\def\pgfsys@global@papersize#1#2{\pgfsys@papersize{#1}{#2}}
+% This command does the same as the papersize command, only for
+% drivers that support this, \global is used to set the papersize.
+% #1 = width
+% #2 = height
+
+\def\pgfsys@prepare@papersize#1#2{\pgfsys@papersize{#1}{#2}}
+% Like \pgfsys@papersize, this prepares the paper size in a portable
+% way -- but it is supposed to be a preparation step before the
+% document has started. Drivers may decide to postpone the action
+% until the document has started.
+%
+% The root cause why I added this method is that image externalization
+% seems to suffer from the fact that some drivers need a "prepared"
+% routine whereas others must not have a prepared routine and have to
+% apply the action right-away. This method is the solution for image
+% externalization.
+% #1 = width
+% #2 = height
+
+\ifx\paperheight\@undefined
+ \def\pgfsys@thepageheight{\the\vsize} % this is wrong, but I do not
+ % know how to compute the page height
+ % in plain tex.
+ \def\pgfsys@thepagewidth{\the\hsize}
+\else
+ \def\pgfsys@thepageheight{\paperheight}
+ \def\pgfsys@thepagewidth{\paperwidth}
+\fi
+
+
+%
+%
+% Position tracking commands
+%
+%
+
+% Marks the current position on the page. This position can later be
+% referenced using \pgfsys@getposition
+\def\pgfsys@markposition#1{\pgf@sys@fail{marking the current position}}
+
+% Sets #2 to a pgfpoint macro that returns the position #1 is
+% returned in a coordinate system where the x-axis goes right and the
+% y-axis goes up. The origin of this coordinate system may or may not
+% lie in the lower left corner; you should shift the coordinate system
+% to the position "pgfpageorigin" to make sure that the origin is at
+% the lower left corner. Typically, getting this position
+% requires two runs of TeX. On the first run, the macro will be set to
+% \relax, indicating that the position is not available.
+%
+% If #1 is set to the special position "pgfpageorigin", the position
+% of the the lower left page corner is returned.
+
+\def\pgfsys@getposition#1#2{\let#2=\relax}
+
+
+
+%
+%
+% Commands having a default implementation. These commands only need
+% not be implemented by drivers if this results in a better
+% performance.
+%
+%
+
+
+\def\pgfsys@shadingoutsidepgfpicture#1{%
+ #1%
+}
+% This command gets the definition of a shading (@pgfshadingxxxx!) as
+% an argument and should insert this shading into the normal text.
+%
+% This command has a default implementation.
+
+
+\def\pgfsys@shadinginsidepgfpicture#1{%
+ \pgf@makehbox{#1}%
+ \setbox\pgf@hbox=\hbox{\hskip-.5\wd\pgf@hbox\lower.5\ht\pgf@hbox\hbox{\box\pgf@hbox}}%
+ \pgfqbox{\pgf@hbox}%
+}
+% This command works like \pgfsys@shadingoutsidepgfpicture, only it is
+% called when a shading should be inserted inside a picture. This
+% command should insert the shading centered on the origin (which will
+% typically have been low-level translated somewhere else.)
+%
+% This command has a default implementation.
+
+
+\def\pgfsys@hbox#1{%
+ \pgfsys@begin@idscope%
+ \pgfsys@beginscope%
+ \setbox#1=\hbox{\box#1}%
+ \wd#1=0pt%
+ \ht#1=0pt%
+ \dp#1=0pt%
+ \box#1%
+ \pgfsys@endscope%
+ \pgfsys@end@idscope%
+}
+% Called to insert a TeX hbox into a pgfpicture.
+
+\def\pgfsys@hboxsynced#1{%
+ \pgfsys@beginscope\pgflowlevelsynccm\pgfsys@hbox#1\pgfsys@endscope%
+}%
+% Called to insert box #1 into a pgfpicture, but with the current
+% coordinate transformation matrix synced with the canvas
+% transformation matrix and surrounded by a scope.
+%
+% In essence, this command does the same as if you first said
+% \pgflowlevelsynccm and then \pgfsys@hbox#1. However, a
+% ``TeX-translation'' is used for the translation part of the
+% transformation cm. This will ensure that hyperlinks ``survive'' at
+% least translations.
+
+\def\pgfsys@pictureboxsynced#1{%
+ {%
+ \setbox0=\hbox{\pgfsys@beginpicture\box#1\pgfsys@endpicture}%
+ \pgfsys@hboxsynced0%
+ }%
+}
+% Basically, this should do the same as doing a (scoped) low level sync
+% followed by inserting the box #1 directly into the output
+% stream. However, the default implementation uses \pgfsys@hboxsynced
+% in conjunction with \pgfsys@beginpicture to ensure that, if
+% possible, hyperlinks survive in pdfs. Drivers that are sensitive to
+% picture-in-picture scopes should replace this implementation by
+% \pgfsys@beginscope\pgflowlevelsynccm\box#1\pgfsys@endscope
+
+\def\pgfsys@beginpicture{}
+% Called at the beginning of a pgfpicture. Used to setup things.
+
+\def\pgfsys@endpicture{}
+% Called at the end of a pgfpicture.
+
+\def\pgfsys@typesetpicturebox#1{%
+ \pgf@ya=\pgf@shift@baseline\relax%
+ \advance\pgf@ya by-\pgf@picminy\relax%
+ %
+ %
+ \advance\pgf@picmaxy by-\pgf@picminy\relax% maxy is now the height
+ \advance\pgf@picmaxx by-\pgf@picminx\relax% maxx is now the width
+ \setbox#1=\hbox{\hskip-\pgf@picminx\lower\pgf@picminy\box#1}%
+ \ht#1=\pgf@picmaxy%
+ \wd#1=\pgf@picmaxx%
+ \dp#1=0pt%
+ \leavevmode%
+ \pgf@xa=\pgf@trimleft@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi
+ \raise-\pgf@ya\box#1%
+ \pgf@xa=\pgf@trimright@final\relax \ifdim\pgf@xa=0pt \else\kern\pgf@xa\fi
+}
+% Called after a picture has been typeset in box #1. This
+% command should insert the box into the normal TeX code. The box #1
+% will still be a ``raw'' box that contains only the \special's. The
+% job of this command is to resize and shift this box according to the
+% baseline shift and the size of the box.
+%
+% This command has a default implementation.
+
+\def\pgfsys@beginpurepicture{\pgfsys@beginpicture}
+% This version of the beginpicture command can be used for pictures
+% that are guaranteed not to contain any hboxes. In this case, a
+% driver might provide a more compact version of the command.
+
+\def\pgfsys@endpurepicture{\pgfsys@endpicture}
+% Called at the end of a ``pure'' pgfpicture.
+
+\def\pgfsys@defineimage{%
+ \ifx\pgf@imagewidth\pgfutil@empty\else\edef\pgf@imagewidth{width=\pgf@imagewidth,}\fi%
+ \ifx\pgf@imageheight\pgfutil@empty\else\edef\pgf@imageheight{height=\pgf@imageheight,}\fi%
+ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{page=\pgf@imagepage,}\fi%
+ \edef\pgf@image{\noexpand\includegraphics[\pgf@imageheight\pgf@imagewidth]{\pgf@filename}}%
+}
+% Called, when an image should be defined.
+%
+% This command does not take any parameters. Instead, certain macros
+% will be preinstalled with appropriate values when this command is
+% invoked. These are:
+%
+% - \pgf@filename
+% File name of the image to be defined.
+%
+% - \pgf@imagewidth
+% Will be set to the desired (scaled) width of the image.
+%
+% - \pgf@imageheight
+% Will be set to the desired (scaled) height of the image.
+%
+% If this macro and also the height macro are empty, the image
+% should have its `natural' size.
+%
+% If exactly only of them is specified, the undefined value the
+% image is scaled so that the aspect ratio is kept.
+%
+% If both are set, the image is scaled in both directions
+% independently, possibly changing the aspect ratio.
+%
+%
+% The following macros presumable mostly make sense for drivers that
+% can handle pdf:
+%
+% - \pgf@imagepage
+% The desired page number to be extracted from a multi-page
+% `image'.
+%
+% - \pgf@imagemask
+% If set, it will be set to `/SMask x 0 R', where x is the pdf
+% object number of a soft mask to be applied to the image.
+%
+% - \pgf@imageinterpolate
+% If set, it will be set to `/Interpolate true' or `/Interpolate
+% false', indicating whether the image should be interpolated in
+% pdf.
+%
+%
+% The command should now setup the macro \pgf@image such that calling
+% this macro will result in typesetting the image. Thus, \pgf@image is
+% the `return value' of the command.
+
+
+\def\pgfsys@defobject#1#2#3#4{%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@temp%
+ {%
+ \pgfpicturetrue%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsys@beginscope%
+ #4%
+ \pgfsys@endscope%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@@temp%
+ \expandafter\global\expandafter\let\csname #1\endcsname=\pgfsys@@temp%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfsys@temp%
+}
+% Declares an object for later use. The idea is that the object can be
+% precached in some way and then be rendered more quickly when used
+% several times. For example, an arrow head might be defined and
+% prerendered in this way.
+%
+% The parameter #1 is the name for later use. #2 and #3 are pgf points
+% specifying a bounding box for the object. #4 is the code for the
+% object. The code may only contain protocolable code.
+
+
+\def\pgfsys@useobject#1#2{%
+ \pgfsysprotocol@getcurrentprotocol\pgfsys@temp%
+ {%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedfalse%
+ #2%
+ \expandafter\pgfsysprotocol@setcurrentprotocol\csname #1\endcsname%
+ \pgfsysprotocol@invokecurrentprotocol%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfsys@temp%
+}
+% Renders a previously declared object. The first parameter is the
+% name of the object. The second parameter is extra code that
+% should be executed right *before* the object is rendered. Typically,
+% this will be some transformation code.
+
+
+\def\pgfsys@begininvisible{\pgfsys@transformcm{1}{0}{0}{1}{2000bp}{2000bp}}
+% Between this command and the closing endinvisible, all output should
+% be suppressed. Nothing should be drawn at all, which includes all
+% paths, images and shadings. This command typically should not open a
+% graphic scope.
+
+\def\pgfsys@endinvisible{\pgfsys@transformcm{1}{0}{0}{1}{-2000bp}{-2000bp}}
+% Ends the invisibility section, unless invisibility blocks have been
+% nested. In this case, only the `last' one restores visibility.
+
+\def\pgfsys@begininvisiblescope{\pgfsys@beginscope\pgfsys@begininvisible}
+% Works like pgfsys@begininvisible, but it may open a graphics scope.
+
+\def\pgfsys@endinvisiblescope{\pgfsys@endinvisible\pgfsys@endscope}
+% Closes the invisibility scope.
+
+
+\def\pgfsys@atbegindocument{}
+% This command will be executed at the begin of the document. If for
+% whatever reason this is not done, you may wish to execute this
+% command yourself. It will setup certain specials that need to be
+% inserted into the resulting .pdf/.ps/.xxx file.
+
+
+% String comparison
+\ifdefined\pdfstrcmp
+ \let\pgfsys@strcmp\pdfstrcmp
+\else\ifdefined\strcmp
+ \let\pgfsys@strcmp\strcmp
+\else\ifdefined\directlua
+ \directlua{
+ local lft = lua.get_functions_table()
+ lft[\string#lft+1] = function()
+ local lhs = token.scan_string()
+ local rhs = token.scan_string()
+ if lhs < rhs then
+ tex.sprint(-2, "-1")
+ elseif lhs == rhs then
+ tex.sprint(-2, "0")
+ else
+ tex.sprint(-2, "1")
+ end
+ end
+ token.set_lua("pgfsys@strcmp", \string#lft, "global")
+ }
+\else
+ \def\pgfsys@strcmp#1#2{\pgf@sys@fail{string comparison}}%
+\fi\fi\fi
+
+
+% Discern the driver:
+
+% Default driver:
+\ifx\pgfsysdriver\@undefined
+ \pgfutil@guessdriver
+\fi
+
+\input pgf.cfg
+
+\immediate\write-1{Driver file for pgf: \pgfsysdriver}
+\pgfutil@InputIfFileExists{\pgfsysdriver}{}{%
+ \pgferror{Driver file ``\pgfsysdriver'' not found.}}
+
+
+
+% This will insert always-present-specials at the beginning of the
+% code.
+\AtBeginDocument{
+ \pgfsys@atbegindocument
+ \let\pgfsys@atbegindocument=\pgfutil@empty
+}
+
+
+
+% Read aux file in plain and context mode:
+
+\pgfutil@aux@read@hook
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsysanimations.code.tex b/graphics/pgf/base/tex/generic/systemlayer/pgfsysanimations.code.tex
new file mode 100644
index 0000000000..05bf9c3328
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsysanimations.code.tex
@@ -0,0 +1,2010 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+
+% Guard against reading twice
+\ifx\pgfsysanimationsloaded\pgfutil@undefined
+ \let\pgfsysanimationsloaded=\relax
+\else
+ \expandafter\endinput
+\fi
+
+
+% We need some support:
+\usepgfmodule{decorations}
+
+
+% Animation abstraction layer
+%
+% This layer provides an abstraction of the
+% \pgfsys@anim... commands. The idea is to provide an interface that
+% can map animation commands either to "real" animations (for instance
+% in the sense of SVG) or to "snapshots" of animations, which are
+% especially useful for printing. For these snapshots, instead of
+% adding an animation property to a scope, the property is actually
+% set to a certain value computed by \TeX.
+%
+% For each \pgfsys@animation@... command there is a corresponding
+% \pgfsysanim command.
+
+
+% Set the current time to a snapshot time
+%
+% #1 = a global snapshot time (a dimensionless number, measured in
+% seconds).
+%
+% Description:
+%
+% When this command is used in a scope, instead of creating an
+% animation, pgf will insert appropriate commands that show the state
+% of the animation at the given time.
+%
+% The value #1 can be thought of as the "global time", which can be
+% thought of as the time that elapsed since the "onload" event.
+%
+% The command \pgfsysanimsnapshotafter works the same way as
+% pgfsysanimsnapshot, only the time #1 is interpreted as "global time
+% #1 + epsilon". This means that when two or more values are specified
+% for time #1, the last of them is used rather than the
+% first. Likewise, when a non-freezing timeline ends at time #1,
+% \pgfsysanimsnapshot will set the value to the last value in the
+% timeline, while \pgfsysanimsnapshotafter removes the animation.
+%
+% The following commands and effect for animations are ignored / not
+% implemented for snapshots (meaning that even if the "real" animation
+% would look in a certain way because of one of the following commands
+% or effects, the snapshot will not reflect this):
+%
+% - Events and restarts are ignored. For the snapshot, all animations
+% start at global time 0, except if the command
+% \pgfsysanimkeysnapshotstart is used to specify a different
+% start for a specific animation.
+% - The "current value" as starting value (pgf has no real chance of
+% determining the correct value of this). Using this with a snapshot
+% will raise an error.
+%
+% Example:
+%
+% {
+% \pgfsyssnapshot{2}%
+% \pgfsysanimkeytime{0}{1}{1}{0}{0}
+% \pgfsysanimvalscalar{1}
+% \pgfsysanimkeytime{5}{1}{1}{0}{0}
+% \pgfsysanimvalscalar{0}
+% \pgfsysanimkeywhom{\someid}{}
+% \pgfsysanimate{fillopacity}%
+% % Will set the opacity of \someid to 0.6
+% }
+
+\def\pgfsysanimsnapshot#1{%
+ \def\pgfsysanim@snaptime{#1}%
+ \pgfsysanim@snap@firsttrue%
+ \pgfsysanim@is@snaptrue%
+}
+\def\pgfsysanimsnapshotafter#1{%
+ \def\pgfsysanim@snaptime{#1}%
+ \pgfsysanim@snap@firstfalse%
+ \pgfsysanim@is@snaptrue%
+}
+\newif\ifpgfsysanim@is@snap
+\newif\ifpgfsysanim@snap@first
+
+
+
+% Companion for \pgfsys@animate
+%
+% #1 = attribute
+%
+% Description:
+%
+% If not snapshot is set, \pgfsys@animate is simply called. Otherwise,
+% appropriate code is generated that sets the specified attribute of
+% the whom object to the value it would have during the animation at
+% the moment of the snapshot.
+
+\def\pgfsysanimate#1{%
+ \csname pgfsysanim@checks@#1\endcsname%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@do@snap{#1}%
+ \else%
+ \pgfsys@animate{#1}%
+ \fi%
+}
+
+\def\pgfsysanim@do@snap#1{%
+ {%
+ \expandafter\ifx\csname pgfsysanim@prep@attr@#1\endcsname\pgfutil@undefined%
+ \else%
+ % First, compute time frame:
+ \pgfsysanim@compute@interval%
+ % Second, compute code:
+ \let\pgfsysanim@code@begin\relax%
+ \let\pgfsysanim@code@end\pgfutil@empty%
+ \csname pgfsysanim@prep@attr@#1\endcsname%
+ \ifx\pgfsysanim@code@begin\relax%
+ \else%
+ % Attach to object:
+ \expandafter\expandafter\expandafter\pgfsysanim@call@attacher%
+ \expandafter\expandafter\expandafter{\expandafter\pgfsysanim@code@begin\expandafter}\expandafter{\pgfsysanim@code@end}{}%
+ \fi%
+ \fi%
+ }%
+}
+\def\pgfsysanim@call@attacher{\pgfsys@attach@to@id{\pgfsysanim@whom@id}{\pgfsysanim@whom@type}}
+
+
+% Do some checks:
+\def\pgfsysanim@checks@path{%
+ \expandafter\global\expandafter\let\csname pgfsysanim@path@is@animated@\pgfsysanim@whom@id @\pgfsysanim@whom@type\endcsname\pgfutil@empty%
+}
+
+
+% Companions for \pgfsys@animation@restart@...
+%
+% Description:
+%
+% These commands just call \pgfsys@animation@restart@... and they are
+% *ignored* when it comes to snapshots.
+
+\def\pgfsysanimkeyrestartalways{\pgfsys@animation@restart@always}
+\def\pgfsysanimkeyrestartnever{\pgfsys@animation@restart@never}
+\def\pgfsysanimkeyrestartwhennotactive{\pgfsys@animation@restart@whennotactive}
+
+
+
+% Companions for \pgfsys@animation@repeat...
+%
+% Description:
+%
+% These commands call \pgfsys@animation@repeat... and, if there is a
+% snapshot installed, the passed values are taken into consideration.
+
+\def\pgfsysanimkeyrepeat#1{%
+ \pgfsys@animation@repeat{#1}%
+ % Snapshot
+ \let\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@normal%
+ {%
+ \pgf@x#1pt\relax%
+ \expandafter}%
+ \expandafter\def\expandafter\pgfsysanim@snap@repeat@arg\expandafter{\the\pgf@x}%
+}
+\def\pgfsysanimkeyrepeatindefinite{%
+ \pgfsys@animation@repeat@indefinite%
+ % Snapshot
+ \let\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@indefinite%
+ \let\pgfsysanim@snap@repeat@arg\pgfutil@empty%
+}
+\def\pgfsysanimkeyrepeatdur#1{%
+ \pgfsys@animation@repeat@dur{#1}%
+ % Snapshot
+ \let\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@dur%
+ {%
+ \pgf@x#1pt\relax%
+ \expandafter}%
+ \expandafter\def\expandafter\pgfsysanim@snap@repeat@arg\expandafter{\the\pgf@x}%
+}
+\def\pgfsysanim@snap@repeat@none{n}%
+\def\pgfsysanim@snap@repeat@normal{m}%
+\def\pgfsysanim@snap@repeat@indefinite{i}%
+\def\pgfsysanim@snap@repeat@dur{d}%
+\let\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@none
+\let\pgfsysanim@snap@repeat@arg\pgfutil@empty
+
+
+
+% Companions for \pgfsys@animation@freezeatend and
+% \pgfsys@animation@removeatend
+%
+% Description:
+%
+% These commands call the two system commands and, if there is a
+% snapshot installed, the settings are taken into consideration.
+
+\def\pgfsysanimkeyfreezeatend{\pgfsys@animation@freezeatend\pgfsysanim@freezeatendtrue}
+\def\pgfsysanimkeyremoveatend{\pgfsys@animation@removeatend\pgfsysanim@freezeatendfalse}
+\newif\ifpgfsysanim@freezeatend
+
+
+
+% Companion for \pgfsys@animation@time
+%
+% #1 to #5 = as in \pgfsys@animation@time
+%
+% Description:
+%
+% Calls \pgfsys@animation@time. Furthermore, the specified times are
+% recorded so that they can later be analysed for the computation
+% needed for a snapshot.
+
+\def\pgfsysanimkeytime#1#2#3#4#5{%
+ % Setup animation
+ \pgfsys@animation@time{#1}{#2}{#3}{#4}{#5}%
+ % and remember for snapshots
+ \def\pgfsysanim@time{{#1}{#2}{#3}{#4}{#5}}%
+}
+
+
+% Sets the base value
+%
+% Description:
+%
+% This will set the "base" value for an animation, which is installed
+% prior to any animation of the attribute.
+
+\def\pgfsysanimkeybase{%
+ \pgfsys@animation@base%
+ \let\pgfsysanim@time\pgfsysanim@base@text%
+}
+\def\pgfsysanim@base@text{base}%
+
+% Sets the beginning of the timeline for snapshots
+%
+% #1 = a time (a scalar)
+%
+% Description:
+%
+% Sets the start of current animation to #1 for snapshots. For
+% instance, if #1 is 5 (=five seconds), and you say
+% \pgfsysanimsnapshot{6}, the attribute will be set to whatever the
+% animation specifies after one second.
+
+\def\pgfsysanimkeysnapshotstart#1{%
+ \def\pgfsysanim@snapshotstart{#1}%
+}
+\def\pgfsysanim@snapshotstart{0}
+
+
+% Companion for \pgfsys@animation@offset
+%
+% #1, #2 = as in \pgfsys@animation@offset
+%
+% Description:
+%
+% Calls \pgfsys@animation@offset.
+
+\def\pgfsysanimkeyoffset#1#2{%
+ \pgfsys@animation@offset{#1}{#2}%
+}
+
+
+% Companion for \pgfsys@animation@sync(begin|end)
+%
+% #1 to #4 = as in \pgfsys@animation@sync(begin|end)
+%
+% Description:
+%
+% Calls \pgfsys@animation@sync(begin|end).
+
+\def\pgfsysanimkeysyncbegin#1#2#3#4{%
+ \pgfsys@animation@syncbegin{#1}{#2}{#3}{#4}%
+}
+
+\def\pgfsysanimkeysyncend#1#2#3#4{%
+ \pgfsys@animation@syncend{#1}{#2}{#3}{#4}%
+}
+
+
+% Companion for \pgfsys@animation@event
+%
+% #1 to #5 = as in \pgfsys@animation@event
+%
+% Description:
+%
+% Calls \pgfsys@animation@event.
+
+\def\pgfsysanimkeyevent#1#2#3#4#5{%
+ \pgfsys@animation@event{#1}{#2}{#3}{#4}{#5}%
+}
+
+
+% Companion for \pgfsys@animation@repeat@event
+%
+% #1 to #5 = as in \pgfsys@animation@repeat@event
+%
+% Description:
+%
+% Calls \pgfsys@animation@repeat@event.
+
+\def\pgfsysanimkeyrepeatevent#1#2#3#4#5{%
+ \pgfsys@animation@repeat@event{#1}{#2}{#3}{#4}{#5}%
+}
+
+
+
+% Companion for \pgfsys@animation@accesskey
+%
+% #1 to #3 = as in \pgfsys@animation@accesskey
+%
+% Description:
+%
+% Calls \pgfsys@animation@accesskey.
+
+\def\pgfsysanimkeyaccesskey#1#2#3{%
+ \pgfsys@animation@accesskey{#1}{#2}{#3}%
+}
+
+
+
+
+% Companions for \pgfsys@animation@(no)accumulate
+%
+% Description:
+%
+% Calls \pgfsys@animaion@(no)accumulate and records the setting for
+% snapshots.
+
+\def\pgfsysanimkeyaccumulate{\pgfsys@animation@accumulate\pgfsysanim@accumulatetrue}
+\def\pgfsysanimkeynoaccumulate{\pgfsys@animation@noaccumulate\pgfsysanim@accumulatefalse}
+\newif\ifpgfsysanim@accumulate
+
+
+
+
+% Companion for \pgfsys@animation@whom
+%
+% #1 and #2 = as for \pgfsys@animation@whom
+%
+% Description:
+%
+% Calls \pgfsys@animation@whom and records the setting for snapshots.
+
+\def\pgfsysanimkeywhom#1#2{%
+ \pgfsys@register@type{#2}%
+ \pgfsys@animation@whom{#1}{#2}%
+ % Snapshots
+ \def\pgfsysanim@whom@id{#1}%
+ \def\pgfsysanim@whom@type{#2}%
+}
+
+
+
+
+
+% Companions for \pgfsys@animation@rotatealong and
+% \pgfsys@animation@norotatealong
+%
+% Description:
+%
+% Calls the system layer command and records the setting for
+% snapshots.
+
+\def\pgfsysanimkeyrotatealong{\pgfsys@animation@rotatealong\pgfsysanim@rotatealongtrue}
+\def\pgfsysanimkeynorotatealong{\pgfsys@animation@norotatealong\pgfsysanim@rotatealongfalse}
+\newif\ifpgfsysanim@rotatealong
+
+
+% Companion for \pgfsys@animation@movealong
+%
+% #1 = the path
+%
+% Description:
+%
+% Calls the system layer command and records the setting for
+% snapshots.
+
+\def\pgfsysanimkeymovealong#1{%
+ \pgfsys@animation@movealong{#1}%
+ % Snapshot
+ \def\pgfsysanim@snap@movealong{#1}%
+}
+
+
+
+
+% Companion for \pgfsys@animation@tip@markers
+%
+% #1, #2 = the markers
+%
+% Description:
+%
+% Calls the system layer command and records the setting for
+% snapshots.
+
+\def\pgfsysanimkeytipmarkers#1#2{%
+ \pgfsys@animation@tip@markers{#1}{#2}%
+ % Snapshot
+ \def\pgfsysanim@snap@tip@start{#1}%
+ \def\pgfsysanim@snap@tip@end{#2}%
+}
+\let\pgfsysanim@snap@tip@start\pgfutil@empty%
+\let\pgfsysanim@snap@tip@end\pgfutil@empty%
+
+
+% Companion for \pgfsys@animation@canvas@transform
+%
+% Description:
+%
+% Calls the system layer command and records the setting for
+% snapshots.
+
+\def\pgfsysanimkeycanvastransform#1#2{%
+ \pgfsys@animation@canvas@transform{#1}{#2}%
+ % Snapshot
+ \def\pgfsysanim@snap@canvas@transform@pre{#1}%
+ \def\pgfsysanim@snap@canvas@transform@post{#2}%
+}
+\let\pgfsysanim@snap@canvas@transform@pre\relax
+\let\pgfsysanim@snap@canvas@transform@post\relax
+
+
+
+% Companion for \pgfsys@animation@val@current
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% an error results.
+
+\def\pgfsysanimvalcurrent{%
+ \pgfsys@animation@val@current%
+ \ifpgfsysanim@is@snap%
+ \pgferror{You may not use "current value" with an animation snapshot}%
+ \fi%
+}
+
+
+% Suppresses the animation value
+%
+% Description:
+%
+% The animation value is simply ignored.
+
+\def\pgfsysanimvalnone{%
+}
+
+
+
+% Companion for \pgfsys@animation@val@text
+%
+% #1 = as for \pgfsys@animation@val@text
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvaltext#1{%
+ \pgfsys@animation@val@text{#1}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{#1}%
+ \fi%
+}
+
+
+
+
+% Companion for \pgfsys@animation@val@scalar
+%
+% #1 = as for \pgfsys@animation@val@scalar
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalscalar#1{%
+ \pgfsys@animation@val@scalar{#1}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{#1}%
+ \fi%
+}
+
+
+
+% Companion for \pgfsys@animation@val@dimension
+%
+% #1 = as for \pgfsys@animation@val@dimension
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvaldimension#1{%
+ \pgfsys@animation@val@dimension{#1}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{#1}%
+ \fi%
+}
+
+
+
+% Dispatcher for different color values
+%
+% #1 = a color value (like "red" or "black!20")
+%
+% Description:
+%
+% This macro transforms #1 into its correct color model and, then,
+% calls the correct \pgfsysanimcolor... macro.
+
+\def\pgfsysanimvalcolor#1{%
+ \pgfutil@colorlet{pgf@anim@temp}{#1}%
+ \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@anim@temp}}%
+ \expandafter\let\expandafter\pgf@sys@temp\csname\string\color@pgf@anim@temp\endcsname
+ \expandafter\pgfanim@parse@type@color@\pgf@sys@temp%
+}
+\def\pgfanim@parse@type@color@#1#2#3#4#5{%
+ \expandafter\ifx\csname pgfsysanimvalcolor#4\endcsname\relax%
+ \pgferror{Unsupported color model `#4'}%
+ \else%
+ \edef\pgf@sys@colmarshal{\expandafter\noexpand\csname pgfsysanimvalcolor#4\endcsname}%
+ \pgf@sys@uncomma#5,,%
+ \pgf@sys@colmarshal%
+ \fi%
+}
+
+\def\pgf@sys@uncomma#1,{%
+ \def\pgf@sys@coltest{#1}%
+ \ifx\pgf@sys@coltest\pgfutil@empty%
+ \else%
+ \expandafter\def\expandafter\pgf@sys@colmarshal\expandafter{\pgf@sys@colmarshal{#1}}%
+ \expandafter\pgf@sys@uncomma%
+ \fi%
+}
+
+
+
+
+% Companion for \pgfsys@animation@val@color@rgb
+%
+% #1, #2, #3 = as for \pgfsys@animation@val@color@rgb
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalcolorrgb#1#2#3{%
+ \pgfsys@animation@val@color@rgb{#1}{#2}{#3}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{{#1}{#2}{#3}}%
+ \fi%
+}
+
+
+
+% Companion for \pgfsys@animation@val@color@cmyk
+%
+% #1, #2, #3, #4 = as for \pgfsys@animation@val@color@cmyk
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalcolorcmyk#1#2#3#4{%
+ \pgfsys@animation@val@color@cmyk{#1}{#2}{#3}{#4}%
+ \ifpgfsysanim@is@snap%
+ {%
+ \pgf@xa=1pt%
+ \advance\pgf@xa by-#1pt%
+ \advance\pgf@xa by-#4pt\relax%
+ \ifdim\pgf@xa<0pt\pgf@xa0pt\fi%
+ \pgf@xb=1pt%
+ \advance\pgf@xb by-#1pt%
+ \advance\pgf@xb by-#4pt\relax%
+ \ifdim\pgf@xb<0pt\pgf@xb0pt\fi%
+ \pgf@xc=1pt%
+ \advance\pgf@xc by-#1pt%
+ \advance\pgf@xc by-#4pt\relax%
+ \ifdim\pgf@xc<0pt\pgf@xc0pt\fi%
+ \edef\pgfsys@temp{{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@xc}}%
+ \expandafter}%
+ \expandafter\pgfsysanim@esnap@record\expandafter{\pgfsys@temp}%
+ \fi%
+}
+
+
+% Companion for \pgfsys@animation@val@color@cmy
+%
+% #1, #2, #3 = as for \pgfsys@animation@val@color@cmy
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalcolorcmy#1#2#3{%
+ \pgfsys@animation@val@color@cmy{#1}{#2}{#3}%
+ \ifpgfsysanim@is@snap%
+ {%
+ \pgf@xa=1pt%
+ \advance\pgf@xa by-#1pt%
+ \pgf@xb=1pt%
+ \advance\pgf@xb by-#1pt%
+ \pgf@xc=1pt%
+ \advance\pgf@xc by-#1pt%
+ \edef\pgfsys@temp{{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@xc}}%
+ \expandafter}%
+ \expandafter\pgfsysanim@esnap@record\expandafter{\pgfsys@temp}%
+ \fi%
+}
+
+
+
+% Companion for \pgfsys@animation@val@color@gray
+%
+% #1 = as for \pgfsys@animation@val@color@gray
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalcolorgray#1{%
+ \pgfsys@animation@val@color@gray{#1}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{{#1}{#1}{#1}}%
+ \fi%
+}
+
+
+
+% Special companion for \pgfsys@animation@val@path
+%
+% #1 = as for \pgfsys@animation@val@path
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalpath#1{%
+ \pgfsys@animation@val@path{#1}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@snap@record{#1}%
+ \fi%
+}
+
+
+% Companion for \pgfsys@animation@val@translate
+%
+% #1, #2 = as for \pgfsys@animation@val@translate
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvaltranslate#1#2{%
+ \pgfsys@animation@val@translate{#1}{#2}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{{#1}{#2}}%
+ \fi%
+}
+
+
+
+% Companion for \pgfsys@animation@val@scale
+%
+% #1, #2 = as for \pgfsys@animation@val@scale
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalscale#1#2{%
+ \pgfsys@animation@val@scale{#1}{#2}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{{#1}{#2}}%
+ \fi%
+}
+
+
+
+% Companion for \pgfsys@animation@val@viewbox
+%
+% #1, #2, #3, #4 = as for \pgfsys@animation@val@viewbox
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvalviewbox#1#2#3#4{%
+ \pgfsys@animation@val@viewbox{#1}{#2}{#3}{#4}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{{#1}{#2}{#3}{#4}}%
+ \fi%
+}
+
+
+
+
+% Companion for \pgfsys@animation@val@dash
+%
+% #1, #2 = as for \pgfsys@animation@val@dash
+%
+% Description:
+%
+% Calls the system layer command. If a snapshot is currently active,
+% the value is recorded in the timeline.
+
+\def\pgfsysanimvaldash#1#2{%
+ \pgfsys@animation@val@dash{#1}{#2}%
+ \ifpgfsysanim@is@snap%
+ \pgfsysanim@esnap@record{{#1}{#2}}%
+ \fi%
+}
+
+
+
+
+
+%
+% Recording mechanism: We record entries in an array.
+%
+
+\def\pgfsysanim@esnap@record#1{% records a new entry for the timeline
+ \edef\pgfsysanim@temp{#1}%
+ \expandafter\pgfsysanim@snap@record\expandafter{\pgfsysanim@temp}%
+}
+\def\pgfsysanim@snap@record#1{% records a new entry for the timeline
+ \ifx\pgfsysanim@time\pgfsysanim@base@text%
+ \def\pgfsysanim@base@value{#1}%
+ \else%
+ \advance\pgfsysanim@snap@count by1\relax%
+ \expandafter\def\expandafter\pgfsysanim@temp\expandafter{\pgfsysanim@time{#1}}%
+ \expandafter\let\csname pgfsysanim@snap@\the\pgfsysanim@snap@count\endcsname\pgfsysanim@temp%
+ \fi%
+}
+\newcount\pgfsysanim@snap@count
+\let\pgfsysanim@base@value\pgfutil@empty%
+
+
+% Compute the time-value interval of the snapshot: Based on the value of \pgfsysanim@snaptime,
+% computes the interval containing the specified time. This interval
+% will start at \pgfsysanim@prev@time and end at
+% \pgfsysanim@next@time. The values will be \pgfsysanim@prev@val and
+% \pgfsysanim@next@val.
+%
+\def\pgfsysanim@compute@interval{%
+ \let\pgfsysanim@prev@val\relax%
+ \let\pgfsysanim@prev@time\relax%
+ \let\pgfsysanim@prev@spline\pgfsysanim@default@spline%
+ \let\pgfsysanim@next@val\relax%
+ \let\pgfsysanim@next@time\relax%
+ \let\pgfsysanim@next@spline\pgfsysanim@default@spline%
+ \let\pgfsysanim@first@time\relax%
+ \let\pgfsysanim@last@time\relax%
+ \let\pgfsysanim@last@val\relax%
+ \ifnum\pgfsysanim@snap@count>0\relax%
+ \pgf@xc\pgfsysanim@snaptime pt\relax%
+ \pgf@x\pgfsysanim@snapshotstart pt\relax%
+ \advance\pgf@xc-\pgf@x\relax%
+ % Compute the start and end times:
+ \pgfsysanim@compute@start@end%
+ \pgfsysanim@compute@value%
+ \fi%
+ % Test whether a valid interval has been found:
+ \pgfsysanim@valid@snapshot@timefalse%
+ \ifx\pgfsysanim@prev@time\relax%
+ \else\ifx\pgfsysanim@next@time\relax%
+ \else\pgfsysanim@valid@snapshot@timetrue%
+ \fi\fi%
+ \ifpgfsysanim@valid@snapshot@time%
+ % ok, computed later
+ \else%
+ \ifx\pgfsysanim@base@value\pgfutil@empty%
+ \else%
+ % Ah, use base value!
+ \let\pgfsysanim@prev@val\pgfsysanim@base@value%
+ \def\pgfsysanim@prev@time{0}%
+ \let\pgfsysanim@prev@spline\pgfsysanim@default@spline%
+ \let\pgfsysanim@next@val\pgfsysanim@base@value%
+ \let\pgfsysanim@next@time\pgfsysanim@prev@time%
+ \let\pgfsysanim@next@spline\pgfsysanim@default@spline%
+ \def\pgfsysanim@first@time{-16382}%
+ \let\pgfsysanim@last@time\pgfsysanim@prev@time%
+ \let\pgfsysanim@last@val\pgfsysanim@base@value%
+ \def\pgfsysanim@frac@a{1}%
+ \def\pgfsysanim@frac@b{0}%
+ \pgfsysanim@valid@snapshot@timetrue% counts as valid!
+ \fi%
+ \fi%
+}
+\newif\ifpgfsysanim@cont%
+\newif\ifpgfsysanim@valid@snapshot@time
+\def\pgfsysanim@default@spline{{0}{0}{1}{1}}
+
+\def\pgfsysanim@compute@start@end{%
+ \expandafter\expandafter\expandafter\pgfsysanim@compute@start\csname pgfsysanim@snap@1\endcsname%
+ \expandafter\expandafter\expandafter\pgfsysanim@compute@end\csname pgfsysanim@snap@\the\pgfsysanim@snap@count\endcsname%
+}
+\def\pgfsysanim@compute@start#1#2#3#4#5#6{%
+ \def\pgfsysanim@first@time{#1}%
+}
+\def\pgfsysanim@compute@end#1#2#3#4#5#6{%
+ \def\pgfsysanim@last@time{#1}%
+ \def\pgfsysanim@last@val{#6}%
+}
+
+
+\def\pgfsysanim@compute@value{%
+ % First, are we before start?
+ \ifdim\pgf@xc<\pgfsysanim@first@time pt\relax%
+ % snapshot time (xc) is before start of animation. So, nothing happens:
+ \else%
+ \ifx\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@none%
+ \pgfsysanim@handle@repeat@none%
+ \else\ifx\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@normal%
+ \pgfsysanim@handle@repeat@normal%
+ \else\ifx\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@indefinite%
+ \pgfsysanim@handle@repeat@indefinite%
+ \else\ifx\pgfsysanim@snap@repeat@kind\pgfsysanim@snap@repeat@dur%
+ \pgfsysanim@handle@repeat@dur%
+ \fi\fi\fi\fi%
+ \fi%
+}
+
+\def\pgfsysanim@handle@repeat@none{%
+ \ifdim\pgf@xc<\pgfsysanim@last@time pt\relax%
+ \pgfsysanim@compute@time%
+ \else%
+ \ifdim\pgf@xc=\pgfsysanim@last@time pt\relax%
+ % A bit tricky:
+ \ifpgfsysanim@snap@first%
+ \pgfsysanim@compute@time%
+ \else%
+ \ifpgfsysanim@freezeatend%
+ \let\pgfsysanim@prev@val\pgfsysanim@last@val%
+ \let\pgfsysanim@prev@time\pgfsysanim@last@time%
+ \let\pgfsysanim@next@val\pgfsysanim@last@val%
+ \let\pgfsysanim@next@time\pgfsysanim@last@time%
+ \fi%
+ \fi%
+ \else%
+ % Called when we are past the end.
+ \ifpgfsysanim@freezeatend%
+ \let\pgfsysanim@prev@val\pgfsysanim@last@val%
+ \let\pgfsysanim@prev@time\pgfsysanim@last@time%
+ \let\pgfsysanim@next@val\pgfsysanim@last@val%
+ \let\pgfsysanim@next@time\pgfsysanim@last@time%
+ \fi%
+ \fi%
+ \fi%
+}
+
+
+\def\pgfsysanim@handle@repeat@indefinite{%
+ \ifdim\pgf@xc<\pgfsysanim@last@time pt\relax%
+ \pgfsysanim@compute@time%
+ \else%
+ % Compute interval length
+ \pgf@xa=\pgfsysanim@last@time pt%
+ \pgf@xb=\pgfsysanim@first@time pt%
+ \advance\pgf@xa by-\pgf@xb%
+ % Compute repeat count and fraction:
+ \pgf@ya\pgf@xc%
+ \advance\pgf@ya by-\pgf@xb%
+ \ifdim\pgf@xa<0.01pt\relax%
+ % Interval too small: Goto end of interval
+ \def\pgfmathresult{1.0}%
+ \else%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@xa}%
+ \fi%
+ \pgf@x\pgfmathresult pt\relax%
+ \expandafter\pgfsysanim@splitter\the\pgf@x%
+ \pgf@xc=\pgfsysanim@repeat@frac\pgf@xa%
+ \advance\pgf@xc by\pgf@xb%
+ \pgfsysanim@compute@time%
+ \fi%
+}
+{\catcode`\p=12\catcode`\t=12\gdef\Pgfsysanim@sPliTTer#1.#2pt{\Pgfsysanim@seTTer{#1}{#2}}}
+\let\pgfsysanim@splitter\Pgfsysanim@sPliTTer
+\def\Pgfsysanim@seTTer#1#2{%
+ \def\pgfsysanim@repeat@decimal{#1}%
+ \def\pgfsysanim@repeat@frac{.#2}%
+ \ifdim\pgfsysanim@repeat@frac pt=0pt% goto one before:
+ \c@pgf@counta\pgfsysanim@repeat@decimal%
+ \advance\c@pgf@counta by-1\relax%
+ \edef\pgfsysanim@repeat@decimal{\the\c@pgf@counta}%
+ \def\pgfsysanim@repeat@frac{1}%
+ \fi%
+}
+\def\pgfsysanim@repeat@decimal{0}%
+
+
+\def\pgfsysanim@handle@repeat@normal{%
+ % Compute interval length
+ \pgf@xa=\pgfsysanim@last@time pt%
+ \pgf@xb=\pgfsysanim@first@time pt%
+ \advance\pgf@xa by-\pgf@xb%
+ % Compute repeat count and fraction:
+ \pgf@ya\pgf@xc%
+ \advance\pgf@ya by-\pgf@xb%
+ \ifdim\pgf@xa<0.01pt\relax%
+ % Interval too small: Goto end of interval
+ \def\pgfmathresult{1.0}%
+ \else%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@xa}%
+ \fi%
+ \pgf@x\pgfmathresult pt\relax%
+ \expandafter\pgfsysanim@splitter\the\pgf@x%
+ % Cases:
+ \ifdim\pgfmathresult pt<\pgfsysanim@snap@repeat@arg\relax%
+ % Ok! Compute!
+ \pgf@xc=\pgfsysanim@repeat@frac\pgf@xa%
+ \advance\pgf@xc by\pgf@xb%
+ \pgfsysanim@compute@time%
+ \else%
+ % Hmm. Freeze?
+ \ifpgfsysanim@freezeatend%
+ \expandafter\pgfsysanim@splitter\pgfsysanim@snap@repeat@arg%
+ \pgf@xc=\pgfsysanim@repeat@frac\pgf@xa%
+ \advance\pgf@xc by\pgf@xb%
+ \pgfsysanim@compute@time%
+ \else%
+ \ifdim\pgfmathresult pt=\pgfsysanim@snap@repeat@arg\relax%
+ \ifpgfsysanim@snap@first%
+ \expandafter\pgfsysanim@splitter\pgfsysanim@snap@repeat@arg%
+ \pgf@xc=\pgfsysanim@repeat@frac\pgf@xa%
+ \advance\pgf@xc by\pgf@xb%
+ \pgfsysanim@compute@time%
+ \fi%
+ % else: nothing!
+ \fi%
+ \fi%
+ \fi%
+}
+
+\def\pgfsysanim@handle@repeat@dur{%
+ \pgf@yb=\pgfsysanim@first@time pt%
+ \advance\pgf@yb by\pgfsysanim@snap@repeat@arg\relax%
+ \ifdim\pgf@xc<\pgf@yb% inside interval
+ \pgf@xa=\pgfsysanim@last@time pt%
+ \pgf@xb=\pgfsysanim@first@time pt%
+ \advance\pgf@xa by-\pgf@xb%
+ % Compute repeat count and fraction:
+ \pgf@ya\pgf@xc%
+ \advance\pgf@ya by-\pgf@xb%
+ \ifdim\pgf@xa<0.01pt\relax%
+ % Interval too small: Goto end of interval
+ \def\pgfmathresult{1.0}%
+ \else%
+ \pgfmathdivide@{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@xa}%
+ \fi%
+ \pgf@x\pgfmathresult pt\relax%
+ \expandafter\pgfsysanim@splitter\the\pgf@x%
+ %
+ \pgf@xc=\pgfsysanim@repeat@frac\pgf@xa%
+ \advance\pgf@xc by\pgf@xb%
+ \pgfsysanim@compute@time%
+ \else%
+ \ifpgfsysanim@freezeatend%
+ \pgfsysanim@handle@repeat@dur@freeze%
+ \else%
+ \ifdim\pgf@xc=\pgf@yb%
+ \ifpgfsysanim@snap@first%
+ \pgfsysanim@handle@repeat@dur@freeze%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+}
+
+\def\pgfsysanim@handle@repeat@dur@freeze{%
+ \pgf@xa=\pgfsysanim@last@time pt%
+ \pgf@xb=\pgfsysanim@first@time pt%
+ \advance\pgf@xa by-\pgf@xb%
+ % Compute repeat count and fraction:
+ \ifdim\pgf@xa<0.01pt\relax%
+ % Interval too small: Goto end of interval
+ \def\pgfmathresult{1.0}%
+ \else%
+ % `\pgfsysanim@snap@repeat@arg` is a macro storing a dimen value, eg "4.0pt"
+ \pgfmathdivide@{\pgf@sys@tonumber\dimexpr\pgfsysanim@snap@repeat@arg}{\pgf@sys@tonumber\pgf@xa}%
+ \fi%
+ \pgf@x\pgfmathresult pt\relax%
+ \expandafter\pgfsysanim@splitter\the\pgf@x%
+ %
+ \pgf@xc=\pgfsysanim@repeat@frac\pgf@xa%
+ \advance\pgf@xc by\pgf@xb%
+ \pgfsysanim@compute@time%
+}
+
+
+
+
+
+\def\pgfsysanim@compute@time{%
+ % Ok, let us iterate over all points of time.
+ \pgfutil@tempcnta=1\relax%
+ \pgfsysanim@conttrue%
+ \pgfutil@loop%
+ \ifnum\pgfutil@tempcnta>\pgfsysanim@snap@count%
+ \pgfsysanim@contfalse%
+ \else%
+ \expandafter\let\expandafter\pgfsys@temp\csname pgfsysanim@snap@\the\pgfutil@tempcnta\endcsname%
+ \expandafter\pgfsysanim@test@time\pgfsys@temp%
+ \fi%
+ \ifpgfsysanim@cont%
+ \advance\pgfutil@tempcnta by1\relax%
+ \pgfutil@repeat%
+}
+
+
+\def\pgfsysanim@test@time#1#2#3#4#5#6{%
+ % #1 = time in seconds
+ % #2 to #5 = spline controls
+ % #6 = value
+ \ifdim#1pt<\pgf@xc%
+ % snap time not yet reached. Update previous:
+ \def\pgfsysanim@prev@val{#6}%
+ \def\pgfsysanim@prev@time{#1}%
+ \def\pgfsysanim@prev@spline{{#2}{#3}{#4}{#5}}%
+ \else%
+ \ifdim#1pt=\pgf@xc%
+ \ifpgfsysanim@snap@first%
+ \ifx\pgfsysanim@next@val\relax%
+ % first? Save!
+ \def\pgfsysanim@prev@val{#6}%
+ \def\pgfsysanim@prev@time{#1}%
+ \def\pgfsysanim@prev@spline{{#2}{#3}{#4}{#5}}%
+ \let\pgfsysanim@next@val\pgfsysanim@prev@val%
+ \let\pgfsysanim@next@time\pgfsysanim@prev@time%
+ \let\pgfsysanim@next@spline\pgfsysanim@prev@spline%
+ \pgfsysanim@contfalse%
+ % else, do nothing
+ \fi
+ \else%
+ % always overwrite:
+ \def\pgfsysanim@prev@val{#6}%
+ \def\pgfsysanim@prev@time{#1}%
+ \def\pgfsysanim@prev@spline{{#2}{#3}{#4}{#5}}%
+ \let\pgfsysanim@next@val\pgfsysanim@prev@val%
+ \let\pgfsysanim@next@time\pgfsysanim@prev@time%
+ \let\pgfsysanim@next@spline\pgfsysanim@prev@spline%
+ \fi%
+ \else%
+ % we passed the time!
+ \ifx\pgfsysanim@next@val\relax%
+ % first? Then save!
+ \def\pgfsysanim@next@val{#6}%
+ \def\pgfsysanim@next@time{#1}%
+ \def\pgfsysanim@next@spline{{#2}{#3}{#4}{#5}}%
+ \else%
+ % ignore later times!
+ \pgfsysanim@contfalse%
+ \fi%
+ \fi%
+ \fi%
+}
+
+\let\pgfsysanim@prev@val\relax%
+\let\pgfsysanim@prev@time\relax%
+\let\pgfsysanim@next@val\relax%
+\let\pgfsysanim@next@time\relax%
+
+% Help function
+\def\pgfsysanim@attach#1#2#3{%
+ \expandafter\pgfsysanim@prep@beg\expandafter{\pgfsysanim@first@time}{#2}{#3}%
+ \expandafter\def\expandafter\pgfsysanim@code@main\expandafter{\csname pgfsysanim@main@of@\pgfsysanim@whom@id @\pgfsysanim@whom@type @#1\endcsname}%
+ \expandafter\ifx\pgfsysanim@code@main\relax%
+ \edef\pgfsysanim@code@begin{%
+ \let\noexpand\pgfsysanim@c@begin\noexpand\pgfutil@empty%
+ \let\noexpand\pgfsysanim@c@end\noexpand\pgfutil@empty%
+ \pgfsysanim@lasttime-16383pt\relax%
+ \expandafter\noexpand\pgfsysanim@code@main%
+ \global\let\expandafter\noexpand\pgfsysanim@code@main\relax%
+ \noexpand\pgfsysanim@c@begin%
+ }%
+ \let\pgfsysanim@code@end\pgfsysanim@code@closer%
+ \expandafter\global\expandafter\let\pgfsysanim@code@main\pgfutil@empty%
+ \else%
+ \let\pgfsysanim@code@begin\relax%
+ \let\pgfsysanim@code@end\relax%
+ \fi%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\def%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfsysanim@new@main%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\pgfsysanim@code@main\pgfsysanim@add@main}
+ \expandafter\global\expandafter\let\pgfsysanim@code@main\pgfsysanim@new@main%
+}
+\def\pgfsysanim@code@closer{\pgfsysanim@c@end}
+
+\def\pgfsysanim@prep@beg#1#2#3{%
+ \edef\pgfsysanim@add@main{%
+ \noexpand\ifdim\pgfsysanim@lasttime>#1pt%
+ % ignore!
+ \noexpand\else%
+ \pgfsysanim@lasttime#1pt%
+ \def\noexpand\pgfsysanim@c@begin{#2}%
+ \def\noexpand\pgfsysanim@c@end{#3}%
+ \noexpand\fi%
+ }
+}
+
+\def\pgfsysanim@prep@beg@special#1#2{%
+ \def\pgfsysanim@add@main{%
+ \ifdim\pgfsysanim@lasttime>#1pt%
+ % ignore!
+ \else%
+ \pgfsysanim@lasttime#1pt%
+ \def\pgfsysanim@c@begin{#2}%
+ \fi%
+ }
+}
+
+
+
+\def\pgfsysanim@attach@special#1#2{%
+ \expandafter\expandafter\expandafter\pgfsysanim@prep@beg@special\expandafter\expandafter\expandafter{\expandafter\pgfsysanim@first@time\expandafter}\expandafter{#2}%
+ \ifx#1\relax%
+ \def#1{%
+ \pgfsysanim@lasttime-16383pt\relax%
+ \let\pgfsysanim@c@begin\pgfutil@empty%
+ }%
+ \fi%
+ \expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter#1\pgfsysanim@add@main}%
+}
+
+
+
+\newdimen\pgfsysanim@lasttime
+
+
+\def\pgfsysanim@add@trans{%
+ \ifx\pgfsysanim@snap@canvas@transform@pre\relax%
+ \else%
+ \ifx\pgfsysanim@code@begin\relax%
+ \let\pgfsysanim@code@begin\pgfutil@empty%
+ \fi%
+ \pgfsysanim@add@trans@%
+ \fi%
+}
+\def\pgfsysanim@add@trans@{%
+ \toks0\expandafter{\pgfsysanim@snap@canvas@transform@pre}%
+ \toks1\expandafter{\pgfsysanim@code@begin}%
+ \toks2\expandafter{\pgfsysanim@snap@canvas@transform@post}%
+ \edef\pgfsysanim@code@begin{{\the\toks0 \the\toks1 \the\toks2}}%
+}
+
+% The code for the different attributes
+
+\def\pgfsysanim@prep@attr@opacity{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@scalar%
+ \pgfsysanim@cap@scalar{\pgfsysanim@x@val}{0}{1}%
+ \pgfsysanim@attach{opacity}{\noexpand\pgfsys@opacity{\pgfsysanim@x@val}}{}%
+ \fi%
+}
+
+\def\pgfsysanim@prep@attr@fillopacity{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@scalar%
+ \pgfsysanim@cap@scalar{\pgfsysanim@x@val}{0}{1}%
+ \pgfsysanim@attach{fillopacity}{\noexpand\pgfsys@fill@opacity{\pgfsysanim@x@val}}{}%
+ \fi%
+}
+
+\def\pgfsysanim@prep@attr@strokeopacity{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@scalar%
+ \pgfsysanim@cap@scalar{\pgfsysanim@x@val}{0}{1}%
+ \pgfsysanim@attach{strokeopacity}{\noexpand\pgfsys@stroke@opacity{\pgfsysanim@x@val}}{}%
+ \fi%
+}
+
+\def\pgfsysanim@prep@attr@visibility{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@text%
+ \ifx\pgfsysanim@text@val\pgf@hidden@text%
+ \pgfsysanim@attach{visibility}{\noexpand\pgfsys@begininvisiblescope}{\noexpand\pgfsys@endinvisiblescope}%
+ \else%
+ \pgfsysanim@attach{visibility}{}{}%
+ \fi%
+ \fi%
+}
+\def\pgf@hidden@text{hidden}
+
+\def\pgfsysanim@prep@attr@linewidth{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@dimension%
+ \pgfsysanim@cap@scalar{\pgfsysanim@x@val}{0}{16382}%
+ \pgfsysanim@attach{linewidth}{\noexpand\pgfsys@setlinewidth{\pgfsysanim@x@val pt}}{}%
+ \fi%
+}
+
+\def\pgfsysanim@prep@attr@dash{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@dash%
+ \pgfsysanim@attach{dash}{\noexpand\pgfsys@setdash{\pgfsysanim@dash@vals}{\pgfsysanim@x@val pt}}{}%
+ \fi%
+}
+
+\def\pgfsysanim@prep@attr@translate{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@translate%
+ \edef\pgfsysanim@code@begin{\noexpand\pgfsys@transformshift{\pgfsysanim@x@val pt}{\pgfsysanim@y@val pt}}%
+ \fi%
+ \pgfsysanim@add@trans%
+}
+
+
+\def\pgfsysanim@prep@attr@scale{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@scale%
+ \edef\pgfsysanim@code@begin{\noexpand\pgfsys@transformxyscale{\pgfsysanim@x@val}{\pgfsysanim@y@val}}%
+ \fi%
+ \pgfsysanim@add@trans%
+}
+
+\def\pgfsysanim@prep@attr@rotate{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@scalar%
+ {%
+ \pgfmathsin@{\pgfsysanim@x@val}%
+ \let\pgftransform@sin=\pgfmathresult%
+ \pgfmathcos@{\pgfsysanim@x@val}%
+ \let\pgftransform@cos=\pgfmathresult%
+ \pgf@x=\pgftransform@sin pt%
+ \pgf@xa=-\pgf@x%
+ \edef\pgfsysanim@code@begin{\noexpand\pgfsys@transformcm{\pgftransform@cos}{\pgftransform@sin}{\pgf@sys@tonumber{\pgf@xa}}{\pgftransform@cos}{0pt}{0pt}}%
+ \expandafter}%
+ \expandafter\def\expandafter\pgfsysanim@code@begin\expandafter{\pgfsysanim@code@begin}%
+ \fi%
+ \pgfsysanim@add@trans%
+}
+
+\def\pgfsysanim@prep@attr@skewx{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@scalar%
+ {%
+ \pgfmathtan@{\pgfsysanim@x@val}%
+ \edef\pgfsysanim@code@begin{\noexpand\pgfsys@transformcm{1}{0}{\pgfmathresult}{1}{0pt}{0pt}}%
+ \expandafter}%
+ \expandafter\def\expandafter\pgfsysanim@code@begin\expandafter{\pgfsysanim@code@begin}%
+ \fi%
+ \pgfsysanim@add@trans%
+}
+
+\def\pgfsysanim@prep@attr@skewy{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@scalar%
+ {%
+ \pgfmathtan@{\pgfsysanim@x@val}%
+ \edef\pgfsysanim@code@begin{\noexpand\pgfsys@transformcm{1}{\pgfmathresult}{0}{1}{0pt}{0pt}}%
+ \expandafter}%
+ \expandafter\def\expandafter\pgfsysanim@code@begin\expandafter{\pgfsysanim@code@begin}%
+ \fi%
+ \pgfsysanim@add@trans%
+}
+
+\def\pgfsysanim@prep@attr@motion{%
+ \ifx\pgfsysanim@base@value\pgfutil@empty%
+ \else%
+ \pgferror{You may not provide a base value for a motion}%
+ \let\pgfsysanim@base@value\pgfutil@empty%
+ \fi%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@motion%
+ \expandafter\pgfsysanim@prep@attr@motion@\pgfsysanim@motion@trans%
+ \fi%
+ \pgfsysanim@add@trans%
+}
+\def\pgfsysanim@prep@attr@motion@#1#2#3#4#5#6{%
+ \ifpgfsysanim@rotatealong%
+ \def\pgfsysanim@code@begin{\pgfsys@transformcm{#1}{#2}{#3}{#4}{#5}{#6}}%
+ \else%
+ \def\pgfsysanim@code@begin{\pgfsys@transformshift{#5}{#6}}%
+ \fi%
+}
+
+
+\def\pgfsysanim@prep@attr@strokecolor{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@color%
+ \pgfsysanim@cap@scalar{\pgfsysanim@x@val}{0}{1}%
+ \pgfsysanim@cap@scalar{\pgfsysanim@y@val}{0}{1}%
+ \pgfsysanim@cap@scalar{\pgfsysanim@z@val}{0}{1}%
+ \pgfsysanim@attach{strokecolor}{\noexpand\pgfsys@color@rgb@stroke{\pgfsysanim@x@val}{\pgfsysanim@y@val}{\pgfsysanim@z@val}}{}%
+ \fi%
+}
+
+\def\pgfsysanim@prep@attr@fillcolor{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@color%
+ \pgfsysanim@cap@scalar{\pgfsysanim@x@val}{0}{1}%
+ \pgfsysanim@cap@scalar{\pgfsysanim@y@val}{0}{1}%
+ \pgfsysanim@cap@scalar{\pgfsysanim@z@val}{0}{1}%
+ \pgfsysanim@attach{fillcolor}{\noexpand\pgfsys@color@rgb@fill{\pgfsysanim@x@val}{\pgfsysanim@y@val}{\pgfsysanim@z@val}}{}%
+ \fi%
+}
+
+\def\pgfsysanim@prep@attr@color{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@color%
+ \pgfsysanim@cap@scalar{\pgfsysanim@x@val}{0}{1}%
+ \pgfsysanim@cap@scalar{\pgfsysanim@y@val}{0}{1}%
+ \pgfsysanim@cap@scalar{\pgfsysanim@z@val}{0}{1}%
+ \pgfsysanim@attach{color}{\noexpand\pgfsys@color@rgb{\pgfsysanim@x@val}{\pgfsysanim@y@val}{\pgfsysanim@z@val}}{}%
+ \fi%
+}
+
+\newif\ifpgfsys@animation@view@hooked
+
+\def\pgfsysanim@prep@attr@viewbox{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@viewbox%
+ \pgfsys@attach@to@id{\pgfsysanim@whom@id}{}{%
+ \ifpgfsys@animation@view@hooked%
+ \else%
+ % Hook into viewbox systems layer commands
+ \let\pgfsys@viewboxmeet@orig\pgfsys@viewboxmeet%
+ \let\pgfsys@viewboxmeet\pgfsysanim@hooked@viewboxmeet%
+ \let\pgfsys@viewboxslice@orig\pgfsys@viewboxslice%
+ \let\pgfsys@viewboxslice\pgfsysanim@hooked@viewboxslice%
+ \pgfsys@animation@view@hookedtrue%
+ \fi%
+ }{}{}%
+ \edef\pgfsysanim@temp{{\pgfsysanim@x@val}{\pgfsysanim@y@val}{\pgfsysanim@z@val}{\pgfsysanim@w@val}}%
+ \expandafter\pgfsysanim@attach@special\csname pgfsysanim@hook@for@\pgfsys@id@ref{\pgfsysanim@whom@id}{\pgfsysanim@whom@type}\endcsname\pgfsysanim@temp%
+ \fi%
+}
+\def\pgfsysanim@hooked@viewboxmeet#1#2#3#4#5#6#7#8{%
+ \expandafter\ifx\csname pgfsysanim@hook@for@\pgfsys@id@refcurrent\endcsname\relax%
+ \pgfsys@viewboxmeet@orig{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
+ \else%
+ \csname pgfsysanim@hook@for@\pgfsys@id@refcurrent\endcsname%
+ \ifx\pgfsysanim@c@begin\pgfutil@empty%
+ % should not happen, but, then, ignore
+ \else%
+ \expandafter\pgfsysanim@hooked@viewboxmeet@\pgfsysanim@c@begin{#1}{#2}{#3}{#4}%
+ \fi%
+ \expandafter\global\expandafter\let\csname pgfsysanim@hook@for@\pgfsys@id@refcurrent\endcsname\relax%
+ \fi%
+}
+\def\pgfsysanim@hooked@viewboxmeet@#1#2#3#4#5#6#7#8{%
+ \pgfsys@viewboxmeet@orig{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}%
+}
+\def\pgfsysanim@hooked@viewboxslice#1#2#3#4#5#6#7#8{%
+ \expandafter\ifx\csname pgfsysanim@hook@for@\pgfsys@id@refcurrent\endcsname\relax%
+ \pgfsys@viewboxslice@orig{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
+ \else%
+ \csname pgfsysanim@hook@for@\pgfsys@id@refcurrent\endcsname%
+ \expandafter\pgfsysanim@hooked@viewboxslice@\pgfsysanim@c@begin{#1}{#2}{#3}{#4}%
+ \expandafter\global\expandafter\let\csname pgfsysanim@hook@for@\pgfsys@id@refcurrent\endcsname\relax%
+ \fi%
+}
+\def\pgfsysanim@hooked@viewboxslice@#1#2#3#4#5#6#7#8{%
+ \pgfsys@viewboxslice@orig{#5}{#6}{#7}{#8}{#1}{#2}{#3}{#4}%
+}
+
+
+\newif\ifpgfsys@animation@path@hooked
+
+\def\pgfsysanim@prep@attr@path{%
+ \ifpgfsysanim@valid@snapshot@time%
+ \pgfsysanim@comp@path%
+ \pgfsys@attach@to@id{\pgfsysanim@whom@id}{}{%
+ \ifpgfsys@animation@path@hooked%
+ \else%
+ % Hook into path systems layer commands
+ \let\pgfsys@discardpath@orig\pgfsys@discardpath%
+ \let\pgfsys@stroke@orig\pgfsys@stroke%
+ \let\pgfsys@fill@orig\pgfsys@fill%
+ \let\pgfsys@fillstroke@orig\pgfsys@fillstroke%
+ \let\pgfsys@closestroke@orig\pgfsys@closestroke%
+ \let\pgfsys@discardpath\pgfsys@discardpath@hook%
+ \let\pgfsys@stroke\pgfsys@stroke@hook%
+ \let\pgfsys@fill\pgfsys@fill@hook%
+ \let\pgfsys@fillstroke\pgfsys@fillstroke@hook%
+ \let\pgfsys@closestroke\pgfsys@closestroke@hook%
+ \pgfsys@animation@path@hookedtrue%
+ \fi%
+ }{}{}%
+ \expandafter\pgfsysanim@attach@special\csname pgfsysanim@phook@for@\pgfsys@id@ref{\pgfsysanim@whom@id}{\pgfsysanim@whom@type}\endcsname\pgfsysanim@path@all%
+ \fi%
+}
+\def\pgfsys@stroke@hook{\pgfsysanim@with@tipstrue\pgfsysanim@path@hooks\pgfsys@stroke@orig}
+\def\pgfsys@fill@hook{\pgfsysanim@with@tipsfalse\pgfsysanim@path@hooks\pgfsys@fill@orig}
+\def\pgfsys@fillstroke@hook{\pgfsysanim@with@tipstrue\pgfsysanim@path@hooks\pgfsys@fillstroke@orig}
+\def\pgfsys@closestroke@hook{\pgfsysanim@with@tipsfalse\pgfsysanim@path@hooks\pgfsys@closestroke@orig}
+\def\pgfsys@discardpath@hook{\pgfsysanim@with@tipsfalse\pgfsysanim@path@hooks\pgfsys@discardpath@orig}
+
+\newif\ifpgfsysanim@with@tips
+
+\def\pgfsysanim@path@hooks#1{%
+ {%
+ \expandafter\ifx\csname pgfsysanim@phook@for@\pgfsys@id@refcurrent\endcsname\relax%
+ #1%
+ \else%
+ \pgfsys@discardpath@orig%
+ \csname pgfsysanim@phook@for@\pgfsys@id@refcurrent\endcsname%
+ \pgfsysanim@c@begin%
+ \pgfsysanim@path@val%
+ #1%
+ \ifpgfsysanim@with@tips%
+ \ifx\pgfsysanim@path@val\pgfutil@empty\else%
+ \pgfsysanim@prepare@end@of@path%
+ \begingroup%
+ \pgfsysanim@prepare@start@of@path%
+ \pgfsysanim@add@marker@at@start%
+ \endgroup%
+ \pgfsysanim@add@marker@at@end%
+ \fi%
+ \fi%
+ \expandafter\global\expandafter\let\csname pgfsysanim@phook@for@\pgfsys@id@refcurrent\endcsname\relax%
+ \fi%
+ }%
+}
+
+
+\def\pgfsysanim@prepare@start@of@path{%
+ \ifx\pgfsysanim@snap@tip@start\pgfutil@empty\else
+ %
+ % Step 1: Split
+ %
+ \ifx\pgfprocessresultpathsuffix\relax%
+ % Ok, still need to compute the split:
+ \pgfprocesssplitpath{\pgf@arrowpath}%
+ \fi%
+ %
+ % Step 2: extract
+ %
+ \expandafter\pgf@parse@start\pgfprocessresultpathsuffix\pgf@stop\pgf@stop\pgf@stop%
+ %
+ % Step 3: prep
+ %
+ \pgf@prep@start%
+ \fi%
+}
+\def\pgfsysanim@add@marker@at@start{%
+ \ifx\pgfsysanim@snap@tip@start\pgfutil@empty\else
+ %
+ % Step 4: draw
+ %
+ {%
+ \pgftransformreset%
+ \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgfsys@beginscope%
+ \pgflowlevelsynccm%
+ \pgfsys@marker@use{\pgfsysanim@snap@tip@start}%
+ \pgfsys@endscope%
+ }%
+ \fi%
+}
+
+
+\def\pgfsysanim@prepare@end@of@path{%
+ \let\pgfprocessresultpathsuffix\relax% flag that nothing has happened...
+ \let\pgfprocessresultsubpathsuffix\relax%
+ \pgf@precise@shorteningfalse%
+ \edef\pgf@path@shortening@distance{0pt}%
+ \ifx\pgfsysanim@snap@tip@end\pgfutil@empty\else
+ %
+ % Step 1: Split
+ %
+ \pgfprocesssplitpath{\pgfsysanim@path@val}%
+ \pgfprocesssplitsubpath{\pgfprocessresultpathsuffix}%
+ %
+ % Step 2: extract
+ %
+ \expandafter\pgf@parse@end\pgfprocessresultsubpathsuffix\pgf@stop\pgf@stop\pgf@stop%
+ %
+ % Step 3: prep
+ %
+ \pgf@prep@end%
+ \fi%
+}
+\def\pgfsysanim@add@marker@at@end{%
+ \ifx\pgfsysanim@snap@tip@end\pgfutil@empty\else
+ %
+ % Step 4: draw
+ %
+ {%
+ \pgftransformreset%
+ \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}%
+ \pgfsys@beginscope%
+ \pgflowlevelsynccm%
+ \pgfsys@marker@use{\pgfsysanim@snap@tip@end}%
+ \pgfsys@endscope%
+ }%
+ \fi%
+}
+
+
+
+%
+% Interpolation functions
+%
+
+% Scalar interpolation
+
+\def\pgfsysanim@comp@scalar{%
+ \pgfsysanim@compute@fractions%
+ \pgfsysanim@mix@scalar%
+ \ifpgfsysanim@accumulate%
+ \ifnum\pgfsysanim@repeat@decimal=0\else%
+ \let\pgfsysanim@frac@b\pgfsysanim@one%
+ \let\pgfsysanim@prev@val\pgfsysanim@x@val%
+ \let\pgfsysanim@frac@a\pgfsysanim@repeat@decimal%
+ \let\pgfsysanim@next@val\pgfsysanim@last@val%
+ \pgfsysanim@mix@scalar%
+ \fi%
+ \fi%
+}
+\def\pgfsysanim@one{1}
+
+\def\pgfsysanim@mix@scalar{%
+ \pgf@x\pgfsysanim@prev@val pt%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y\pgfsysanim@next@val pt%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\pgf@sys@tonumber\pgf@x}%
+}
+\def\pgfsysanim@cap@scalar#1#2#3{%
+ \ifdim#1 pt<#2 pt%
+ \def#1{#2}%
+ \else\ifdim#1 pt>#3 pt%
+ \def#1{#3}%
+ \fi\fi%
+}
+
+
+% Scale interpolation
+
+\def\pgfsysanim@comp@scale{%
+ \pgfsysanim@compute@fractions%
+ \expandafter\expandafter\expandafter\pgfsysanim@mix@scale\expandafter\pgfsysanim@prev@val\pgfsysanim@next@val%
+ \ifpgfsysanim@accumulate%
+ \ifnum\pgfsysanim@repeat@decimal=0\else%
+ \let\pgfsysanim@frac@b\pgfsysanim@one%
+ \let\pgfsysanim@frac@a\pgfsysanim@repeat@decimal%
+ \expandafter\pgfsysanim@mix@scale\expandafter\pgfsysanim@x@val\expandafter\pgfsysanim@y@val\pgfsysanim@last@val%
+ \fi%
+ \fi%
+}
+\def\pgfsysanim@mix@scale#1#2#3#4{%
+ \pgf@x#1pt%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#3pt%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\pgf@sys@tonumber\pgf@x}%
+ \pgf@x#2pt%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#4pt%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@y@val{\pgf@sys@tonumber\pgf@x}%
+}
+
+
+% Dimension interpolation
+
+\def\pgfsysanim@comp@dimension{%
+ \pgfsysanim@compute@fractions%
+ \pgfsysanim@mix@dimension%
+ \ifpgfsysanim@accumulate%
+ \ifnum\pgfsysanim@repeat@decimal=0\else%
+ \let\pgfsysanim@frac@b\pgfsysanim@one%
+ \def\pgfsysanim@prev@val{\pgfsysanim@x@val pt}%
+ \let\pgfsysanim@frac@a\pgfsysanim@repeat@decimal%
+ \let\pgfsysanim@next@val\pgfsysanim@last@val%
+ \pgfsysanim@mix@dimension%
+ \fi%
+ \fi%
+}
+\def\pgfsysanim@mix@dimension{%
+ \pgf@x\pgfsysanim@prev@val%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y\pgfsysanim@next@val%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\pgf@sys@tonumber\pgf@x}%
+}
+
+
+
+% Translate interpolation
+
+\def\pgfsysanim@comp@translate{%
+ \pgfsysanim@compute@fractions%
+ \expandafter\expandafter\expandafter\pgfsysanim@mix@translate\expandafter\pgfsysanim@prev@val\pgfsysanim@next@val%
+ \ifpgfsysanim@accumulate%
+ \ifnum\pgfsysanim@repeat@decimal=0\else%
+ \let\pgfsysanim@frac@b\pgfsysanim@one%
+ \let\pgfsysanim@frac@a\pgfsysanim@repeat@decimal%
+ \edef\pgfsysanim@prev@val{{\pgfsysanim@x@val pt}{\pgfsysanim@y@val pt}}
+ \expandafter\expandafter\expandafter\pgfsysanim@mix@translate\expandafter\pgfsysanim@prev@val\pgfsysanim@last@val%
+ \fi%
+ \fi%
+}
+\def\pgfsysanim@mix@translate#1#2#3#4{%
+ \pgf@x#1%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#3%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\pgf@sys@tonumber\pgf@x}%
+ \pgf@x#2%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#4%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@y@val{\pgf@sys@tonumber\pgf@x}%
+}
+
+
+
+% Color interpolation
+
+\def\pgfsysanim@comp@color{%
+ \pgfsysanim@compute@fractions%
+ \expandafter\expandafter\expandafter\pgfsysanim@mix@color\expandafter\pgfsysanim@prev@val\pgfsysanim@next@val%
+ \ifpgfsysanim@accumulate%
+ \ifnum\pgfsysanim@repeat@decimal=0\else%
+ \let\pgfsysanim@frac@b\pgfsysanim@one%
+ \let\pgfsysanim@frac@a\pgfsysanim@repeat@decimal%
+ \expandafter\pgfsysanim@mix@color\expandafter\pgfsysanim@x@val\expandafter\pgfsysanim@y@val\expandafter\pgfsysanim@z@val\pgfsysanim@last@val%
+ \fi%
+ \fi%
+}
+\def\pgfsysanim@mix@color#1#2#3#4#5#6{%
+ \pgf@x#1pt%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#4pt%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\pgf@sys@tonumber\pgf@x}%
+ \pgf@x#2pt%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#5pt%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@y@val{\pgf@sys@tonumber\pgf@x}%
+ \pgf@x#3pt%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#6pt%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@z@val{\pgf@sys@tonumber\pgf@x}%
+}
+
+
+% Text interpolation
+
+\def\pgfsysanim@comp@text{%
+ \let\pgfsysanim@text@val\pgfsysanim@prev@val%
+}
+
+
+
+% Dash interpolation
+
+\def\pgfsysanim@comp@dash{%
+ \pgfsysanim@compute@fractions%
+ \expandafter\expandafter\expandafter\pgfsysanim@mix@dash\expandafter\pgfsysanim@prev@val\pgfsysanim@next@val%
+ \ifpgfsysanim@accumulate%
+ \ifnum\pgfsysanim@repeat@decimal=0\else%
+ \let\pgfsysanim@frac@b\pgfsysanim@one%
+ \let\pgfsysanim@frac@a\pgfsysanim@repeat@decimal%
+ \edef\pgfsysanim@prev@val{{\pgfsysanim@dash@vals}{\pgfsysanim@x@val pt}}%
+ \expandafter\expandafter\expandafter\pgfsysanim@mix@dash\expandafter\pgfsysanim@prev@val\pgfsysanim@last@val%
+ \fi%
+ \fi%
+}
+\def\pgfsysanim@mix@dash#1#2#3#4{%
+ \pgf@x#2\relax%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#4\relax%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\pgf@sys@tonumber\pgf@x}%
+ \let\pgfsysanim@dash@vals\pgfutil@empty%
+ \pgfsysanim@parse@dash#1,\pgf@stop#3,\pgf@stop%
+}
+\def\pgfsysanim@parse@dash{\pgfutil@ifnextchar\pgf@stop\pgfsysanim@parse@dash@done\pgfsysanim@parse@dash@first}
+\def\pgfsysanim@parse@dash@done\pgf@stop\pgf@stop{}%
+\def\pgfsysanim@parse@dash@first#1,#2\pgf@stop#3\pgf@stop{%
+ \pgf@x#1\relax%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgfsysanim@parse@dash@second#3\pgf@stop{#2}%
+}
+\def\pgfsysanim@parse@dash@second#1,#2\pgf@stop#3{%
+ \pgf@y#1\relax%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \def\pgfsys@temp{#2}%
+ \edef\pgfsysanim@dash@vals{\pgfsysanim@dash@vals\the\pgf@x\ifx\pgfsys@temp\pgfutil@empty\else,\fi}%
+ \pgfsysanim@parse@dash#3\pgf@stop#2\pgf@stop%
+}
+
+
+
+
+% Viewbox interpolation
+
+\def\pgfsysanim@comp@viewbox{%
+ \pgfsysanim@compute@fractions%
+ \expandafter\expandafter\expandafter\pgfsysanim@mix@viewbox\expandafter\pgfsysanim@prev@val\pgfsysanim@next@val%
+ \ifpgfsysanim@accumulate%
+ \pgferror{viewbox animations cannot accumulate / add}%
+ \fi%
+}
+\def\pgfsysanim@mix@viewbox#1#2#3#4#5#6#7#8{%
+ \pgf@x#1%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#5%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\the\pgf@x}%
+ \pgf@x#2%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#6%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@y@val{\the\pgf@x}%
+ \pgf@x#3%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#7%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@z@val{\the\pgf@x}%
+ \pgf@x#4%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#8%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@w@val{\the\pgf@x}%
+}
+
+
+
+
+% Path interpolation
+
+\def\pgfsysanim@comp@path{%
+ \pgfsysanim@compute@fractions%
+ \edef\pgfsysanim@path@tips{%
+ \def\noexpand\pgfsysanim@snap@tip@start{\pgfsysanim@snap@tip@start}%
+ \def\noexpand\pgfsysanim@snap@tip@end{\pgfsysanim@snap@tip@end}%
+ }%
+ \let\pgfsysanim@path@val\pgfutil@empty%
+ \expandafter\expandafter\expandafter\pgfsysanim@parse@path\expandafter\pgfsysanim@prev@val\expandafter\pgf@stop\expandafter\relax\pgfsysanim@next@val\pgf@stop\relax%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfsysanim@path@all\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfsysanim@path@val\expandafter\expandafter\expandafter{\expandafter\pgfsysanim@path@val\expandafter}\pgfsysanim@path@tips}%
+ \ifpgfsysanim@accumulate%
+ \pgferror{path animations cannot accumulate / add}%
+ \fi%
+}
+\def\pgfsysanim@parse@path{\pgfutil@ifnextchar\pgf@stop\pgfsysanim@parse@path@done\pgfsysanim@parse@path@first}
+\def\pgfsysanim@parse@path@done\pgf@stop\relax\pgf@stop\relax{}%
+\def\pgfsysanim@parse@path@first{\pgfutil@ifnextchar\bgroup\pgfsysanim@parse@path@first@num\pgfsysanim@parse@path@token}
+\def\pgfsysanim@parse@path@token#1#2\relax#3#4\relax{%
+ \expandafter\def\expandafter\pgfsysanim@path@val\expandafter{\pgfsysanim@path@val#1}%
+ \pgfsysanim@parse@path#2\relax#4\relax%
+}
+\def\pgfsysanim@parse@path@first@num#1#2\relax#3#4\relax{%
+ \pgf@x#1%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y#3%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfsysanim@path@val\expandafter\expandafter\expandafter{\expandafter\pgfsysanim@path@val\expandafter{\the\pgf@x}}%
+ \pgfsysanim@parse@path#2\relax#4\relax%
+}
+
+
+
+% Motion interpolation
+
+\def\pgfsysanim@comp@motion{%
+ \pgfsysanim@compute@fractions%
+ \pgf@x\pgfsysanim@prev@val pt%
+ \pgf@x\pgfsysanim@frac@b\pgf@x%
+ \pgf@y\pgfsysanim@next@val pt%
+ \advance\pgf@x by\pgfsysanim@frac@a\pgf@y%
+ \edef\pgfsysanim@x@val{\pgf@sys@tonumber\pgf@x}%
+ \ifdim\pgfsysanim@x@val pt=1pt%
+ \def\pgfsysanim@x@val{0.9999}% because of rounding problems in decorations
+ \fi%
+ \pgf@relevantforpicturesizefalse%
+ \pgfdecoratepath{pgfsysanim@motion}{%
+ \pgfsyssoftpath@setcurrentpath\pgfsysanim@snap@movealong%
+ }%
+ \ifpgfsysanim@accumulate%
+ \pgferror{motion animations cannot accumulate / add}%
+ \fi%
+}
+\pgfdeclaredecoration{pgfsysanim@motion}{s}{%
+ \state{s}[width=\pgfsysanim@x@val\pgfdecoratedremainingdistance,next state=final]{}%
+ \state{final}{\pgfgettransform\pgfsysanim@motion@trans\global\let\pgfsysanim@motion@trans\pgfsysanim@motion@trans}%
+}
+
+
+
+
+
+
+% Compute fractions and splines:
+
+\def\pgfsysanim@compute@fractions{%
+ \ifdim\pgf@xc=\pgfsysanim@prev@time pt%
+ \def\pgfsysanim@frac@a{0}%
+ \def\pgfsysanim@frac@b{1}%
+ \else%
+ \pgfmathsubtract@{\pgfsysanim@next@time}{\pgfsysanim@prev@time}%
+ \ifdim\pgfmathresult pt<0.01pt%
+ \def\pgfsysanim@frac@a{0}%
+ \def\pgfsysanim@frac@b{1}%
+ \else%
+ \let\pgfsysanim@divby\pgfmathresult%
+ \pgfmathsubtract@{\pgf@sys@tonumber\pgf@xc}{\pgfsysanim@prev@time}%
+ \pgfmathdivide@{\pgfmathresult}{\pgfsysanim@divby}%
+ \ifdim\pgfmathresult pt<0pt\def\pgfmathresult{0}\fi%
+ \ifdim\pgfmathresult pt>1pt\def\pgfmathresult{1}\fi%
+ \let\pgfsysanim@frac@a\pgfmathresult%
+ \pgfmathsubtract@{1}{\pgfmathresult}%
+ \let\pgfsysanim@frac@b\pgfmathresult%
+ \fi%
+ \fi%
+ \ifdim\pgfsysanim@frac@a pt=0pt%
+ \else\ifdim\pgfsysanim@frac@b pt=0pt%
+ \else%
+ \expandafter\expandafter\expandafter\pgfsysanim@apply@spline\expandafter\pgfsysanim@prev@spline\pgfsysanim@next@spline%
+ \fi\fi%
+}
+
+
+\def\pgfsysanim@apply@spline#1#2#3#4#5#6#7#8{%
+ \edef\pgfsys@temp{#3,#5,#4,#6}%
+ \ifx\pgfsys@temp\pgfsysanim@id@spline%
+ \else%
+ \def\pgfsysanim@prev@out@time{{#3}{#4}}%
+ \def\pgfsysanim@next@in@time{{#5}{#6}}%
+ \ifx\pgfsysanim@prev@out@time\pgfsys@stay@text%
+ \pgfsysanim@jump@splines%
+ \else\ifx\pgfsysanim@next@in@time\pgfsys@jump@text%
+ \pgfsysanim@jump@splines%
+ \else%
+ \pgf@xa#3pt%
+ \pgf@xb#5pt%
+ % #4 is val support a
+ % #6 is val support b
+ % our first approximation
+ \let\pgfsysanim@t\pgfsysanim@frac@a%
+ \let\pgfsysanim@s\pgfsysanim@frac@b%
+ \pgfsysanim@eval@spline%
+ \edef\pgfsysanim@ft{\the\pgf@x}%
+ \pgf@x\pgfsysanim@t pt%
+ \advance\pgf@x by256sp%
+ \pgf@y1pt%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgfsysanim@t{\pgf@sys@tonumber\pgf@x}%
+ \edef\pgfsysanim@s{\pgf@sys@tonumber\pgf@y}%
+ \pgfsysanim@eval@spline%
+ % Ok, now do Newton one step
+ \advance\pgf@x by-\pgfsysanim@ft%
+ \pgf@x256\pgf@x%
+ % \pgf@x is f'(t)
+ % must compute t - (f(t)-frac@a)/f'(t)
+ \pgf@ya\pgfsysanim@ft%
+ \advance\pgf@ya by-\pgfsysanim@frac@a pt%
+ \pgf@yb\pgf@x
+ \pgfmathreciprocal@{\pgf@sys@tonumber\pgf@yb}%
+ \ifdim\pgfmathresult pt>2.5pt%
+ \def\pgfmathresult{2.5}%
+ \fi%
+ \ifdim\pgfmathresult pt<-2.5pt%
+ \def\pgfmathresult{-2.5}%
+ \fi%
+ \pgf@x\pgfsysanim@t pt%
+ \advance\pgf@x by-\pgfmathresult\pgf@ya%
+ % \pgf@x is new t:
+ \pgf@y1pt%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgfsysanim@t{\pgf@sys@tonumber\pgf@x}%
+ \edef\pgfsysanim@s{\pgf@sys@tonumber\pgf@y}%
+ \pgfsysanim@eval@spline%
+ \edef\pgfsysanim@ft{\the\pgf@x}%
+ \pgf@x\pgfsysanim@t pt%
+ \advance\pgf@x by256sp%
+ \pgf@y1pt%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgfsysanim@t{\pgf@sys@tonumber\pgf@x}%
+ \edef\pgfsysanim@s{\pgf@sys@tonumber\pgf@y}%
+ \pgfsysanim@eval@spline%
+ % Ok, now do Newton one step2
+ \advance\pgf@x by-\pgfsysanim@ft%
+ \pgf@x256\pgf@x%
+ % \pgf@x is f'(t)
+ % must compute t - (f(t)-frac@a)/f'(t)
+ \pgf@ya\pgfsysanim@ft%
+ \advance\pgf@ya by-\pgfsysanim@frac@a pt%
+ \pgf@yb\pgf@x
+ \pgfmathreciprocal@{\pgf@sys@tonumber\pgf@yb}%
+ \ifdim\pgfmathresult pt>2.5pt%
+ \def\pgfmathresult{2.5}%
+ \fi%
+ \ifdim\pgfmathresult pt<-2.5pt%
+ \def\pgfmathresult{-2.5}%
+ \fi%
+ \pgf@x\pgfsysanim@t pt%
+ \advance\pgf@x by-\pgfmathresult\pgf@ya%
+ % \pgf@x is new t:
+ \pgf@y1pt%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgfsysanim@t{\pgf@sys@tonumber\pgf@x}%
+ \edef\pgfsysanim@s{\pgf@sys@tonumber\pgf@y}%
+ % Third Newton:
+ \pgfsysanim@eval@spline%
+ \edef\pgfsysanim@ft{\the\pgf@x}%
+ \pgf@x\pgfsysanim@t pt%
+ \advance\pgf@x by256sp%
+ \pgf@y1pt%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgfsysanim@t{\pgf@sys@tonumber\pgf@x}%
+ \edef\pgfsysanim@s{\pgf@sys@tonumber\pgf@y}%
+ \pgfsysanim@eval@spline%
+ % Ok, now do Newton one step2
+ \advance\pgf@x by-\pgfsysanim@ft%
+ \pgf@x256\pgf@x%
+ % \pgf@x is f'(t)
+ % must compute t - (f(t)-frac@a)/f'(t)
+ \pgf@ya\pgfsysanim@ft%
+ \advance\pgf@ya by-\pgfsysanim@frac@a pt%
+ \pgf@yb\pgf@x
+ \pgfmathreciprocal@{\pgf@sys@tonumber\pgf@yb}%
+ \ifdim\pgfmathresult pt>2.5pt%
+ \def\pgfmathresult{2.5}%
+ \fi%
+ \ifdim\pgfmathresult pt<-2.5pt%
+ \def\pgfmathresult{-2.5}%
+ \fi%
+ \pgf@x\pgfsysanim@t pt%
+ \advance\pgf@x by-\pgfmathresult\pgf@ya%
+ % \pgf@x is new t:
+ \pgf@y1pt%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgfsysanim@t{\pgf@sys@tonumber\pgf@x}%
+ \edef\pgfsysanim@s{\pgf@sys@tonumber\pgf@y}%
+ % now, evaluate target:
+ \pgf@xa#4pt%
+ \pgf@xb#6pt%
+ \pgfsysanim@eval@spline%
+ % \pgf@x is result:
+ \pgf@y1pt%
+ \advance\pgf@y by-\pgf@x%
+ \edef\pgfsysanim@frac@a{\pgf@sys@tonumber\pgf@x}%
+ \edef\pgfsysanim@frac@b{\pgf@sys@tonumber\pgf@y}%
+ \fi\fi%
+ \fi%
+}
+\def\pgfsysanim@id@spline{0,1,0,1}
+
+\def\pgfsysanim@eval@spline{%
+ % Iteration one: (0,#1,#2,1) reduced to (ya,yb,yc)
+ \pgf@ya\pgfsysanim@t\pgf@xa%
+ \pgf@yb\pgfsysanim@t\pgf@xb%
+ \advance\pgf@yb by\pgfsysanim@s\pgf@xa%
+ \pgf@yc\pgfsysanim@t pt%
+ \advance\pgf@yc by\pgfsysanim@s\pgf@xb%
+ % Iteration two: (ya,yb,yc) reduced to (y,xc)
+ \pgf@y\pgfsysanim@t\pgf@yb%
+ \advance\pgf@y by\pgfsysanim@s\pgf@ya%
+ \pgf@xc\pgfsysanim@t\pgf@yc%
+ \advance\pgf@xc by\pgfsysanim@s\pgf@yb%
+ % Iteration three: (y,xc) reduced to (x)
+ \pgf@x\pgfsysanim@t\pgf@xc%
+ \advance\pgf@x by\pgfsysanim@s\pgf@y%
+}
+
+\def\pgfsysanim@jump@splines{%
+ \ifx\pgfsysanim@prev@out@time\pgfsys@stay@text%
+ \ifx\pgfsysanim@next@in@time\pgfsys@jump@text%
+ \ifdim\pgfsysanim@frac@a pt<0.5pt%
+ \def\pgfsysanim@frac@a{0}%
+ \def\pgfsysanim@frac@b{1}%
+ \else%
+ \def\pgfsysanim@frac@a{1}%
+ \def\pgfsysanim@frac@b{0}%
+ \fi%
+ \else%
+ % Only stay, so go to begin
+ \def\pgfsysanim@frac@a{0}%
+ \def\pgfsysanim@frac@b{1}%
+ \fi%
+ \else
+ % Only jump, so go to end
+ \def\pgfsysanim@frac@a{1}%
+ \def\pgfsysanim@frac@b{0}%
+ \fi%
+}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsysprotocol.code.tex b/graphics/pgf/base/tex/generic/systemlayer/pgfsysprotocol.code.tex
new file mode 100644
index 0000000000..32052b8a29
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsysprotocol.code.tex
@@ -0,0 +1,70 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsysprotocol.code.tex}
+
+
+
+% This package provides the pgf system protocol layer. Protocolling is
+% used to record a bunch of graphic operations so that they can be
+% reused quickly at a later point.
+%
+% Basically, all ``recordable'' \pgfsys@xxxx commands call
+% \pgfsysprotocol@protocol for their protocolable literal
+% specials. The literal text will either be stored in the current
+% protocol. At a later point (actually, normally this happens
+% immediately afterwards), the accumulated protocolled text is invoked
+% using pgfsys@invokeprotocol.
+
+
+
+\let\pgfsysprotocol@currentprotocol=\pgfutil@empty
+\newif\ifpgfsysprotocol@buffered
+
+
+% Add to the protocol buffered
+\def\pgfsysprotocol@literalbuffered#1{%
+ \edef\pgfsysprotocol@temp{{#1\space}}%
+ \expandafter\pgfutil@g@addto@macro\expandafter\pgfsysprotocol@currentprotocol\pgfsysprotocol@temp%
+}
+
+% Add to the protocol
+\def\pgfsysprotocol@literal#1{%
+ \pgfsysprotocol@literalbuffered{#1}%
+ \ifpgfsysprotocol@buffered%
+ \else%
+ \pgfsysprotocol@flushcurrentprotocol%
+ \fi%
+}
+
+% Getting and setting the current protocol
+\def\pgfsysprotocol@getcurrentprotocol#1{%
+ \let#1=\pgfsysprotocol@currentprotocol%
+}
+
+\def\pgfsysprotocol@setcurrentprotocol#1{%
+ \global\let\pgfsysprotocol@currentprotocol=#1%
+}
+
+
+% Invoking the current protocol
+\def\pgfsysprotocol@invokecurrentprotocol{%
+ \ifx\pgfsysprotocol@currentprotocol\pgfutil@empty%
+ \else%
+ \expandafter\pgfsys@invoke\expandafter{\pgfsysprotocol@currentprotocol}%
+ \fi%
+}
+
+\def\pgfsysprotocol@flushcurrentprotocol{%
+ \pgfsysprotocol@invokecurrentprotocol%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/systemlayer/pgfsyssoftpath.code.tex b/graphics/pgf/base/tex/generic/systemlayer/pgfsyssoftpath.code.tex
new file mode 100644
index 0000000000..9fe3f1e7db
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/systemlayer/pgfsyssoftpath.code.tex
@@ -0,0 +1,204 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfsyssoftpath.code.tex}
+
+
+% This package provides the pgf system path abstraction layer. This
+% layer is used to construct paths first ``abstractly.'' These
+% abstract paths can still be modified, before they are ``made
+% concrete.''
+%
+% An abstract path consists of a sequence of basic building blocks,
+% each of which is a tuple consisting of two numbers (specifying a
+% coordinate) and a token. Possible tokens are:
+%
+% 1. moveto
+% 2. lineto
+% 3. rectcorner
+% 4. rectsize
+% 5. curvetosupporta
+% 6. curvetosupportb
+% 7. curveto
+% 8. closepath
+% 9. specialround
+%
+% A curveto must always be preceded by a curvetosupporta and a
+% curvetosupportb. A non-empty path must always begin with a
+% moveto. The coordinates of a closepath are non-specified, currently,
+% but they might be set to the coordinate of the path segment start,
+% in the future.
+
+
+% Access to the current path:
+%
+% Lots of stuff is added to the current path and it can get very long
+% (containing literally tens of thousands of tokens). For such macros,
+% adding things using a simple "g@addtomacro" takes more and more
+% time, resulting in quadratic runtime. To avoid this, ideally, one
+% would collect things in an array and then use a divide and conquer
+% merger. A simple intermediate solution is the following, implemented
+% here: We have the path and two buffers. New tokens are added to the
+% first buffer, which is quite small. When it overflow, its contents
+% is added to the second buffer, which is large. If that buffer
+% overflow, the contents is finally added to the main path (which can
+% have arbitrary length). Whenever the main path is set or read, the
+% buffers are flushed.
+%
+% Because of this buffering, it is imperative that the main path is
+% accessed only via appropriate interface macros.
+
+
+
+% The current path
+\let\pgfsyssoftpath@thepath=\pgfutil@empty
+\let\pgfsyssoftpath@bigbuffer=\pgfutil@empty
+\let\pgfsyssoftpath@smallbuffer=\pgfutil@empty
+\newcount\pgfsyssoftpath@smallbuffer@items
+\newcount\pgfsyssoftpath@bigbuffer@items
+
+\def\pgfsyssoftpath@flushbuffers{%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gdef%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfsyssoftpath@thepath%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
+ \expandafter\expandafter\expandafter\pgfsyssoftpath@thepath%
+ \expandafter\pgfsyssoftpath@bigbuffer\pgfsyssoftpath@smallbuffer}%
+ \global\let\pgfsyssoftpath@smallbuffer=\pgfutil@empty
+ \global\let\pgfsyssoftpath@bigbuffer=\pgfutil@empty
+ \global\pgfsyssoftpath@bigbuffer@items0\relax%
+ \global\pgfsyssoftpath@smallbuffer@items0\relax%
+}
+
+% Getting and setting the current path
+\def\pgfsyssoftpath@getcurrentpath#1{%
+ \pgfsyssoftpath@flushbuffers%
+ \let#1=\pgfsyssoftpath@thepath%
+}
+
+\def\pgfsyssoftpath@setcurrentpath#1{%
+ \global\let\pgfsyssoftpath@thepath=#1%
+ \global\let\pgfsyssoftpath@smallbuffer=\pgfutil@empty
+ \global\let\pgfsyssoftpath@bigbuffer=\pgfutil@empty
+ \global\pgfsyssoftpath@bigbuffer@items0\relax%
+ \global\pgfsyssoftpath@smallbuffer@items0\relax%
+}
+
+
+% Invoking the current path (slightly optimized)
+\def\pgfsyssoftpath@invokecurrentpath{%
+ \pgfsyssoftpath@thepath%
+ \pgfsyssoftpath@bigbuffer%
+ \pgfsyssoftpath@smallbuffer%
+}
+
+\def\pgfsyssoftpath@flushcurrentpath{%
+ \pgfsyssoftpath@invokecurrentpath%
+ \pgfsyssoftpath@setcurrentpath\pgfutil@empty%
+}
+
+% Add an item at the end
+\def\pgfsyssoftpath@addtocurrentpath#1{%
+ \global\advance\pgfsyssoftpath@smallbuffer@items by1\relax%
+ \ifnum\pgfsyssoftpath@smallbuffer@items<40\relax% good number?
+ \expandafter\gdef\expandafter\pgfsyssoftpath@smallbuffer\expandafter{\pgfsyssoftpath@smallbuffer#1}%
+ \else%
+ \pgfsyssoftpath@smalloverflow{#1}%
+ \fi%
+}
+\def\pgfsyssoftpath@smalloverflow#1{%
+ \global\advance\pgfsyssoftpath@bigbuffer@items by1\relax%
+ \ifnum\pgfsyssoftpath@bigbuffer@items<30\relax% good number?
+ \expandafter\expandafter\expandafter\gdef%
+ \expandafter\expandafter\expandafter\pgfsyssoftpath@bigbuffer%
+ \expandafter\expandafter\expandafter{\expandafter\pgfsyssoftpath@bigbuffer\pgfsyssoftpath@smallbuffer#1}%
+ \global\let\pgfsyssoftpath@smallbuffer=\pgfutil@empty%
+ \global\pgfsyssoftpath@smallbuffer@items0\relax%
+ \else%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gdef%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfsyssoftpath@thepath%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
+ \expandafter\expandafter\expandafter\pgfsyssoftpath@thepath
+ \expandafter\pgfsyssoftpath@bigbuffer\pgfsyssoftpath@smallbuffer#1}%
+ \global\let\pgfsyssoftpath@smallbuffer=\pgfutil@empty
+ \global\let\pgfsyssoftpath@bigbuffer=\pgfutil@empty
+ \global\pgfsyssoftpath@bigbuffer@items0\relax%
+ \global\pgfsyssoftpath@smallbuffer@items0\relax%
+ \fi%
+}
+
+
+
+\def\pgfsyssoftpath@lastmoveto{{0pt}{0pt}}
+
+\newif\ifpgfsyssoftpathmovetorelevant
+\pgfsyssoftpathmovetorelevanttrue
+
+% Add a moveto element to the current path
+\def\pgfsyssoftpath@moveto#1#2{%
+ \edef\pgfsyssoftpath@coord{{#1}{#2}}%
+ \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@movetotoken\pgfsyssoftpath@coord}%
+ \ifpgfsyssoftpathmovetorelevant%
+ \global\let\pgfsyssoftpath@lastmoveto\pgfsyssoftpath@coord%
+ \fi%
+}
+
+% Add a lineto element to the current path
+\def\pgfsyssoftpath@lineto#1#2{%
+ \edef\pgfsyssoftpath@coord{{#1}{#2}}%
+ \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@linetotoken\pgfsyssoftpath@coord}%
+}
+
+
+% Add curveto elements to the current path
+\def\pgfsyssoftpath@curveto#1#2#3#4#5#6{%
+ \edef\pgfsyssoftpath@temp{{%
+ \noexpand\pgfsyssoftpath@curvetosupportatoken{#1}{#2}%
+ \noexpand\pgfsyssoftpath@curvetosupportbtoken{#3}{#4}%
+ \noexpand\pgfsyssoftpath@curvetotoken{#5}{#6}%
+ }}%
+ \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp%
+}
+
+
+% Add rectangle elements to the current path
+\def\pgfsyssoftpath@rect#1#2#3#4{%
+ \edef\pgfsyssoftpath@temp{{%
+ \noexpand\pgfsyssoftpath@rectcornertoken{#1}{#2}%
+ \noexpand\pgfsyssoftpath@rectsizetoken{#3}{#4}%
+ }}%
+ \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp%
+}
+
+% Add closepath element to the current path
+\def\pgfsyssoftpath@closepath{%
+ \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@closepathtoken\pgfsyssoftpath@lastmoveto}%
+}
+
+% Add special element to the current path
+\def\pgfsyssoftpath@specialround#1#2{%
+ \edef\pgfsyssoftpath@temp{{#1}{#2}}%
+ \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@specialroundtoken\pgfsyssoftpath@temp}%
+}
+
+% Marshallers
+\def\pgfsyssoftpath@movetotoken#1#2{\pgfsys@moveto{#1}{#2}}
+\def\pgfsyssoftpath@linetotoken#1#2{\pgfsys@lineto{#1}{#2}}
+\def\pgfsyssoftpath@rectcornertoken#1#2#3#4#5{\pgfsys@rect{#1}{#2}{#4}{#5}} % #3 = \pgfsyssoftpath@rectsizetoken
+\def\pgfsyssoftpath@curvetosupportatoken#1#2#3#4#5#6#7#8{\pgfsys@curveto{#1}{#2}{#4}{#5}{#7}{#8}}
+\def\pgfsyssoftpath@closepathtoken#1#2{\pgfsys@closepath}
+\let\pgfsyssoftpath@specialroundtoken=\pgfutil@gobbletwo
+\def\pgfsyssoftpath@curvetosupportbtoken#1#2{curvetotokenb} % make sure this \ifx-equal only to itself
+\def\pgfsyssoftpath@curvetotoken#1#2{curvetotoken}% make sure this \ifx-equal only to itself
+
+
+\endinput
+
+%%% Local Variables:
+%%% mode: latex
+%%% End:
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfcalendar.code.tex b/graphics/pgf/base/tex/generic/utilities/pgfcalendar.code.tex
new file mode 100644
index 0000000000..0b02457d1f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfcalendar.code.tex
@@ -0,0 +1,801 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesFileRCS{pgfcalendar.code.tex}
+
+\ifdefined\pgfintloaded\else
+ \input pgfint.code.tex
+\fi
+
+% Translation stuff
+
+\ifx\translate\@undefined
+ \def\translate#1{#1}
+\fi
+
+% Load month dictionary, if possible
+
+\ifx\usedictionary\@undefined
+\else
+ \usedictionary{translator-months-dictionary}
+\fi
+
+
+
+
+% Typeset a calendar
+%
+% #1 = prefix for the calendar nodes
+% #2 = begin date in ISO format
+% #3 = end date in ISO format
+% #4 = date rendering code
+%
+% Description:
+%
+% First note that this macro need not be called inside a pgfpicture
+% (even though it often will be). You can use it to typeset
+% calendars also using packages other than pgf. You do not even need
+% to load pgf to use this file.
+%
+% A calendar is typeset as follows: You specify a range of dates (by
+% providing a begin and an end date). Then, for each date the code #4
+% is executed. When the code is called, lots of information about the
+% current date (like its day of week) is available. The job of
+% #4 is to render the date. Typically, this is done by placing nodes
+% somewhere, but the function could do other things as well.
+% It is also the job of #4 to position the calendar correctly.
+%
+% The different calls of #4 are not surrounded by TeX groups (though
+% you can do so yourself, of course). This means that settings can
+% accumulate between different calls, which is often desirable and
+% useful.
+%
+% Inside #4 code, different macros can be access:
+%
+% \pgfcalendarprefix
+% The parameter #1. This prefix is recommended for nodes inside the
+% calendar, but you have to use it yourself explicitly.
+%
+% \pgfcalendarbeginiso
+% Start date of range being typeset in ISO format (like 2006-01-10)
+%
+% \pgfcalendarbeginjulian
+% Julian day number of start date begin typeset
+%
+% \pgfcalendarendiso
+% End date of range begin typeset
+%
+% \pgfcalendarendjulian
+% Same as Julian day number
+%
+% \pgfcalendarcurrentjulian (a TeX-count)
+% Julian day number of day to be rendered/considered
+%
+% \pgfcalendarcurrentweekday
+% Weekday (0 = Monday) of day to be checked
+%
+% \pgfcalendarcurrentyear
+% Year of day to be checked
+%
+% \pgfcalendarcurrentmonth
+% Month of day to be checked
+%
+% \pgfcalendarcurrentday
+% Day of month of day to be checked
+%
+%
+% Inside the \pgfcalendar macro the macro \ifdate is available, which
+% has the same effect as \pgfcalendarifdate{\pgfcalendarcurrentjulian}
+% (only faster). This means that you
+% can write, say, \ifdate{Monday}{current date is a Monday}{Not a Monday}.
+%
+% Example:
+%
+% \begin{tikzpicture}
+% \pgfcalendar{cal}{2007-01-20}{2007-02-10}
+% {\node[anchor=base] {\pgfcalendaronday}; \pgftransformyshift{-1.5em}}
+% \end{tikzpicture}
+%
+% \pgfcalendar{cal}{2007-01-20}{2007-02-10}{ \pgfcalendaronday\ }
+
+\long\def\pgfcalendar#1#2#3#4{%
+ \begingroup%
+ % Setup local \ifdate
+ \let\ifdate=\pgfcalendar@local@ifdate%
+ % Let's start with computing start and end dates...
+ \def\pgfcalendarprefix{#1}%
+ \pgfcalendardatetojulian{#2}{\pgfcalendarcurrentjulian}%
+ \edef\pgfcalendarbeginjulian{\the\pgfcalendarcurrentjulian}%
+ \edef\pgfcalendarbeginiso{#2}%
+ \pgfcalendardatetojulian{#3}{\pgfutil@tempcnta}%
+ \edef\pgfcalendarendjulian{\the\pgfutil@tempcnta}%
+ \advance\pgfutil@tempcnta by1\relax%
+ \edef\pgfcalendarendjulianplus{\the\pgfutil@tempcnta}%
+ \edef\pgfcalendarendiso{#3}%
+ %
+ % Start main loop
+ %
+ \loop%
+ \ifnum\pgfcalendarcurrentjulian<\pgfcalendarendjulianplus\relax%
+ % Setup information about current date
+ \pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}%
+ {\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
+ \pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\pgfutil@tempcntb}%
+ \edef\pgfcalendarcurrentweekday{\the\pgfutil@tempcntb}%
+ % Render:
+ #4%
+ % Advance day:
+ \advance\pgfcalendarcurrentjulian by1\relax%
+ \repeat%
+ \endgroup%
+}
+
+\newcount\pgfcalendarcurrentjulian
+
+\def\pgfcalendar@local@ifdate{%
+ \let\pgfcalendarifdatejulian=\pgfcalendarcurrentjulian%
+ \let\pgfcalendarifdateyear=\pgfcalendarcurrentyear%
+ \let\pgfcalendarifdatemonth=\pgfcalendarcurrentmonth%
+ \let\pgfcalendarifdateday=\pgfcalendarcurrentday%
+ \let\pgfcalendarifdateweekday=\pgfcalendarcurrentweekday%
+ \pgfcalendar@launch@ifdate%
+}
+
+
+
+% Execute on specific kinds of dates
+%
+% #1 = ISO-format date
+% #2 = date specification
+% #3 = code
+%
+% Description:
+%
+% The given code #3 is execute on every day that matches the date
+% specification #2. This specification is a comma-separated list of
+% key-value pairs with the path /pgf/calendar. The code for a
+% key-value should check whether the given day matches its
+% specification. If so, it should set \pgfcalendarmatches to true.
+%
+% When the key-value code is executed, the following macros will have
+% been setup:
+%
+% \pgfcalendarifdatejulian
+% Julian day number of day to be checked
+%
+% \pgfcalendarifdateweekday
+% Weekday (0 = Monday) of day to be checked
+%
+% \pgfcalendarifdateyear
+% Year of day to be checked
+%
+% \pgfcalendarifdatemonth
+% Month of day to be checked
+%
+% \pgfcalendarifdateday
+% Day of month of day to be checked
+%
+% The setting of these macros will persist after the call, so a
+% side-effect of calling this macro is to setup these macros.
+%
+% By setting \ifpgfcalendar@do@not@recompute to false, the computation
+% of the year, month etc. is suppressed.
+%
+% Examples:
+%
+% \pgfcalendarifdate{2007-01-10}{all}{}
+% % Simply setup the macros
+%
+% \pgfcalendarifdate{2007-01-10}{mondays}{Is a monday}
+%
+% \pgfcalendarifdate{\mydate}{date=05-01}{\mydate is a Worker's Day}
+
+\def\pgfcalendarifdate#1#2#3#4{%
+ \pgfcalendardatetojulian{#1}{\pgfutil@tempcnta}%
+ \pgfcalendarjuliantodate{\pgfutil@tempcnta}
+ {\pgfcalendarifdateyear}{\pgfcalendarifdatemonth}{\pgfcalendarifdateday}%
+ \edef\pgfcalendarifdatejulian{\the\pgfutil@tempcnta}%
+ % Compute info about date
+ \pgfcalendarjuliantoweekday{\pgfutil@tempcnta}{\pgfutil@tempcntb}%
+ \edef\pgfcalendarifdateweekday{\the\pgfutil@tempcntb}%
+ %
+ \pgfcalendar@launch@ifdate{#2}{#3}{#4}%
+}
+
+
+\long\def\pgfcalendar@launch@ifdate#1{%
+ % When this macro is called, the pgfcalendarifdatexxxx macros must
+ % be setup correctly
+ %
+ % Set match to false
+ \pgfcalendarmatchesfalse%
+ \pgfqkeys{/pgf/calendar}{#1}%
+ \ifpgfcalendarmatches%
+ \expandafter\pgfutil@firstoftwo
+ \else%
+ \expandafter\pgfutil@secondoftwo
+ \fi%
+}
+
+\newif\ifpgfcalendarmatches
+
+
+% Keys for matching
+
+\pgfkeys{/pgf/calendar/all/.code=\pgfcalendarmatchestrue}
+
+\pgfkeys{/pgf/calendar/Monday/.code={\ifnum\pgfcalendarifdateweekday=0\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/Tuesday/.code={\ifnum\pgfcalendarifdateweekday=1\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/Wednesday/.code={\ifnum\pgfcalendarifdateweekday=2\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/Thursday/.code={\ifnum\pgfcalendarifdateweekday=3\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/Friday/.code={\ifnum\pgfcalendarifdateweekday=4\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/Saturday/.code={\ifnum\pgfcalendarifdateweekday=5\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/Sunday/.code={\ifnum\pgfcalendarifdateweekday=6\relax\pgfcalendarmatchestrue\fi}}
+
+\pgfkeys{/pgf/calendar/workday/.code={\ifnum\pgfcalendarifdateweekday<5\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/weekend/.code={\ifnum\pgfcalendarifdateweekday>4\relax\pgfcalendarmatchestrue\fi}}
+
+\pgfkeys{/pgf/calendar/equals/.cd,.value required,.code={%
+ \pgfcalendar@special@datetojulian{#1}%
+ \ifnum\pgfcalendarifdatejulian=\pgfutil@tempcnta\relax%
+ \pgfcalendarmatchestrue%
+ \fi}%
+}
+
+\pgfkeys{/pgf/calendar/day of month/.cd,.value required,.code={\ifnum#1=\pgfcalendarifdateday\relax\pgfcalendarmatchestrue\fi}}
+\pgfkeys{/pgf/calendar/end of month/.cd,.default=1,.code={%
+ % Tricky and expensive ... do only if necessary
+ \ifpgfcalendarmatches%
+ \else% sigh
+ {%
+ \pgfutil@tempcnta=\pgfcalendarifdatejulian\relax%
+ \advance\pgfutil@tempcnta by#1\relax%
+ \pgfcalendarjuliantodate{\pgfutil@tempcnta}{\pgf@dummy}{\pgf@dummy}{\pgf@cal@temp}%
+ \global\let\pgf@cal@temp=\pgf@cal@temp%
+ }%
+ \ifnum\pgf@cal@temp=1\relax\pgfcalendarmatchestrue\fi%
+ \fi}%
+}
+
+\pgfkeys{/pgf/calendar/at least/.cd,.value required,.code={%
+ \pgfcalendar@special@datetojulian{#1}%
+ \ifnum\pgfcalendarifdatejulian<\pgfutil@tempcnta\relax%
+ \else%
+ \pgfcalendarmatchestrue%
+ \fi%
+}}
+
+\pgfkeys{/pgf/calendar/at most/.cd,.value required,.code={%
+ \pgfcalendar@special@datetojulian{#1}%
+ \ifnum\pgfcalendarifdatejulian>\pgfutil@tempcnta\relax%
+ \else%
+ \pgfcalendarmatchestrue%
+ \fi%
+}}
+
+\pgfkeys{/pgf/calendar/between/.cd,.value required,.code args={#1and#2}{%
+ \pgfcalendar@special@datetojulian{#1}%
+ \ifnum\pgfcalendarifdatejulian<\pgfutil@tempcnta\relax%
+ \else%
+ \pgfcalendar@special@datetojulian{#2}%
+ \ifnum\pgfcalendarifdatejulian>\pgfutil@tempcnta\relax%
+ \else%
+ \pgfcalendarmatchestrue%
+ \fi%
+ \fi%
+}}
+
+\def\pgfcalendar@special@datetojulian#1{%
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfcalendar@special@split@test\pgf@temp-\relax{#1}%
+}
+
+\def\pgfcalendar@special@split@test#1-#2-#3\relax#4{%
+ \def\pgf@temp{#3}%
+ \ifx\pgf@temp\pgfutil@empty%
+ \def\pgf@temp{\pgfcalendarifdateyear-#1-#2}%
+ \else%
+ \def\pgf@temp{#4}%
+ \fi%
+ \pgfcalendardatetojulian{\pgf@temp}{\pgfutil@tempcnta}%
+}
+
+
+% Suggested name for nodes inside a calendar
+%
+% Description:
+%
+% It is suggested that (main) nodes (if present) in a calendar should
+% get this name.
+%
+% Example:
+%
+% \pgfcalendar{cal}{2007-01-20}{2007-02-10}{}
+% { \node[anchor=base] (\pgfcalendarsuggestedname) {\pgfcalendarifdateday};
+% \pgftransformyshift{-1.5em} }
+%
+% \draw (cal-2007-01-30) -- (cal-2007-02-08);
+
+\def\pgfcalendarsuggestedname{%
+ \ifx\pgfcalendarprefix\pgfutil@empty\else\pgfcalendarprefix-%
+ \pgfcalendarcurrentyear-\pgfcalendarcurrentmonth-\pgfcalendarcurrentday\fi%
+}
+
+
+
+%
+%
+% Date conversion functions
+%
+%
+
+
+
+% Convert a date to the Julian day number (number of days since
+% January 1st, -4712)
+%
+% #1 = date specification
+% #2 = counter that should be set to the number of days
+%
+% Description:
+%
+% The conversion is taken from the Wikipedia entry on Julian days.
+%
+% The date specification works as follows:
+%
+% - It starts with a year. Use \year for the current year (the year
+% the file is being typeset).
+% - Next comes a hyphen.
+% - Next comes a month (number). Use \month for the current month.
+% - Next comes a hyphen.
+% - Next comes either a day of month (number, use \day for current
+% day) or "last". The keyword "last" refers the last day of the
+% month. Thus, 2006-01-last is the same as 2006-01-31 and
+% 2000-02-last is the same as 2002-02-29.
+% - Next may come a plus sign, followed by a number (positive or
+% negative). This will adjust the date by the given number of
+% days. Thus, 2006-01-31+1 is the same as 2006-02-01 and
+% 2006-02-01+-2 is the same as 2006-01-30. And \year-\month-day+1 is
+% tomorrow. You may add a space before the +.
+%
+% Example:
+%
+% \pgfcalendardatetojulian{2006-01-10}{\mycount}
+
+\def\pgfcalendardatetojulian#1#2{\edef\pgf@temp{#1}\expandafter\pgfcalendar@datetojulian\pgf@temp+/{#2}}
+\def\pgfcalendar@datetojulian#1-#2-#3+#4/#5{%
+ {%
+ %
+ % Store year, month and days.
+ %
+ \count1=#1\relax%
+ \count2=#2\relax%
+ % If #3=="last", then calculate first day of next month
+ \edef\pgf@temp{#3}%
+ \ifx\pgf@temp\pgfcalendar@last@text%
+ \advance\count2 by1\relax%
+ \count3=1\relax%
+ \else%
+ \count3=#3\relax%
+ \fi%
+ %
+ % Store offset
+ %
+ \edef\pgf@@temp{#4}%
+ \ifx\pgf@@temp\pgfutil@empty%
+ \count8=0\relax%
+ \else%
+ \pgfcalendar@unpack#4%
+ \fi%
+ %
+ %
+ % 4) a = \lfloor (14-month) /12 \rfloor
+ %
+ \ifnum\count2<3\relax%
+ \count4=1\relax%
+ \else%
+ \count4=0\relax%
+ \fi%
+ %
+ % 5) y = year + 4800 - a
+ %
+ \count5=\count1\relax%
+ \advance\count5 by 4800\relax%
+ \advance\count5 by-\count4\relax%
+ %
+ % 6) m = month + 12a - 3
+ %
+ \count6=\count2\relax%
+ \count0=\count4\relax%
+ \multiply\count0 by12\relax
+ \advance\count6 by\count0\relax%
+ \advance\count6 by-3\relax%
+ %
+ % 7) jdn = day + \floor{(153 m+2)/5} + 365y + \floor{y/4} -
+ % \floor{y/100} + \florr{y/400} - 32045
+ %
+ \count7=\count3\relax%
+ % + \floor{(153 m+2)/5} :
+ \count0=\count6\relax%
+ \multiply\count0 by 153\relax%
+ \advance\count0 by 2\relax%
+ \divide\count0 by 5\relax%
+ \advance\count7 by \count0\relax%
+ % + 365y :
+ \count0=\count5%
+ \multiply\count0by365\relax%
+ \advance\count7 by\count0\relax%
+ % + \floor{y/4}
+ \count0=\count5\relax%
+ \divide\count0 by 4\relax%
+ \advance\count7 by\count0%
+ % - \floor{y/100}
+ \count0=\count5\relax%
+ \divide\count0 by 100\relax%
+ \advance\count7 by-\count0\relax%
+ % + \floor{y/400}
+ \count0=\count5\relax%
+ \divide\count0 by 400\relax%
+ \advance\count7 by\count0%
+ % - 32045
+ \advance\count7 by-32045\relax%
+ %
+ % Undo "last" advance
+ \ifx\pgf@temp\pgfcalendar@last@text%
+ \advance\count7by-1\relax%
+ \fi%
+ % Add offset
+ \advance\count7by\count8\relax%
+ \expandafter%
+ }%
+ \expandafter#5\the\count7\relax%
+}
+\def\pgfcalendar@last@text{last}
+\def\pgfcalendar@unpack#1+{%
+ \count8=#1\relax%
+}
+
+% Convert Julian day number date.
+%
+% #1 = the number of Julian days
+% #2 = a macro in which the year should be stored.
+% #3 = a macro in which the month should be stored.
+% #4 = a macro in which the day should be stored.
+%
+% Formula used:
+%
+% 1) J = Julian day number
+% 2) j = J + 32044
+% 3) g = j div 146097
+% 4) dg = j mod 146097
+% 5) c = (dg div 36524 + 1) * 3 div 4
+% 6) dc = dg - c * 36524
+% 7) b = dc div 1461
+% 8) db = dc mod 1461
+% 9) a = (db div 365 + 1) * 3 div 4
+% 10)da = db - a * 365
+% 11)y = g * 400 + c * 100 + b * 4 + a
+% 12)m = (da * 5 + 308) div 153 - 2
+% 13)d = da - (m + 4) * 153 div 5 + 122
+% 14)Y = y - 4800 + (m + 2) div 12
+% 15)M = (m + 2) mod 12 + 1
+% 16)D = d + 1
+%
+% Example
+%
+% \pgfcalendarjuliantodate{\mynumber}{\myyear}{\mymonth}{\myday}
+
+\def\pgfcalendarjuliantodate#1#2#3#4{%
+ {%
+ % 1) J = Julian day number
+ \count1=#1\relax%
+ % 2) j = J + 32044
+ \count2=\count1\relax%
+ \advance\count2 by 32044\relax%
+ % 3) g = j div 146097
+ \count3=\count2\relax%
+ \divide\count3 by 146097\relax%
+ % 4) dg = j mod 146097
+ \count4=\count3\relax%
+ \multiply\count4 by-146097\relax%
+ \advance\count4 by\count2\relax%
+ % 5) c = (dg div 36524 + 1) * 3 div 4
+ \count5=\count4\relax%
+ \divide\count5 by36524\relax%
+ \advance\count5 by1\relax%
+ \multiply\count5 by3\relax%
+ \divide\count5 by4\relax%
+ % 6) dc = dg - c * 36524
+ \count6=\count4\relax%
+ \count0=\count5\relax%
+ \multiply\count0 by-36524\relax%
+ \advance\count6 by\count0\relax%
+ % 7) b = dc div 1461
+ \count7=\count6\relax%
+ \divide\count7 by1461\relax%
+ % 8) db = dc mod 1461
+ \count8=\count7\relax%
+ \multiply\count8 by-1461\relax%
+ \advance\count8 by\count6\relax%
+ % 9) a = (db div 365 + 1) * 3 div 4
+ \count9=\count8\relax%
+ \divide\count9 by 365\relax%
+ \advance\count9 by 1\relax%
+ \multiply\count9 by3\relax%
+ \divide\count9 by4\relax%
+ % 10)da = db - a * 365
+ \count10=\count8\relax%
+ \count0=\count9\relax%
+ \multiply\count0 by-365\relax%
+ \advance\count10 by\count0\relax%
+ % 11)y = g * 400 + c * 100 + b * 4 + a
+ \count11=\count3\relax%
+ \multiply\count11 by400\relax%
+ \count0=\count5\relax%
+ \multiply\count0 by100\relax%
+ \advance\count11 by\count0\relax%
+ \count0=\count7\relax%
+ \multiply\count0 by4\relax%
+ \advance\count11 by\count0\relax%
+ \advance\count11 by\count9\relax%
+ % 12)m = (da * 5 + 308) div 153 - 2
+ \count12=\count10\relax%
+ \multiply\count12 by5\relax%
+ \advance\count12 by 308\relax%
+ \divide\count12 by 153\relax%
+ \advance\count12 by -2\relax%
+ % 13)d = - (m + 4) * 153 div 5 + 122 + da
+ \count13=\count12\relax%
+ \advance\count13 by 4\relax%
+ \multiply\count13 by153\relax%
+ \divide\count13 by5\relax%
+ \count13=-\count13\relax%
+ \advance\count13 by 122\relax%
+ \advance\count13 by \count10\relax%
+ % 14)Y = (m + 2) div 12 + y - 4800
+ \count14=\count12\relax%
+ \advance\count14 by 2\relax%
+ \divide\count14 by12\relax%
+ \advance\count14 by\count11\relax%
+ \advance\count14 by-4800\relax%
+ % 15)M = (m + 2) mod 12 + 1
+ \count15=\count12\relax%
+ \advance\count15 by2\relax%
+ \count0=\count15\relax%
+ \divide\count0 by12\relax%
+ \multiply\count0 by12\relax%
+ \advance\count15 by-\count0\relax%
+ \advance\count15 by1\relax%
+ % 16)D = d + 1
+ \count16=\count13%
+ \advance\count16by 1\relax%
+ %
+ \xdef\pgf@temp@year{\the\count14}%
+ \xdef\pgf@temp@month{\ifnum\count15<10 0\fi\the\count15}%
+ \xdef\pgf@temp@day{\ifnum\count16<10 0\fi\the\count16}%
+ }%
+ \let#2=\pgf@temp@year%
+ \let#3=\pgf@temp@month%
+ \let#4=\pgf@temp@day%
+}
+
+
+
+% Returns the day of week as a number between 0 = Monday and 6 =
+% Sunday
+%
+% #1 = a Julian day number
+% #2 = a counter into which the weekday should be put.
+%
+% Example:
+%
+% \pgfcalendardatetojulian{2006-01-10}{\mycount}
+% \pgfcalendarjuliantoweekday{\mycount}{\myweekday}
+
+\def\pgfcalendarjuliantoweekday#1#2{%
+ {%
+ \pgfutil@tempcnta=#1\relax%
+ #2=\pgfutil@tempcnta%
+ \divide#2by7\relax%
+ \multiply#2by-7\relax%
+ \advance#2by\pgfutil@tempcnta\relax%
+ \expandafter%
+ }%
+ \expandafter#2\the#2\relax%
+}
+
+
+
+% Converts a day of week into a weekday name (long or short)
+%
+% #1 = a number representing a weekday (0=Monday)
+%
+% Example:
+%
+% \pgfcalendardatetojulian{2006-01-10}{\mycount}
+% \pgfcalendarjuliantoweekday{\mycount}{\myweekday}
+% October 1st, 2006 was a \pgfcalendarweekdayname{\myweekday}
+
+\def\pgfcalendarweekdayname#1{%
+ \pgfutil@translate{\ifcase#1Monday\or Tuesday\or Wednesday\or Thursday\or Friday\or Saturday\or Sunday\fi}%
+}
+
+\def\pgfcalendarweekdayshortname#1{%
+ \pgfutil@translate{\ifcase#1Mon\or Tue\or Wed\or Thu\or Fri\or Sat\or Sun\fi}%
+}
+
+
+% Converts a month of year number into a month name (long or short)
+%
+% #1 = a number representing a month (1=January)
+%
+% Example:
+%
+% \pgfcalendarmonthname
+
+\def\pgfcalendarmonthname#1{%
+ \pgfutil@translate{\ifcase#1\or January\or February\or March\or April\or
+ May\or June\or July\or August\or September\or October\or
+ November\or December\fi}%
+}
+
+\def\pgfcalendarmonthshortname#1{%
+ \pgfutil@translate{\ifcase#1\or Jan\or Feb\or Mar\or Apr\or
+ May\or Jun\or Jul\or Aug\or Sep\or Oct\or
+ Nov\or Dec\fi}%
+}
+
+
+
+
+
+
+% Macro for easy typesetting of days, etc.
+%
+% #1 = kind selection
+% #2 = length and representation selection
+%
+% Description:
+%
+% Replaces the shorthand according to the following rules: The
+% first letter of the shorthand describes the kind of
+% shorthand. Possible kinds are:
+%
+% d = day of current date (in an invocation of \pgfcalendar)
+% m = month of current date
+% y = year of current date
+% w = week day of current date
+%
+% The second parameter determines how the kind is represented:
+%
+% - = shortest possible numerical way (allowed only for d, m, y)
+% = = same, but always of the same length (padded with blanks as
+% needed, allowed only for d, m, y)
+% 0 = numerical representation for d and m padded with leading zeros.
+% t = textual representation (allowed only for d, m, w)
+% . = abbreviated textual representation (allowed only for d, m, w)
+%
+% It is advised that you say, for example,
+% \let\%=\pgfcalendarshorthand.
+%
+% With this setting, you can typeset an ISO-date by saying \%y0-\%m0-\%d0.
+% For another example, on 2007-02-09, which is a
+% Friday, you can write "\%wt, \%mt \%d-, \%y0" to get "Friday, February 9, 2007"
+
+\def\pgfcalendarshorthand#1#2{\csname pgfcalendar@shorthand@#1#2\endcsname}
+\expandafter\def\csname pgfcalendar@shorthand@d-\endcsname{%
+ {\pgfutil@tempcnta=\pgfcalendarcurrentday\relax\the\pgfutil@tempcnta}}
+\expandafter\def\csname pgfcalendar@shorthand@d=\endcsname{%
+ {\pgfutil@tempcnta=\pgfcalendarcurrentday\relax\ifnum\pgfutil@tempcnta<10\relax\setbox0=\hbox{1}\kern\wd0\relax\fi\the\pgfutil@tempcnta}}
+\expandafter\def\csname pgfcalendar@shorthand@d0\endcsname{%
+ \pgfcalendarcurrentday}
+\expandafter\def\csname pgfcalendar@shorthand@m-\endcsname{%
+ {\pgfutil@tempcnta=\pgfcalendarcurrentmonth\relax\the\pgfutil@tempcnta}}
+\expandafter\def\csname pgfcalendar@shorthand@m=\endcsname{%
+ {\pgfutil@tempcnta=\pgfcalendarcurrentmonth\relax\ifnum\pgfutil@tempcnta<10\relax\setbox0=\hbox{1}\kern\wd0\relax\fi\the\pgfutil@tempcnta}}
+\expandafter\def\csname pgfcalendar@shorthand@m0\endcsname{%
+ \pgfcalendarcurrentmonth}
+\expandafter\def\csname pgfcalendar@shorthand@y-\endcsname{%
+ \pgfcalendarcurrentyear}
+\expandafter\def\csname pgfcalendar@shorthand@y=\endcsname{%
+ \pgfcalendarcurrentyear}
+\expandafter\def\csname pgfcalendar@shorthand@y0\endcsname{%
+ \pgfcalendarcurrentyear}
+\expandafter\def\csname pgfcalendar@shorthand@w.\endcsname{%
+ \pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}}
+\expandafter\def\csname pgfcalendar@shorthand@wt\endcsname{%
+ \pgfcalendarweekdayname{\pgfcalendarcurrentweekday}}
+\expandafter\def\csname pgfcalendar@shorthand@m.\endcsname{%
+ \pgfcalendarmonthshortname{\pgfcalendarcurrentmonth}}
+\expandafter\def\csname pgfcalendar@shorthand@mt\endcsname{%
+ \pgfcalendarmonthname{\pgfcalendarcurrentmonth}}
+
+% Calculate the date of Easter
+
+% Credits to HÃ¥kon Malmedal on TeX.SX https://tex.stackexchange.com/a/57243
+% and Donald Knuth, TAoCP, Vol 1, 3rd Ed, Section 1.3.2, Algorithm E, p. 160.
+
+\newcount\pgf@cal@easter@Y
+\newcount\pgf@cal@easter@G
+\newcount\pgf@cal@easter@C
+\newcount\pgf@cal@easter@X
+\newcount\pgf@cal@easter@Z
+\newcount\pgf@cal@easter@D
+\newcount\pgf@cal@easter@E
+\newcount\pgf@cal@easter@N
+\newcount\pgf@cal@easter@M
+\newcount\pgf@cal@easter@julianday
+
+\pgfutil@protected\def\pgfcalendareastersunday#1#2{%
+ \pgfintset\pgf@cal@easter@Y{#1}%
+ % E1. Golden number
+ \pgfintset\pgf@cal@easter@G{%
+ \pgfintmod{\pgf@cal@easter@Y}{19}+1
+ }%
+ % E2. Century
+ \pgfintset\pgf@cal@easter@C{%
+ \pgfintdivfloor{\pgf@cal@easter@Y}{100}+1
+ }%
+ % E3. Corrections
+ \pgfintset\pgf@cal@easter@X{%
+ \pgfintdivfloor{3*\pgf@cal@easter@C}{4}-12
+ }%
+ \pgfintset\pgf@cal@easter@Z{%
+ \pgfintdivfloor{8*\pgf@cal@easter@C+5}{25}-5
+ }%
+ % E4. Find Sunday
+ \pgfintset\pgf@cal@easter@D{%
+ \pgfintdivfloor{5*\pgf@cal@easter@Y}{4}-\pgf@cal@easter@X-10
+ }%
+ % E5. Epact (full moon)
+ \pgfintset\pgf@cal@easter@E{%
+ \pgfintmod{11*\pgf@cal@easter@G+20+\pgf@cal@easter@Z-\pgf@cal@easter@X}{30}
+ }%
+ \ifnum\pgf@cal@easter@E<0
+ \pgfintset\pgf@cal@easter@E{\pgf@cal@easter@E+30}%
+ \fi
+ \ifnum\pgf@cal@easter@E=25
+ \ifnum\pgf@cal@easter@G>11
+ \pgfintset\pgf@cal@easter@E{\pgf@cal@easter@E+1}%
+ \fi
+ \else
+ \ifnum\pgf@cal@easter@E=24
+ \pgfintset\pgf@cal@easter@E{\pgf@cal@easter@E+1}%
+ \fi
+ \fi
+ % E6. Find full moon
+ \pgfintset\pgf@cal@easter@N{44-\pgf@cal@easter@E}%
+ \ifnum\pgf@cal@easter@N<21
+ \pgfintset\pgf@cal@easter@N{\pgf@cal@easter@N+30}%
+ \fi
+ % E7. Advance to Sunday
+ \pgfintset\pgf@cal@easter@N{%
+ \pgf@cal@easter@N+7-\pgfintmod{\pgf@cal@easter@D+\pgf@cal@easter@N}{7}
+ }%
+ % E8. Get month
+ \ifnum\pgf@cal@easter@N>31
+ \pgfintset\pgf@cal@easter@N{\pgf@cal@easter@N-31}%
+ \pgfintset\pgf@cal@easter@M{4}% April
+ \else
+ \pgfintset\pgf@cal@easter@M{3}% March
+ \fi
+ \pgfcalendardatetojulian
+ {\pgf@cal@easter@Y-\pgf@cal@easter@M-\pgf@cal@easter@N}%
+ {#2}%
+}
+
+\pgfkeys{/pgf/calendar/Easter/.cd,.default=0,.code={%
+ \pgfcalendareastersunday{\pgfcalendarifdateyear}{\pgf@cal@easter@julianday}%
+ \ifnum\pgfcalendarifdatejulian=\pgfinteval{\pgf@cal@easter@julianday+#1}
+ \expandafter\pgfcalendarmatchestrue
+ \fi}%
+}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfexternal.tex b/graphics/pgf/base/tex/generic/utilities/pgfexternal.tex
new file mode 100644
index 0000000000..7f9c4a0293
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfexternal.tex
@@ -0,0 +1,32 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% In addition to the above licenses, this particular file may also be
+% directly inlined into other documents and this copyright notice may
+% be removed. Additionally, when you inline this file, you may modify
+% it as needed and you may remove comments.
+%
+% This file is intended to be distributed or even inlined into a file
+% when a document needs to be typeset on a system that does not have
+% pgf/TikZ installed.
+
+% "environment" for reading an external graphic. Note that there are
+% no (!) braces around the "name" of the environment
+%
+% #1 = name of the graphics file
+%
+% Example:
+%
+% \beginpgfgraphicnamed{mygraph}
+% \begin{tikzpicture}
+% ...
+% \end{tikzpicture}
+% \endpgfgraphicnamed
+
+\long\def\beginpgfgraphicnamed#1#2\endpgfgraphicnamed{\includegraphics{#1}}
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfexternalwithdepth.tex b/graphics/pgf/base/tex/generic/utilities/pgfexternalwithdepth.tex
new file mode 100644
index 0000000000..907083ef3b
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfexternalwithdepth.tex
@@ -0,0 +1,43 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% In addition to the above licenses, this particular file may also be
+% directly inlined into other documents and this copyright notice may
+% be removed. Additionally, when you inline this file, you may modify
+% it as needed and you may remove comments.
+%
+% This file is intended to be distributed or even inlined into a file
+% when a document needs to be typeset on a system that does not have
+% pgf/TikZ installed.
+
+% "environment" for reading an external graphic. Note that there are
+% no (!) braces around the "name" of the environment
+%
+% #1 = name of the graphics file
+%
+% Example:
+%
+% \beginpgfgraphicnamed{mygraph}
+% \begin{tikzpicture}
+% ...
+% \end{tikzpicture}
+% \endpgfgraphicnamed
+
+\long\def\beginpgfgraphicnamed#1#2\endpgfgraphicnamed{%
+ \begingroup
+ \setbox1=\hbox{\includegraphics{#1}}%
+ \openin1=#1.dpth
+ \ifeof1 \box1
+ \else
+ \read1 to\pgfincludeexternalgraphicsdp \closein1
+ \dimen0=\pgfincludeexternalgraphicsdp\relax
+ \hbox{\lower\dimen0 \box1 }%
+ \fi
+ \endgroup
+}
diff --git a/graphics/pgf/base/tex/generic/utilities/pgffor.code.tex b/graphics/pgf/base/tex/generic/utilities/pgffor.code.tex
new file mode 100644
index 0000000000..f81a61c9e1
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgffor.code.tex
@@ -0,0 +1,767 @@
+% Copyright 2019 by Till Tantau and Mark Wibrow
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ProvidesPackageRCS{pgffor.code.tex}
+
+% pgfmath is needed
+\ifdefined\pgfmathloaded\else
+ \input pgfmath.code.tex
+\fi
+
+\newdimen\pgffor@iter
+\newdimen\pgffor@skip
+\newif\ifpgffor@continue
+
+
+\def\pgffor@reset@hooks{%
+ \let\pgffor@beginhook=\relax%
+ \let\pgffor@endhook=\relax%
+ \let\pgffor@afterhook=\relax%
+}
+\pgffor@reset@hooks
+
+
+% Stack emulation
+%
+\newtoks\pgffor@stack
+\pgffor@stack={{}{}{}}
+
+\def\pgffor@stackpush#1{%
+ \def\pgffor@stacktemp{#1}%
+ \expandafter\expandafter\expandafter\pgffor@stack\expandafter\expandafter\expandafter=%
+ \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter%
+ {\expandafter\pgffor@stacktemp\expandafter}\the\pgffor@stack}%
+}
+
+\def\pgffor@stackpop{\expandafter\pgffor@@stackpop\the\pgffor@stack\pgffor@stackstop}
+\def\pgffor@@stackpop#1#2\pgffor@stackstop{\pgffor@stack{#2}#1}
+
+\def\pgffor@emptyvalues{, \pgffor@stop,}%
+
+\def\pgffor@foreach{%
+ \pgffor@atbeginforeach%
+ \let\pgffor@assign@before@code=\pgfutil@empty%
+ \let\pgffor@assign@after@code=\pgfutil@empty%
+ \let\pgffor@assign@once@code=\pgfutil@empty%
+ \let\pgffor@remember@code=\pgfutil@empty%
+ \let\pgffor@remember@once@code=\pgfutil@empty%
+ \pgffor@alphabeticsequencefalse%
+ \pgffor@contextfalse%
+ %
+ \let\pgffor@var=\pgfutil@empty
+ %
+ \pgffor@vars%
+}
+
+\let\foreach=\pgffor@foreach
+
+\def\pgffor@vars{%
+ \pgfutil@ifnextchar i{\pgffor@@vars@end}{%
+ \pgfutil@ifnextchar[{\pgffor@@vars@opt}{%]
+ \pgfutil@ifnextchar/{\pgffor@@vars@slash@gobble}{%
+ \pgffor@@vars}}}}%
+
+\def\pgffor@@vars@end in{\pgfutil@ifnextchar\bgroup{\pgffor@normal@list}{\pgffor@macro@list}}
+\def\pgffor@@vars@opt[#1]{\pgfkeys{/pgf/foreach/.cd,#1}\pgffor@vars}
+\def\pgffor@@vars#1{\pgffor@var@add#1\pgffor@stop\pgffor@vars}
+\def\pgffor@@vars@slash@gobble/{\pgffor@@vars}
+
+\def\pgffor@var@add#1#2\pgffor@stop{%
+ \ifx\pgffor@var\pgfutil@empty%
+ \def\pgffor@var{#1}%
+ \def\pgffor@mainvar{#1}%
+ \else%
+ \expandafter\def\expandafter\pgffor@var\expandafter{\pgffor@var/#1}%
+ \fi%
+}
+
+\def\pgffor@expand@list@true{\let\pgffor@expand@list\edef}
+\def\pgffor@expand@list@false{\let\pgffor@expand@list\def}
+\def\pgffor@macro@list#1{%
+ \expandafter\pgffor@normal@list\expandafter{#1}}
+\def\pgffor@normal@list#1{%
+ \pgffor@expand@list\pgffor@values{#1}%
+ \expandafter\def\expandafter\pgffor@values\expandafter{\pgffor@values, \pgffor@stop,}%
+ \ifx\pgffor@values\pgffor@emptyvalues
+ \def\pgffor@values{\pgffor@stop,}%
+ \fi%
+ \let\pgffor@body=\pgfutil@empty%
+ \global\pgffor@continuetrue%
+ \pgffor@collectbody}
+\def\pgffor@collectbody{%
+ \pgfutil@ifnextchar\foreach{\pgffor@collectforeach}{%
+ \pgfutil@ifnextchar\bgroup{\pgffor@collectargument}{\pgffor@collectsemicolon}}%
+}
+
+\def\pgffor@collectforeach\foreach#1in{%
+ \pgfutil@ifnextchar\bgroup{\pgffor@collectforeach@normal{#1}}{\pgffor@collectforeach@macro{#1}}}
+\def\pgffor@collectforeach@macro#1#2{%
+ \expandafter\long\expandafter\def\expandafter\pgffor@body\expandafter{\pgffor@body\foreach#1in#2}%
+ \pgffor@collectbody%
+}
+\def\pgffor@collectforeach@normal#1#2{%
+ \expandafter\long\expandafter\def\expandafter\pgffor@body\expandafter{\pgffor@body\foreach#1in{#2}}%
+ \pgffor@collectbody%
+}
+\long\def\pgffor@collectargument#1{%
+ \expandafter\pgfutil@in@\expandafter\foreach\expandafter{\pgffor@body}%
+ \ifpgfutil@in@%
+ \expandafter\long\expandafter\def\expandafter\pgffor@body\expandafter%
+ {\pgffor@body{#1}}%
+ \else%
+ \expandafter\long\expandafter\def\expandafter\pgffor@body\expandafter%
+ {\pgffor@body#1}%
+ \fi%
+ \pgffor@iterate%
+}
+
+\def\pgffor@collectsemicolon{%
+ \let\pgffor@next=\pgffor@collectnormalsemicolon%
+ \ifnum\the\catcode`\;=\active\relax%
+ \let\pgffor@next=\pgffor@collectactivesemicolon%
+ \fi%
+ \pgffor@next%
+}
+
+\def\pgffor@collectnormalsemicolon#1;{%
+ \expandafter\long\expandafter\def\expandafter\pgffor@body\expandafter{\pgffor@body#1;}%
+ \pgffor@iterate%
+}
+
+{
+ \catcode`\;=\active
+
+ \gdef\pgffor@collectactivesemicolon#1;{%
+ \expandafter\long\expandafter\def\expandafter\pgffor@body\expandafter{\pgffor@body#1;}%
+ \pgffor@iterate%
+ }
+}
+
+\def\pgffor@iterate{%
+ % Must do all of these in case the internal stack is used.
+ \let\pgffor@last=\pgfutil@empty%
+ \let\pgffor@prevlast=\pgfutil@empty%
+ \let\pgffor@dotsend=\pgfutil@empty%
+ \let\pgffor@dots@pre=\pgfutil@empty%
+ \let\pgffor@dots@post=\pgfutil@empty%
+ %
+ \expandafter\pgffor@scan\pgffor@values}
+
+\def\pgffor@stop{\pgffor@stop}%
+\def\pgffor@dots{...}%
+
+\def\pgffor@scan{\pgfutil@ifnextchar({\pgffor@scanround}{\pgffor@scanone}}
+\def\pgffor@scanround(#1)#2,{\def\pgffor@value{(#1)#2}\pgffor@scanned}
+\def\pgffor@scanone#1,{\def\pgffor@value{#1}\pgffor@scanned}
+
+
+% Check for dots.
+\newif\ifpgffor@dots@in@
+\def\pgffor@dots@in@#1...#2#3\pgffor@stop{%
+ \ifx\pgffor@dots@@#2%
+ \pgffor@dots@in@false%
+ \else%
+ \pgffor@dots@in@true%
+ \fi%
+}
+
+\def\pgffor@dots@@{\pgffor@dots@@}
+
+\def\pgffor@scanned{%
+ \ifx\pgffor@value\pgffor@stop%
+ \let\pgffor@next=\pgffor@after% Done!
+ \else%
+ % Check for dots. Quicker than \pgfutil@in@ and not suceptable
+ % to false-positives when a token sequence ends in a single full-stop.
+ \expandafter\pgffor@dots@in@\pgffor@value\pgffor@dots@...\pgffor@dots@@\pgffor@stop%
+ \ifpgffor@dots@in@%
+ \let\pgffor@next=\pgffor@handledots%
+ \else%
+ \let\pgffor@next=\pgffor@handlevalue%
+ \fi%
+ \ifpgffor@continue%
+ \else%
+ \let\pgffor@next=\pgffor@scan% Done!
+ \fi%
+ \fi%
+ \pgffor@next}
+
+
+\def\pgffor@after{%
+ \global\pgffor@continuetrue%
+ \pgffor@atendforeach%
+ \pgffor@afterhook}
+
+\def\pgffor@handlevalue{%
+ \let\pgffor@prevlast=\pgffor@last%
+ \let\pgffor@last=\pgffor@value%
+ \pgffor@invokebody%
+ \pgffor@scan%
+}
+
+
+\def\pgffor@invokebody{%
+ \pgffor@begingroup%
+ \expandafter\pgfutil@in@\expandafter/\expandafter{\pgffor@var}%
+ \ifpgfutil@in@%
+ \expandafter\def\expandafter\pgffor@valuerest\expandafter{\pgffor@value//\relax}%
+ \expandafter\pgffor@multiassign\pgffor@var/\pgffor@stop/\pgffor@stop/\relax%
+ \else%
+ \expandafter\expandafter\expandafter\def\expandafter\pgffor@var\expandafter{\pgffor@value}%
+ \fi%
+ % Execute assign once code.
+ \ifx\pgffor@assign@once@code\pgfutil@empty%
+ \else%
+ \pgffor@assign@once@code%
+ \fi%
+ % Execute assign before code.
+ \ifx\pgffor@assign@before@code\pgfutil@empty%
+ \else%
+ \pgffor@assign@before@code%
+ \fi%
+ %
+ \expandafter\expandafter\expandafter\pgffor@reset@hooks\expandafter\pgffor@beginhook\expandafter\pgffor@body\pgffor@endhook%
+ % Execute assign after code.
+ \ifx\pgffor@assign@after@code\pgfutil@empty%
+ \else%
+ \pgffor@assign@after@code%
+ \fi%
+ %
+ \pgffor@endgroup%
+}
+
+
+\def\pgffor@multiassign#1/#2/\relax{%
+ \def\pgffor@currentvar{#1}%
+ \def\pgffor@rest{#2}%
+ \ifx\pgffor@currentvar\pgffor@stop%
+ \let\pgffor@next=\relax%
+ \else%
+ \let\pgffor@next=\pgffor@multiassignrest%
+ \fi%
+ \pgffor@next%
+}
+
+\def\pgffor@multiassignrest{\expandafter\pgffor@multiassignfinal\pgffor@valuerest}
+\def\pgffor@multiassignfinal#1/#2/\relax{%
+ \def\pgffor@temp{#1}%
+ \ifx\pgffor@currentvar\pgffor@mainvar%
+ \ifpgffor@alphabeticsequence%
+ \pgffor@makealphabetic\pgffor@temp%
+ \fi%
+ \fi%
+ \def\pgffor@test{#2}%
+ \ifx\pgffor@test\pgfutil@empty%
+ \expandafter\def\expandafter\pgffor@valuerest\expandafter{\pgffor@temp//\relax}% repeat
+ \else%
+ \def\pgffor@valuerest{#2/\relax}%
+ \fi%
+ \expandafter\expandafter\expandafter\def\expandafter\pgffor@currentvar\expandafter{\pgffor@temp}%
+ %
+ \expandafter\pgffor@multiassign\pgffor@rest/\relax%
+}
+
+\def\pgffor@gobblespaces#1{\pgfutil@ifnextchar x{#1}{#1}}
+
+\def\pgffor@handledots{%
+ \pgffor@gobblespaces{\expandafter\pgffor@@handledots\pgffor@value\pgffor@@stop}%
+}
+
+\newif\ifpgffor@context
+
+\def\pgffor@@handledots#1...#2\pgffor@@stop{%
+ % Define the context if any.
+ \def\pgffor@dots@pre{#1}%
+ \def\pgffor@dots@post{#2}%
+ \def\pgffor@dots@stripcontext#1##1#2\pgffor@@stop{\def\pgffor@dotsvalue{##1}}%
+ \pgffor@contexttrue%
+ \ifx\pgffor@dots@pre\pgfutil@empty%
+ \ifx\pgffor@dots@post\pgfutil@empty%
+ \pgffor@contextfalse%
+ \def\pgffor@dots@stripcontext##1\pgffor@@stop{\def\pgffor@dotsvalue{##1}}%
+ \fi%
+ \fi%
+ \pgffor@gobblespaces{\pgffor@dotsscanend}%
+}
+
+\def\pgffor@dots@value@process#1{%
+ \expandafter\pgffor@dots@stripcontext#1\pgffor@@stop%
+ \expandafter\pgffor@dots@charcheck\pgffor@dotsvalue\pgffor@@stop%
+ \ifpgffor@alphabeticsequence
+ \else
+ \ifpgffor@assign@parse
+ \begingroup
+ \pgfkeys{/pgf/fpu/false/.try}%
+ \pgfmathparse{\pgffor@dotsvalue}%
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+ \let\pgffor@dotsvalue=\pgfmathresult
+ \fi
+ \fi
+ \let#1=\pgffor@dotsvalue%
+}
+
+\def\pgffor@dotsscanend#1,{%
+ \pgffor@alphabeticsequencefalse%
+ % Strip context and check for a character sequence.
+ \def\pgffor@dotsend{#1}%
+ \pgffor@dots@value@process{\pgffor@dotsend}%
+ %
+ \pgffor@dots@value@process{\pgffor@last}%
+ %
+ % calculate skip%
+ \ifx\pgffor@prevlast\pgfutil@empty%
+ \ifdim\pgffor@dotsend pt>\pgffor@last pt%
+ \pgffor@skip=1pt%
+ \else%
+ \pgffor@skip=-1pt%
+ \fi%
+ \else%
+ \pgffor@dots@value@process{\pgffor@prevlast}%
+ \pgffor@skip=\pgffor@last pt%
+ \pgffor@iter=\pgffor@prevlast pt%
+ \advance\pgffor@skip by-\pgffor@iter%
+ \fi%
+ \pgffor@iter=\pgffor@last pt%
+ % do loop
+ \pgffor@loop%
+}
+
+\def\pgffor@loop{%
+ \advance\pgffor@iter by\pgffor@skip%
+ \let\pgffor@next=\pgffor@doloop%
+ \ifdim\pgffor@skip<0pt%
+ \ifdim\pgffor@iter<\pgffor@dotsend pt%
+ \let\pgffor@next=\pgffor@endloop%
+ \fi%
+ \else%
+ \ifdim\pgffor@iter>\pgffor@dotsend pt%
+ \let\pgffor@next=\pgffor@endloop%
+ \fi%
+ \fi%
+ \ifpgffor@continue%
+ \else%
+ \let\pgffor@next=\pgffor@endloop% Done!
+ \fi%
+ \pgffor@next%
+}
+
+\def\pgffor@endloop{%
+ \pgffor@alphabeticsequencefalse%
+ \pgffor@scan%
+}
+
+{\catcode`\p=12\catcode`\t=12\gdef\Pgffor@geT#1pt{#1}}
+
+\def\pgffor@doloop{%
+ \pgffor@begingroup
+ \edef\pgffor@temp{\expandafter\Pgffor@geT\the\pgffor@iter}%
+ \edef\pgffor@incheck{{.0/}{\pgffor@temp/}}%
+ \expandafter\pgfutil@in@\pgffor@incheck%
+ \ifpgfutil@in@%
+ \expandafter\pgffor@strip\pgffor@temp%
+ \fi%
+ \expandafter\pgfutil@in@\expandafter/\expandafter{\pgffor@var}%
+ \ifpgfutil@in@%
+ \expandafter\def\expandafter\pgffor@valuerest\expandafter{\pgffor@temp//\relax}%
+ \expandafter\pgffor@multiassign\pgffor@var/\pgffor@stop/\pgffor@stop/\relax%
+ \else%
+ % Convert to alphabetic sequence, if necessary.
+ \ifpgffor@alphabeticsequence%
+ \pgffor@makealphabetic\pgffor@temp%
+ \expandafter\let\pgffor@var=\pgffor@temp%
+ \else%
+ \expandafter\expandafter\expandafter\def\expandafter\pgffor@var\expandafter{\pgffor@temp}%
+ \fi%
+ \fi%
+ % Insert any context, if any.
+ \ifpgffor@context%
+ \let\pgffor@temp=\pgffor@dots@pre%
+ \expandafter\pgfutil@append@macrotomacro\expandafter%
+ {\expandafter\pgffor@temp\expandafter}\expandafter{\pgffor@var}%
+ \expandafter\pgfutil@append@macrotomacro\expandafter%
+ {\expandafter\pgffor@temp\expandafter}\expandafter{\pgffor@dots@post}%
+ \expandafter\let\pgffor@var=\pgffor@temp%
+ \fi%
+ % Perform assignments before loop body.
+ \ifx\pgffor@assign@before@code\pgfutil@empty%
+ \else%
+ \pgffor@assign@before@code%
+ \fi%
+ %
+ \expandafter\expandafter\expandafter\pgffor@reset@hooks\expandafter\pgffor@beginhook\expandafter\pgffor@body\pgffor@endhook%
+ %
+ % Perform assignments after loop body.
+ \ifx\pgffor@assign@after@code\pgfutil@empty%
+ \else%
+ \pgffor@assign@after@code%
+ \fi%
+ \pgffor@endgroup%
+ \pgffor@loop%
+}
+
+\def\pgffor@strip#1.0{\def\pgffor@temp{#1}}
+
+\def\breakforeach{\global\pgffor@continuefalse}
+
+\def\pgffor@gobbletil@pgffor@@stop#1\pgffor@@stop{}
+
+
+\newif\ifpgffor@registeriscount
+
+\def\pgffor@ifcsregister#1{%
+ \expandafter\pgffor@@ifcsregister\meaning#1\pgffor@stop}
+
+\def\pgffor@@ifcsregister#1#2#3#4#5\pgffor@stop{%
+ \if#1m% It is an ordinary (m)acro.
+ \pgffor@registeriscountfalse%
+ \let\pgffor@csnext=\pgfutil@secondoftwo%
+ \else%
+ \if#1u% It is (u)ndefined.
+ \let\pgffor@csnext=\pgfutil@secondoftwo%
+ \pgffor@registeriscountfalse%
+ \else%
+ \let\pgffor@csnext=\pgfutil@firstoftwo%
+ \if#4u% It is a co(u)nt
+ \pgffor@registeriscounttrue%
+ \else% Assume it is a dimen or skip (bad assumption in the general case).
+ \pgffor@registeriscountfalse%
+ \let\pgffor@csnext=\pgfutil@firstoftwo%
+ \fi%
+ \fi%
+ \fi%
+ \pgffor@csnext}
+
+\newif\ifpgffor@alphabeticsequence
+
+%
+\def\pgffor@dots@charcheck#1\pgffor@@stop{%
+ \edef\pgffor@dots@charcheck@temp{#1}%
+ \expandafter\expandafter\expandafter\pgffor@@dotscharcheck\expandafter\meaning\pgffor@dots@charcheck@temp\pgffor@@stop%
+}
+\def\pgffor@@dotscharcheck#1#2\pgffor@@stop{%
+ \if#1t%
+ \afterassignment\pgffor@gobbletil@pgffor@@stop%
+ \expandafter\chardef\expandafter\pgffor@char\expandafter=\expandafter`\pgffor@dots@charcheck@temp\relax\pgffor@@stop%
+ \edef\pgffor@char{\the\pgffor@char}%
+ \ifnum\pgffor@char>64\relax% From A-Z?
+ \ifnum\pgffor@char<91\relax%
+ \let\pgffor@dotsvalue=\pgffor@char%
+ \pgffor@alphabeticsequencetrue%
+ \else%
+ \ifnum\pgffor@char>96\relax% From a-z?
+ \ifnum\pgffor@char<123\relax%
+ \let\pgffor@dotsvalue=\pgffor@char%
+ \pgffor@alphabeticsequencetrue%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+}
+
+\def\pgffor@makealphabetic#1{%
+ % Convert the number in the macro passed as #1 to a-z or A-Z.
+ \pgfutil@tempcnta=#1\relax%
+ \ifnum\pgfutil@tempcnta>95\relax%
+ \advance\pgfutil@tempcnta by-96\relax%
+ \edef#1{\pgffor@alpha\pgfutil@tempcnta}%
+ \else%
+ \advance\pgfutil@tempcnta by-64 %
+ \edef#1{\pgffor@Alpha\pgfutil@tempcnta}%
+ \fi%
+}
+
+\def\pgffor@Alpha#1{%
+ \ifcase#1\relax\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M%
+ \or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\else?\fi%
+}
+
+\def\pgffor@alpha#1{%
+ \ifcase#1\relax\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m%
+ \or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\else?\fi%
+}
+
+\newtoks\pgffor@toks
+
+\def\pgffor@addcstotoks#1{%
+ \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\expandafter\def\expandafter#1\expandafter{#1}}%
+ \pgffor@@addcstotoks}
+
+\def\pgffor@addregtotoks#1{%
+ \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\expandafter#1\expandafter=\the#1}%
+ \pgffor@@addcstotoks}
+
+\def\pgffor@addiftotoks#1{%
+ \begingroup%
+ \escapechar=-1\relax%
+ \expandafter\pgffor@@addiftotoks\string#1\pgffor@stop}
+\def\pgffor@@addiftotoks#1#2#3#4\pgffor@stop{%
+ \endgroup
+ \csname if#3#4\endcsname%
+ \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#3#4true\endcsname}%
+ \else%
+ \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#3#4false\endcsname}%
+ \fi%
+ \pgffor@@addcstotoks%
+}
+
+\def\pgffor@@addcstotoks{%
+ \expandafter\expandafter\expandafter\pgffor@toks\expandafter\expandafter\expandafter=%
+ \expandafter\expandafter\expandafter{\expandafter\pgffor@tokstemp\the\pgffor@toks}%
+}
+
+% Set up the pgffor scopes.
+
+\def\pgffor@atbeginforeach{%
+ \begingroup%
+}
+
+\def\pgffor@atendforeach{%
+ \global\edef\pgffor@remember@expanded{\pgffor@remember@code}%
+ \ifx\pgffor@remember@expanded\pgfutil@empty%
+ \else%
+ \pgffor@remember@expanded%
+ \global\let\pgffor@remember@expanded=\pgfutil@empty%
+ \fi%
+ \endgroup%
+}
+\def\pgffor@default@begingroup{%
+ \begingroup%
+}
+
+\let\pgffor@remember@once@expanded=\pgfutil@empty
+\let\pgffor@remember@expanded=\pgfutil@empty
+
+\def\pgffor@default@endgroup{%
+ \ifx\pgffor@remember@once@code\pgfutil@empty
+ \else
+ \xdef\pgffor@remember@once@expanded{\pgffor@remember@once@code}%
+ \fi
+ \ifx\pgffor@remember@code\pgfutil@empty
+ \else
+ \xdef\pgffor@remember@expanded{\pgffor@remember@code}%
+ \fi
+ \endgroup
+ %
+ \ifx\pgffor@remember@once@expanded\pgfutil@empty
+ \else
+ \pgffor@remember@once@expanded%
+ % \let\pgffor@assign@once@code=\pgfutil@empty % Not needed anymore? (CJ)
+ \global\let\pgffor@remember@once@expanded=\pgfutil@empty
+ \fi
+ \ifx\pgffor@assign@once@code\pgfutil@empty
+ \else
+ \global\let\pgffor@assign@once@code=\pgfutil@empty
+ \fi
+ %
+ \ifx\pgffor@remember@expanded\pgfutil@empty
+ \else
+ \pgffor@remember@expanded%
+ \global\let\pgffor@remember@expanded=\pgfutil@empty
+ \fi
+}
+
+\let\pgffor@begingroup=\pgffor@default@begingroup
+\let\pgffor@endgroup=\pgffor@default@endgroup
+
+
+\def\pgffor@stack@begingroup{%
+ \pgffor@toks={}%
+ \pgffor@addcstotoks{\pgffor@mainvar}%
+ \pgffor@addcstotoks{\pgffor@var}%
+ \pgffor@addcstotoks{\pgffor@body}%
+ %
+ \pgffor@addcstotoks{\pgffor@last}%
+ \pgffor@addcstotoks{\pgffor@prevlast}%
+ \pgffor@addcstotoks{\pgffor@dotsend}%
+ %
+ \pgffor@addcstotoks{\pgffor@assign@before@code}%
+ \pgffor@addcstotoks{\pgffor@assign@after@code}%
+ \pgffor@addcstotoks{\pgffor@remember@code}%
+ \pgffor@addcstotoks{\pgffor@remember@once@code}%
+ \pgffor@addcstotoks{\pgffor@dots@pre}%
+ \pgffor@addcstotoks{\pgffor@dots@post}%
+ %
+ \pgffor@addregtotoks{\pgffor@iter}%
+ \pgffor@addregtotoks{\pgffor@skip}%
+ %
+ \pgffor@addiftotoks{\ifpgffor@alphabeticsequence}%
+ \pgffor@addiftotoks{\ifpgffor@context}%
+ \expandafter\pgffor@stackpush\expandafter{\the\pgffor@toks}%
+}
+
+\def\pgffor@stack@endgroup{\pgffor@stackpop}
+
+% Keys stuff.
+
+\newif\ifpgffor@assign@evaluate
+\newif\ifpgffor@assign@once
+\newif\ifpgffor@assign@parse
+
+\pgfkeys{/pgf/foreach/.cd,
+ var/.code=\pgffor@var@add#1\pgffor@stop,
+ scope iterations/.code={
+ \csname if#1\endcsname%
+ \let\pgffor@begingroup=\pgffor@default@begingroup%
+ \let\pgffor@endgroup=\pgffor@default@endgroup%
+ \else%
+ \let\pgffor@begingroup=\pgffor@stack@begingroup%
+ \let\pgffor@endgroup=\pgffor@stack@endgroup%
+ \fi%
+ },
+ evaluate/.code=\pgffor@assign@evaluatetrue\pgffor@assign@oncefalse\pgffor@assign@parse{#1},%
+ assign/.code=\pgffor@assign@evaluatefalse\pgffor@assign@oncefalse\pgffor@assign@parse{#1},%
+ evaluate once/.code=\pgffor@assign@evaluatetrue\pgffor@assign@oncetrue\pgffor@assign@parse{#1},%
+ assign once/.code=\pgffor@assign@evaluatefalse\pgffor@assign@oncetrue\pgffor@assign@parse{#1},%
+ remember/.code=\pgffor@remember@parse{#1},%
+ count/.code=\pgffor@count@parse#1\pgffor@stop,
+ parse/.is if=pgffor@assign@parse,
+ parse/.default=false,
+ expand list/.is if=pgffor@expand@list@,
+ expand list/.default=true,
+ expand list=false,
+}
+
+\def\pgffor@assign@parse#1{%
+ \pgfutil@in@;{#1}%
+ \ifpgfutil@in@%
+ \else%
+ \pgfutil@in@={#1}%
+ \fi%
+ \ifpgfutil@in@%
+ \pgffor@assign@@parse#1;\pgffor@stop;%
+ \else%
+ \pgffor@assign@parse@old#1\pgffor@stop%%
+ \fi%
+}
+
+\def\pgffor@stop{\pgffor@stop}
+\def\pgffor@assign@@parse#1;{%
+ \def\pgffor@test{#1}%
+ \ifx\pgffor@test\pgffor@stop%
+ \let\pgffor@next=\relax%
+ \else%
+ \let\pgffor@next=\pgffor@assign@@parse%
+ \ifx\pgffor@test\pgfutil@empty%
+ \else%
+ \pgfutil@in@={#1}%
+ \ifpgfutil@in@%
+ \pgffor@assign@@@parse#1\pgffor@stop%
+ \else%
+ \pgffor@assign@@@parse#1=#1\pgffor@stop%
+ \fi%
+ \fi%
+ \fi%
+ \pgffor@next}
+
+\def\pgffor@assign@@@parse#1=#2\pgffor@stop{%
+ \ifpgffor@assign@evaluate%
+ \ifpgffor@assign@once%
+ \pgfutil@append@tomacro{\pgffor@assign@once@code}{\pgfmathparse{#2}\let#1=\pgfmathresult}%
+ \pgfutil@append@tomacro{\pgffor@remember@once@code}{\noexpand\def\noexpand#1{#2}}%
+ \else
+ \pgfutil@append@tomacro{\pgffor@assign@before@code}{\pgfmathparse{#2}\let#1=\pgfmathresult}%
+ \fi%
+ \else%
+ \ifpgffor@assign@once%
+ \pgfutil@append@tomacro{\pgffor@assign@once@code}{\def#1{#2}}%
+ \pgfutil@append@tomacro{\pgffor@remember@once@code}{\noexpand\def\noexpand#1{#2}}%
+ \else
+ \pgfutil@append@tomacro{\pgffor@assign@before@code}{\def#1{#2}}%
+ \fi%
+ \fi%
+}
+
+\def\pgffor@assign@parse@old#1#2\pgffor@stop{%
+ \pgffor@assign@@parse@old#2\pgffor@stop as#1using #1\pgffor@@stop}
+
+\def\pgffor@assign@@parse@old#1as#2#3\pgffor@@stop{%
+ \pgffor@assign@@@parse@old{#2}#1#3\pgffor@stop\pgffor@@stop}
+
+\def\pgffor@assign@@@parse@old#1#2using #3\pgffor@stop#4\pgffor@@stop{%
+ \pgffor@assign@@@parse#1=#3\pgffor@stop}
+
+
+
+\def\pgffor@remember@parse#1{%
+ \pgfutil@in@ a{#1}% This matches the 'a' in 'as' or 'initially'.
+ \ifpgfutil@in@%
+ \pgffor@remember@parse@old#1\pgffor@stop%
+ \else%
+ \pgffor@remember@@parse#1;\pgffor@stop;%
+ \fi%
+}
+
+\def\pgffor@remember@@parse#1;{%
+ \def\pgffor@test{#1}%
+ \ifx\pgffor@test\pgffor@stop%
+ \let\pgffor@next=\relax%
+ \else%
+ \let\pgffor@next=\pgffor@remember@@parse%
+ \ifx\pgffor@test\pgfutil@empty%
+ \else%
+ \pgfutil@in@={#1}%
+ \ifpgfutil@in@%
+ \pgffor@remember@@@parse#1\pgffor@stop%
+ \else%
+ \pgffor@ifcsregister{#1}{%
+ \pgfutil@append@tomacro{\pgffor@remember@code}{\noexpand#1=\the#1\noexpand\relax}%
+ }%
+ {%
+ \pgfutil@append@tomacro{\pgffor@remember@code}{\noexpand\def\noexpand#1{#1}}%
+ }%
+ \fi%
+ \fi%
+ \fi%
+ \pgffor@next%
+}
+
+\def\pgffor@remember@@@parse#1=#2\pgffor@stop{%
+ \pgffor@ifcsregister{#2}{%
+ \pgfutil@append@tomacro{\pgffor@assign@after@code}{\expandafter\def\expandafter#1\expandafter{\the#2}}%
+ \pgfutil@append@tomacro{\pgffor@remember@code}{\noexpand\def\noexpand#1{#1}}%
+ }%
+ {%
+ \pgfutil@append@tomacro{\pgffor@assign@after@code}{\expandafter\def\expandafter#1\expandafter{#2}}%
+ \pgfutil@append@tomacro{\pgffor@remember@code}{\noexpand\def\noexpand#1{#1}}%
+ }%
+}
+
+\def\pgffor@remember@parse@old#1#2\pgffor@stop{%
+ \pgffor@remember@@parse@old#1#2\pgffor@stop as#1(initially 0)\pgffor@@stop}
+
+\def\pgffor@remember@@parse@old#1#2as#3#4\pgffor@@stop{%
+ \pgffor@remember@@@parse@old{#1}{#3}#2#4\pgffor@stop\pgffor@@stop}
+
+\def\pgffor@remember@@@parse@old#1#2#3(initially #4)#5\pgffor@stop#6\pgffor@@stop{%
+ \pgfutil@append@tomacro{\pgffor@assign@after@code}{\edef#2{#1}}%
+ \pgfutil@append@tomacro{\pgffor@remember@code}{\noexpand\def\noexpand#2{#2}}%
+ \pgfutil@append@tomacro{\pgffor@assign@once@code}{\def#2{#4}}%
+}
+
+\def\pgffor@count@parse#1#2\pgffor@stop{%
+ \pgffor@count@@parse#1#2\pgffor@stop from 1\pgffor@stop\pgffor@@stop}
+
+\def\pgffor@count@@parse#1#2from#3\pgffor@stop#4\pgffor@@stop{%
+ \pgfutil@append@tomacro\pgffor@remember@code{\noexpand\def\noexpand#1{#1}}%
+ \pgfutil@append@tomacro\pgffor@assign@before@code{\pgfmathparse{int(#1+1)}\let#1=\pgfmathresult}%
+ \pgfmathparse{int(#3-1)}\let#1=\pgfmathresult%
+}
+
+
+\def\pgfutil@append@macrotomacro#1#2{%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ #1\expandafter\expandafter\expandafter{\expandafter#1#2}}
+
+\def\pgfutil@append@tomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}}
+
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfkeys.code.tex b/graphics/pgf/base/tex/generic/utilities/pgfkeys.code.tex
new file mode 100644
index 0000000000..f24557f842
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfkeys.code.tex
@@ -0,0 +1,1232 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+% The files pgfkeys.code.tex and pgfkeysfiltered.code.tex are
+% perfectly self-contained, except that the catcode of @
+% should be made a letter.
+
+
+% Guard against reading twice
+\ifx\pgfkeysloaded\undefined
+ \let\pgfkeysloaded=\relax
+\else
+ \expandafter\endinput
+\fi
+
+% The purpose of this file is to provide a general settings engine that
+% works with all TeX formats and has no save-stack impact
+
+\def\pgfkeys@empty{}
+\long\def\pgfkeys@firstoftwo#1#2{#1}
+\long\def\pgfkeys@secondoftwo#1#2{#2}
+\long\def\pgfkeys@ifcsname#1{%
+ \ifcsname#1\endcsname
+ \expandafter\pgfkeys@firstoftwo
+ \else
+ \expandafter\pgfkeys@secondoftwo
+ \fi
+}
+
+% This is useful:
+
+\ifx\PackageError\undefined
+ \def\pgfkeys@error#1{\errmessage{Package pgfkeys Error: #1}}%
+\else
+ \def\pgfkeys@error#1{\PackageError{pgfkeys}{#1}{}}%
+\fi
+
+\ifx\eTeXrevision\undefined%
+ \pgfkeys@error{PGF requires etex in extended mode}%
+ \csname @@end\expandafter\endcsname\expandafter\end%
+\fi
+
+\ifnum\eTeXversion<2
+ \pgfkeys@error{PGF requires etex version 2}%
+ \csname @@end\expandafter\endcsname\expandafter\end%
+\fi
+
+% e-TeX primitives and beyond
+
+\ifx\contextversion\undefined
+ \let\pgfkeys@expanded \expanded
+ \let\pgfkeys@unexpanded \unexpanded
+\else
+ \let\pgfkeys@expanded \normalexpanded
+ \let\pgfkeys@unexpanded \normalunexpanded
+\fi
+
+\begingroup
+ \edef\pgfkeys@tmpa{\string\expanded}
+ \edef\pgfkeys@tmpb{\meaning\pgfkeys@expanded}
+ \expandafter
+\endgroup
+\ifx\pgfkeys@tmpa\pgfkeys@tmpb
+\else
+ \pgfkeys@error{PGF requires the \noexpand\expanded primitive}
+ \csname @@end\expandafter\endcsname\expandafter\end%
+\fi
+
+
+% Set a key to a value
+%
+% #1 = key
+% #2 = tokens
+%
+% Description:
+%
+% This command sets the key to the given tokens. The tokens are stored as
+% is and can even contain things like #9.
+%
+% Keys are organized hierarchically using something similar to Unix
+% paths. Thus, a typically key might be called "/tikz/length" or
+% "/tikz/length dimension/.@cmd". Some keys starting with a dot are
+% special, so they should not be used as normal key names (they are
+% similar to Unix files starting with a dot -- you can use them, but
+% be careful).
+%
+% Keys are always local to the current TeX group.
+%
+% Example:
+%
+% \pgfkeyssetvalue{/tikz/length}{2cm-3cm}
+% \pgfkeyssetvalue{/algo/swap}{{#2}{#1}}
+
+\long\def\pgfkeyssetvalue#1#2{%
+ \pgfkeys@temptoks{#2}\expandafter\edef\csname pgfk@#1\endcsname{\the\pgfkeys@temptoks}%
+}
+
+\long\def\pgfkeyssetevalue#1#2{%
+ \expandafter\edef\csname pgfk@#1\endcsname
+ {\pgfkeys@unexpanded\expandafter{\pgfkeys@expanded{#2}}}%
+}
+
+% Add text to a key at the end
+%
+% #1 = key
+% #2 = a value to be added at the beginning
+% #3 = a value to be added at the end
+%
+% Description:
+%
+% This command adds #2 to the definition of the key. The key should
+% have been set previously using \pgfkeyssetvalue.
+%
+% Example:
+%
+% \pgfkeysaddvalue{/tikz/length}{}{-3cm}
+
+\long\def\pgfkeysaddvalue#1#2#3{%
+ {%
+ \toks0{#2}%
+ \pgfkeysifdefined{#1}
+ {\pgfkeys@temptoks\expandafter\expandafter\expandafter{\csname pgfk@#1\endcsname}}%
+ {\pgfkeys@temptoks{}}%
+ \toks1{#3}%
+ \xdef\pgfkeys@global@temp{\the\toks0 \the\pgfkeys@temptoks \the\toks1}% believe or don't: the spaces are important
+ }%
+ \pgfkeyslet{#1}\pgfkeys@global@temp%
+}
+
+
+
+% Makes a key equal a given code
+%
+% #1 = key
+% #2 = a code name
+%
+% Description:
+%
+% This command executes a \let command so that a key gets the same
+% value as the parameter #2.
+%
+% Keys are always local to the current TeX group.
+%
+% Example:
+%
+% \pgfkeyslet{/algo/swap}{\myswap}
+
+\long\def\pgfkeyslet#1#2{%
+ \expandafter\let\csname pgfk@#1\endcsname#2%
+}
+
+
+% Retrieve the code stored in a key into a code
+%
+% #1 = key
+% #2 = code
+%
+% Description:
+%
+% This command will set #2 to "point" to the value stored in the key.
+%
+% Example:
+%
+% \pgfkeysgetvalue{/tikz/swap}{\myswap}
+
+\long\def\pgfkeysgetvalue#1#2{%
+ \pgfkeys@ifcsname{pgfk@#1}%
+ {\expandafter\let\expandafter#2\csname pgfk@#1\endcsname}%
+ {\let#2\relax}}
+
+
+
+% Retrieve the value stored in a key
+%
+% #1 = key
+%
+% Description:
+%
+% This command will expand to the value stored in the key. The key
+% should previously have been set using \pgfkeyasetkey or \pgfkeyslet.
+%
+% Example:
+%
+% The length is \pgfkeysvalue{/tikz/length}.
+
+\let\pgfkeys@relax\relax
+\long\def\pgfkeysvalueof#1{\csname\pgfkeys@ifcsname{pgfk@#1}{pgfk@#1}{pgfkeys@relax}\endcsname}
+
+
+
+% If for testing whether a key exists
+%
+% #1 = key
+% #2 = if-case
+% #3 = else-case
+%
+% Description:
+%
+% This if will be executed if the key exists. In eTeX mode this works
+% like a normal if, in normal TeX mode you need to provide an \else.
+%
+% Example:
+%
+% \pgfkeysifdefined{/tikz/length}{key exists}{does not exist}
+
+\long\def\pgfkeysifdefined#1{%
+ \ifcsname pgfk@#1\endcsname
+ \expandafter\pgfkeys@firstoftwo
+ \else
+ \expandafter\pgfkeys@secondoftwo
+ \fi
+}
+
+% Tests whether a key is assignable. For standard keys which just
+% store their value, this is identical to \pgfkeysifdefined.
+%
+% But \pgfkeysifassignable is true for command keys as well (but not
+% for handled keys).
+\long\def\pgfkeysifassignable#1#2#3{%
+ \pgfkeysifdefined{#1}%
+ {#2}
+ {\pgfkeysifdefined{#1/.@cmd}%
+ {#2}%
+ {#3}}%
+}%
+
+
+
+% Execute settings
+%
+% #1 = list of settings
+%
+% Description:
+%
+% The list of settings should contain comma-separated settings. Each
+% setting has the following form:
+%
+% /path/key=value
+%
+% The parts "/path/" and "=value" are optional. When the path is not
+% specified, the value of the token register "\pgfkeypath" is used. If
+% "=value" is missing, the value of the setting "/path/key/.@def" is used
+% instead. If this key is set to "\pgfvaluerequired", the key
+% "/errors/value required/.@cmd" is executed. This error handler,
+% like all other error handlers, will get the current key as its first
+% parameter (unexpanded) and the current value as its second value
+% (also unexpanded).
+%
+% Any spaces at the beginning and at the end and around the
+% equals-sign are removed. The key with the complete path is set to
+% the code \pgfcurrentkey.
+%
+% The setting is then processed according to the following rules:
+%
+% 1) If the key /path/key/.@cmd" is present, its code is executed
+% with the value computed above, followed by \pgfeov (end of
+% value). So, to handle
+%
+% "/stuff/height= 1.5 ,"
+%
+% /stuff/height/.@cmd should be set to some code, that can
+% handle the parameter
+%
+% "1.5\pgfeov"
+%
+% For instance, saying
+%
+% \pgfkeys{/stuff/height/.@cmd}{#1\pgfeov}{\def\myheight{#1}}
+%
+% will do nicely.
+%
+% 2) Otherwise, if the key /path/key is present, this key is
+% set to the value computed above.
+%
+% 3) Otherwise, if the key /handlers/key/.@cmd is present, it is executed
+% with the same parameters as in 1). Additionally, the
+% token register \pgfcurrentkeypath will be set to "/path/" and the
+% macro \pgfcurrentkeywithoutpath to "key". So, in the above
+% example if neither "/stuff/height/.@cmd" nor
+% "/stuff/height" is present, but "/handlers/height" is,
+% then "/handlers/height" is executed with the parameters:
+%
+% "1.5\pgfeov"
+%
+% and \pgfcurrentkey is set to "/stuff/height" and \pgfcurrentkeypath
+% is set to "/stuff/" and \pgfcurrentkeywithoutpath to "height".
+%
+% 4) Otherwise, if the key "/path/.unknown/.@cmd" is present, its code is
+% executed with the same parameters as in 3).
+%
+% 5) Otherwise, the key "/handlers/.unknown/.@cmd" is executed with the same
+% parameters as in 1).
+%
+% After all settings have been processed, the value of the token
+% register \pgfdefaultkeypath is set to its original value. Thus, any local
+% change of this token register has no effect outside the call.
+%
+% Example:
+%
+% \pgfkeys{/tikz/.is family}
+% \pgfkeys{/tikz/line width/.cd,
+% .def=\pgfsetlinewidth{##1},
+% .set default=.4pt}
+% \pgfkeys{tikz,line width=1pt}
+
+\newtoks\pgfkeys@pathtoks
+\def\pgfkeyscurrentpath{\the\pgfkeys@pathtoks}
+\newtoks\pgfkeys@temptoks
+
+\def\pgfkeys@root{/}
+\let\pgfkeysdefaultpath\pgfkeys@root
+
+\def\pgfkeys{\expandafter\pgfkeys@@set\expandafter{\pgfkeysdefaultpath}}%
+\long\def\pgfkeys@@set#1#2{%
+ \let\pgfkeysdefaultpath\pgfkeys@root%
+ \pgfkeys@parse#2,\pgfkeys@mainstop%
+ \def\pgfkeysdefaultpath{#1}}
+
+\def\pgfkeys@parse{\futurelet\pgfkeys@possiblerelax\pgfkeys@parse@main}
+\def\pgfkeys@parse@main{%
+ \ifx\pgfkeys@possiblerelax\pgfkeys@mainstop%
+ \expandafter\pgfkeys@cleanup%
+ \else%
+ \expandafter\pgfkeys@normal%
+ \fi%
+}
+\newif\ifpgfkeys@syntax@handlers
+\def\pgfkeys@normal{%
+ \ifpgfkeys@syntax@handlers%
+ \expandafter\pgfkeys@syntax@handlers%
+ \else%
+ \expandafter\pgfkeys@@normal%
+ \fi%
+}
+\def\pgfkeys@syntax@handlers{\pgf@keys@utilifnextchar\relax\pgfkeys@syntax@@handlers\pgfkeys@syntax@@handlers}%get rid of spaces
+\def\pgfkeys@syntax@@handlers{\futurelet\pgfkeys@first@char\pgfkeys@syntax@handlers@test}
+\def\pgfkeys@syntax@handlers@test{%
+ \pgfkeysgetvalue{/handlers/first char syntax/\meaning\pgfkeys@first@char}\pgfkeys@the@handler%
+ \ifx\pgfkeys@the@handler\relax%
+ \expandafter\pgfkeys@@normal%
+ \else%
+ \expandafter\pgfkeys@use@handler%
+ \fi%
+}
+\long\def\pgfkeys@use@handler#1,{%
+ \pgfkeys@the@handler{#1}%
+ \pgfkeys@parse%
+}
+
+\long\def\pgfkeys@@normal#1,{%
+ \pgfkeys@unpack#1=\pgfkeysnovalue=\pgfkeys@stop%
+ \pgfkeys@parse%
+}
+\def\pgfkeys@cleanup\pgfkeys@mainstop{}
+
+\def\pgfkeys@mainstop{\pgfkeys@mainstop} % equals only itself
+\def\pgfkeys@novalue{}
+\def\pgfkeysnovalue{\pgfkeys@novalue} % equals only itself
+\def\pgfkeysnovalue@text{\pgfkeysnovalue}
+\def\pgfkeysvaluerequired{\pgfkeysvaluerequired} % equals only itself
+
+\long\def\pgfkeys@unpack#1=#2=#3\pgfkeys@stop{%
+ \pgfkeys@spdef\pgfkeyscurrentkey{#1}%
+ \edef\pgfkeyscurrentkey{\pgfkeyscurrentkey}%
+ \ifx\pgfkeyscurrentkey\pgfkeys@empty%
+ % Skip
+ \else%
+ \pgfkeys@add@path@as@needed%
+ \pgfkeys@spdef\pgfkeyscurrentvalue{#2}%
+ \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value
+ \pgfkeysifdefined{\pgfkeyscurrentkey/.@def}%
+ {\pgfkeysgetvalue{\pgfkeyscurrentkey/.@def}{\pgfkeyscurrentvalue}}
+ {}% no default, so leave it
+ \fi%
+ \ifx\pgfkeyscurrentvalue\pgfkeysvaluerequired%
+ \def\pgf@marshal{\pgfkeysvalueof{/errors/value required/.@cmd}}%
+ \expandafter\pgf@marshal\expandafter{\pgfkeyscurrentkey}{}\pgfeov%
+ \else%
+ \pgfkeys@case@one%
+ \fi%
+ \fi}
+
+\def\pgfkeys@case@one{%
+ \pgfkeysifdefined{\pgfkeyscurrentkey/.@cmd}%
+ {\pgfkeysgetvalue{\pgfkeyscurrentkey/.@cmd}{\pgfkeys@code}%
+ \ifx\pgfkeys@code\relax\expandafter\pgfkeys@firstoftwo\else\expandafter\pgfkeys@secondoftwo\fi
+ {\pgfkeys@unknown}%
+ {\expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov}}
+ {\pgfkeys@case@two}%
+}
+
+\def\pgfkeys@case@two{%
+ \pgfkeysifdefined{\pgfkeyscurrentkey}%
+ {\pgfkeys@case@two@extern}%
+ {\pgfkeys@case@three}%
+}
+
+\def\pgfkeys@case@two@extern{%
+ \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text%
+ \pgfkeysvalueof{\pgfkeyscurrentkey}%
+ \else%
+ \pgfkeyslet{\pgfkeyscurrentkey}\pgfkeyscurrentvalue%
+ \fi%
+}
+
+
+% either handled key or unknown.
+%
+% This macro will be replaced by the /handler config/handle only existing
+% configuration, see below.
+\def\pgfkeys@case@three{%
+ \pgfkeys@split@path%
+ \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}%
+ {\pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov}
+ {\pgfkeys@unknown}%
+}
+\let\pgfkeys@case@three@handleall=\pgfkeys@case@three
+\def\pgfkeys@case@three@handle@restricted{%
+ \pgfkeys@split@path%
+ \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{%
+ \pgfkeys@ifexecutehandler{%
+ \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov
+ }{%
+ % this here is necessary: /my search path/key/.code
+ % won't be called, so \pgfkeyscurrentpath == '/my search path/key'
+ % -> it should be one directory higher! We want to invoke the
+ % .unknown handler in
+ % '/my search path'
+ %
+ % Idea:
+ % set
+ % - path := '/my search path'
+ % - name := 'key/.code'
+ % - key = '/my search path/key/.code'
+ \let\pgfkeys@tempa=\pgfkeyscurrentkey
+ \let\pgfkeys@tempb=\pgfkeyscurrentname
+ \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}%
+ \pgfkeys@split@path%
+ \let\pgfkeyscurrentkey=\pgfkeys@tempa
+ \edef\pgfkeyscurrentname{\pgfkeyscurrentname/\pgfkeys@tempb}%
+ \pgfkeys@unknown
+ }%
+ }{%
+ \pgfkeys@unknown
+ }%
+}
+
+% this macro is to implement the |handle only existing| key in key filtering:
+% #1: the code to invoke IF the key handler shall be executed
+% #2: the code to invoke if it shall not run.
+\def\pgfkeys@ifexecutehandler#1#2{#1}%
+\let\pgfkeys@ifexecutehandler@handleall=\pgfkeys@ifexecutehandler
+\def\pgfkeys@ifexecutehandler@handleonlyexisting#1#2{%
+ \pgfkeys@ifcsname{pgfk@excpt@\pgfkeyscurrentname}{%
+ #1% ok, this particular key handler is known and should be processed in any case (for example .try)
+ }{%
+ % implement the 'only existing' feature here:
+ \pgfkeysifdefined{\pgfkeyscurrentpath}{#1}{%
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{#1}{#2}%
+ }{}%
+ }%
+}%
+\def\pgfkeys@ifexecutehandler@handlefullorexisting#1#2{%
+ \ifpgfkeysaddeddefaultpath
+ \pgfkeys@ifcsname{pgfk@excpt@\pgfkeyscurrentname}{%
+ #1% ok, this particular key handler is known and be processed in any case (for example .try)
+ }{%
+ % implement the 'only existing' feature here:
+ \pgfkeysifdefined{\pgfkeyscurrentpath}{%
+ #1%
+ }{%
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{%
+ #1%
+ }{%
+ #2%
+ }%
+ }%
+ }%
+ \else
+ #1% ok, always true if the USER explicitly provided the full key path.
+ \fi
+}%
+\def\pgfkeysaddhandleonlyexistingexception#1{\expandafter\def\csname pgfk@excpt@#1\endcsname{1}}%
+
+\def\pgfkeys@unknown{%
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.unknown/.@cmd}%
+ {%
+ \pgfkeysgetvalue{\pgfkeyscurrentpath/.unknown/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov}
+ {%
+ \pgfkeysgetvalue{/handlers/.unknown/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov%
+ }%
+}
+
+
+\long\def\pgfkey@argumentisspace#1{%
+ \long\def\pgfkeys@spdef##1##2{%
+ \futurelet\pgfkeys@possiblespace\pgfkeys@sp@a##2\pgfkeys@stop\pgfkeys@stop#1\pgfkeys@stop\relax##1}%
+ \def\pgfkeys@sp@a{%
+ \ifx\pgfkeys@possiblespace\pgfkeys@sptoken%
+ \expandafter\pgfkeys@sp@b%
+ \else%
+ \expandafter\pgfkeys@sp@b\expandafter#1%
+ \fi}%
+ \long\def\pgfkeys@sp@b#1##1 \pgfkeys@stop{\pgfkeys@sp@c##1}%
+}
+\pgfkey@argumentisspace{ }
+\long\def\pgfkeys@sp@c#1\pgfkeys@stop#2\relax#3{\pgfkeys@temptoks{#1}\edef#3{\the\pgfkeys@temptoks}}
+{\def\:{\global\let\pgfkeys@sptoken= } \: }
+
+
+
+\def\pgfkeys@add@path@as@needed{% Should add the path if the
+ % \pgfkeyscurrentkey does not start with /
+ \expandafter\futurelet\expandafter\pgfkeys@possibleslash\expandafter\pgfkeys@check@slash\pgfkeyscurrentkey\relax%
+}
+\newif\ifpgfkeysaddeddefaultpath
+\def\pgfkeys@check@slash{%
+ \ifx\pgfkeys@possibleslash/%
+ \expandafter\pgfkeys@nevermind%
+ \else%
+ \expandafter\pgfkeys@addpath%
+ \fi%
+}
+
+\def\pgfkeys@nevermind#1\relax{%
+ \pgfkeysaddeddefaultpathfalse
+ \let\pgfkeyscurrentkeyRAW\pgfkeyscurrentkey
+}
+\def\pgfkeys@addpath#1\relax{%
+ \pgfkeysaddeddefaultpathtrue
+ \def\pgfkeyscurrentkeyRAW{#1}%
+ \edef\pgfkeyscurrentkey{\pgfkeysdefaultpath#1}%
+}
+
+
+\def\pgfkeys@split@path{% Should assign the two codes
+ % \pgfkeyscurrentname and \pgfcurrentlkeypath
+ \pgfkeys@pathtoks{}%
+ \expandafter\pgfkeys@splitter\pgfkeyscurrentkey//%
+}
+\def\pgfkeys@splitter#1/#2/{%
+ \def\pgfkeys@temp{#2}%
+ \ifx\pgfkeys@temp\pgfkeys@empty%
+ % Ah. done
+ \def\pgfkeyscurrentname{#1}%
+ \expandafter\pgfkeys@gobbletoslash%
+ \else%
+ \expandafter\pgfkeys@pathtoks\expandafter{\the\pgfkeys@pathtoks#1/}%
+ \fi%
+ \pgfkeys@splitter#2/%
+}
+\def\pgfkeys@gobbletoslash\pgfkeys@splitter/{%
+ \if\relax\detokenize\expandafter{\the\pgfkeys@pathtoks}\relax\else
+ \expandafter\pgfkeys@remove@slash\the\pgfkeys@pathtoks\relax
+ \fi
+}%
+\def\pgfkeys@remove@slash#1/\relax{\pgfkeys@pathtoks{#1}}
+
+
+
+% Quickly set keys
+%
+% #1 = default path
+% #2 = key-value pairs
+%
+% Description:
+%
+% This command starts the execution with the default path set to
+% #1. This command should only be used when speed is important (like
+% in a heavily used macro like \tikzset). Normally, keys should be
+% used to set the path. Note that if #1 equals /, then \pgfkeys will
+% actually be quicker!
+%
+% Example:
+%
+% \pgfqkeys{/tikz}{myother length/.code=\def\myotherlength{#1}\pgfkeysalso{length={#1}}}
+
+\def\pgfqkeys{\expandafter\pgfkeys@@qset\expandafter{\pgfkeysdefaultpath}}%
+\long\def\pgfkeys@@qset#1#2#3{\def\pgfkeysdefaultpath{#2/}\pgfkeys@parse#3,\pgfkeys@mainstop\def\pgfkeysdefaultpath{#1}}
+
+
+% Sets keys while setting keys
+%
+% #1 = key-value pairs
+%
+% Description:
+%
+% This code may only be called inside the code that is executed for a
+% key. The #1 should be a list of settings pairs. They will be executed
+% as if they had been given as the argument to the \pgfkeys command.
+%
+% Example:
+%
+% \pgfkeys{tikz,myother length/.code=\def\myotherlength{#1}\pgfkeysalso{length={#1}}}
+
+\long\def\pgfkeysalso#1{\pgfkeys@parse#1,\pgfkeys@mainstop}
+
+
+
+% Quickly sets keys while setting keys
+%
+% #1 = default path
+% #2 = key-value pairs
+%
+% Description:
+%
+% This command executes #2 with the default path set to #1. This
+% command will cause chaos if used incorrectly. The only safe
+% place to use it instead of \pgfkeys is at the beginning of a TeX group.
+%
+% Example:
+%
+% \begingroup
+% \pgfqkeysalso{/tikz}{myother length/.code=\def\myotherlength{#1}\pgfkeysalso{length={#1}}}
+
+\long\def\pgfqkeysalso#1#2{\def\pgfkeysdefaultpath{#1/}\pgfkeys@parse#2,\pgfkeys@mainstop}
+
+
+
+
+% Now setup the default handlers and keys:
+
+% Define a key macro with one argument (\def or \edef)
+%
+% #1 = key
+% #2 = code
+%
+% Description:
+%
+% This command will setup things so the key/.@cmd contains a macro
+% that takes one parameter and has #2 as its code.
+%
+% Example:
+%
+% \pgfkeysdef{/my key}{\show#1}
+
+\long\def\pgfkeysdef#1#2{%
+ \long\def\pgfkeys@temp##1\pgfeov{#2}%
+ \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}%
+ \pgfkeyssetvalue{#1/.@body}{#2}%
+}
+\long\def\pgfkeysedef#1#2{%
+ \long\edef\pgfkeys@temp##1\pgfeov{#2}%
+ \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}%
+ \pgfkeyssetevalue{#1/.@body}{#2}%
+}
+
+
+% Define a key macro with multiple arguments (\def or \edef)
+%
+% #1 = key
+% #2 = argument pattern
+% #2 = code
+%
+% Description:
+%
+% This command will setup things so the key/.@cmd contains a macro
+% that takes #2 as its parameter pattern and has #3 as its code.
+%
+% Example:
+%
+% \pgfkeysdefargs{/swap}{#1#2}{#2#1}
+
+\long\def\pgfkeysdefargs#1#2#3{%
+ \long\def\pgfkeys@temp#2\pgfeov{#3}%
+ \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}%
+ \pgfkeyssetvalue{#1/.@args}{#2\pgfeov}%
+ \pgfkeyssetvalue{#1/.@body}{#3}%
+}
+
+\long\def\pgfkeysedefargs#1#2#3{%
+ \long\edef\pgfkeys@temp#2\pgfeov{#3}%
+ \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}%
+ \pgfkeyssetvalue{#1/.@args}{#2\pgfeov}%
+ \pgfkeyssetevalue{#1/.@body}{#3}%
+}
+
+% Like \pgfkeysdefargs, but `#2' is an integer denoting the expected
+% *number* of arguments.
+%
+% There is a subtle difference between the 'args' command, when it
+% comes to spaces:
+% a key defined with defargs{#1#2} must not have spaces between the
+% arguments when it is used.
+%
+% See this:
+%
+%--------------------------------------------------
+% % defnargs:
+% \pgfkeysdefnargs{/a}{2}{1=`#1', 2=`#2'}
+% \pgfkeys{
+% /a=
+% {1}
+% {2}
+% }
+% ->defnargs: 1=`1', 2=`2'
+%
+% defargs:
+% \pgfkeysdefargs{/b}{#1#2}{1=`#1', 2=`#2'}
+% \pgfkeys{
+% /b=
+% {1}
+% {2}
+% }
+% ->defargs: 1=`1', 2=` 2' (note the space!)
+%
+% defargs:
+% \pgfkeysdefargs{/b}{#1#2}{1=`#1', 2=`#2'}
+% \pgfkeys{
+% /b=
+% {1}%
+% {2}
+% }
+% ->defargs: 1=`1', 2=`2'
+% --------------------------------------------------
+\long\def\pgfkeysdefnargs#1#2#3{\pgfkeysdefnargs@{#1}{#2}{#3}{\def}{\pgfkeyssetvalue}}%
+\long\def\pgfkeysedefnargs#1#2#3{\pgfkeysdefnargs@{#1}{#2}{#3}{\edef}{\pgfkeyssetevalue}}%
+\long\def\pgfkeysdefnargs@#1#2#3#4#5{%
+ \ifcase#2\relax
+ \pgfkeyssetvalue{#1/.@args}{}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2##3}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}%
+ \or
+ \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}%
+ \else
+ \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}%
+ \fi
+ \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs
+ \def\pgfkeys@temp{\expandafter\long\expandafter#4\csname pgfk@#1/.@@body\endcsname}%
+ \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}%
+ % eliminate the \pgfeov at the end such that TeX gobbles spaces
+ % by using
+ % \pgfkeysdef{#1}{\pgfkeysvalueof{#1/.@@body}##1}
+ % (with expansion of '#1'):
+ \edef\pgfkeys@tempargs{\noexpand\pgfkeysvalueof{#1/.@@body}}%
+ \def\pgfkeys@temp{\pgfkeysdef{#1}}%
+ \ifnum#2=1\relax
+ \expandafter\pgfkeys@temp\expandafter{\pgfkeys@tempargs{##1}}%
+ \else
+ \expandafter\pgfkeys@temp\expandafter{\pgfkeys@tempargs##1}%
+ \fi
+ #5{#1/.@body}{#3}%
+}
+
+% Defining a key command
+
+\pgfkeysdef{/handlers/.code}{\pgfkeysdef{\pgfkeyscurrentpath}{#1}}
+\pgfkeysdef{/handlers/.code 2 args}{\pgfkeysdefargs{\pgfkeyscurrentpath}{##1##2}{#1}}
+\pgfkeysdef{/handlers/.ecode}{\pgfkeysedef{\pgfkeyscurrentpath}{#1}}
+\pgfkeysdef{/handlers/.ecode 2 args}{\pgfkeysedefargs{\pgfkeyscurrentpath}{##1##2}{#1}}
+\pgfkeysdefnargs{/handlers/.code args}{2}{\pgfkeysdefargs{\pgfkeyscurrentpath}{#1}{#2}}
+\pgfkeysdefnargs{/handlers/.ecode args}{2}{\pgfkeysedefargs{\pgfkeyscurrentpath}{#1}{#2}}
+\pgfkeysdefnargs{/handlers/.code n args}{2}{\pgfkeysdefnargs{\pgfkeyscurrentpath}{#1}{#2}}
+\pgfkeysdefnargs{/handlers/.ecode n args}{2}{\pgfkeysedefnargs{\pgfkeyscurrentpath}{#1}{#2}}
+
+% Adding to a key command
+
+\pgfkeys{/handlers/.add code/.code 2 args=%
+ % Find out, whether with args or not.
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@args}%
+ {% Yes, so add to body and reuse args
+ \pgfkeysaddvalue{\pgfkeyscurrentpath/.@body}{#1}{#2}%
+ % Redefine code
+ {%
+ \pgfkeysgetvalue{\pgfkeyscurrentpath/.@args}{\pgfkeys@tempargs}%
+ \pgfkeysgetvalue{\pgfkeyscurrentpath/.@body}{\pgfkeys@tempbody}%
+ \def\pgfkeys@marshal{\expandafter\long\expandafter\gdef\expandafter\pgfkeys@global@temp\pgfkeys@tempargs}%
+ \expandafter\pgfkeys@marshal\expandafter{\pgfkeys@tempbody}%
+ }%
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@@body}{%
+ % support for \pgfkeysndefargs:
+ \pgfkeyslet{\pgfkeyscurrentpath/.@@body}{\pgfkeys@global@temp}%
+ }{%
+ % support for \pgfkeysdefargs:
+ \pgfkeyslet{\pgfkeyscurrentpath/.@cmd}{\pgfkeys@global@temp}%
+ }%
+ }%
+ {%
+ % No, so single argument (simple \pgfkeysdef). Redefine accordingly.
+ \edef\pgf@expanded@path{\pgfkeyscurrentpath}%
+ {%
+ \toks0{#1}%
+ \pgfkeysifdefined{\pgf@expanded@path/.@cmd}%
+ {\expandafter\expandafter\expandafter\pgfkeys@temptoks\expandafter\expandafter\expandafter{\csname pgfk@\pgf@expanded@path/.@body\endcsname}}%
+ {\expandafter\pgfkeys@temptoks\expandafter{\expandafter\pgfkeyssetvalue\expandafter{\pgf@expanded@path}{##1}}}%
+ \toks1{#2}%
+ \xdef\pgfkeys@global@temp{\the\toks0 \the\pgfkeys@temptoks \the\toks1 }%
+ }%
+ \def\pgf@temp{\pgfkeyssetvalue{\pgf@expanded@path/.@body}}%
+ \expandafter\pgf@temp\expandafter{\pgfkeys@global@temp}%
+ \expandafter\long\expandafter\def\expandafter\pgfkeys@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}%
+ \pgfkeyslet{\pgf@expanded@path/.@cmd}\pgfkeys@temp%
+ }%
+}
+\pgfkeys{/handlers/.prefix code/.code=\pgfkeys{\pgfkeyscurrentpath/.add code={#1}{}}}%
+\pgfkeys{/handlers/.append code/.code=\pgfkeys{\pgfkeyscurrentpath/.add code={}{#1}}}%
+
+
+% Defining a style
+
+\pgfkeys{/handlers/.style/.code=\pgfkeys{\pgfkeyscurrentpath/.code=\pgfkeysalso{#1}}}
+\pgfkeys{/handlers/.estyle/.code=\pgfkeys{\pgfkeyscurrentpath/.ecode=\noexpand\pgfkeysalso{#1}}}
+\pgfkeys{/handlers/.style args/.code 2 args=\pgfkeys{\pgfkeyscurrentpath/.code args={#1}{\pgfkeysalso{#2}}}}
+\pgfkeys{/handlers/.estyle args/.code 2 args=\pgfkeys{\pgfkeyscurrentpath/.ecode args={#1}{\noexpand\pgfkeysalso{#2}}}}
+\pgfkeys{/handlers/.style 2 args/.code=\pgfkeys{\pgfkeyscurrentpath/.code 2 args=\pgfkeysalso{#1}}}
+\pgfkeys{/handlers/.style n args/.code 2 args=\pgfkeys{\pgfkeyscurrentpath/.code n args={#1}{\pgfkeysalso{#2}}}}
+
+% Adding to a style
+
+\pgfkeys{/handlers/.add style/.code 2 args=\pgfkeys{\pgfkeyscurrentpath/.add code={\pgfkeysalso{#1}}{\pgfkeysalso{#2}}}}%
+\pgfkeys{/handlers/.prefix style/.code=\pgfkeys{\pgfkeyscurrentpath/.add code={\pgfkeysalso{#1}}{}}}%
+\pgfkeys{/handlers/.append style/.code=\pgfkeys{\pgfkeyscurrentpath/.add code={}{\pgfkeysalso{#1}}}}%
+
+
+% Defining a value
+
+\pgfkeys{/handlers/.initial/.code=\pgfkeyssetvalue{\pgfkeyscurrentpath}{#1}}
+\pgfkeys{/handlers/.add/.code 2 args=\pgfkeysaddvalue{\pgfkeyscurrentpath}{#1}{#2}}
+\pgfkeys{/handlers/.prefix/.code=\pgfkeysaddvalue{\pgfkeyscurrentpath}{#1}{}}
+\pgfkeys{/handlers/.append/.code=\pgfkeysaddvalue{\pgfkeyscurrentpath}{}{#1}}
+\pgfkeys{/handlers/.get/.code=\pgfkeysgetvalue{\pgfkeyscurrentpath}{#1}}
+\pgfkeys{/handlers/.link/.code=\pgfkeyssetvalue{\pgfkeyscurrentpath}{\pgfkeysvalueof{#1}}}
+
+
+% Defining a default
+
+\pgfkeys{/handlers/.default/.code=\pgfkeyssetvalue{\pgfkeyscurrentpath/.@def}{#1}}
+\pgfkeys{/handlers/.value required/.code=\pgfkeyssetvalue{\pgfkeyscurrentpath/.@def}{\pgfkeysvaluerequired}}
+\pgfkeys{/handlers/.value forbidden/.code=\pgfkeys{\pgfkeyscurrentpath/.add code=%
+{%
+ \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text%
+ \else%
+ \def\pgf@marshal{\pgfkeysvalueof{/errors/value forbidden/.@cmd}}%
+ \expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkey\expandafter}\expandafter{\pgfkeyscurrentvalue}\pgfeov%
+ \fi%
+}{}}}
+
+
+% High-level cmds
+
+\pgfkeys{/handlers/.store in/.code=\pgfkeysalso{\pgfkeyscurrentpath/.code=\def#1{##1}}}
+\pgfkeys{/handlers/.estore in/.code=\pgfkeysalso{\pgfkeyscurrentpath/.code=\edef#1{##1}}}
+
+\pgfkeys{/handlers/.is if/.code=\pgfkeysalso{%
+ \pgfkeyscurrentpath/.code=\pgfkeys@handle@boolean{#1}{##1},
+ \pgfkeyscurrentpath/.default=true%
+ }%
+}
+\def\pgfkeys@handle@boolean#1#2{%
+ \pgfkeys@ifcsname{#1#2}{%
+ \csname#1#2\endcsname%
+ }{%
+ \def\pgf@marshal{\pgfkeysvalueof{/errors/boolean expected/.@cmd}}%
+ \expandafter\pgf@marshal\expandafter{\pgfkeyscurrentkey}{#2}\pgfeov%
+ }%
+}
+
+\pgfkeys{/handlers/.is choice/.code=%
+ \pgfkeys{%
+ \pgfkeyscurrentpath/.cd,%
+ .code=\def\pgfkeys@was@choice{##1}\expandafter\pgfkeysalso\expandafter{\pgfkeyscurrentkey/##1},
+ .unknown/.code={%
+ \def\pgf@marshal{\pgfkeysvalueof{/errors/unknown choice value/.@cmd}}%
+ {\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@pathtoks\expandafter}\expandafter{\pgfkeys@was@choice}\pgfeov}%
+ }%
+ }%
+}
+
+
+% Repeatedly setting a key
+
+\pgfkeys{/handlers/.list/.code=%
+ {%
+ \ifx\foreach\@undefined%
+ \pgfkeys@error{You need to load the pgffor package to use the .list key syntax.}%
+ \fi%
+ % Use foreach to unfold the list
+ \def\pgf@keys@temp{}%
+ \foreach \pgf@keys@key in{#1}%
+ {\expandafter\expandafter\expandafter\gdef%
+ \expandafter\expandafter\expandafter\pgf@keys@temp%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@keys@temp\expandafter{\pgf@keys@key}}}%
+ \edef\pgf@keys@list@path{\pgfkeyscurrentpath}%
+ \expandafter\expandafter\expandafter\pgf@keys@do@list%
+ \expandafter\expandafter\expandafter{\expandafter\pgf@keys@list@path\expandafter}\pgf@keys@temp\pgf@stop%
+ }%
+}
+\def\pgf@keys@do@list#1{\pgf@keys@utilifnextchar\bgroup{\pgf@keys@do@list@item{#1}}\pgf@keys@gobble}
+\def\pgf@keys@do@list@item#1#2{\pgfkeysalso{#1={#2}}\pgf@keys@do@list{#1}}
+
+
+% Forwarding
+
+\pgfkeys{/handlers/.forward to/.code=%
+ \pgfkeys{\pgfkeyscurrentpath/.add code={}{\pgfkeys{#1={##1}}}}
+}
+
+
+% Inspection handlers
+
+\pgfkeys{/handlers/.show value/.code=\pgfkeysgetvalue{\pgfkeyscurrentpath}{\pgfkeysshower}\show\pgfkeysshower} % inspect the value
+\pgfkeys{/handlers/.show code/.code=\pgfkeysgetvalue{\pgfkeyscurrentpath/.@cmd}{\pgfkeysshower}\show\pgfkeysshower} % inspect the body of the command
+
+
+% First char syntax handlers
+\pgfkeys{/handlers/first char syntax/.is if=pgfkeys@syntax@handlers}
+
+% Path handling
+
+% Prepares the .unknown handler used by '.search also'.
+% It will be stored into \pgfkeys@global@temp.
+\def\pgfkeys@searchalso@prepare@unknown@handler#1{%
+ \global\def\pgfkeys@global@temp##1\pgfeov{}%
+ \pgfkeys@searchalso@parse#1,\pgfkeys@mainstop
+ {%
+ \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}%
+ \toks1={%
+ \pgfkeysgetvalue{/handlers/.unknown/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeys@searchalso@temp@value\pgfeov
+ }%
+ \xdef\pgfkeys@global@temp{%
+ \noexpand\def\noexpand\pgfkeys@searchalso@temp@value{####1}%
+ \noexpand\ifpgfkeysaddeddefaultpath
+ \noexpand\expandafter\noexpand\pgfkeys@firstoftwo
+ \noexpand\else
+ \noexpand\expandafter\noexpand\pgfkeys@secondoftwo
+ \noexpand\fi{%
+ \noexpand\pgfkeyssuccessfalse
+ \noexpand\let\noexpand\pgfkeys@searchalso@name=\noexpand\pgfkeyscurrentkeyRAW
+ \the\toks0 % one or more /.try things; one for each path. The last element won't have a /.try
+ %\noexpand\ifpgfkeyssuccess
+ %\noexpand\else
+ % \the\toks1 % invoke /handlers/.unknown handler
+ %\noexpand\fi
+ }{%
+ \the\toks1 % invoke /handlers/.unknown handler
+ }%
+ }%
+ \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}%
+ }%
+}%
+
+\def\pgfkeys@searchalso@parse{\futurelet\pgfkeys@possiblerelax\pgfkeys@searchalso@parse@main}
+\def\pgfkeys@searchalso@parse@main{%
+ \ifx\pgfkeys@possiblerelax\pgfkeys@mainstop%
+ \expandafter\pgfkeys@cleanup%
+ \else%
+ \expandafter\pgfkeys@searchalso@appendentry%
+ \fi%
+}
+\def\pgfkeys@searchalso@appendentry#1,#2{%
+ \def\pgfkeys@searchalso@nexttok{#2}%
+ \pgfkeys@spdef\pgfkeys@temp{#1}%
+ {%
+ \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}%
+ \toks1=\expandafter{\pgfkeys@temp}%
+ \xdef\pgfkeys@global@temp{%
+ \the\toks0 % the space is important!
+ \noexpand\ifpgfkeyssuccess\noexpand\else
+ \noexpand\pgfqkeys{\the\toks1 }{\noexpand\pgfkeys@searchalso@name
+ \ifx\pgfkeys@searchalso@nexttok\pgfkeys@mainstop\else/.try\fi /.expand once=\noexpand\pgfkeys@searchalso@temp@value}%
+ \noexpand\fi}%
+ \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}%
+ }%
+ \pgfkeys@searchalso@parse#2%
+}
+\pgfkeys{%
+ /handlers/.is family/.code=\pgfkeys{\pgfkeyscurrentpath/.ecode=\edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}},%
+ /handlers/.cd/.code=\edef\pgfkeysdefaultpath{\pgfkeyscurrentpath/},%
+ /handlers/.search also/.code={%
+ \pgfkeys@searchalso@prepare@unknown@handler{#1}%
+%\message{I prepared the '\pgfkeyscurrentpath/.unknown' handler \meaning\pgfkeys@global@temp\space for '#1'.}%
+ \pgfkeyslet{\pgfkeyscurrentpath/.unknown/.@cmd}{\pgfkeys@global@temp}%
+ }
+}%
+
+
+% Value expansion
+
+\pgfkeys{/handlers/.expand once/.code=\expandafter\pgfkeys@exp@call\expandafter{#1}}
+\pgfkeys{/handlers/.expand twice/.code=\expandafter\expandafter\expandafter\pgfkeys@exp@call\expandafter\expandafter\expandafter{#1}}
+\pgfkeys{/handlers/.expanded/.code=\edef\pgfkeys@temp{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfkeys@temp}}
+
+\long\def\pgfkeys@exp@call#1{\pgfkeysalso{\pgfkeyscurrentpath={#1}}}
+
+\def\pgfkeys@mathparse{%
+ \pgfkeys@ifcsname{pgfmathparse}{%
+ \pgfmathparse
+ }{%
+ \pgfkeys@error{You have to load `pgfmath' to use \string\pgfmathparse}%
+ \def\pgfmathresult
+ }%
+}
+\pgfkeys{/handlers/.evaluated/.code=\pgfkeys@mathparse{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
+
+% Try to set a key and do nothing if not define
+
+\newif\ifpgfkeyssuccess
+\pgfkeys{/handlers/.try/.code=\pgfkeys@try}
+\pgfkeys{/handlers/.retry/.code=\ifpgfkeyssuccess\else\pgfkeys@try\fi}
+\def\pgfkeys@try{%
+ \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% make sure that \pgfkeys@code doesn't know about 'try'. Important for .is choice
+ \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@def}%
+ {\pgfkeysgetvalue{\pgfkeyscurrentpath/.@def}{\pgfkeyscurrentvalue}}
+ {}% no default, so leave it
+ \fi%
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}%
+ {%
+ \pgfkeysgetvalue{\pgfkeyscurrentpath/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov%
+ \pgfkeyssuccesstrue%
+ }%
+ {%
+ \pgfkeysifdefined{\pgfkeyscurrentpath}%
+ {%
+ \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text%
+ \pgfkeysvalueof{\pgfkeyscurrentpath}%
+ \else%
+ \pgfkeyslet{\pgfkeyscurrentpath}\pgfkeyscurrentvalue%
+ \fi%
+ \pgfkeyssuccesstrue%
+ }%
+ {%
+ \pgfkeys@split@path%
+ \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{%
+ % in the standard configuration, this check here is redundant
+ % because pgfkeys@ifexecutehandler === true.
+ % It is only interesting for 'handle only existing'.
+ \pgfkeys@ifexecutehandler{%
+ \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov
+ \pgfkeyssuccesstrue%
+ }{%
+ \pgfkeyssuccessfalse
+ }%
+ }{%
+ \pgfkeyssuccessfalse
+ }%
+ }%
+ }%
+}
+
+% Utilities
+
+\pgfkeys{/utils/exec/.code={#1}} % simply execute the given code directly.
+
+
+% Errors
+
+\pgfkeys{
+ /errors/boolean expected/.code 2 args=%
+ {%
+ \toks1={#1}%
+ \toks2={#2}%
+ \pgfkeys@error{%
+ Boolean parameter of key '\the\toks1' must be 'true' or 'false', not
+ '\the\toks2'. I am going to ignore it%
+ }%
+ },
+ /errors/value required/.code 2 args=%
+ {%
+ \toks1={#1}%
+ \pgfkeys@error{%
+ The key '\the\toks1' requires a value. I am going to ignore this
+ key%
+ }%
+ },
+ /errors/value forbidden/.code 2 args=%
+ {%
+ \toks1={#1}%
+ \toks2={#2}%
+ \pgfkeys@error{%
+ You may not specify a value for the key '\the\toks1'. I am going to ignore
+ the value '\the\toks2' that you provided%
+ }%
+ },
+ /errors/unknown choice value/.code 2 args=%
+ {%
+ \toks1={#1}%
+ \toks2={#2}%
+ \pgfkeys@error{%
+ Choice '\the\toks2' unknown in choice key '\the\toks1'. I am
+ going to ignore this key%
+ }%
+ },
+ /errors/unknown key/.code 2 args=%
+ {%
+ \toks1={#1}%
+ \toks2={#2}%
+ \def\pgf@temp{#2}%
+ \pgfkeys@error{%
+ I do not know the key '\the\toks1'\ifx\pgf@temp\pgfkeysnovalue@text\space\else, to which you passed
+ '\the\toks2', \fi and I am going to ignore it. Perhaps you
+ misspelled it%
+ }%
+ }
+}
+
+\pgfkeys{/handlers/.unknown/.code=%
+ {%
+ \def\pgf@marshal{\pgfkeysvalueof{/errors/unknown key/.@cmd}}%
+ {\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkey\expandafter}\expandafter{\pgfkeyscurrentvalue}\pgfeov}%
+ }%
+}
+
+\pgfkeys{
+ /handler config/.is choice,
+ /handler config/all/.code={%
+ \let\pgfkeys@case@three=\pgfkeys@case@three@handleall
+ \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleall
+ },
+ /handler config/only existing/.code={%
+ \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted
+ \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleonlyexisting
+ },
+ /handler config/full or existing/.code={%
+ \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted
+ \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handlefullorexisting
+ },
+ /handler config/only existing/add exception/.code={\pgfkeysaddhandleonlyexistingexception{#1}},
+}%
+\pgfkeysaddhandleonlyexistingexception{.cd}%
+\pgfkeysaddhandleonlyexistingexception{.try}%
+\pgfkeysaddhandleonlyexistingexception{.retry}%
+\pgfkeysaddhandleonlyexistingexception{.lastretry}%
+\pgfkeysaddhandleonlyexistingexception{.unknown}%
+\pgfkeysaddhandleonlyexistingexception{.expand once}%
+\pgfkeysaddhandleonlyexistingexception{.expand twice}%
+\pgfkeysaddhandleonlyexistingexception{.expanded}%
+
+
+% Utilities for self-containment
+\def\pgf@keys@gobble#1{}
+\long\def\pgf@keys@utilifnextchar#1#2#3{%
+ \let\pgf@keys@utilreserved@d=#1%
+ \def\pgf@keys@utilreserved@a{#2}%
+ \def\pgf@keys@utilreserved@b{#3}%
+ \futurelet\pgf@keys@utillet@token\pgf@keys@utilifnch}
+\def\pgf@keys@utilifnch{%
+ \ifx\pgf@keys@utillet@token\pgf@keys@utilsptoken
+ \let\pgf@keys@utilreserved@c\pgf@keys@utilxifnch
+ \else
+ \ifx\pgf@keys@utillet@token\pgf@keys@utilreserved@d
+ \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@a
+ \else
+ \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@b
+ \fi
+ \fi
+ \pgf@keys@utilreserved@c}
+{%
+ \def\:{\global\let\pgf@keys@utilsptoken= } \:
+ \def\:{\pgf@keys@utilxifnch} \expandafter\gdef\: {\futurelet\pgf@keys@utillet@token\pgf@keys@utilifnch}
+}
+
+\chardef\pgfkeys@inputcheck0
+\def\pgfkeys@IfFileExists#1{%
+ \openin\pgfkeys@inputcheck=#1
+ \ifeof\pgfkeys@inputcheck
+ \expandafter\closein\expandafter\pgfkeys@inputcheck
+ \expandafter\pgfkeys@secondoftwo
+ \else
+ \expandafter\closein\expandafter\pgfkeys@inputcheck
+ \expandafter\pgfkeys@firstoftwo
+ \fi
+}
+
+% Library system for pgfkeys
+\def\usepgfkeyslibrary{\pgf@keys@utilifnextchar[{\pgfkeys@@uselibrary}{\pgfkeys@uselibrary}}
+\def\pgfkeys@@uselibrary[#1]{\pgfkeys@uselibrary{#1}}
+\def\pgfkeys@uselibrary#1{\pgfkeys@uselibrary@parse#1,\pgfkeys@mainstop}
+\def\pgfkeys@uselibrary@parse{%
+ \pgf@keys@utilifnextchar\pgfkeys@mainstop{\pgfkeys@cleanup}{\pgfkeys@uselibrary@normal}%
+}%
+\def\pgfkeys@uselibrary@normal#1,{%
+ \pgfkeys@uselibrary@load{#1}%
+ \pgfkeys@uselibrary@parse
+}
+\def\pgfkeys@uselibrary@load#1{%
+ \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{#1}%
+ \ifx\pgf@temp\pgfkeys@empty\expandafter\pgfkeys@firstoftwo\else\expandafter\pgfkeys@secondoftwo\fi{}{%
+ \pgfkeys@ifcsname{pgfkeys@library@\pgf@temp @loaded}{}{%
+ \expandafter\let\csname pgfkeys@library@\pgf@temp @loaded\endcsname=\pgfkeys@empty
+ \expandafter\edef\csname pgfkeys@library@#1@atcode\endcsname{\the\catcode`\@}%
+ \expandafter\edef\csname pgfkeys@library@#1@barcode\endcsname{\the\catcode`\|}%
+ \expandafter\edef\csname pgfkeys@library@#1@dollarcode\endcsname{\the\catcode`\$}%
+ \catcode`\@=11
+ \catcode`\|=12
+ \catcode`\$=3
+ \pgfkeys@IfFileExists{pgfkeyslibrary\pgf@temp.code.tex}{%
+ \input pgfkeyslibrary\pgf@temp.code.tex
+ }{%
+ \pgfkeys@error{I did not find the pgfkeys library '\pgf@temp'. I looked for the
+ file named pgfkeyslibrary\pgf@temp.code.tex, but could not find it in the
+ current texmf trees.}%
+ }%
+ \catcode`\@=\csname pgfkeys@library@#1@atcode\endcsname
+ \catcode`\|=\csname pgfkeys@library@#1@barcode\endcsname
+ \catcode`\$=\csname pgfkeys@library@#1@dollarcode\endcsname
+ }%
+ }%
+}
+
+\let\pgfkeys@library@filtered@loaded\pgfkeys@empty
+\input pgfkeyslibraryfiltered.code.tex
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfkeyslibraryfiltered.code.tex b/graphics/pgf/base/tex/generic/utilities/pgfkeyslibraryfiltered.code.tex
new file mode 100644
index 0000000000..37972ba7e0
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfkeyslibraryfiltered.code.tex
@@ -0,0 +1,1015 @@
+% Copyright 2019 by Christian Feuersaenger
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% This file contains additions to pgfkeys.code.tex (loaded
+% automatically at the end of pgfkeys.code.tex)
+%
+% Improvements:
+%
+% - option filtering
+% you provide
+% - a boolean predicate
+% - a "filter handler" which will be invoked for non-matching options,
+% - a key=value list as usual.
+% The filter sets only matching options and invokes the handler for
+% unmatching ones.
+%
+% - Fast family support as in xkeyval.
+% - A key like /my tree/my option can be associated with /my family
+% - You can efficiently set keys which belong to a set of "active"
+% families.
+% Remaining options can be collected into a macro.
+
+% WARNING:
+% this file overwrites
+% \pgfkeys@addpath
+% \pgfkeys@nevermind
+%
+% all other features are 'additive'
+
+
+% these implementations will be switched dynamically with their
+% filtered versions (in \pgfkeys@install@filter@and@invoke)
+\let\pgfkeys@orig@case@one=\pgfkeys@case@one
+\let\pgfkeys@orig@@set=\pgfkeys@@set
+\let\pgfkeys@orig@@qset=\pgfkeys@@qset
+\let\pgfkeys@orig@try=\pgfkeys@try
+\let\pgfkeys@orig@unknown=\pgfkeys@unknown
+
+\newif\ifpgfkeysfilteringisactive
+\newif\ifpgfkeysfiltercontinue
+\let\pgfkeys@key@predicate=\pgfkeys@empty
+\let\pgfkeys@filtered@handler=\pgfkeys@empty
+\newtoks\pgfkeys@tmptoks
+
+% Performs 'filtered' key settings.
+%
+% For every option for which the path prefixing has already been done,
+% the current key filter predicate will be invoked. If the predicate
+% returns true, pgfkeys will process this key in the normal manner.
+% If not, a key filter handler will be invoked.
+%
+% The *predicate* and *handler* semantics are as follows:
+% PRECONDITION:
+% 1. The variables
+% \pgfkeyscurrentkey (full path including name)
+% \pgfkeyscurrentkeyRAW (the current key as it has been
+% found in the key=value list
+% without path modification)
+% \pgfkeyscurrentvalue
+% are all set. If the current key is a handler variable,
+% \pgfkeyscurrentname
+% and
+% \pgfkeyscurrentpath
+% are also set.
+% 2. The type of option has already been checked, that means
+% case (1) whether '.@cmd' exists
+% case (2) whether the key as such has its value
+% case (3) it is a handler like '.code', '.cd' or whatever.
+% case (0) it is unknown.
+% The actual case number (0-3) will be provided as contents
+% of the macro
+% \pgfkeyscasenumber.
+% It is always a one-character token, so it may be compared
+% with both, \ifnum or \if.
+% Please note that unknown options will be processed with
+% the usual '.unknown' handlers unless the key filter takes
+% control over unknown options as well.
+%
+% POSTCONDITION:
+% the predicate sets
+% \pgfkeysfiltercontinuetrue
+% or
+% \pgfkeysfiltercontinuefalse
+% (the boolean \ifpgfkeysfiltercontinue).
+% Depending on this 'if', option processing will be continued or
+% skipped.
+%
+% The handler can do anything with the option, for example collect
+% unmatched ones.
+%
+% ATTENTION: \pgfkeysfiltered can't be nested (yet). Use the
+% \pgfkeyspredicateAND if you need multiple predicates at once.
+% Nesting would produce unexpected results because the current filter
+% state can't be stored/restored without TeX-groups, therefor it is
+% disabled.
+%
+% ATTENTION: you can't filter error messages.
+%
+% REMARK: In case (3), the macros \pgfkeyscurrentpath and
+% \pgfkeyscurrentname have already been computed, you do not need to
+% invoke \pgfkeyssplitpath. In any other case, neither path nor name
+% are required for the options processing - if you need them for
+% predicates/handlers, you need to compute them by hand.
+%
+%
+% Example:
+% \def\unmatched{}
+% \pgfkeys{/pgf/key filters/is descendant of/.install key filter=/my group}
+% \pgfkeys{/pgf/key filter handlers/append filtered to/.install key filter handler=\unmatched}
+% \pgfkeysfiltered%
+% {/my group/option 1=value 1,/tikz/option 2=value 2}
+% ->
+% will set '/my group/option 1' as usual, but '/tikz/option 2' will not
+% be set. Instead, it will be appended to '\unmatched' such that
+% \unmatched = {/tikz/option 2=value2}
+% after the operation.
+%
+% Arguments:
+% #1: key-value list.
+\def\pgfkeysfiltered{%
+ % produce
+ % '{<default path>}'
+ % each expanded exactly one time into the register:
+ \expandafter\pgfkeysfiltered@@install\expandafter{\pgfkeysdefaultpath}%
+}
+
+% #1: old value of default path.
+% #2: key-value-list.
+\long\def\pgfkeysfiltered@@install#1#2{%
+ \pgfkeys@install@filter@and@invoke{%
+ \let\pgfkeysdefaultpath\pgfkeys@root%
+ \pgfkeys@parse#2,\pgfkeys@mainstop%
+ \def\pgfkeysdefaultpath{#1}%
+ }%
+}
+
+% Assuming that macro #1 contains a key=value list, this command
+% performs an \pgfkeysalso command for the content of macro #1.
+%
+% It can be used in conjunction with
+% - \pgfkeysfiltered and
+% - \pgfkeysappendfilterednamestomacro:
+% the first pass fill only process options matching the filter, then,
+% a \pgfkeysalsofrom can be used at a later time to set the remaining
+% options.
+%
+% Example:
+% \pgfkeys{/my group/.cd,/utils/exec=\pgfkeysalsofrom\filtered}
+\long\def\pgfkeysalsofrom#1{%
+ \expandafter\pgfkeysalso\expandafter{#1}%
+}
+
+% The same as \pgfkeysalsofrom, but it invokes \pgfkeysalsofiltered.
+\long\def\pgfkeysalsofilteredfrom#1{%
+ \expandafter\pgfkeysalsofiltered\expandafter{#1}%
+}
+
+% #1 = options
+\long\def\pgfkeysalsofiltered#1{%
+ \pgfkeys@install@filter@and@invoke{\pgfkeysalso{#1}}%
+}%
+
+% The same like \pgfkeysfiltered, but with quick search path setting.
+%
+% #1: default path
+% #2: key-value-pairs
+\long\def\pgfqkeysfiltered#1{%
+ \expandafter\pgfqkeysfiltered@@install\expandafter{\pgfkeysdefaultpath}{#1}%
+}
+
+% #1: old value of default path.
+% #2: default path
+% #3: key-value-list.
+\long\def\pgfqkeysfiltered@@install#1#2#3{%
+ \pgfkeys@install@filter@and@invoke{%
+ \def\pgfkeysdefaultpath{#2/}\pgfkeys@parse#3,\pgfkeys@mainstop\def\pgfkeysdefaultpath{#1}%
+ }%
+}
+
+% Family management
+%
+% The family code provides the following features:
+% 1. every key can be associated with 0 or 1 'family'.
+% 2. Families are a loose association which are independent of the key
+% hierarchy.
+% For example, /my tree/key1 can belong to family /tikz.
+%
+% 3. It is possible to "activate" or "deactivate" single families.
+% Furthermore, it is possible to set only keys which belong to
+% active families (using \pgfkeysfiltered).
+% 4. Runtime complexities:
+% If you have N options and you only want to process K active
+% families, the runtime is O( N + K ):
+% - activate every family O(K)
+% - use \pgfkeyshasactivefamily as filter predicate O(N)
+% - deactivate every family O(K)
+
+
+% Activates family #1.
+%
+% #1 maybe a macro.
+\def\pgfkeysactivatefamily#1{%
+ \pgfkeysiffamilydefined
+ {#1}%
+ {\csname pgfk@#1/familyactivetrue\endcsname}%
+ {\pgfkeysvalueof{/errors/family unknown/.@cmd}{#1}\pgfeov}%
+%\message{[ACTIVATING FAMILY #1]}%
+}
+
+% Deactivates family #1.
+%
+% #1 maybe a macro.
+\def\pgfkeysdeactivatefamily#1{%
+ \pgfkeysiffamilydefined
+ {#1}%
+ {\csname pgfk@#1/familyactivefalse\endcsname}%
+ {\pgfkeysvalueof{/errors/family unknown/.@cmd}{#1}\pgfeov}%
+%\message{[DEACTIVATING FAMILY #1]}%
+}
+
+% Activates all families in the comma separated list #1.
+%
+% It will also generate code for deactivation of all those families
+% into the command #2.
+%
+% #1: a comma-separated list of fully qualified family names.
+% #2: a command which will be filled with a deactivate-all command.
+\def\pgfkeysactivatefamilies#1#2{%
+ \pgfkeyssavekeyfilterstateto\pgfkeys@cur@state
+ \expandafter\pgfkeysactivatefamilies@impl\expandafter{\pgfkeys@cur@state}{#1}{#2}%
+}
+% #1: commands needed to restore the old filtering state
+% #2: family name list
+% #3: macro name for de-activate command
+\def\pgfkeysactivatefamilies@impl#1#2#3{%
+ \pgfkeysinstallkeyfilter{/pgf/key filters/false}{}%
+ \let#3=\pgfkeys@empty%
+ \def\pgfkeys@filtered@handler{\pgfkeys@family@activate@handler{#3}}%
+ \pgfkeysalsofiltered{#2}%
+ #1%
+}
+
+\def\pgfkeys@family@activate@handler#1{%
+ \pgfkeysactivatefamily{\pgfkeyscurrentkey}%
+ % produce
+ % <old list> '\pgfkeysdeactivatefamily{' <current key> '}'
+ \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter#1\expandafter\pgfkeysdeactivatefamily\expandafter{\pgfkeyscurrentkey}}%
+ \edef#1{\the\pgfkeys@tmptoks}%
+}
+
+% If for testing whether a family exists.
+%
+% #1 = fully qualified family name
+% #2 = if-case
+% #3 = else-case
+%
+% Description:
+%
+% If the family exists, #2 will be executed. Otherwise, #3 will be
+% called.
+\long\def\pgfkeysiffamilydefined#1#2#3{\ifcsname ifpgfk@#1/familyactive\endcsname#2\else#3\fi}
+
+% Sets the TeX boolean
+% \ifpgfkeysfiltercontinue := ( family #1 is active )
+%
+% Argument:
+% #1 the family name. Maybe a macro.
+\def\pgfkeysisfamilyactive#1{%
+ \pgfkeysiffamilydefined{#1}{%
+ \expandafter\let\expandafter\ifpgfkeysfiltercontinue\csname ifpgfk@#1/familyactive\endcsname
+ }{%
+ \pgfkeysvalueof{/errors/family unknown/.@cmd}{#1}\pgfeov%
+ \expandafter\expandafter\expandafter\let\csname ifpgfkeysfiltercontinue\endcsname\csname iffalse\endcsname
+ }%
+}%
+
+% Retrieve the family of full key #1 into macro #2.
+%
+% Will set the TeX boolean \ifpgfkeyssuccess to whether the full key
+% really has a family.
+%
+% The family for any key is stored in the sub-key #1/family.
+%
+% Parameters:
+% #1: the full key name for which the family is requested. Maybe a
+% macro.
+% #2: a macro name which will be filled with the result.
+\def\pgfkeysgetfamily#1#2{%
+ \pgfkeysifdefined{#1/family}{\pgfkeysgetvalue{#1/family}{#2}\pgfkeyssuccesstrue}{\pgfkeyssuccessfalse}%
+}
+
+% Equivalent to \pgfkeys{#1/.belongs to family=#2}
+\def\pgfkeyssetfamily#1#2{%
+ \pgfkeysiffamilydefined{#2}{%
+ \pgfkeyssetvalue{#1/family}{#2}%
+ }{%
+ \pgfkeysalso{/errors/family unknown={#2}}%
+ }%
+}%
+
+
+% Sets \ifpgfkeysfiltercontinue to true iff the current key belongs to
+% the /errors tree.
+\long\def\pgfkeys@cur@is@descendant@of@errors{%
+ \expandafter\pgfkeys@cur@is@descendant@of@errors@impl\pgfkeyscurrentkey/errors\pgf@@eov
+}%
+\long\def\pgfkeys@cur@is@descendant@of@errors@impl#1/errors#2\pgf@@eov{%
+ \def\pgfkeyspred@TMP{#1}%
+ \ifx\pgfkeyspred@TMP\pgfkeys@empty
+%\message{[SPECIAL CHECK] '\pgfkeyscurrentkey' is descendant of '/errors': TRUE.}%
+ \pgfkeysfiltercontinuetrue
+ \else
+%\message{[SPECIAL CHECK] '\pgfkeyscurrentkey' is descendant of '/errors': FALSE.}%
+ \pgfkeysfiltercontinuefalse
+ \fi
+}%
+
+% \pgfkeysinterruptkeyfilter
+% ...
+% \endpgfkeysinterruptkeyfilter
+% temporarily interrupts key filtering and enables it in
+% \endpgfkeysinterruptkeyfilter.
+%
+% If key filtering it not active, this has no effect at all.
+%
+% REMARK:
+% \pgfkeysinterruptkeyfilter...\endpgfkeysinterruptkeyfilter does NOT
+% introduce a \TeX-group.
+\def\pgfkeysinterruptkeyfilter{%
+ \ifpgfkeysfilteringisactive
+ \let\pgfkeys@case@one=\pgfkeys@orig@case@one
+ \let\pgfkeys@try=\pgfkeys@orig@try
+ \let\pgfkeys@unknown=\pgfkeys@orig@unknown
+ \fi
+}
+
+\def\endpgfkeysinterruptkeyfilter{%
+ \ifpgfkeysfilteringisactive
+ \let\pgfkeys@case@one=\pgfkeys@case@one@filtered
+ \let\pgfkeys@try=\pgfkeys@try@filtered
+ \let\pgfkeys@unknown=\pgfkeys@unknown@filtered
+ \fi
+}
+
+% Activates families #1, calls \pgfkeysfiltered and deactivates the
+% families afterwards.
+%
+% REMARK: you need to install a family-based key filter predicate
+% manually to benefit from the activated families!
+%
+% #1: comma separated family list
+% #2: key-value pairs
+%
+% @see \pgfkeysactivatefamiliesandfilteroptions
+\def\pgfkeysactivatefamiliesandfilteroptions#1#2{%
+ \pgfkeysactivatefamilies{#1}{\pgfkeys@family@deactivation}%
+ \pgfkeysfiltered{#2}%
+ \pgfkeys@family@deactivation
+}
+
+% The "quick" variant of \pgfkeysactivatefamiliesandfilteroptions: it
+% also assigns a default path.
+%
+% #1: comma separated family list
+% #2: default path
+% #3: key-value pairs
+\def\pgfqkeysactivatefamiliesandfilteroptions#1#2#3{%
+ \pgfkeysactivatefamilies{#1}{\pgfkeys@family@deactivation}%
+ \pgfqkeysfiltered{#2}{#3}%
+ \pgfkeys@family@deactivation
+}
+
+% Public version of split path:
+\def\pgfkeyssplitpath{\pgfkeys@split@path}%
+
+
+% The same as \pgfkeysactivatefamiliesandfilteroptions but just for
+% ONE family.
+%
+% #1: family (maybe a macro)
+% #2: key-value pairs
+\def\pgfkeysactivatesinglefamilyandfilteroptions#1#2{%
+ \pgfkeysactivatefamily{#1}%
+ \pgfkeysfiltered{#2}%
+ \pgfkeysdeactivatefamily{#1}%
+}
+
+% The "quick" variant of \pgfkeysactivatesinglefamilyandfilteroptions
+%
+% #1: family (maybe a macro)
+% #2: default path
+% #3: key-value pairs
+\def\pgfqkeysactivatesinglefamilyandfilteroptions#1#2#3{%
+ \pgfkeysactivatefamily{#1}%
+ \pgfqkeysfiltered{#2}{#3}%
+ \pgfkeysdeactivatefamily{#1}%
+}
+
+% Installs the key filter '#1' with argument '#2'.
+% This is equivalent to
+% \pgfkeys{#1/.install key filter=#2}
+%
+% The current values of the key filter handler is stored into the public
+% macros
+% \pgfkeyscurrentkeyfilter
+% and
+% \pgfkeyscurrentkeyfilterargs
+%
+% #1: a full key name; may be a macro
+% #2: optional arguments for the key. If the key expects more than one
+% argument, supply '{{first}{second}}'
+\def\pgfkeysinstallkeyfilter#1#2{%
+ \pgfkeysifdefined{#1/.@cmd}{%
+ \edef\pgfkeyscurrentkeyfilter{#1}%
+ \def\pgfkeyscurrentkeyfilterargs{#2}%
+ \pgfkeysgetvalue{#1/.@cmd}{\pgfkeys@key@predicate@}%
+ \def\pgfkeys@key@predicate{\pgfkeys@key@predicate@#2\pgfeov}%
+ }{%
+ \pgfkeysvalueof{/errors/no such key filter/.@cmd}{#1}{#2}\pgfeov%
+ }%
+}
+
+% Installs the key filter handler '#1' with argument '#2'.
+% This is equivalent to
+% \pgfkeys{#1/.install key filter handler=#2}
+%
+% The current values of the key filter handler is stored into the public
+% macros
+% \pgfkeyscurrentkeyfilterhandler
+% and
+% \pgfkeyscurrentkeyfilterhandlerargs
+%
+% #1: a full key name; may be a macro
+% #2: optional arguments for the handler. If the handler expects more than one
+% argument, supply '{{first}{second}}'
+\def\pgfkeysinstallkeyfilterhandler#1#2{%
+ \pgfkeysifdefined{#1/.@cmd}{%
+ \edef\pgfkeyscurrentkeyfilterhandler{#1}%
+ \def\pgfkeyscurrentkeyfilterhandlerargs{#2}%
+ \pgfkeysgetvalue{#1/.@cmd}{\pgfkeys@filtered@handler@}%
+ \def\pgfkeys@filtered@handler{\pgfkeys@filtered@handler@#2\pgfeov}%
+ }{%
+ \pgfkeysvalueof{/errors/no such key filter handler/.@cmd}{#1}{#2}\pgfeov%
+ }%
+}
+
+% Creates a macro which contains commands to re-activate the current
+% key filter and key filter handler. It can be used to temporarily
+% switch the key filter.
+\def\pgfkeyssavekeyfilterstateto#1{%
+ % produce the string
+ % \pgfkeysinstallkeyfilter{...}{...}
+ % \pgfkeysinstallkeyfilterhandler{...}{...}
+ % where each argument is expanded once
+ % FIXME: Do the same with less overhead!
+ \pgfkeys@tmptoks={\pgfkeysinstallkeyfilter}%
+ \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilter}}%
+ \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilterargs}\pgfkeysinstallkeyfilterhandler}%
+ \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilterhandler}}%
+ \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@tmptoks\expandafter{\pgfkeyscurrentkeyfilterhandlerargs}}%
+ \edef#1{%
+ \the\pgfkeys@tmptoks
+ }%
+}
+
+
+\pgfkeys{%
+ /errors/family unknown/.code=\pgfkeys@error{%
+ Sorry, I do not know family '#1' and can't work with any assoicated family handling. Perhaps you misspelled it?},
+ /errors/no such key filter/.code 2 args=\pgfkeys@error{Sorry, there is no such key filter '#1'.},
+ /errors/no such key filter handler/.code 2 args=\pgfkeys@error{Sorry, there is no such key filter handler '#1'.},
+ % HANDLERS:
+ %
+ % .is family should
+ % 1. '.cd' into the families' path,
+ % 2. define booleans to activate/deactive the family
+ % (see \pgfkeysisfamilyactive)
+ % 3. make sure that \pgfkeyshasactivefamily returns true for
+ % the family itself.
+ /handlers/.is family/.append code={%
+ %\newif is an \outer macro in plain tex, so this here is not portable:
+ %\expandafter\newif\csname if\pgfkeyscurrentpath/familyactive\endcsname
+ \edef\pgfkeyspred@TMP{pgfk@\pgfkeyscurrentpath/familyactive}%
+ \expandafter\pgfkeys@non@outer@newif\expandafter{\pgfkeyspred@TMP}%
+ \edef\pgfkeyspred@TMP{\pgfkeyscurrentpath/.belongs to family=\pgfkeyscurrentpath}%
+ \expandafter\pgfkeysalso\expandafter{\pgfkeyspred@TMP}%
+ },%
+ /handlers/.activate family/.code=\pgfkeysactivatefamily{\pgfkeyscurrentpath},
+ /handlers/.deactivate family/.code=\pgfkeysdeactivatefamily{\pgfkeyscurrentpath},
+ /handlers/.belongs to family/.code={\pgfkeyssetfamily{\pgfkeyscurrentpath}{#1}},%
+ %
+ %
+ % An addition to the '.try' and '.retry' handlers:
+ %
+ % It is the same as '.retry', but if the option is still unknown, the
+ % usual handlers for unknown keys will be invoked.
+ /handlers/.lastretry/.code={%
+ \ifpgfkeyssuccess\else
+ \pgfkeys@try
+ \ifpgfkeyssuccess\else
+ \pgfkeys@split@path%
+ \pgfkeys@unknown
+ \fi
+ \fi
+ },
+ %
+ %
+ /handlers/.install key filter/.code={%
+ \pgfkeysinstallkeyfilter{\pgfkeyscurrentpath}{#1}%
+ },%
+ /handlers/.install key filter handler/.code={%
+ \pgfkeysinstallkeyfilterhandler{\pgfkeyscurrentpath}{#1}%
+ },%
+ %
+ %
+ % KEY FILTER HANDLERS:
+ %
+ /pgf/key filter handlers/append filtered to/.code={%
+ % Produce
+ % <orig key> '={' <value> '}'
+ % where both, the key and the value are expanded just ONCE:
+ \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkeyRAW\expandafter=\expandafter{\pgfkeyscurrentvalue}}%
+ \ifx#1\pgfkeys@empty
+ \else
+ % Produce <old list> ',' <orig key> '={' <value> '}'
+ \pgfkeys@tmptoks=\expandafter\expandafter\expandafter{\expandafter#1\expandafter,\the\pgfkeys@tmptoks}%
+ \fi
+ \edef#1{\the\pgfkeys@tmptoks}%
+ },%
+ /pgf/key filter handlers/ignore/.code={},
+ /pgf/key filter handlers/ignore/.install key filter handler,
+ /pgf/key filter handlers/log/.code={%
+ \pgf@typeout{LOG: the option '\pgfkeyscurrentkey' (was originally '\pgfkeyscurrentkeyRAW') (case \pgfkeyscasenumber) has not been processed due to pgfkeysfiltered.}%
+ },
+ %
+ %
+ % KEY FILTER PREDICATES:
+ %
+ % Returns true if the currently processed key belongs to an active family.
+ % A family is active if it has been activated before.
+ /pgf/key filters/active families/.code={%
+ \if\pgfkeyscasenumber0%
+ % unknown options shall be processed with the
+ % unknown-handlers.
+ \pgfkeysfiltercontinuetrue
+ \else
+ \if\pgfkeyscasenumber3%
+ \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP
+ \else
+ \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP
+ \fi
+ \ifpgfkeyssuccess
+ \pgfkeysisfamilyactive{\pgfkeyspred@TMP}%
+ \else% Ok, it does not belong to any family.
+ \pgfkeysfiltercontinuefalse
+ \fi
+ \fi
+ },%
+ %
+ %
+ %
+ % This filter works as follows:
+ % 1. if the current key belongs to a family:
+ % return whether its family is active,
+ % 2. if the current key does NOT belong to a family:
+ % return the result of criterion '#1',
+ % 3. the current key is unknown:
+ % return the result of criterion '#2'.
+ %
+ % Arguments:
+ % #1: the predicate which will be invoked in case 2.
+ % It will be invoked with the current case number as argument.
+ % #2: the predicate which will be invoked in case 3 with
+ % the current case number as argument.
+ /pgf/key filters/active families or no family/.code 2 args={%
+ \if\pgfkeyscasenumber0%
+ \pgfkeysevalkeyfilterwith{#2}%
+ \else
+ \if\pgfkeyscasenumber3%
+ \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP
+ \else
+ \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP
+ \fi
+ \ifpgfkeyssuccess
+ \pgfkeysisfamilyactive{\pgfkeyspred@TMP}%
+ \else% Ok, it does not belong to any family.
+ \pgfkeysevalkeyfilterwith{#1}%
+ \fi
+ \fi
+ },
+ /pgf/key filters/active families or no family DEBUG/.code 2 args={%
+ \if\pgfkeyscasenumber0%
+ \pgf@typeout{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) invoking unknown handler '#2']}%
+ \pgfkeysevalkeyfilterwith{#2}%
+ \else
+ \if\pgfkeyscasenumber3%
+ \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP
+ \else
+ \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP
+ \fi
+ \ifpgfkeyssuccess
+ \pgfkeysisfamilyactive{\pgfkeyspred@TMP}%
+ \ifpgfkeysfiltercontinue
+ \pgf@typeout{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) family is ACTIVE]}%
+ \else
+ \pgf@typeout{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) family is NOT active.]}%
+ \fi
+ \else% Ok, it does not belong to any family.
+ \pgf@typeout{[pgfkeyshasactivefamilyornofamily(\pgfkeyscurrentkey, \pgfkeyscasenumber) invoking has-no-family-handler '#1']}%
+ \pgfkeysevalkeyfilterwith{#1}%
+ \fi
+ \fi
+ },
+ %
+ % A (faster) shortcut for
+ % /pgf/key filters/active families or no family=
+ % {/pgf/keys filters/false}
+ % {/pgf/keys filters/false}
+ /pgf/key filters/active families and known/.code={%
+ \if\pgfkeyscasenumber0%
+ \pgfkeysfiltercontinuefalse
+ \else
+ \if\pgfkeyscasenumber3%
+ \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP
+ \else
+ \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP
+ \fi
+ \ifpgfkeyssuccess
+ \pgfkeysisfamilyactive{\pgfkeyspred@TMP}%
+ \else% Ok, it does not belong to any family.
+ \pgfkeysfiltercontinuefalse
+ \fi
+ \fi
+ },
+ % A (faster) shortcut for
+ % /pgf/key filters/active families or no family=
+ % {/pgf/key filters/is descendant of=#1}% for keys without family
+ % {/pgf/keys filters/false}
+ /pgf/key filters/active families or descendants of/.code={%
+ \if\pgfkeyscasenumber0%
+ \pgfkeysfiltercontinuefalse
+ \else
+ \if\pgfkeyscasenumber3%
+ \pgfkeysgetfamily\pgfkeyscurrentpath\pgfkeyspred@TMP
+ \else
+ \pgfkeysgetfamily\pgfkeyscurrentkey\pgfkeyspred@TMP
+ \fi
+ \ifpgfkeyssuccess
+ \pgfkeysisfamilyactive{\pgfkeyspred@TMP}%
+ \else% Ok, it does not belong to any family.
+ % the 'is descendant of' implementation has been
+ % COPY PASTED here:
+ %
+ % string prefix comparison:
+ \def\pgfkeysisdescendantof@impl##1#1##2\pgf@@eov{%
+ \def\pgfkeyspred@TMP{##1}%
+ \ifx\pgfkeyspred@TMP\pgfkeys@empty
+ \pgfkeysfiltercontinuetrue
+ \else
+ \pgfkeysfiltercontinuefalse
+ \fi
+ }%
+ \expandafter\pgfkeysisdescendantof@impl\pgfkeyscurrentkey#1\pgf@@eov
+ \fi
+ \fi
+ },
+ %
+ % Processes only options which are children of #1.
+ % Example:
+ % is descendant of/.install key filter=/foo
+ % will be true for
+ % /foo/bar/x=y
+ % /foo/.cd
+ % /foo/bar/.style=...
+ % but not for
+ % /bar/foo/...
+ /pgf/key filters/is descendant of/.code={%
+ \if\pgfkeyscasenumber0%
+%\message{'\pgfkeyscurrentkey' (case \pgfkeyscasenumber) is UNKNOWN. Calling unknown handler.}%
+ % unknown options shall be processed with the
+ % unknown-handlers.
+ \pgfkeysfiltercontinuetrue
+ \else
+ % string prefix comparison:
+ % [ note : this has been COPY-PASTED to
+ % |active families or descendants of| ]
+ \def\pgfkeysisdescendantof@impl##1#1##2\pgf@@eov{%
+ \def\pgfkeyspred@TMP{##1}%
+ \ifx\pgfkeyspred@TMP\pgfkeys@empty
+%\message{'\pgfkeyscurrentkey' (case \pgfkeyscasenumber) is descendant of '#1': TRUE.}%
+ \pgfkeysfiltercontinuetrue
+ \else
+%\message{'\pgfkeyscurrentkey' (case \pgfkeyscasenumber) is descendant of '#1': FALSE.}%
+ \pgfkeysfiltercontinuefalse
+ \fi
+ }%
+ \expandafter\pgfkeysisdescendantof@impl\pgfkeyscurrentkey#1\pgf@@eov
+ \fi
+ },%
+ %
+ %
+ %
+ % Returns true if the currently processed full key equals #2.
+ /pgf/key filters/equals/.code={%
+ \if\pgfkeyscasenumber0%
+ % Unknown option:
+ \pgfkeysfiltercontinuetrue
+ \else
+ \def\pgfkeyspred@TMP{#1}%
+ \ifx\pgfkeyscurrentkey\pgfkeyspred@TMP
+ \pgfkeysfiltercontinuetrue
+ \else
+ \pgfkeysfiltercontinuefalse
+ \fi
+ \fi
+ },%
+ %
+ %
+ % Argument #1 can be any other (evaluated) filter predicate, its logical return
+ % value will be inverted.
+ % Example:
+ % not/.install key filter={is descendant of=/tikz}
+ % will install a key filter which evaluates 'is descendant of' with argument
+ % '/tikz' and returns the logical negation of the result.
+ %
+ /pgf/key filters/not/.code={%
+ \pgfkeysevalkeyfilterwith{#1}%
+ \ifpgfkeysfiltercontinue
+ \pgfkeysfiltercontinuefalse
+ \else
+ \pgfkeysfiltercontinuetrue
+ \fi
+ },%
+ /pgf/key filters/and/.code 2 args={%
+ \pgfkeysevalkeyfilterwith{#1}%
+ \ifpgfkeysfiltercontinue
+ \pgfkeysevalkeyfilterwith{#2}%
+ \fi
+ },%
+ /pgf/key filters/or/.code 2 args={%
+ \pgfkeysevalkeyfilterwith{#1}%
+ \ifpgfkeysfiltercontinue
+ \else
+ \pgfkeysevalkeyfilterwith{#2}%
+ \fi
+ },%
+ /pgf/key filters/true/.code={\pgfkeysfiltercontinuetrue},%
+ /pgf/key filters/true/.install key filter,
+ /pgf/key filters/false/.code={%
+ \pgfkeysfiltercontinuefalse
+ },%
+ %
+ % Returns false if the current key is unknown, which avoids calling
+ % the unknown handlers.
+ /pgf/key filters/defined/.code={%
+ \if\pgfkeyscasenumber0%
+ \pgfkeysfiltercontinuefalse
+ \else
+ \pgfkeysfiltercontinuetrue
+ \fi
+ },
+}%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Private IMPLEMENTATION
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+% This command does THE SAME work as \pgfkeys@case@one,
+% but it applies filtering whenever it identified the type of an
+% option.
+\def\pgfkeys@case@one@filtered{%
+ \pgfkeys@cur@is@descendant@of@errors
+ \ifpgfkeysfiltercontinue
+ \pgfkeys@orig@case@one
+ \else
+ \pgfkeysfiltercontinuetrue
+ \pgfkeysifdefined{\pgfkeyscurrentkey/.@cmd}{%
+ % CASE ONE: a command option
+ \def\pgfkeyscasenumber{1}%
+ \pgfkeys@key@predicate%
+ \ifpgfkeysfiltercontinue
+%\message{PROCESSING KEY \pgfkeyscurrentkey!}%
+ \pgfkeysgetvalue{\pgfkeyscurrentkey/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov
+ \else
+%\message{FILTERED OUT KEY \pgfkeyscurrentkey!}%
+ \pgfkeys@filtered@handler%
+ \fi
+ }{%
+ % CASE TWO: a normal value option
+ \pgfkeysifdefined{\pgfkeyscurrentkey}{%
+ \def\pgfkeyscasenumber{2}%
+ \pgfkeys@key@predicate%
+ \ifpgfkeysfiltercontinue
+%\message{PROCESSING KEY \pgfkeyscurrentkey!}%
+ \pgfkeys@case@two@extern
+ \else
+%\message{FILTERED OUT KEY \pgfkeyscurrentkey!}%
+ \pgfkeys@filtered@handler%
+ \fi
+ }{%
+ \pgfkeys@split@path
+ % CASE THREE: a handler
+ \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{%
+ \pgfkeys@ifexecutehandler{%
+ \def\pgfkeyscasenumber{3}%
+ \pgfkeys@key@predicate%
+ \ifpgfkeysfiltercontinue
+%\message{PROCESSING KEY \pgfkeyscurrentkey!}%
+ \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov
+ \else
+%\message{FILTERED OUT KEY \pgfkeyscurrentkey!}%
+ \pgfkeys@filtered@handler%
+ \fi
+ }{%
+ \pgfkeys@unknown
+ }%
+ }{%
+ \pgfkeys@unknown
+ }%
+ }%
+ }%
+ \fi
+}%
+
+\def\pgfkeys@unknown@filtered{%
+ % CASE ZERO: an unknown option.
+ \def\pgfkeyscasenumber{0}%
+ \pgfkeys@key@predicate%
+ \ifpgfkeysfiltercontinue
+%\message{PROCESSING KEY \pgfkeyscurrentkey!}%
+ % start normal 'unknown' handlers:
+ \pgfkeys@orig@unknown
+ \else
+%\message{FILTERED OUT KEY \pgfkeyscurrentkey!}%
+ \pgfkeys@filtered@handler%
+ \fi
+}
+
+% Does the same as \pgfkeys@try, but it also invokes the key filters.
+\def\pgfkeys@try@filtered{%
+ \ifpgfkeysfiltercontinue
+ \pgfkeys@orig@try
+ \else
+ \pgfkeysfiltercontinuetrue
+ \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% make sure that \pgfkeys@code doesn't know about 'try'. Important for .is choice
+ \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@def}%
+ {\pgfkeysgetvalue{\pgfkeyscurrentpath/.@def}{\pgfkeyscurrentvalue}}
+ {}% no default, so leave it
+ \fi%
+ \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}%
+ {%
+ % CASE ONE: a command option
+ \def\pgfkeyscasenumber{1}%
+ \pgfkeys@key@predicate%
+ \ifpgfkeysfiltercontinue
+ \pgfkeysgetvalue{\pgfkeyscurrentkey/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov%
+ \else
+ \pgfkeys@filtered@handler%
+ \fi
+ \pgfkeyssuccesstrue%
+ }%
+ {%
+ \pgfkeysifdefined{\pgfkeyscurrentpath}%
+ {% CASE TWO: a normal value option
+ \def\pgfkeyscasenumber{2}%
+ \pgfkeys@key@predicate%
+ \ifpgfkeysfiltercontinue
+ \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text%
+ \pgfkeysvalueof{\pgfkeyscurrentpath}%
+ \else%
+ \pgfkeyslet{\pgfkeyscurrentpath}\pgfkeyscurrentvalue%
+ \fi%
+ \else
+ \pgfkeys@filtered@handler%
+ \fi
+ \pgfkeyssuccesstrue%
+ }%
+ {%
+ \pgfkeys@split@path%
+ \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{%
+ % CASE THREE: a handled key
+ %
+ % in the standard configuration, this check here is redundant
+ % because pgfkeys@ifexecutehandler === true.
+ % It is only interesting for 'handle only existing'.
+ \pgfkeys@ifexecutehandler{%
+ \def\pgfkeyscasenumber{3}%
+ \pgfkeys@key@predicate%
+ \ifpgfkeysfiltercontinue
+%\message{PROCESSING KEY \pgfkeyscurrentkey!}%
+ \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov
+ \else
+%\message{FILTERED OUT KEY \pgfkeyscurrentkey!}%
+ \pgfkeys@filtered@handler%
+ \fi
+ \pgfkeyssuccesstrue%
+ }{%
+ \pgfkeyssuccessfalse
+ }%
+ }{%
+ \pgfkeyssuccessfalse
+ }%
+ }%
+ }%
+ \fi
+}
+
+
+% #1 the code to invoke after init and before cleanup
+\long\def\pgfkeys@install@filter@and@invoke#1{%
+ \ifpgfkeysfilteringisactive
+ \pgfkeys@error{Sorry, nested calls to key filtering routines are not allowed. (reason: It is not possible to properly restore the previous filtering state after returning from the nested call)}%
+ \fi
+ \pgfkeysfilteringisactivetrue
+ \let\pgfkeys@case@one=\pgfkeys@case@one@filtered
+ \let\pgfkeys@try=\pgfkeys@try@filtered
+ \let\pgfkeys@unknown=\pgfkeys@unknown@filtered
+ #1%
+ \let\pgfkeys@case@one=\pgfkeys@orig@case@one
+ \let\pgfkeys@try=\pgfkeys@orig@try
+ \let\pgfkeys@unknown=\pgfkeys@orig@unknown
+ \pgfkeysfilteringisactivefalse
+}
+
+
+%--------------------------------------------------
+% \def\pgfkeys@eval@key@filter@subroutine@case@one{%
+% \pgfkeysifdefined{\pgfkeyscurrentkey/.@cmd}{%
+% \pgfkeysgetvalue{\pgfkeyscurrentkey/.@cmd}{\pgfkeys@code}%
+% \let\pgfkeyspred@TMP=\pgfkeyscurrentvalue
+% \pgfkeys@eval@key@filter@subroutine@restorestate
+% \expandafter\pgfkeys@code\pgfkeyspred@TMP\pgfeov
+% }{%
+% \pgfkeysvalueof{/errors/no such key filter/.@cmd}\pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov%
+% }%
+% }
+% % THIS VERSION IS TOO SLOW. See below.
+% \def\pgfkeysevalkeyfilterwith#1{%
+% \edef\pgfkeys@eval@key@filter@subroutine@restorestate{%
+% \noexpand\def\noexpand\pgfkeyscurrentkey{\pgfkeyscurrentkey}%
+% \noexpand\def\noexpand\pgfkeyscurrentkeyRAW{\pgfkeyscurrentkeyRAW}%
+% \noexpand\def\noexpand\pgfkeyscurrentname{\pgfkeyscurrentname}%
+% \noexpand\def\noexpand\pgfkeyscurrentvalue{\pgfkeyscurrentvalue}%
+% \noexpand\pgfkeys@pathtoks={\pgfkeyscurrentpath}%
+% }%
+% \pgfkeysinterruptkeyfilter
+% \let\pgfkeys@case@one=\pgfkeys@eval@key@filter@subroutine@case@one
+% \pgfkeysalso{#1}%
+% \endpgfkeysinterruptkeyfilter% this here also restored \pgfkeys@case@one.
+% \pgfkeys@eval@key@filter@subroutine@restorestate
+% }%
+%--------------------------------------------------
+
+
+% Evaluates a key filter '#1'. Example:
+% \pgfkeysevalkeyfilterwith{/pgf/key filters/equals=/tikz}
+%
+% \pgfkeysevalkeyfilterwith works only if key filtering is
+% active.
+%
+% The argument '#1' MUST be a FULL KEY.
+%
+% The implementation employs a subset of the \pgfkeysalso code.
+\long\def\pgfkeysevalkeyfilterwith#1{%
+ \pgfkeys@eval@key@filter@subroutine@unpack#1=\pgfkeysnovalue=\pgfkeys@stop
+}%
+\long\def\pgfkeys@eval@key@filter@subroutine@unpack#1=#2=#3\pgfkeys@stop{%
+ \pgfkeys@spdef\pgfkeyspred@TMP{#1}%
+ \edef\pgfkeyspred@TMP{\pgfkeyspred@TMP}%
+ \pgfkeys@spdef\pgfkeyspred@TMPB{#2}% TMPB=value
+ \ifx\pgfkeyspred@TMPB\pgfkeysnovalue@text% Hmm... no value
+ \pgfkeysifdefined{\pgfkeyspred@TMP/.@def}%
+ {\pgfkeysgetvalue{\pgfkeyspred@TMP/.@def}{\pgfkeyspred@TMPB}}
+ {}% no default, so leave it
+ \fi%
+ \ifx\pgfkeyspred@TMPB\pgfkeysvaluerequired%
+ \pgfkeysvalueof{/errors/value required/.@cmd}\pgfkeyspred@TMP\pgfkeyspred@TMPB\pgfeov%
+ \else%
+ \pgfkeysifdefined{\pgfkeyspred@TMP/.@cmd}{%
+ \pgfkeysgetvalue{\pgfkeyspred@TMP/.@cmd}{\pgfkeys@code}%
+ \expandafter\pgfkeys@code\pgfkeyspred@TMPB\pgfeov
+ }{%
+ \pgfkeysvalueof{/errors/no such key filter/.@cmd}\pgfkeyspred@TMP\pgfkeyspred@TMPB\pgfeov%
+ }%
+ \fi%
+}
+
+
+\def\pgfkeys@non@outer@newif@#1#2{%
+ \expandafter\edef\csname #2true\endcsname{\noexpand\let\noexpand#1=\noexpand\iftrue}%
+ \expandafter\edef\csname #2false\endcsname{\noexpand\let\noexpand#1=\noexpand\iffalse}%
+ \csname #2false\endcsname
+}%
+
+% For latex and context, this here has the same effect as a \newif
+% applied to 'if#1'. For plain tex, it has also the same effect, but
+% it is not an \outer macro as the plain-tex \newif.
+\def\pgfkeys@non@outer@newif#1{%
+ \expandafter\pgfkeys@non@outer@newif@\csname if#1\endcsname{#1}%
+}
+\endinput
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfrcs.code.tex b/graphics/pgf/base/tex/generic/utilities/pgfrcs.code.tex
new file mode 100644
index 0000000000..ee194939ee
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfrcs.code.tex
@@ -0,0 +1,153 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+\ifx\eTeXrevision\undefined%
+ \pgfutil@packageerror{PGF}{PGF requires etex in extended mode}{}%
+ \csname @@end\expandafter\endcsname\expandafter\end%
+\fi
+
+\ifnum\eTeXversion<2
+ \pgfutil@packageerror{PGF}{PGF requires etex version 2}{}%
+ \csname @@end\expandafter\endcsname\expandafter\end%
+\fi
+
+% The purpose of this file is to define the command
+% \ProvidesPackageRCS, which should be followed by an RCS id
+% string. This command will also be available in plain TeX, where it
+% prints out a message to the log.
+
+\pgfutil@IfFileExists{pgf.revision.tex}{\input pgf.revision.tex } {%
+ \def\pgfrevision{0.0}%
+ \def\pgfversion{0.0}%
+ \def\pgfversiondate{2014-07-01}%
+ \def\pgfrevisiondate{2014-07-01}%
+}
+
+\begingroup
+\catcode`\"=12
+\pgfutil@IfUndefined{directlua}{}{%
+ \directlua{pgf = {}; pgf.pgfversion = "\pgfversion"}%
+}%
+\endgroup
+
+% \def\pgftypesetversion{\oldstylenums{3}.\oldstylenums{0}.\oldstylenums{1}}
+% XXX : implement pretty-printing:
+% which is better? 'version' is something like 3.0.1 . revision is
+% 3.0.1-151-g62184b3 which might be better for instable builds
+%\let\pgftypesetversion=\pgfversion
+\let\pgftypesetversion=\pgfrevision
+
+
+\ifx\pgfrcsloaded\undefined
+\def\pgfrcsloaded{}
+
+\edef\pgfrcsatcode{\the\catcode`\@}
+\catcode`\@=11
+
+% not used in PGF, deprecated
+\def\ProvidesFileRCS{%
+ \let\pgfrcs@final=\ProvidesFileRCS@
+ \pgfrcs@parseinput
+}
+\def\ProvidesFileRCS@#1{%
+ \ProvidesFile{#1}[\pgfversiondate\space v\pgfversion\space(\pgfrevision)]%
+}
+
+\def\pgf@remove@ext#1.#2\relax{%
+ \def\pgfretval{#1}%
+}%
+
+\def\ProvidesPackageRCS{%
+ \let\pgfrcs@final=\ProvidesPackageRCS@
+ \pgfrcs@parseinput
+}
+\def\ProvidesPackageRCS@#1{%
+ \pgf@remove@ext#1.\relax
+ \edef\pgfrcs@marshal{{\pgfretval}[\pgfversiondate\space v\pgfversion\space(\pgfrevision)]}%
+ \expandafter\ProvidesPackage\pgfrcs@marshal
+}
+
+% not used in PGF, deprecated
+\def\ProvidesClassRCS{%
+ \let\pgfrcs@final=\ProvidesClassRCS@
+ \pgfrcs@parseinput
+}
+\def\ProvidesClassRCS@#1{%
+ \pgf@remove@ext#1.\relax
+ \edef\pgfrcs@marshal{{\pgfretval}[\pgfversiondate\space v\pgfversion\space(\pgfrevision)]}%
+ \expandafter\ProvidesClass\pgfrcs@marshal
+}
+
+\def\pgfrcs@parseinput@bracket{[}%
+\def\pgfrcs@parseinput@dollarsign{$}%
+
+\def\pgfrcs@parseinput#1{%
+ \def\pgfrcs@parseinput@{#1}%
+ \ifx\pgfrcs@parseinput@\pgfrcs@parseinput@bracket%
+ % still accept it if someone has written his own pgfrcs files with headers of sorts
+ % \ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcore.code.tex,v 1.7 2010/04/11 07:09:19 username Exp $
+ \let\next=\pgfrcs@parseinput@opt
+ \else
+ \ifx\pgfrcs@parseinput@\pgfrcs@parseinput@dollarsign
+ % still accept it if someone has written his own pgfrcs files with headers of sorts
+ % \ProvidesPackageRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcore.code.tex,v 1.7 2010/04/11 07:09:19 username Exp $
+ \let\next\pgfrcs@parseinput@dollar
+ \else
+ % the new, normal pgf-way is \ProvidesPackageRCS{pgfcore.code.tex}
+ \def\next{\pgfrcs@final{#1}}%
+ \fi
+ \fi
+ \next
+}
+\def\pgfrcs@parseinput@opt#1] ${%
+ % just backwards compatibility -- ignore the information, but parse the input tokens:
+ \pgfrcs@parseinput@dollar
+}%
+\def\pgfrcs@parseinput@dollar#1${%
+ \pgf@parseid $#1$%
+ % we ignore pretty much everything except for the file name:
+ \edef\pgfrcs@parseinput@{\pgf@rcsfile.\pgf@rcssuffix}%
+ \expandafter\pgfrcs@final\expandafter{\pgfrcs@parseinput@}%
+}%
+% Get date and version from RCS Ids
+\def\pgf@parseid $#1: #2.#3,v #4 #5/#6/#7 #8${%
+ \pgf@parsercsfile$#2/$
+ \def\pgf@rcssuffix{#3}
+ \def\pgf@rcsrevision{#4}
+ \def\pgf@rcsdate{#5/#6/#7}
+}
+\def\pgf@parsercsfile$#1/#2${
+ \def\pgf@temp{#2}
+ \ifx\pgf@temp\pgfutil@empty
+ \def\pgf@rcsfile{#1}
+ \else
+ \pgf@parsercsfile$#2$
+ \fi}
+
+
+\ifx\ProvidesPackage\@undefined
+ % plain tex
+ \def\ProvidesPackage#1[#2]{\wlog{Loading package #1 version #2.}}
+\fi
+
+\ifx\ProvidesFile\@undefined
+ % plain tex
+ \def\ProvidesFile#1[#2]{\wlog{Loading file #1 version #2.}}
+\fi
+
+\ProvidesPackageRCS{pgfrcs.code.tex}
+
+\catcode`\@=\pgfrcsatcode
+
+\fi
+
+
+% Local Variables:
+% coding: undecided-unix
+% End:
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfutil-common-lists.tex b/graphics/pgf/base/tex/generic/utilities/pgfutil-common-lists.tex
new file mode 100644
index 0000000000..783a53e11e
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfutil-common-lists.tex
@@ -0,0 +1,163 @@
+% Copyright 2019 by Christian Feuersaenger
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
+%
+% This list here is a general re-implementation of the list used in
+% the PGF system layer.
+% It employs two collect-buffers to reduce the runtime.
+%
+% - It has pre-asymptotical runtime O(N), but is O(N^2) asymptotically.
+% - It requires only 5 macros per list.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\pgfutil@packagewarning
+ {pgfutil-common-lists}%
+ {This package is deprecated and will be removed by the end of 2022}
+
+% Usage:
+% \pgfapplistnewempty\macro
+\def\pgfapplistnewempty#1{%
+ \expandafter\let\csname pgfapp@#1\endcsname=\pgfutil@empty
+ \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty
+ \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}%
+ \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}%
+}%
+
+% #1: the item to append
+% #2: the list as macro name
+\long\def\pgfapplistpushback#1\to#2{%
+ \begingroup
+ \c@pgf@counta=\csname pgfapp@#2@smallbuf@c\endcsname\relax
+ \advance\c@pgf@counta by1
+ \xdef\pgf@glob@TMPa{\the\c@pgf@counta}%
+ \endgroup
+ \expandafter\let\csname pgfapp@#2@smallbuf@c\endcsname=\pgf@glob@TMPa
+ \ifnum\csname pgfapp@#2@smallbuf@c\endcsname<40
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}%
+ \expandafter\edef\csname pgfapp@#2@smallbuf\endcsname{\the\t@pgf@toka}%
+ \else
+ \pgfapplistpushback@smallbufoverfl{#1}{#2}%
+ \fi
+}%
+\long\def\pgfapplistpushback@smallbufoverfl#1#2{%
+ \begingroup
+ \c@pgf@counta=\csname pgfapp@#2@bigbuf@c\endcsname\relax
+ \advance\c@pgf@counta by1
+ \xdef\pgf@glob@TMPa{\the\c@pgf@counta}%
+ \endgroup
+ \expandafter\let\csname pgfapp@#2@bigbuf@c\endcsname=\pgf@glob@TMPa
+ %
+ \ifnum\csname pgfapp@#2@bigbuf@c\endcsname<30
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}%
+ \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}%
+ \expandafter\edef\csname pgfapp@#2@bigbuf\endcsname{\the\t@pgf@toka\the\t@pgf@tokb}%
+ \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}%
+ \else%
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2\endcsname}%
+ \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}%
+ \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}%
+ \expandafter\edef\csname pgfapp@#2\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}%
+ \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}%
+ \expandafter\let\csname pgfapp@#2@bigbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfapp@#2@bigbuf@c\endcsname{0}%
+ \fi%
+}%
+\def\pgfapplist@flushbuffers#1{%
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#1\endcsname}%
+ \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#1@bigbuf\endcsname}%
+ \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#1@smallbuf\endcsname}%
+ \expandafter\edef\csname pgfapp@#1\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}%
+ \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}%
+ \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}%
+}%
+
+\def\pgfapplistlet#1=#2{%
+ \pgfapplist@flushbuffers{#2}%
+ \expandafter\let\expandafter#1\csname pgfapp@#2\endcsname
+}%
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% A variant of applist which has the same runtime requirements, but
+% does PUSH FRONT only.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+% Usage:
+% \pgfprependlistnewempty{list}
+\def\pgfprependlistnewempty#1{%
+ \expandafter\let\csname pgfpPRP@#1\endcsname=\pgfutil@empty
+ \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty
+ \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}%
+ \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}%
+}%
+
+% #1: the item to prepend
+% #2: the list as macro name
+\long\def\pgfprependlistpushfront#1\to#2{%
+ \begingroup
+ \c@pgf@counta=\csname pgfpPRP@#2@smallbuf@c\endcsname\relax
+ \advance\c@pgf@counta by1
+ \xdef\pgf@glob@TMPa{\the\c@pgf@counta}%
+ \endgroup
+ \expandafter\let\csname pgfpPRP@#2@smallbuf@c\endcsname=\pgf@glob@TMPa
+ \ifnum\csname pgfpPRP@#2@smallbuf@c\endcsname<40
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}%
+ \t@pgf@tokb={#1}%
+ \expandafter\edef\csname pgfpPRP@#2@smallbuf\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}%
+ \else
+ \pgfprependlistpushfront@smallbufoverfl{#1}{#2}%
+ \fi
+}%
+\long\def\pgfprependlistpushfront@smallbufoverfl#1#2{%
+ \begingroup
+ \c@pgf@counta=\csname pgfpPRP@#2@bigbuf@c\endcsname\relax
+ \advance\c@pgf@counta by1
+ \xdef\pgf@glob@TMPa{\the\c@pgf@counta}%
+ \endgroup
+ \expandafter\let\csname pgfpPRP@#2@bigbuf@c\endcsname=\pgf@glob@TMPa
+ %
+ \ifnum\csname pgfpPRP@#2@bigbuf@c\endcsname<30
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@bigbuf\endcsname}%
+ \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}%
+ \t@pgf@tokc={#1}%
+ \expandafter\edef\csname pgfpPRP@#2@bigbuf\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}%
+ \expandafter\let\csname pgfpPRP@#2@smallbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfpPRP@#2@smallbuf@c\endcsname{0}%
+ \else%
+ \pgfprependlist@flushbuffers{#2}%
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2\endcsname}%
+ \t@pgf@tokb={#1}%
+ \expandafter\edef\csname pgfpPRP@#2\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}%
+ \fi%
+}%
+\def\pgfprependlist@flushbuffers#1{%
+ \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1\endcsname}%
+ \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@bigbuf\endcsname}%
+ \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@smallbuf\endcsname}%
+ \expandafter\edef\csname pgfpPRP@#1\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}%
+ \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}%
+ \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty
+ \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}%
+}%
+\def\pgfprependlistlet#1=#2{%
+ \pgfprependlist@flushbuffers{#2}%
+ \expandafter\let\expandafter#1\csname pgfpPRP@#2\endcsname
+}%
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfutil-common.tex b/graphics/pgf/base/tex/generic/utilities/pgfutil-common.tex
new file mode 100644
index 0000000000..0ecdc68887
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfutil-common.tex
@@ -0,0 +1,913 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+%
+% This file provides utility commands that are used throughout pgf.
+%
+% For most commands, the definition of these commands is just given
+% below. We cannot use the LaTeX definition of these commands since
+% LaTeX may not be the current format and since LaTeX packages tend to
+% redefine these commands.
+%
+% For some commands the actual definition of the format (like latex or
+% context) is to be preferred over the generic definition below. In
+% this case, the definition of the format is installed when the file
+% pgfutil-XXXX.tex is read, where XXXX is the format name (latex,
+% plain, or context).
+
+
+
+\catcode`\@=11\relax
+
+
+% Which format is loaded?
+\newif\ifpgfutil@format@is@latex
+\newif\ifpgfutil@format@is@plain
+\newif\ifpgfutil@format@is@context
+
+% Aliases
+
+\let\pgfutil@exp\romannumeral
+\chardef\pgfutil@exp@end=0
+
+% Simple stuff
+
+% \pgfutil@trimspaces{<token list>}
+%
+% Removes spaces on both sides of <token list>. Same as trimspaces.sty
+\catcode`\Q=3
+\def\pgfutil@trimspaces#1{%
+ \romannumeral-`0\pgfutil@trimspaces@\noexpand#1Q Q}
+\def\pgfutil@trimspaces@#1 Q{\pgfutil@trimspaces@@#1Q}
+\def\pgfutil@trimspaces@@#1Q#2{#1}
+\catcode`\Q=11
+
+% \pgfutil@ifx{<token 1>}{<token 2>}{<true code>}{<false code>}
+%
+% This macro is expandable.
+\long\def\pgfutil@ifx#1#2{%
+ \ifx#1#2%
+ \expandafter\pgfutil@firstoftwo
+ \else
+ \expandafter\pgfutil@secondoftwo
+ \fi}
+
+% \pgfutil@ifstrequal{<lhs>}{<rhs>}{<true code>}{<false code>}
+%
+% Check if <lhs> and <rhs> are equal by string comparison
+%
+% This macro is expandable.
+\long\def\pgfutil@ifstrequal#1#2{%
+ \ifnum\pgfsys@strcmp{\pgfutil@unexpanded{#1}}{\pgfutil@unexpanded{#2}}=0
+ \expandafter\pgfutil@firstoftwo
+ \else
+ \expandafter\pgfutil@secondoftwo
+ \fi
+}
+
+% \pgfutil@ifxempty{<token 1>}{<true code>}{<false code>}
+%
+% Shortcut for \pgfutil@ifx\pgfutil@empty{<token 1>}{<true code>}{<false code>}
+%
+% This macro is expandable.
+\def\pgfutil@ifxempty{\pgfutil@ifx\pgfutil@empty}
+
+% pgfutil@ifempty
+%
+% Check if #1 is empty. No expansion is performed on #1.
+%
+% This macro is expandable.
+\long\def\pgfutil@ifempty#1{%
+ \if\relax\detokenize{#1}\relax
+ \expandafter\pgfutil@firstoftwo
+ \else
+ \expandafter\pgfutil@secondoftwo
+ \fi}
+
+% \pgfutil@ifundefined{<macro name with backslash>}
+% {<is undefined code>}{<is defined code>}
+%
+% This will let #1 to \relax if it undefined.
+%
+% This macro is expandable.
+\def\pgfutil@ifundefined#1{%
+ \expandafter\pgfutil@ifx\csname#1\endcsname\relax}
+
+% A variant of \pgfutil@ifundefined which will NOT let #1 to \relax it
+% is undefined.
+\def\pgfutil@IfUndefined#1{%
+ \ifcsname#1\endcsname
+ \expandafter\pgfutil@secondoftwo
+ \else
+ \expandafter\pgfutil@firstoftwo
+ \fi
+}
+
+\long\def\pgfutil@firstofone#1{#1}
+\long\def\pgfutil@firstoftwo#1#2{#1}
+\long\def\pgfutil@secondoftwo#1#2{#2}
+\def\pgfutil@empty{}
+\long\def\pgfutil@gobble@until@relax#1\relax{}
+\long\def\pgfutil@gobble#1{}
+\long\def\pgfutil@gobbletwo#1#2{}
+\def\pgfutil@namedef#1{\expandafter\def\csname #1\endcsname}
+\def\pgfutil@namelet#1{\expandafter\pgfutil@@namelet\csname#1\endcsname}
+\def\pgfutil@@namelet#1#2{\expandafter\let\expandafter#1\csname#2\endcsname}
+\long\def\pgfutil@g@addto@macro#1#2{%
+ \begingroup
+ \pgfutil@toks@\expandafter{#1#2}%
+ \xdef#1{\the\pgfutil@toks@}%
+ \endgroup}
+\newif\ifpgfutil@tempswa
+\newif\ifpgfutil@tempswb
+
+% \pgfutil@pushmacro
+% \pgfutil@popmacro
+%
+% Macro stack. Allows pushing a macro over \egroup. Taken from ConTeXt
+
+\let\pgfutil@pushmacro@string\pgfutil@empty
+
+\def\pgfutil@pushmacro#1{%
+ \xdef\pgfutil@pushmacro@string{\string#1}%
+ \ifcsname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\else
+ % \newcount is \outer in Plain
+ \csname newcount\expandafter\endcsname\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname
+ \fi
+ \global\advance\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname 1\relax
+ \global\expandafter\let\csname\the\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\pgfutil@pushmacro@string\endcsname#1%
+}
+
+\def\pgfutil@popmacro#1{%
+ \xdef\pgfutil@pushmacro@string{\string#1}%
+ \expandafter\let\expandafter#1\csname\the\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\pgfutil@pushmacro@string\endcsname
+ \global\advance\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname -1\relax
+}
+
+% pgfutil@ifnextchar
+
+\long\def\pgfutil@ifnextchar#1#2#3{%
+ \let\pgfutil@reserved@d=#1%
+ \def\pgfutil@reserved@a{#2}%
+ \def\pgfutil@reserved@b{#3}%
+ \futurelet\pgfutil@let@token\pgfutil@ifnch}
+\def\pgfutil@ifnch{%
+ \ifx\pgfutil@let@token\pgfutil@sptoken
+ \let\pgfutil@reserved@c\pgfutil@xifnch
+ \else
+ \ifx\pgfutil@let@token\pgfutil@reserved@d
+ \let\pgfutil@reserved@c\pgfutil@reserved@a
+ \else
+ \let\pgfutil@reserved@c\pgfutil@reserved@b
+ \fi
+ \fi
+ \pgfutil@reserved@c}
+{%
+ \def\:{\global\let\pgfutil@sptoken= } \:
+ \def\:{\pgfutil@xifnch} \expandafter\gdef\: {\futurelet\pgfutil@let@token\pgfutil@ifnch}
+}
+
+% pgfutil@ignorespaces
+
+\def\pgfutil@ignorespaces
+ {\ifx\pgfutil@let@token\pgfutil@sptoken
+ \expandafter\pgfutil@ignorespaces@helper
+ \else
+ \expandafter\pgfutil@next
+ \fi}
+
+{
+ \def\:{\pgfutil@ignorespaces@helper}
+ \expandafter\gdef\: {\futurelet\pgfutil@let@token\pgfutil@ignorespaces}
+}
+
+% pgfutil@in@
+
+\newif\ifpgfutil@in@
+
+% Usage:
+% \pgfutil@in@{one}{three two one}
+% \ifpgfutil@in@
+% -> will be true!
+% \else
+% \fi
+%
+% \pgfutil@in@{,}{1234,456567}
+% \ifpgfutil@in@
+% -> will be true!
+% \else
+% \fi
+\def\pgfutil@in@#1#2{%
+ \def\pgfutil@in@@##1#1##2##3\pgfutil@in@@{%
+ \ifx\pgfutil@in@##2\pgfutil@in@false\else\pgfutil@in@true\fi}%
+ \pgfutil@in@@#2#1\pgfutil@in@\pgfutil@in@@}
+
+
+% pgfutil@for
+
+\def\pgfutil@nnil{\pgfutil@nil}
+\def\pgfutil@fornoop#1\@@#2#3{}
+\long\def\pgfutil@for#1:=#2\do#3{%
+ \expandafter\def\expandafter\pgfutil@fortmp\expandafter{#2}%
+ \ifx\pgfutil@fortmp\pgfutil@empty \else
+ \expandafter\pgfutil@forloop#2,\pgfutil@nil,\pgfutil@nil\@@#1{#3}\fi}
+\long\def\pgfutil@forloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\pgfutil@nnil \else
+ #5\def#4{#2}\ifx #4\pgfutil@nnil \else#5\pgfutil@iforloop #3\@@#4{#5}\fi\fi}
+\long\def\pgfutil@iforloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\pgfutil@nnil
+ \expandafter\pgfutil@fornoop \else
+ #4\relax\expandafter\pgfutil@iforloop\fi#2\@@#3{#4}}
+\def\pgfutil@tfor#1:={\pgfutil@tf@r#1 }
+\long\def\pgfutil@tf@r#1#2\do#3{\def\pgfutil@fortmp{#2}\ifx\pgfutil@fortmp\pgfutil@space\else
+ \pgfutil@tforloop#2\pgfutil@nil\pgfutil@nil\@@#1{#3}\fi}
+\long\def\pgfutil@tforloop#1#2\@@#3#4{\def#3{#1}\ifx #3\pgfutil@nnil
+ \expandafter\pgfutil@fornoop \else
+ #4\relax\expandafter\pgfutil@tforloop\fi#2\@@#3{#4}}
+
+\def\pgfutil@space{ }
+
+% pgfutil@IfFileExists
+
+\chardef\pgfutil@inputcheck0
+\def\pgfutil@IfFileExists#1#2#3{%
+ \openin\pgfutil@inputcheck=#1 %
+ \ifeof\pgfutil@inputcheck
+ #3\relax
+ \else
+ #2\relax
+ \fi
+ \closein\pgfutil@inputcheck}
+
+\def\pgfutil@InputIfFileExists#1#2#3{\pgfutil@IfFileExists{#1}{\input #1\relax#2}{#3}}%
+
+
+% pgfutil@loop (from plain.tex)
+
+\def\pgfutil@loop#1\pgfutil@repeat{\def\pgfutil@body{#1}\pgfutil@iterate}
+\def\pgfutil@iterate{\pgfutil@body \let\pgfutil@next\pgfutil@iterate \else\let\pgfutil@next\relax\fi \pgfutil@next}
+\let\pgfutil@repeat=\fi % this makes \loop...\if...\repeat skippable
+
+% \pgfutil@switch
+%
+% #1: comparison function of the form
+% \comp{<lhs>}{<rhs>}{<true code>}{<false code>}
+% Has to be expandable!
+% #2: lhs
+% #3: sequence of rhs-value pairs
+% #4: default statement in case of match
+% #5: default statement in case of no match
+%
+% Example:
+%
+% \pgfutil@switch\pgfutil@ifx\pgf@let@token{%
+% {(}{\tikz@movetoabs}%)
+% {+}{\tikz@movetorel}%
+% {-}{\tikz@lineto}%
+% }{}{\tikz@expand}
+
+\let\pgfutil@scan@mark\relax
+\let\pgfutil@scan@stop\relax
+
+\long\def\pgfutil@switch#1#2#3#4#5{%
+ \pgfutil@exp
+ \pgfutil@switch@@{#1}%
+ {#2}#3% user-defined cases
+ {#2}{}% default case
+ \pgfutil@scan@mark{#4}% true code
+ \pgfutil@scan@mark{#5}% false code
+ \pgfutil@scan@stop
+}
+\long\def\pgfutil@switch@@#1#2#3#4{%
+ #1{#2}{#3}%
+ {\pgfutil@switch@end{#4}}%
+ {\pgfutil@switch@@{#1}{#2}}%
+}
+\long\def\pgfutil@switch@end#1#2#3\pgfutil@scan@mark#4#5\pgfutil@scan@stop{\pgfutil@exp@end#1#4}
+
+% aux-read-hook
+
+\let\pgfutil@aux@read@hook=\relax
+
+
+% Tokens for the end of the typesetting -- they will be added at the
+% end of every job (hopefully...).
+
+\newtoks\pgfutil@everybye
+
+
+%
+% PDF-Resource management -- might seem strange that this is here, but
+% it turns out to be the correct place since latex and context handle
+% this stuff quite differently
+%
+
+% Adding something to the pdf-resources:
+
+\def\pgfutil@addpdfresource@extgs#1{\pgf@sys@addpdfresource@extgs@plain{#1}}
+\def\pgfutil@addpdfresource@colorspaces#1{\pgf@sys@addpdfresource@colorspaces@plain{#1}}
+\def\pgfutil@addpdfresource@patterns#1{\pgf@sys@addpdfresource@patterns@plain{#1}}
+\def\pgfutil@setuppdfresources{\pgf@sys@setuppdfresources@plain}
+
+
+% Inserts the argument at the begin of the current page (hopefully)
+
+\let\pgfutil@insertatbegincurrentpage=\relax
+
+
+% Ragged left and ragged right
+
+\def\pgfutil@raggedright{\rightskip\z@ plus2em \spaceskip.3333em \xspaceskip.5em\relax}
+\def\pgfutil@raggedleft{\leftskip\z@ plus2em \rightskip\z@ \spaceskip.3333em \xspaceskip.5em\parfillskip0pt\relax}
+
+
+% Error Messages
+\def\pgfutil@packageerror#1#2#3{\errhelp{#3}\errmessage{Package #1 Error: #2}}
+\def\pgfutil@packagewarning#1#2{\immediate\write17{Package #1: Warning! #2.}}
+\def\pgferror#1{\pgfutil@packageerror{pgf}{#1}{}}
+\def\pgfwarning#1{\pgfutil@packagewarning{pgf}{#1}}
+
+
+% Library files inclusion
+
+
+% Include a library file.
+%
+% #1 = List of names of library file.
+%
+% Description:
+%
+% This command includes a list of library files. For each file X in the
+% list, the file pgflibraryX.code.tex is included, provided this has
+% not been done earlier.
+%
+% For the convenience of Context users, both round and square brackets
+% are possible for the argument.
+%
+% Example:
+%
+% \usepgflibrary{arrows}
+% \usepgflibrary[patterns,snakes]
+
+\def\usepgflibrary{\pgfutil@ifnextchar[{\use@pgflibrary}{\use@@pgflibrary}}%}
+\def\use@pgflibrary[#1]{\use@@pgflibrary{#1}}
+\def\use@@pgflibrary#1{%
+ \edef\pgf@list{#1}%
+ \pgfutil@for\pgf@temp:=\pgf@list\do{%
+ \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}%
+ \ifx\pgf@temp\pgfutil@empty
+ \else
+ \expandafter\ifx\csname pgf@library@\pgf@temp @loaded\endcsname\relax%
+ \expandafter\let\csname pgf@library@\pgf@temp @loaded\endcsname=\pgfutil@empty%
+ \expandafter\edef\csname pgf@library@#1@atcode\endcsname{\the\catcode`\@}
+ \expandafter\edef\csname pgf@library@#1@barcode\endcsname{\the\catcode`\|}
+ \expandafter\edef\csname pgf@library@#1@dollarcode\endcsname{\the\catcode`\$}
+ \catcode`\@=11
+ \catcode`\|=12
+ \catcode`\$=3
+ \pgfutil@InputIfFileExists{pgflibrary\pgf@temp.code.tex}{}{%
+ \pgferror{I did not find the pgf library
+ '\pgf@temp'. I looked for the file named
+ pgflibrary\pgf@temp.code.tex, but could not find it in
+ the current texmf trees.}
+ }%
+ \catcode`\@=\csname pgf@library@#1@atcode\endcsname
+ \catcode`\|=\csname pgf@library@#1@barcode\endcsname
+ \catcode`\$=\csname pgf@library@#1@dollarcode\endcsname
+ \fi%
+ \fi
+ }%
+}
+
+
+% Include a module file.
+%
+% #1 = List of names of module files.
+%
+% Description:
+%
+% This command includes a list of module files. For each file X in the
+% list, the file pgfmoduleX.code.tex is included, provided this has
+% not been done earlier.
+%
+% For the convenience of Context users, both round and square brackets
+% are possible for the argument.
+%
+% Example:
+%
+% \usepgfmodule{matrix}
+
+\def\usepgfmodule{\pgfutil@ifnextchar[{\use@pgfmodule}{\use@@pgfmodule}}%}
+\def\use@pgfmodule[#1]{\use@@pgfmodule{#1}}
+\def\use@@pgfmodule#1{%
+ \edef\pgf@list{#1}%
+ \pgfutil@for\pgf@temp:=\pgf@list\do{%
+ \expandafter\ifx\csname pgf@module@\pgf@temp @loaded\endcsname\relax%
+ \expandafter\let\csname pgf@module@\pgf@temp @loaded\endcsname=\pgfutil@empty%
+ \expandafter\edef\csname pgf@module@#1@atcode\endcsname{\the\catcode`\@}
+ \expandafter\edef\csname pgf@module@#1@barcode\endcsname{\the\catcode`\|}
+ \expandafter\edef\csname pgf@module@#1@dollarcode\endcsname{\the\catcode`\$}
+ \catcode`\@=11
+ \catcode`\|=12
+ \catcode`\$=3
+ \input pgfmodule\pgf@temp.code.tex
+ \catcode`\@=\csname pgf@module@#1@atcode\endcsname
+ \catcode`\|=\csname pgf@module@#1@barcode\endcsname
+ \catcode`\$=\csname pgf@module@#1@dollarcode\endcsname
+ \fi%
+ }%
+}
+
+\def\pgfutilensuremath#1{%
+ \ifmmode#1\else$#1$\fi
+}
+
+
+%
+% Guess the driver:
+%
+
+\begingroup
+ \catcode`\"=12
+ \edef\pgf@loc@TMPa{"}%
+ %
+ % prepares file names by checking for double colons.
+ %
+ % If '#1' is a usual file name without anything fancy, \pgfretval
+ % will simply contain it. However, if '#1' contains double colons
+ % (introduces, for example, by pdftex because there are white
+ % spaces in '#1'), the routine
+ % - removes the double colons,
+ % - re-inserts them outside of the string.
+ %
+ % \pgfutilpreparefilename{file.tex} -> file.tex
+ % \pgfutilpreparefilename{"A file name".file} -> "A file name.file"
+ %
+ % The resulting file name is returned in '\pgfretval',
+ % furthermore, a *quoted* version of the file name is returned in
+ % \pgfretvalquoted. The latter result is to have some sort of
+ % output normalisation: if the file name as such contains double
+ % quotes, we don't want to insert another set of them.
+ %
+ % This special handling has the following purposes:
+ % 1. Both, treatment of white spaces and double colons is not
+ % properly defined in TeX. Thus, we should only work with them if
+ % necessary and maintain backwards compatibility as far as
+ % possible.
+ % 2. It *should* work if there are spaces.
+ %
+ \gdef\pgfutilpreparefilename#1{%
+ \begingroup
+ \ifnum\the\catcode`\"=13
+ \pgfutilconvertdcolon
+ \fi
+ \xdef\pgf@temp{#1}%
+ \endgroup
+ \expandafter\pgfutil@in@\expandafter"\expandafter{\pgf@temp}%
+ \ifpgfutil@in@
+ \def\pgf@loc@TMPa{\pgfutilstrreplace{"}{}}%
+ \expandafter\pgf@loc@TMPa\expandafter{\pgf@temp}%
+ \edef\pgfretval{"\pgfretval"}% re-insert quotes! Otherwise, TeX can't use the file name.
+ \let\pgfretvalquoted=\pgfretval
+ \else
+ \let\pgfretval=\pgf@temp
+ \edef\pgfretvalquoted{"\pgfretval"}%
+ \fi
+ }%
+ \catcode`\"=13
+ \xdef\pgfutilconvertdcolon{%
+ \noexpand\def\noexpand"{\pgf@loc@TMPa}%
+ }%
+\endgroup
+
+% Converts an arbitrary command (without arguments) to a string in which all characters
+% have category 12.
+%
+% #1: a macro name (which takes no arguments)
+% #2: a macro name which will be assigned to '#1' converted to string.
+%
+% This uses '\meaning#1' hackery.
+\def\pgfutil@command@to@string#1#2{%
+ \expandafter\pgfutil@command@to@string@@\meaning#1\pgfutil@EOI{#2}%
+}%
+\xdef\pgfutil@glob@TMPa{\meaning\pgfutil@empty}%
+\expandafter\def\expandafter\pgfutil@command@to@string@@\pgfutil@glob@TMPa#1\pgfutil@EOI#2{%
+ \def#2{#1}%
+}%
+\begingroup
+\catcode`\|=0
+\catcode`\\=12
+|gdef|pgfutil@backslash@as@other{\}%
+|endgroup
+
+% Checks if the token sequence #1 (unexpanded) contains a macro and
+% invokes #2 if so and #3 if not.
+\def\pgfutilifcontainsmacro#1#2#3{%
+ \def\pgf@marshal{#1}%
+ \pgfutil@command@to@string\pgf@marshal\pgf@marshal
+ \edef\pgf@marshal{\noexpand\pgfutil@in@{\pgfutil@backslash@as@other}{\pgf@marshal}}%
+ \pgf@marshal
+ \ifpgfutil@in@
+ \def\pgf@marshal{#2}%
+ \else
+ \def\pgf@marshal{#3}%
+ \fi
+ \pgf@marshal
+}%
+
+% Tests if string '#2' starts with pattern '#1'.
+%
+% If so, it executes #3 and defines \pgfretval to contain the
+% suffix which is not equal to #1. Otherwise it executes #4.
+\def\pgfutilifstartswith#1#2#3#4{%
+ \def\pgfutilifstartswith@ ##1#1##2\pgf@EOI{%
+ \def\pgfutil@tmp{##1}%
+ \ifx\pgfutil@tmp\pgfutil@empty
+ % Ah - a hit!
+ %
+ % define \pgfretval to be the suffix...
+ \def\pgfutil@tmp#1####1\pgf@EOI{%
+ \def\pgfretval{####1}%
+ }%
+ \pgfutil@tmp#2\pgf@EOI%
+ %
+ % ... and execute the <true> code:
+ #3\relax%
+ \else
+ % hm. No such prefix.
+ #4\relax%
+ \fi
+ }%
+ \pgfutilifstartswith@#2--#1\pgf@EOI%
+}%
+
+% Usage:
+% \pgfutilstrreplace{<token>}{<replacement>}{<string>}
+%
+% -> will assign the modified string into \pgfretval.
+%
+% #1: the string to search (one or more tokens)
+% #2: zero, one or more tokens which will be inserted instead of '#1'.
+% #3: the string to search in
+\long\def\pgfutilstrreplace#1#2#3{%
+ \def\pgfretval{}%
+ \long\def\pgfutil@search@and@replace@@##1#1##2\pgf@EOI{%
+ \expandafter\def\expandafter\pgfretval\expandafter{\pgfretval ##1#2}%
+ \pgfutil@search@and@replace@loop{#1}{##2}%
+ }%
+ \pgfutil@search@and@replace@loop{#1}{#3}%
+}
+\long\def\pgfutil@search@and@replace@loop#1#2{%
+ \pgfutil@in@{#1}{#2}%
+ \ifpgfutil@in@
+ \def\pgf@loc@TMPa{\pgfutil@search@and@replace@@ #2\pgf@EOI}%
+ \else
+ \expandafter\def\expandafter\pgfretval\expandafter{\pgfretval #2}%
+ \let\pgf@loc@TMPa=\relax
+ \fi
+ \pgf@loc@TMPa
+}%
+
+% Solves a linear equation system of size 2x2 using gauss elimination.
+%
+% It employs TeX register arithmetics to do so.
+% #1: should contain 4 sets of braces with matrix entries,
+% {<a11>}{<a12>}
+% {<a21>}{<a22>}
+% where each entry should be a number without unit.
+% It is acceptable if '#1' is a macro which expands to the expected
+% format.
+% #2: should contain 2 sets of braces with the right-hand-side,
+% {<r1>}{<r2>}
+% where each entry should be a number without unit.
+% It is acceptable if '#2' is a macro which expands to the expected
+% format.
+%
+% It will assign \pgfmathresult to contain two sets of braces with the
+% result.
+%
+% Example:
+% \pgfutilsolvetwotwoleq{
+% {0.24}{1}
+% {-0.97}{0}
+% }{
+% {-7}
+% {18}
+% }
+% -> yields \pgfmathresult={−18.55618}{−2.54642}
+%
+% The algorithm employs column pivotisation.
+%
+% If the matrix is singular, the routine will return {}.
+\def\pgfutilsolvetwotwoleq#1#2{%
+ \begingroup
+ \dimendef\aa=0
+ \dimendef\ab=1
+ \dimendef\ba=2
+ \dimendef\bb=3
+ \dimendef\ra=4
+ \dimendef\rb=5
+ \dimendef\tmpa=6
+ \dimendef\tmpb=7
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutilsolvetwotwoleq@A\pgf@temp
+ \edef\pgf@temp{#2}%
+ \expandafter\pgfutilsolvetwotwoleq@r\pgf@temp
+ %
+ \pgfutilsolvetwotwoleq@ifislarger\aa\ba{%
+ % identity "permutation":
+ \def\Pa{a}%
+ \def\Pb{b}%
+ }{%
+ % permutation matrix: switch rows!
+ \def\Pa{b}%
+ \def\Pb{a}%
+ }%
+ % \pivot := 1/aa
+ \tmpa=\csname m\Pa a\endcsname pt %
+ \ifdim\tmpa<0pt \tmpa=-\tmpa\fi
+ \ifdim\tmpa<0.0001pt
+ % singular matrix!
+ \let\pgfmathresult=\pgfutil@empty
+ \else
+ \pgfmathreciprocal@
+ {\csname m\Pa a\endcsname}%
+ \let\pivot=\pgfmathresult
+ %
+ % \factor := 1/aa * ba
+ \csname \Pb a\endcsname=\pivot\csname \Pb a\endcsname
+ \edef\factor{\expandafter\pgf@sys@tonumber\csname \Pb a\endcsname}%
+ %
+ % bb -= ba/aa * ab
+ \tmpa=-\factor\csname \Pa b\endcsname
+ \advance\csname \Pb b\endcsname by\tmpa
+ %
+ % rb -= ba/aa * ra
+ \tmpa=-\factor\csname r\Pa\endcsname
+ \advance\csname r\Pb\endcsname by\tmpa
+ %
+ \tmpa=\csname \Pb b\endcsname%
+ \ifdim\tmpa<0pt \tmpa=-\tmpa\fi
+ \ifdim\tmpa<0.0001pt
+ % singular matrix!
+ \let\pgfmathresult=\pgfutil@empty
+ \else
+ % xb := rb / bb (the modified rb and modified bb!)
+ \pgfmathdivide@
+ {\expandafter\pgf@sys@tonumber\csname r\Pb\endcsname}
+ {\expandafter\pgf@sys@tonumber\csname \Pb b\endcsname}%
+ \expandafter\let\csname pgfmathresult\Pb\endcsname=\pgfmathresult
+ %
+ % ra := ra - xb * ab
+ \tmpa=\csname pgfmathresult\Pb\endcsname\csname \Pa b\endcsname
+ \advance\csname r\Pa\endcsname by-\tmpa
+ %
+ % xa := 1/aa * ra (the modified ra!)
+ \tmpa=\pivot\csname r\Pa\endcsname
+ \expandafter\edef\csname pgfmathresult\Pa\endcsname{\pgf@sys@tonumber\tmpa}%
+ %
+ \edef\pgfmathresult{%
+ {\csname pgfmathresult\Pa\endcsname}%
+ {\csname pgfmathresult\Pb\endcsname}%
+ }%
+ \fi
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+\def\pgfutilsolvetwotwoleq@ifislarger#1#2#3#4{%
+ \tmpa=#1
+ \ifdim\tmpa<0pt
+ \multiply\tmpa by-1
+ \fi
+ \tmpb=#2
+ \ifdim\tmpb<0pt
+ \multiply\tmpb by-1
+ \fi
+ \ifdim\tmpa>\tmpb
+ #3%
+ \else
+ #4%
+ \fi
+}%
+
+\def\pgfutilsolvetwotwoleqfloat@ifislarger#1#2#3#4{%
+ \pgfmathfloatabs@{#1}\let\tmpa=\pgfmathresult
+ \pgfmathfloatabs@{#2}\let\tmpb=\pgfmathresult
+ \pgfmathfloatlessthan@{\tmpb}{\tmpa}%
+ \ifpgfmathfloatcomparison
+ #3%
+ \else
+ #4%
+ \fi
+}%
+\def\pgfutilsolvetwotwoleq@A#1#2#3#4{%
+ \def\maa{#1}\def\mab{#2}%
+ \def\mba{#3}\def\mbb{#3}%
+ \aa=#1pt \ab=#2pt
+ \ba=#3pt \bb=#4pt
+}
+\def\pgfutilsolvetwotwoleq@r#1#2{%
+ \ra=#1pt \rb=#2pt
+}%
+\def\pgfutilsolvetwotwoleqfloat@A#1#2#3#4{%
+ \pgfmathfloatparsenumber{#1}\let\maa=\pgfmathresult
+ \pgfmathfloatparsenumber{#2}\let\mab=\pgfmathresult
+ \pgfmathfloatparsenumber{#3}\let\mba=\pgfmathresult
+ \pgfmathfloatparsenumber{#4}\let\mbb=\pgfmathresult
+}
+\def\pgfutilsolvetwotwoleqfloat@r#1#2{%
+ \pgfmathfloatparsenumber{#1}\let\ra=\pgfmathresult
+ \pgfmathfloatparsenumber{#2}\let\rb=\pgfmathresult
+}%
+
+% Same as \pgfutilsolvetwotwoleq, but using floating point
+% arithmetics. The return value is still in fixed point.
+\def\pgfutilsolvetwotwoleqfloat#1#2{%
+ \begingroup
+ \pgfmathfloatcreate{1}{1.0}{-4}% FIXME : use a smaller threshold for FPU?
+ \let\thresh=\pgfmathresult
+ %
+ \edef\pgf@temp{#1}%
+ \expandafter\pgfutilsolvetwotwoleqfloat@A\pgf@temp
+ \edef\pgf@temp{#2}%
+ \expandafter\pgfutilsolvetwotwoleqfloat@r\pgf@temp
+ %
+ \pgfutilsolvetwotwoleqfloat@ifislarger\maa\mba{%
+ % identity "permutation":
+ \def\Pa{a}%
+ \def\Pb{b}%
+ }{%
+ % permutation matrix: switch rows!
+ \def\Pa{b}%
+ \def\Pb{a}%
+ }%
+ % \pivot := 1/aa
+ \expandafter\pgfmathfloatabs@\expandafter{\csname m\Pa a\endcsname}%
+ \let\tmpa=\pgfmathresult
+ \pgfmathfloatlessthan@{\tmpa}{\thresh}%
+ \ifpgfmathfloatcomparison
+ % singular matrix!
+ \let\pgfmathresult=\pgfutil@empty
+ \else
+ \expandafter\pgfmathfloatreciprocal@\expandafter{\csname m\Pa a\endcsname}%
+ \let\pivot=\pgfmathresult
+ %
+ % \factor := 1/aa * ba
+ \expandafter\pgfmathfloatmultiply@\expandafter{\csname m\Pb a\endcsname}{\pivot}%
+ \let\factor=\pgfmathresult
+ \expandafter\let\csname m\Pb a\endcsname=\factor
+ %
+ % bb -= ba/aa * ab
+ \expandafter\pgfmathfloatmultiply@\expandafter{\csname m\Pa b\endcsname}{\factor}%
+ \let\tmpa=\pgfmathresult
+ \expandafter\pgfmathfloatsubtract@\expandafter{\csname m\Pb b\endcsname}{\tmpa}%
+ \expandafter\let\csname m\Pb b\endcsname=\pgfmathresult
+ %
+ % rb -= ba/aa * ra
+ \expandafter\pgfmathfloatmultiply@\expandafter{\csname r\Pa\endcsname}{\factor}%
+ \let\tmpa=\pgfmathresult
+ \expandafter\pgfmathfloatsubtract@\expandafter{\csname r\Pb\endcsname}{\tmpa}%
+ \expandafter\let\csname r\Pb\endcsname=\pgfmathresult
+ %
+ \expandafter\pgfmathfloatabs@\expandafter{\csname m\Pb b\endcsname}%
+ \let\tmpa=\pgfmathresult
+ \pgfmathfloatlessthan@{\tmpa}{\thresh}%
+ \ifpgfmathfloatcomparison
+ % singular matrix!
+ \let\pgfmathresult=\pgfutil@empty
+ \else
+ % xb := rb / bb (the modified rb and modified bb!)
+ \edef\pgf@marshal{%
+ \noexpand\pgfmathfloatdivide@
+ {\csname r\Pb\endcsname}
+ {\csname m\Pb b\endcsname}%
+ }%
+ \pgf@marshal
+ \expandafter\let\csname pgfmathresult\Pb\endcsname=\pgfmathresult
+ \let\tmpa=\pgfmathresult
+ %
+ % ra := ra - xb * ab
+ \expandafter\pgfmathfloatmultiply@\expandafter{\csname m\Pa b\endcsname}{\tmpa}%
+ \let\tmpa=\pgfmathresult
+ \expandafter\pgfmathfloatsubtract@\expandafter{\csname r\Pa\endcsname}{\tmpa}%
+ \expandafter\let\csname r\Pa\endcsname=\pgfmathresult
+ %
+ % xa := 1/aa * ra (the modified ra!)
+ \expandafter\pgfmathfloatmultiply@\expandafter{\csname r\Pa\endcsname}{\pivot}%
+ \expandafter\let\csname pgfmathresult\Pa\endcsname=\pgfmathresult
+ %
+ \edef\pgfmathresult{%
+ {\csname pgfmathresult\Pa\endcsname}%
+ {\csname pgfmathresult\Pb\endcsname}%
+ }%
+ \expandafter\pgfutilsolvetwotwoleqfloat@to@pgf@range\pgfmathresult
+ \fi
+ \fi
+ \pgfmath@smuggleone\pgfmathresult
+ \endgroup
+}%
+
+
+\def\pgfutilsolvetwotwoleqfloat@to@pgf@range#1#2{%
+ \pgfmathfloatcreate{1}{1.6}{4}\let\pgfutilsolvetwotwoleqfloat@to@pgf@range@max=\pgfmathresult
+ \pgfmathfloatabs@{#1}%
+ \expandafter\pgfmathfloatlessthan@\expandafter{\pgfmathresult}{\pgfutilsolvetwotwoleqfloat@to@pgf@range@max}%
+ \ifpgfmathfloatcomparison
+ \pgfmathfloatabs@{#2}%
+ \expandafter\pgfmathfloatlessthan@\expandafter{\pgfmathresult}{\pgfutilsolvetwotwoleqfloat@to@pgf@range@max}%
+ \ifpgfmathfloatcomparison
+ % ok.
+ \pgfmathfloattofixed{#1}\let\tmpa=\pgfmathresult
+ \pgfmathfloattofixed{#2}%
+ \edef\pgfmathresult{{\tmpa}{\pgfmathresult}}%
+ \else
+ % singular (because PGF cannot represent its result
+ \let\pgfmathresult=\pgfutil@empty
+ \fi
+ \else
+ % singular (because PGF cannot represent its result
+ \let\pgfmathresult=\pgfutil@empty
+ \fi
+}%
+
+% there are funny programs which overwrite \read and \write (like
+% tabularx).
+\let\pgfutil@write=\write
+\let\pgfutil@read=\read
+
+% curtesy for latex:
+\let\pgfutil@protect\relax
+
+% Used by latex for doing reruns
+% #1 = an internal label
+% #2 = a to-be-tested text
+\def\pgfutil@check@rerun#1#2{}
+
+% new tempdims:
+\newdimen\pgfutil@tempdima
+\newdimen\pgfutil@tempdimb
+
+
+% luatex stuff
+% We assume luatex version > 0.39:
+% - \directlua <general text> will work
+% - \directlua is the only luatex primitive that we can assume
+% accessible without being prefixed by the format via
+% tex.enableprimitives.
+% Ideas taken from the ifluatex package (Heiko Oberdiek)
+\let\pgfutil@ifluatex\iffalse
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+\else
+ \expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname
+ \csname iftrue\endcsname
+\fi
+
+\pgfutil@ifluatex
+ \let\pgfutil@directlua\directlua
+ \pgfutil@directlua{%
+ tex.enableprimitives('pgfutil@',{'luaescapestring'})}
+\else
+ \def\pgfutil@directlua#1{}
+ \def\pgfutil@luaescapestring#1{}
+\fi
+
+
+\def\pgfutil@shellescape@lua@eightseven#1{%
+ \pgfutil@directlua{os.execute("\pgfutil@luaescapestring{#1}")}%
+}%
+\def\pgfutil@shellescape#1{%
+ \immediate\write18{#1}%
+}%
+\pgfutil@IfUndefined{directlua}{%
+}{%
+ \pgfutil@IfUndefined{lastsavedimageresourcepages}{%
+ % Ah - an old version of luatex. It still supports \write18
+ }{%
+ % take the new variant...
+ \let\pgfutil@shellescape=\pgfutil@shellescape@lua@eightseven
+ }%
+}%
+
+% End of luatex stuff
+
+% Advances a number stored in a macro and writes the result back into
+% the macro.
+% #1 is a macro containing a number.
+\def\pgfutil@advancestringcounter#1{%
+ \begingroup
+ \c@pgf@counta=#1\relax
+ \advance\c@pgf@counta by1
+ \edef#1{\the\c@pgf@counta}%
+ \pgfmath@smuggleone#1%
+ \endgroup
+}%
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfutil-context.def b/graphics/pgf/base/tex/generic/utilities/pgfutil-context.def
new file mode 100644
index 0000000000..eddab09aba
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfutil-context.def
@@ -0,0 +1,373 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+%
+% Adapted for colors and pdf resources by Hans Hagen. There can be a few more
+% optimizations but they are not critital.
+
+\pgfutil@format@is@contexttrue
+
+
+% The aux files, needed for reading back coordinates
+\def\pgfutil@aux@read@hook{%
+ \pgfutil@IfFileExists{\jobname.pgf}{\input \jobname.pgf\relax}{}
+ \csname newwrite\endcsname\pgfutil@auxout
+ \immediate\csname openout\endcsname\pgfutil@auxout\jobname.pgf\relax
+}
+\def\pgfutil@writetoaux#1{\write\pgfutil@auxout{#1}}
+
+% XColor-like support for ConTeXt
+
+\def\pgfutil@definecolor#1#2#3{\csname pgfutil@emu@#2\endcsname{#1}#3\@nil}
+
+\def\pgfutil@emu@rgb#1#2,#3,#4\@nil{\expandafter\def\csname\string\color@#1\endcsname{\xcolor@{}{}{rgb}{#2,#3,#4}}}
+\def\pgfutil@emu@gray#1#2\@nil{\expandafter\def\csname\string\color@#1\endcsname{\xcolor@{}{}{rgb}{#2,#2,#2}}}
+\def\pgfutil@emu@cmyk#1#2,#3,#4,#5\@nil{\expandafter\def\csname\string\color@#1\endcsname{\xcolor@{}{}{cmyk}{#2,#3,#4,#5}}}
+
+
+% no need for x colors (users can load it if needed)
+%\pgfutil@definecolor{white}{gray}{1}
+%\pgfutil@definecolor{black}{gray}{0}
+%\pgfutil@definecolor{gray}{gray}{0.5}
+%\pgfutil@definecolor{red}{rgb}{1,0,0}
+%\pgfutil@definecolor{green}{rgb}{0,1,0}
+%\pgfutil@definecolor{blue}{rgb}{0,0,1}
+%\pgfutil@definecolor{cyan}{rgb}{0,1,1}
+%\pgfutil@definecolor{magenta}{rgb}{1,0,1}
+%\pgfutil@definecolor{yellow}{rgb}{1,1,0}
+%\pgfutil@definecolor{orange}{rgb}{1,0.5,0}
+%\pgfutil@definecolor{violet}{rgb}{0.5,0,0.5}
+%\pgfutil@definecolor{purple}{rgb}{0.75,0,0.25}
+%\pgfutil@definecolor{brown}{rgb}{0.75,0.5,0.25}
+
+\def\pgfutil@color#1{%
+ \pgfutil@colorlet{.}{#1}%
+ \pgfsysprotocol@getcurrentprotocol\pgfutil@emu@temp%
+ {%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsetcolor{.}%
+ \expandafter\pgfsys@outerinvoke\expandafter{\pgfsysprotocol@currentprotocol}%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@emu@temp%
+ \aftergroup\pgfutil@reset@color%
+}
+
+\def\pgfutil@extractcolorspec#1#2{%
+ \def#2{{#1}}%
+}
+
+\def\pgfutil@convertcolorspec#1#2#3{%
+ \edef#3{\expandafter\expandafter\expandafter\pgfutil@emu@select\csname\string\color@#1\endcsname}%
+}
+
+\def\pgfutil@doifcolorelse#1#2#3{%
+ \expandafter\ifx\csname\string\color@#1\endcsname\relax%
+ \doifcolorelse{#1}{\let\pgf@next=\pgfutil@firstoftwo}{\let\pgf@next=\pgfutil@secondoftwo}%
+ \else
+ \let\pgf@next=\pgfutil@firstoftwo%
+ \fi%
+ \pgf@next{#2}{#3}%
+}
+
+\def\pgfutil@reset@color{%
+ \pgfsysprotocol@getcurrentprotocol\pgfutil@emu@temp%
+ {%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsetcolor{.}%
+ \expandafter\pgfsys@outerinvoke\expandafter{\pgfsysprotocol@currentprotocol}%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@emu@temp%
+}
+
+\expandafter\def\csname\string\color@.\endcsname{\xcolor@{}{}{rgb}{0,0,0}}
+
+\def\pgfutil@colorlet#1#2{%
+ \edef\pgf@marshal{#2}%
+ \expandafter\pgfutil@in@\expandafter!\expandafter{\pgf@marshal}%
+ \ifpgfutil@in@%
+ % compute mixture
+ {%
+ \expandafter\pgfutil@emu@mix\pgf@marshal!white!\@nil%
+ \xdef\pgf@marshal{\noexpand\def\expandafter\noexpand\csname\string\color@#1\endcsname{%
+ \noexpand\xcolor@{}{}{rgb}{\pgf@sys@tonumber\pgf@xa,\pgf@sys@tonumber\pgf@xb,\pgf@sys@tonumber\pgf@xc}}}%
+ }%
+ \pgf@marshal%
+ \else%
+ \expandafter\ifx\csname\string\color@#2\endcsname\relax%
+ \pgfutil@registercolor{#2}%
+ \fi%
+ \edef\pgf@marshal{\noexpand\let\expandafter\noexpand\csname\string\color@#1\endcsname=%
+ \expandafter\noexpand\csname\string\color@#2\endcsname}%
+ \pgf@marshal%
+ \fi%
+}
+
+\def\pgfutil@emu@mix#1!#2!#3!#4\@nil{%
+ \expandafter\ifx\csname\string\color@#1\endcsname\relax%
+ \pgfutil@registerrgb{#1}%
+ \fi%
+ \expandafter\ifx\csname\string\color@#3\endcsname\relax%
+ \pgfutil@registerrgb{#3}%
+ \fi%
+ \expandafter\expandafter\expandafter\pgfutil@emu@unpack\csname\string\color@#1\endcsname%
+ \pgf@ya=\pgf@xa%
+ \pgf@yb=\pgf@xb%
+ \pgf@yc=\pgf@xc%
+ \expandafter\expandafter\expandafter\pgfutil@emu@unpack\csname\string\color@#3\endcsname%
+ \c@pgf@counta=#2\relax%
+ \c@pgf@countb=100\relax%
+ \advance\c@pgf@countb by-\c@pgf@counta\relax%
+ \pgf@xa=\c@pgf@countb\pgf@xa%
+ \advance\pgf@xa by\c@pgf@counta\pgf@ya%
+ \divide\pgf@xa by 100\relax%
+ \pgf@xb=\c@pgf@countb\pgf@xb%
+ \advance\pgf@xb by\c@pgf@counta\pgf@yb%
+ \divide\pgf@xb by 100\relax%
+ \pgf@xc=\c@pgf@countb\pgf@xc%
+ \advance\pgf@xc by\c@pgf@counta\pgf@yc%
+ \divide\pgf@xc by 100\relax%
+}
+
+\def\pgfutil@emu@unpack#1#2#3#4#5{%
+ \pgfutil@emu@@unpack#5\@nil%
+}
+
+\def\pgfutil@emu@@unpack#1,#2,#3\@nil{%
+ \pgf@xa=#1pt%
+ \pgf@xb=#2pt%
+ \pgf@xc=#3pt%
+}
+
+\def\pgfutil@emu@select#1#2#3#4#5{#5}
+
+\def\XC@tgt@mod#1{#1}
+\def\XC@sdef#1#2{\edef#1{#2}}
+\def\XC@mod@cmyk{cmyk}
+\def\XC@mod@rgb{rgb}
+
+% goody
+
+\let\colorlet=\pgfutil@colorlet
+
+% latex stuff
+
+\newskip\pgfutil@flushglue
+\pgfutil@flushglue=0pt plus 1fil
+
+
+% pgfutil@minipage
+
+\def\pgfutil@minipage[#1]#2{%
+ \hbox to#2\bgroup
+ \hsize=#2\relax
+ \vbox\bgroup
+ \noindentation
+}
+
+\def\pgfutil@endminipage{%
+ \egroup
+ \egroup
+}
+
+% global colors
+
+\let\pgfutil@globalcolorsfalse\relax
+\let\pgfutil@globalcolorstrue \relax
+
+% font stuff
+
+\def\pgfutil@font@tiny {\tfxx}
+\def\pgfutil@font@scriptsize {\tfxx}
+\def\pgfutil@font@footnotesize{\tfx}
+\def\pgfutil@font@small {\tfx}
+\def\pgfutil@font@normalsize {\tf}
+\def\pgfutil@font@large {\tfa}
+\def\pgfutil@font@Large {\tfb}
+\def\pgfutil@font@huge {\tfc}
+\def\pgfutil@font@Huge {\tfc}
+\def\pgfutil@font@itshape {\it}
+\def\pgfutil@font@bfseries {\bf}
+\def\pgfutil@font@normalfont {\tf}
+\def\pgfutil@selectfont {\tf}
+
+% registers
+
+\newcount\pgfutil@tempcnta
+\newcount\pgfutil@tempcntb
+
+\newbox \pgfutil@tempboxa
+
+\newbox \pgfutil@voidb@x
+\newtoks \pgfutil@toks@
+
+\let\pgfmath@tempdima\pgfutil@tempdima
+\let\pgfmath@tempdima\pgfutil@tempdima
+\let\pgfmath@tempcnta\pgfutil@tempcnta
+\let\pgfmath@tempcntb\pgfutil@tempcntb
+
+% module stuff
+
+\def\pgfutil@usemodule#1{\usemodule[#1]}
+
+% more adaptions
+
+\let\pgfutil@insertatbegincurrentpagefrombox\flushatshipout
+\let\pgfutil@insertatbegincurrentpage \flushatshipout
+\def\pgfutil@insertatbegineverypage #1{\appendtoks#1\to\everyshipout} % space removed after #1
+
+\let\pgfutil@setuppdfresources \relax
+
+\doifmodeelse {mkiv} {
+
+ \def\pgfutil@guessdriver{\def\pgfsysdriver{pgfsys-luatex.def}}
+
+ \def\pgfutil@driver@if@in#1#2{%
+ \edef\pgf@marshal{\noexpand\pgfutil@in@{#1}{\preloadedspecials}}%
+ \pgf@marshal
+ \ifpgfutil@in@
+ \def\pgfsysdriver{#2}%
+ \fi
+ }
+
+ \def\pgf@sys@pdf@pdfbackendset@one#1#2%
+ {\normalexpanded{\noexpand\pgf@sys@pdf@pdfbackendset@two\noexpand#1#2\relax}}
+
+ \def\pgf@sys@pdf@pdfbackendset@two#1/#2 #3\relax
+ {#1{#2}{#3}}
+
+ \def\pgf@sys@pdf@addtopageresource@pattern {\pgf@sys@pdf@pdfbackendset@one\pdfbackendsetpattern}
+ \def\pgf@sys@pdf@addtopageresource@colorspace{\pgf@sys@pdf@pdfbackendset@one\pdfbackendsetcolorspace}
+ \def\pgf@sys@pdf@addtopageresource@extgstate {\pgf@sys@pdf@pdfbackendset@one\pdfbackendsetextgstate}
+ \def\pgf@sys@pdf@possible@resources {\pdfbackendcurrentresources}
+ \def\pgf@sys@pdf@check@resources {}
+
+ \let\pgfutil@registercolor\pgf@context@registercolor
+ \let\pgfutil@registerrgb \pgf@context@registerrgb
+ \let\pgfutil@registercmyk \pgf@context@registercmyk
+ \let\pgfutil@registergray \pgf@context@registergray
+
+} {
+ \def\pgf@sys@pdf@addtopageresource@extgstate {\appendtoPDFdocumentextgstates }
+ \def\pgf@sys@pdf@addtopageresource@colorspace {\appendtoPDFdocumentcolorspaces}
+ \def\pgf@sys@pdf@addtopageresource@pattern {\appendtoPDFdocumentpatterns }
+ \def\pgf@sys@pdf@possible@resources {\currentPDFresources}
+ \def\pgf@sys@pdf@check@resources {}
+
+
+ \ifx\pdfoutput\undefined\newcount\pdfoutput\fi
+ \ifx\pdfoutput\relax \newcount\pdfoutput\fi
+
+ \def\pgfutil@guessdriver{
+ \ifx\XeTeXversion\@undefined
+ \ifx\preloadedspecials\@undefined%
+ \ifcase\pdfoutput%
+ \def\pgfsysdriver{pgfsys-dvips.def}%
+ \else%
+ \def\pgfsysdriver{pgfsys-pdftex.def}% pdfTeX & LuaTeX
+ \fi%
+ \else%
+ \pgfutil@driver@if@in{postscript}{pgfsys-dvips.def}
+ \pgfutil@driver@if@in{tpd}{pgfsys-pdftex.def}
+ \pgfutil@driver@if@in{dpm}{pgfsys-dvipdfm.def}
+ \pgfutil@driver@if@in{dpx}{pgfsys-dvipdfmx.def}
+ \pgfutil@driver@if@in{xetex}{pgfsys-xetex.def}
+ \ifx\pgfsysdriver\relax%
+ \PackageWarning{pgf}{I was not able to discern the driver, the
+ preloaded specials were \preloadedspecials. I am going to use
+ pgfsys-dvips.def}%
+ \def\pgfsysdriver{pgfsys-dvips.def}
+ \fi%
+ \fi
+ \else
+ \def\pgfsysdriver{pgfsys-xetex.def}% should be right
+ \fi
+ }
+
+ \def\pgfutil@driver@if@in#1#2{%
+ \edef\pgf@marshal{\noexpand\pgfutil@in@{#1}{\preloadedspecials}}%
+ \pgf@marshal
+ \ifpgfutil@in@
+ \def\pgfsysdriver{#2}%
+ \fi
+ }
+
+ % The cmyk part is from Joseph Wright.
+ % See tex.stackexchange.com/questions/27952/cmyk-context-colors-in-tikz
+ \def\pgfutil@registercolor#1{%
+ \edef\pgf@temp{\PDFcolor{#1}}%
+ \edef\pgf@marshal{\noexpand\pgfutil@in@{rg}{\pgf@temp}}%
+ \pgf@marshal
+ \ifpgfutil@in@
+ \expandafter\pgfutil@context@parse@rgb\pgf@temp\pgf@stop{#1}%
+ \else
+ \edef\pgf@marshal{\noexpand\pgfutil@in@{g}{\pgf@temp}}%
+ \pgf@marshal
+ \ifpgfutil@in@
+ \expandafter\pgfutil@context@parse@gray\pgf@temp\pgf@stop{#1}%
+ \else
+ \edef\pgf@marshal{\noexpand\pgfutil@in@{k}{\pgf@temp}}%
+ \pgf@marshal
+ \ifpgfutil@in@
+ \expandafter\pgfutil@context@parse@cmyk\pgf@temp\pgf@stop{#1}%
+ \else
+ \pgferror{Color #1 has an unsupported color model.}%
+ \pgfutil@definecolor{#1}{gray}{0}%
+ \fi
+ \fi
+ \fi
+ }
+
+ \def\pgfutil@context@parse@gray#1 g#2\pgf@stop#3{%
+ \pgfutil@definecolor{#3}{gray}{#1}
+ }
+
+ \def\pgfutil@context@parse@rgb#1 #2 #3 rg#4\pgf@stop#5{%
+ \pgfutil@definecolor{#5}{rgb}{#1,#2,#3}
+ }
+
+ \def\pgfutil@context@parse@cmyk#1 #2 #3 #4k#5\pgf@stop #6{%
+ \pgfutil@definecolor{#6}{cmyk}{#1,#2,#3,#4}%
+ }
+
+ \def\pgfutil@emu@cmyk#1#2,#3,#4,#5\@nil{%
+ \expandafter\def\csname\string\color@#1\endcsname
+ {\xcolor@{}{}{cmyk}{#2,#3,#4,#5}}%
+ }
+
+ \let\pgfutil@registerrgb \pgfutil@registercolor
+ \let\pgfutil@registercmyk \pgfutil@registercolor
+ \let\pgfutil@registergray \pgfutil@registercolor
+
+
+}
+
+\let\pgf@sys@addpdfresource@extgs@plain \pgf@sys@pdf@addtopageresource@extgstate
+\let\pgf@sys@addpdfresource@patterns@plain \pgf@sys@pdf@addtopageresource@pattern
+\let\pgf@sys@addpdfresource@colorspaces@plain\pgf@sys@pdf@addtopageresource@colorspace
+\let\pgf@sys@pdf@check@resources@plain \pgf@sys@pdf@check@resources
+
+\pgf@sys@addpdfresource@colorspaces@plain{/pgfprgb [/Pattern /DeviceRGB]}
+
+% do something at the end of a job
+
+\appendtoks \the\pgfutil@everybye \to \everybye
+
+\long\def\AtBeginDocument#1{\appendtoks#1\to\everystarttext}%
+
+% pgfcalendar uses translations
+
+\def\pgfutil@translate#1{#1} % \translate works very different in ConTeXt
+
+% e-TeX primitives
+
+\let\pgfutil@protected\normalprotected
+\let\pgfutil@unexpanded\normalunexpanded
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfutil-latex.def b/graphics/pgf/base/tex/generic/utilities/pgfutil-latex.def
new file mode 100644
index 0000000000..e88cfb9427
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfutil-latex.def
@@ -0,0 +1,217 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+\catcode`\@=11\relax
+
+\pgfutil@format@is@latextrue
+
+\let\pgfutil@auxout=\@auxout
+\def\pgfutil@writetoaux#1{\if@filesw\write\pgfutil@auxout{#1}\fi}
+
+\let\pgfutil@tempcnta=\@tempcnta
+\let\pgfutil@tempcntb=\@tempcntb
+\let\pgfutil@voidb@x=\voidb@x
+\let\pgfutil@toks@=\toks@
+
+\let\pgfutil@packageerror=\PackageError
+\let\pgfutil@packagewarning=\PackageWarning
+
+\def\pgfutil@protect{\protect}
+
+
+\def\pgfutil@definecolor{\definecolor}
+\def\pgfutil@color{\color}
+\def\pgfutil@colorlet#1#2{%
+ % If the color is a defined named color, we have to use the [named]
+ % option for colorlet to force xcolor to perform color model
+ % conversion.
+ \expandafter\ifx\csname\expandafter\string\csname color@#2\endcsname\endcsname\relax
+ \colorlet{#1}{#2}%
+ \else
+ \colorlet[named]{#1}{#2}%
+ \fi
+}
+
+\def\pgfutil@extractcolorspec{\extractcolorspec}
+\def\pgfutil@convertcolorspec{\convertcolorspec}
+
+\def\pgfutil@globalcolorsfalse{\let\ifglobalcolors\iffalse}
+\def\pgfutil@globalcolorstrue{\let\ifglobalcolors\iftrue}
+
+\let\pgfutil@minipage=\minipage
+\let\pgfutil@endminipage=\endminipage
+
+\def\pgfutil@doifcolorelse#1#2#3{%
+ \expandafter\ifx\csname\string\color@#1\endcsname\relax%
+ \let\pgf@next=\pgfutil@secondoftwo%
+ \else
+ \let\pgf@next=\pgfutil@firstoftwo%
+ \fi%
+ \pgf@next{#2}{#3}%
+}
+
+\let\pgfutil@raggedleft\raggedleft
+\let\pgfutil@raggedright\raggedright
+
+\let\pgfutil@flushglue=\@flushglue
+
+\def\pgfutil@font@tiny{\tiny}
+\def\pgfutil@font@scriptsize{\scriptsize}
+\def\pgfutil@font@footnotesize{\footnotesize}
+\def\pgfutil@font@small{\small}
+\def\pgfutil@font@normalsize{\normalsize}
+\def\pgfutil@font@large{\large}
+\def\pgfutil@font@Large{\Large}
+\def\pgfutil@font@huge{\huge}
+\def\pgfutil@font@Huge{\Huge}
+
+\def\pgfutil@font@itshape{\itshape}
+\def\pgfutil@font@bfseries{\bfseries}
+
+\def\pgfutil@font@normalfont{\normalfont}
+
+\def\pgfutil@usemodule#1{\usepackage{#1}}
+
+\let\pgfutil@selectfont=\selectfont
+
+\let\pgfutil@tempboxa=\@tempboxa
+
+\let\pgfmath@tempdima\pgfutil@tempdima
+\let\pgfmath@tempdima\pgfutil@tempdima
+\let\pgfmath@tempcnta\pgfutil@tempcnta
+\let\pgfmath@tempcntb\pgfutil@tempcntb
+
+\def\pgfutil@check@rerun#1#2{\@newl@bel{pgf@lab}{#1}{#2}}
+
+\AtBeginDocument{\AtEndDocument{%
+ \if\relax\detokenize\expandafter{\the\pgfutil@everybye}\relax\else
+ \expandafter\clearpage\expandafter\the\expandafter\pgfutil@everybye
+ \fi}}
+
+% \@ifl@t@r is defined \@onlypremable so we have to save it here
+\let\pgfutil@ifl@t@r=\@ifl@t@r
+
+\def\pgfutil@insertatbegincurrentpagefrombox#1{%
+ \edef\pgf@temp{\the\wd\pgfutil@abb}%
+ \global\setbox\pgfutil@abb\hbox{%
+ \unhbox\pgfutil@abb%
+ %
+ % the order in which \pgfutil@insertatbegincurrentpagefrombox
+ % matters unless we make the following -shift!
+ % To see this, consider writing two such statements. The second
+ % one will (naturally) be placed more to the right, although there
+ % is no apparent reason why it should.
+ %
+ % CF observed problems when placing patterns in XObjects without
+ % this skip (dvipdfmx driver for pgfplots shader=interp)
+ \hskip\dimexpr\pgfutil@ifl@t@r\fmtversion{2020/10/01}{2in-2\hoffset}{}-\pgf@temp\relax%
+ #1%
+ \pgfutil@ifl@t@r\fmtversion{2020/10/01}{\hskip\dimexpr-2in-2\hoffset\relax}{}%
+ }%
+}
+\newbox\pgfutil@abb%
+\def\pgfutil@insertatbegincurrentpage#1{%
+ \expandafter\gdef\expandafter\pgfutil@abc\expandafter{\pgfutil@abc#1}%
+}
+\let\pgfutil@abc\pgfutil@empty%
+\def\pgfutil@insertatbegineverypage#1{%
+ \expandafter\gdef\expandafter\pgfutil@abe\expandafter{\pgfutil@abe#1}%
+}
+\let\pgfutil@abe\pgfutil@empty%
+
+\pgfutil@ifl@t@r\fmtversion{2020/10/01}{%
+ \AddToHook{shipout/background}{%
+ \put(\hoffset-1in,\voffset-1in){%
+ \pgfutil@abe\unhbox\pgfutil@abb\pgfutil@abc\global\let\pgfutil@abc\pgfutil@empty
+ }%
+ }%
+}{%
+ \RequirePackage{everyshi}
+ \EveryShipout{%
+ % Add at begin page stuff
+ \setbox\@cclv=\vbox{%
+ \setbox\z@=\hbox{%
+ % the boxes \pgfutil@abe ("every page") and \pgfutil@abb ("current page")
+ % are used to generate pdf objects / dictionaries which are
+ % required for the graphics which are somewhere in the "real"
+ % page content.
+ % BUT: these pdf objects MUST NOT be affected by text layout
+ % shifts! Consequently, we have to undo \hoffset and \voffset
+ % (which are h/v shifts to the page layout).
+ %
+ % Note that this of importance for shadings. To be more
+ % specific: try out shadings with standalone (which uses
+ % \hoffset) and with xdvipdfmx (which appears to be more
+ % fragile than pdflatex) - they break unless we undo \hoffset
+ % and \voffset.
+ \ifdim\hoffset=0pt \else \hskip-\hoffset\fi
+ \pgfutil@abe\unhbox\pgfutil@abb\pgfutil@abc\global\let\pgfutil@abc\pgfutil@empty
+ \ifdim\hoffset=0pt \else \hskip+\hoffset\fi
+ }%
+ \wd\z@=\z@%
+ \ht\z@=\z@%
+ \dp\z@=\z@%
+ % ... see remark above regarding \hoffset/\voffset:
+ \ifdim\voffset=0pt \else \vskip-\voffset\fi
+ \box\z@%
+ \ifdim\voffset=0pt \else \vskip+\voffset\fi
+ %
+ % if TeX changes into vertical mode, it inserts \parskip and
+ % \lineskip. Disable it here:
+ \nointerlineskip%
+ \ifvbox\@cclv \unvbox\@cclv \else\hsize=\wd\@cclv \noindent\unhbox\@cclv \fi%
+ %\box\@cclv
+ % using \box instead of \unhbox or \unvbox
+ % has the advantage that glue settings won't be
+ % altered (as for \unhbox/\unvbox). But \box breaks compatibility
+ % with the 'remember picture' feature.
+ }%
+ }
+
+ % Preview hack: preview.sty hacks into \shipout (which is ok), but
+ % does not honour everyshi.sty (which is not ok). This causes everyshi
+ % material to get lost.
+ \AtBeginDocument{
+ \@ifpackageloaded{preview}{%
+ % Ok, package loaded. Swap definitions of everyshi.sty's shipout
+ % and preview.sty's shipout:
+ \ifPreview
+ \let\shipout\@EveryShipout@Org@Shipout%This is the null version of \shipout, created by preview and saved by everyshi
+ \let\@EveryShipout@Org@Shipout\pr@shipout% This is the original shipout
+ \let\pr@shipout\@EveryShipout@Shipout%
+ \fi
+ }{}%
+ }
+}
+
+% Guess the driver:
+
+\def\pgfutil@guessdriver{
+ \ifx\HCode\@undefined%
+ \edef\pgfsysdriver{pgfsys-\Gin@driver}% should be right
+ \else%
+ \def\pgfsysdriver{pgfsys-tex4ht.def}% should be right
+ \fi%
+}
+
+% pgfcalendar uses translations
+
+\ifx\translate\@undefined % check if \translate is available
+ \def\pgfutil@translate#1{#1}
+\else
+ \def\pgfutil@translate#1{\translate{#1}}
+\fi
+
+% e-TeX primitives
+
+\let\pgfutil@protected\protected
+\let\pgfutil@unexpanded\unexpanded
+
+\endinput
diff --git a/graphics/pgf/base/tex/generic/utilities/pgfutil-plain.def b/graphics/pgf/base/tex/generic/utilities/pgfutil-plain.def
new file mode 100644
index 0000000000..2d08c5303f
--- /dev/null
+++ b/graphics/pgf/base/tex/generic/utilities/pgfutil-plain.def
@@ -0,0 +1,343 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+
+\pgfutil@format@is@plaintrue
+
+
+% The aux files, needed for reading back coordinates
+\def\pgfutil@aux@read@hook{
+ \pgfutil@IfFileExists{\jobname.pgf}{\input \jobname.pgf\relax}{}
+ \csname newwrite\endcsname\pgfutil@auxout
+ \immediate\csname openout\endcsname\pgfutil@auxout\jobname.pgf
+}
+\def\pgfutil@writetoaux#1{\write\pgfutil@auxout{#1}}
+
+% XColor-like support for plain TeX
+
+\def\pgfutil@definecolor#1#2#3{\csname pgfutil@emu@#2\endcsname{#1}#3\@nil}
+
+\def\pgfutil@emu@rgb#1#2,#3,#4\@nil{\expandafter\def\csname\string\color@#1\endcsname{\xcolor@{}{}{rgb}{#2,#3,#4}}}
+\def\pgfutil@emu@gray#1#2\@nil{\expandafter\def\csname\string\color@#1\endcsname{\xcolor@{}{}{rgb}{#2,#2,#2}}}
+\def\pgfutil@emu@RGB#1#2,#3,#4\@nil{%
+ \begingroup
+ \pgfmathdivide@{#2}{255}\let\pgfutil@emu@RGB@r\pgfmathresult
+ \pgfmathdivide@{#3}{255}\let\pgfutil@emu@RGB@g\pgfmathresult
+ \pgfmathdivide@{#4}{255}\let\pgfutil@emu@RGB@b\pgfmathresult
+ \edef\pgf@marshal{\def\expandafter\noexpand\csname\string\color@#1\endcsname{%
+ \noexpand\xcolor@{}{}{rgb}{\pgfutil@emu@RGB@r,\pgfutil@emu@RGB@g,\pgfutil@emu@RGB@b}}}%
+ \expandafter\endgroup\pgf@marshal
+}
+
+\pgfutil@definecolor{white}{gray}{1}
+\pgfutil@definecolor{black}{gray}{0}
+\pgfutil@definecolor{gray}{gray}{0.5}
+\pgfutil@definecolor{red}{rgb}{1,0,0}
+\pgfutil@definecolor{green}{rgb}{0,1,0}
+\pgfutil@definecolor{blue}{rgb}{0,0,1}
+\pgfutil@definecolor{cyan}{rgb}{0,1,1}
+\pgfutil@definecolor{magenta}{rgb}{1,0,1}
+\pgfutil@definecolor{yellow}{rgb}{1,1,0}
+\pgfutil@definecolor{orange}{rgb}{1,0.5,0}
+\pgfutil@definecolor{violet}{rgb}{0.5,0,0.5}
+\pgfutil@definecolor{purple}{rgb}{0.75,0,0.25}
+\pgfutil@definecolor{brown}{rgb}{0.75,0.5,0.25}
+
+\def\pgfutil@color#1{%
+ \pgfutil@colorlet{.}{#1}%
+ \pgfsysprotocol@getcurrentprotocol\pgfutil@emu@temp%
+ {%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsetcolor{.}%
+ \expandafter\pgfsys@outerinvoke\expandafter{\pgfsysprotocol@currentprotocol}%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@emu@temp%
+ \aftergroup\pgfutil@reset@color%
+}
+
+\def\pgfutil@extractcolorspec#1#2{%
+ \def#2{{#1}}%
+}
+
+\def\pgfutil@convertcolorspec#1#2#3{%
+ \edef#3{\expandafter\expandafter\expandafter\pgfutil@emu@select\csname\string\color@#1\endcsname}%
+}
+
+
+\def\pgfutil@doifcolorelse#1#2#3{%
+ \expandafter\ifx\csname\string\color@#1\endcsname\relax%
+ \let\pgf@next=\pgfutil@secondoftwo%
+ \else
+ \let\pgf@next=\pgfutil@firstoftwo%
+ \fi%
+ \pgf@next{#2}{#3}%
+}
+
+
+\def\pgfutil@reset@color{%
+ \pgfsysprotocol@getcurrentprotocol\pgfutil@emu@temp%
+ {%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty%
+ \pgfsysprotocol@bufferedtrue%
+ \pgfsetcolor{.}%
+ \expandafter\pgfsys@outerinvoke\expandafter{\pgfsysprotocol@currentprotocol}%
+ }%
+ \pgfsysprotocol@setcurrentprotocol\pgfutil@emu@temp%
+}
+\expandafter\def\csname\string\color@.\endcsname{\xcolor@{}{}{rgb}{0,0,0}}
+
+\def\pgfutil@colorlet#1#2{%
+ \edef\pgf@marshal{#2}%
+ \expandafter\pgfutil@in@\expandafter!\expandafter{\pgf@marshal}%
+ \ifpgfutil@in@%
+ % compute mixture
+ {%
+ \expandafter\pgfutil@emu@mix\pgf@marshal!white!\@nil%
+ \xdef\pgf@marshal{\noexpand\def\expandafter\noexpand\csname\string\color@#1\endcsname{%
+ \noexpand\xcolor@{}{}{rgb}{\pgf@sys@tonumber\pgf@xa,\pgf@sys@tonumber\pgf@xb,\pgf@sys@tonumber\pgf@xc}}}%
+ }%
+ \pgf@marshal%
+ \else%
+ \edef\pgf@marshal{\noexpand\let\expandafter\noexpand\csname\string\color@#1\endcsname=%
+ \expandafter\noexpand\csname\string\color@#2\endcsname}%
+ \pgf@marshal%
+ \fi%
+}
+\def\pgfutil@emu@mix#1!#2!#3!#4\@nil{%
+ \expandafter\expandafter\expandafter\pgfutil@emu@unpack\csname\string\color@#1\endcsname%
+ \pgf@ya=\pgf@xa%
+ \pgf@yb=\pgf@xb%
+ \pgf@yc=\pgf@xc%
+ \expandafter\expandafter\expandafter\pgfutil@emu@unpack\csname\string\color@#3\endcsname%
+ \c@pgf@counta=#2\relax%
+ \c@pgf@countb=100\relax%
+ \advance\c@pgf@countb by-\c@pgf@counta\relax%
+ \pgf@xa=\c@pgf@countb\pgf@xa%
+ \advance\pgf@xa by\c@pgf@counta\pgf@ya%
+ \divide\pgf@xa by 100\relax%
+ \pgf@xb=\c@pgf@countb\pgf@xb%
+ \advance\pgf@xb by\c@pgf@counta\pgf@yb%
+ \divide\pgf@xb by 100\relax%
+ \pgf@xc=\c@pgf@countb\pgf@xc%
+ \advance\pgf@xc by\c@pgf@counta\pgf@yc%
+ \divide\pgf@xc by 100\relax%
+}
+\def\pgfutil@emu@unpack#1#2#3#4#5{%
+ \pgfutil@emu@@unpack#5\@nil%
+}
+\def\pgfutil@emu@@unpack#1,#2,#3\@nil{%
+ \pgf@xa=#1pt%
+ \pgf@xb=#2pt%
+ \pgf@xc=#3pt%
+}
+
+\def\pgfutil@emu@select#1#2#3#4#5{#5}
+
+
+
+\let\definecolor=\pgfutil@definecolor
+\let\color=\pgfutil@color
+\let\colorlet=\pgfutil@colorlet
+\let\extractcolorspec=\pgfutil@extractcolorspec
+\let\convertcolorspec=\pgfutil@convertcolorspec
+
+\def\XC@tgt@mod#1{#1}
+\def\XC@sdef#1#2{\edef#1{#2}}
+\def\XC@mod@cmyk{cmyk}
+\def\XC@mod@rgb{rgb}
+
+
+% pgfutil@minipage
+
+\def\pgfutil@minipage[#1]#2{%
+ \hbox to#2\bgroup%
+ \hsize=#2\relax%
+ \vbox\bgroup\noindent%
+}
+\def\pgfutil@endminipage{\egroup\egroup}
+
+
+
+% Driver detector (not so good):
+
+\ifx\pdfoutput\@undefined\alloc@0\count\countdef\insc@unt\pdfoutput\fi
+\ifx\pdfoutput\relax\alloc@0\count\countdef\insc@unt\pdfoutput\fi
+
+\def\pgfutil@guessdriver{
+ \ifx\directlua\@undefined
+ \ifx\HCode\@undefined%
+ \ifcase\pdfoutput%
+ \ifx\XeTeXversion\@undefined
+ \def\pgfsysdriver{pgfsys-dvips.def}% hopefully
+ \else
+ \def\pgfsysdriver{pgfsys-xetex.def}% should be right
+ \fi
+ \else%
+ \def\pgfsysdriver{pgfsys-pdftex.def}% should be right
+ \fi%
+ \else%
+ \def\pgfsysdriver{pgfsys-tex4ht.def}% should be right
+ \fi%
+ \else
+ \def\pgfsysdriver{pgfsys-luatex.def}%
+ \fi
+}
+
+
+
+% Global colors
+
+\let\pgfutil@globalcolorsfalse=\relax
+\let\pgfutil@globalcolorstrue=\relax
+
+
+
+% Font stuff
+
+\def\pgfutil@font@tiny{\fam\z@\fiverm} % How to do this correctly?
+\def\pgfutil@font@scriptsize{\fam\z@\sevenrm}
+\def\pgfutil@font@footnotesize{\rm}
+\def\pgfutil@font@small{\fam\z@\ninerm}
+\def\pgfutil@font@normalsize{\rm}
+\def\pgfutil@font@large{\rm}
+\def\pgfutil@font@Large{\rm}
+\def\pgfutil@font@huge{\rm}
+\def\pgfutil@font@Huge{\rm}
+
+\def\pgfutil@font@itshape{\it}
+\def\pgfutil@font@bfseries{\bf}
+
+\let\pgfutil@font@normalfont=\rm
+
+\let\pgfutil@selectfont=\rm
+
+
+% Extra counters, registers, boxes
+
+\newcount\pgfutil@tempcnta
+\newcount\pgfutil@tempcntb
+
+\newbox\pgfutil@tempboxa
+
+\let\pgfmath@tempdima\pgfutil@tempdima
+\let\pgfmath@tempdima\pgfutil@tempdima
+\let\pgfmath@tempcnta\pgfutil@tempcnta
+\let\pgfmath@tempcntb\pgfutil@tempcntb
+
+% From LaTeX
+\newskip\pgfutil@flushglue
+\pgfutil@flushglue=0pt plus 1fil
+
+% Module stuff
+
+\def\pgfutil@usemodule#1{\input #1.tex}
+
+
+
+% End of file stuff
+
+\let\pgfutil@origend=\end
+\def\end{\the\pgfutil@everybye\pgfutil@origend}
+
+% Link to existing stuff
+\let\pgfutil@voidb@x\voidb@x
+\let\pgfutil@toks@\toks@
+
+
+
+
+% Hack shipout. Now use atbegshi
+
+\def\pgfutil@insertatbegincurrentpagefrombox#1{%
+ \edef\pgf@temp{\the\wd\pgfutil@abb}%
+ \global\setbox\pgfutil@abb\hbox{%
+ \unhbox\pgfutil@abb
+ %
+ % the order in which \pgfutil@insertatbegincurrentpagefrombox
+ % matters unless we make the following -shift!
+ % To see this, consider writing two such statements. The second
+ % one will (naturally) be placed more to the right, although there
+ % is no apparent reason why it should.
+ %
+ % CF observed problems when placing patterns in XObjects without
+ % this skip (dvipdfmx driver for pgfplots shader=interp)
+ \hskip-\pgf@temp\relax
+ #1%
+ }%
+}
+\newbox\pgfutil@abb%
+\def\pgfutil@insertatbegincurrentpage#1{%
+ \expandafter\gdef\expandafter\pgfutil@abc\expandafter{\pgfutil@abc#1}%
+}
+\let\pgfutil@abc\pgfutil@empty%
+\def\pgfutil@insertatbegineverypage#1{%
+ \expandafter\gdef\expandafter\pgfutil@abe\expandafter{\pgfutil@abe#1}%
+}
+\let\pgfutil@abe\pgfutil@empty%
+
+% Code by Heiko Oberdiek on ctt
+\input atbegshi.sty\relax
+\AtBeginShipout{%
+ \setbox\AtBeginShipoutBox=\vbox{%
+ \setbox0=\hbox{%
+ \begingroup
+ % the boxes \pgfutil@abe ("every page") and \pgfutil@abb ("current page")
+ % are used to generate pdf objects / dictionaries which are
+ % required for the graphics which are somewhere in the "real"
+ % page content.
+ % BUT: these pdf objects MUST NOT be affected by text layout
+ % shifts! Consequently, we have to undo \hoffset and \voffset
+ % (which are h/v shifts to the page layout).
+ %
+ % Note that this of importance for shadings. To be more
+ % specific: try out shadings with standalone (which uses
+ % \hoffset) and with xdvipdfmx (which appears to be more
+ % fragile than pdflatex) - they break unless we undo \hoffset
+ % and \voffset.
+ \ifdim\hoffset=0pt \else \hskip-\hoffset\fi
+ \pgfutil@abe
+ \unhbox\pgfutil@abb
+ \pgfutil@abc
+ \global\let\pgfutil@abc\pgfutil@empty
+ \ifdim\hoffset=0pt \else \hskip+\hoffset\fi
+ \endgroup
+ }%
+ \wd0=0pt\relax
+ \ht0=0pt\relax
+ \dp0=0pt\relax
+ % ... see remark above regarding \hoffset/\voffset:
+ \ifdim\voffset=0pt \else \vskip-\voffset\fi
+ \box0 %
+ \ifdim\voffset=0pt \else \vskip+\voffset\fi
+ \nointerlineskip
+ \box\AtBeginShipoutBox
+ }%
+}%
+% End of HO code
+
+% The following is still messy and needs to be cleanup up (everything
+% prefixed by pgfutil@):
+
+%\def\PackageInfo#1#2{}
+%\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}%
+%\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}%
+\long\def\AtBeginDocument#1{#1}%
+
+% pgfcalendar uses translations
+
+\def\pgfutil@translate#1{#1} % is there a translator package for plain?
+
+% e-TeX primitives
+
+\let\pgfutil@protected\protected
+\let\pgfutil@unexpanded\unexpanded
+
+\endinput