diff --git a/docs/changelog.md b/docs/changelog.md index 6ffd8b7b..a8ddab17 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -11,6 +11,9 @@ Release notes for `quimb`. - {class}`~quimb.tensor.Circuit` : remove `target_size` in preparation for all contraction specifications to be encapsulated at the contract level (e.g. with `cotengra`) +* add [quimb.schematic.Drawing](quimb.schematic.Drawing) from experimental + submodule, add example docs at {ref}`schematic`. Add methods `text_between`, + `wedge`, `line_offset` and other tweaks for future use by main TN drawing. **Enhancements:** diff --git a/quimb/experimental/schematic demo.ipynb b/docs/examples/schematic-demo.ipynb similarity index 60% rename from quimb/experimental/schematic demo.ipynb rename to docs/examples/schematic-demo.ipynb index acaef677..59a592fd 100644 --- a/quimb/experimental/schematic demo.ipynb +++ b/docs/examples/schematic-demo.ipynb @@ -1,27 +1,33 @@ { "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%config InlineBackend.figure_formats = ['svg']\n", - "from quimb.experimental import schematic" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Illustrative example" + "(schematic)=\n", + "## `schematic` - manual drawing\n", + "\n", + "This example demonstrates the basic functionality of the `schematic` module.\n", + "The schematic module is a simple wrapper around `matplotlib` that allows \n", + "programatically drawing diagrams, e.g. for tensor networks, in 2D and also\n", + "pseudo-3D. It is used as the backend for automatic drawing in\n", + "[TensorNetwork.draw](quimb.tensor.drawing.draw_tn), but it also useful for \n", + "making manual diagrams not associated with a tensor network. The main object\n", + "is the [`Drawing`](quimb.schematic.Drawing) class.\n", + "\n", + "\n", + "### Illustrative full examples\n", + "\n", + "The following examples are intended to be illustrative of a full drawing.\n", + "If you supply a dict of `presets` to `Drawing`, then you can provide default\n", + "styling for various elements simply by name.\n", + "\n", + "#### 2D example" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": { "tags": [] }, @@ -37,11 +43,11 @@ " \n", " \n", " \n", - " 2023-05-04T18:32:41.438950\n", + " 2023-11-29T15:13:58.553605\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -77,7 +83,7 @@ "C 11.952402 33.1906 10.701176 37.860239 10.701176 40.048474 \n", "C 10.701176 42.23671 11.952402 46.906348 13.04652 48.801415 \n", "C 14.140638 50.696483 17.55905 54.114895 19.454118 55.209013 \n", - "\" clip-path=\"url(#p26ddd37a5e)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #33cc80; fill-opacity: 0.4; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #0072b2; stroke: #004c77; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #0072b2; stroke: #004c77; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #0072b2; stroke: #004c77; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #0072b2; stroke: #004c77; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #0072b2; stroke: #004c77; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: url(#h93aaeb4410); stroke: #996a00; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #56b4e9; stroke: #39789b; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #56b4e9; stroke: #39789b; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #56b4e9; stroke: #39789b; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: #56b4e9; stroke: #39789b; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p2d7dabfa1b)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", + "\" style=\"fill: #996a00; stroke: #996a00; stroke-width: 1.0; stroke-linecap: butt; stroke-linejoin: miter\"/>\n", " \n", " \n", "\n" @@ -668,13 +674,23 @@ } ], "source": [ + "%config InlineBackend.figure_formats = ['svg']\n", + "from quimb import schematic\n", + "\n", "presets = {\n", " 'bond': {'linewidth': 3},\n", " 'phys': {'linewidth': 1.5},\n", " 'center': {\n", + " # `get_wong_color` uses more colorblind friendly colors\n", " 'color': schematic.get_wong_color('orange'),\n", " 'hatch': '/////',\n", - " }\n", + " },\n", + " 'left': {\n", + " 'color': schematic.get_wong_color('bluedark'),\n", + " },\n", + " 'right': {\n", + " 'color': schematic.get_wong_color('blue'),\n", + " },\n", "}\n", "\n", "d = schematic.Drawing(presets=presets)\n", @@ -684,15 +700,19 @@ "\n", "for i in range(10):\n", " # draw tensor\n", - " d.circle((i, 0), preset=\"center\" if i == center else None)\n", - " \n", + " d.circle((i, 0), preset=(\n", + " \"center\" if i == center else\n", + " \"left\" if i < center else\n", + " \"right\"\n", + " ))\n", + "\n", " # draw physical index\n", " d.line((i, 0), (i, -2/3), preset='phys')\n", - " \n", + "\n", " # draw virtual bond\n", " if i + 1 < L:\n", " d.line((i, 0), (i + 1, 0), preset='bond')\n", - " \n", + "\n", " # draw isometric conditions\n", " if i != center:\n", " d.arrowhead((i, -2/3), (i, 0), preset='phys')\n", @@ -700,12 +720,12 @@ " d.arrowhead((i, 0), (i + 1, 0), preset='bond')\n", " if i > center + 1:\n", " d.arrowhead((i, 0), (i - 1, 0), preset='bond')\n", - " \n", + "\n", "# label the left\n", "if center > 0:\n", " d.text((center - 1, 0.8), 'LEFT')\n", " d.patch_around([(i, 0) for i in range(center)], radius=0.5)\n", - " \n", + "\n", "# label pair\n", "if center + 1 < L:\n", " d.patch_around_circles(\n", @@ -713,16 +733,27 @@ " (center + 1, 0), 0.3,\n", " facecolor=(.2, .8, .5, .4),\n", " )\n", - " \n", + "\n", "# label the right\n", "if center + 2 < L:\n", " d.text((center + 2, 0.8), 'RIGHT')\n", " d.patch_around([(i, 0) for i in range(center + 2, L)], radius=0.5)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Pseudo-3D example\n", + "\n", + "If you supply 3D coordinates to `Drawing` methods then the objects will be \n", + "mapped by the axonometric projection to 2D and given appropriate z-ordering.\n", + "The projection and orientation can be controlled in the `Drawing` constructor." + ] + }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": { "tags": [] }, @@ -738,11 +769,11 @@ " \n", " \n", " \n", - " 2023-05-04T18:32:42.246602\n", + " 2023-11-29T15:13:59.271634\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -765,13 +796,13 @@ " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", @@ -3231,7 +3262,7 @@ "L 91.527648 106.070441 \n", "L 91.527648 114.820316 \n", "z\n", - "\" clip-path=\"url(#p7df3ee1992)\" style=\"fill: url(#h2bc2b14f73); stroke: #735000; stroke-width: 2\"/>\n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #33b24c; fill-opacity: 0.3; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #56b4e9; stroke: #39789b\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: url(#h226ab10e8d); stroke: #996a00\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 3; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: round\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: none; stroke: #242629; stroke-width: 1.5; stroke-linecap: square\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd37d49c893)\" style=\"fill: #0072b2; stroke: #004c77\"/>\n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", + "\" style=\"fill: #996a00; stroke: #996a00; stroke-width: 1.0; stroke-linecap: butt; stroke-linejoin: miter\"/>\n", " \n", " \n", "\n" @@ -8094,10 +8125,14 @@ "for center in range(L):\n", " # map the stage into a 3D x-coordinate\n", " x = 2 * center\n", - " \n", + "\n", " for i in range(10):\n", " # draw tensor, can now use cube rather than circle\n", - " d.cube((x, i, 0), radius=radius, preset=\"center\" if i == center else None)\n", + " d.cube((x, i, 0), radius=radius, preset=(\n", + " \"center\" if i == center else\n", + " \"left\" if i < center else\n", + " \"right\"\n", + " ))\n", "\n", " # draw physical index\n", " d.line((x, i, 0), (x, i, -2/3), preset='phys')\n", @@ -8129,7 +8164,7 @@ " # label the right\n", " if center + 2 < L:\n", " d.patch_around([(x, i, 0) for i in range(center + 2, L)], radius=3 * radius, smoothing=0.0)\n", - " \n", + "\n", "d.text((0, 0, 1), '$T^i_{e_i}$', color=schematic.get_wong_color('orange'))" ] }, @@ -8137,7 +8172,32 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Individual elements:" + "### Individual elements:\n", + "\n", + "Here we demonstrate the different types of individual element that can be placed.\n", + "The `hash_to_color` function is useful way to deterministically generate colors\n", + "from hashable objects." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from quimb.tensor.drawing import hash_to_color" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "#### Circles\n", + "\n", + "[Drawing.circle](quimb.schematic.Drawing.circle) draws a circle with a given\n", + "radius and center coordinates." ] }, { @@ -8153,16 +8213,16 @@ "\n", "\n", - "\n", + "\n", " \n", " \n", " \n", " \n", - " 2023-05-04T18:32:42.448891\n", + " 2023-11-29T15:13:59.439363\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -8173,241 +8233,241 @@ " \n", " \n", " \n", - " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", "\n" @@ -8423,9 +8483,6 @@ } ], "source": [ - "import numpy as np\n", - "from quimb.tensor.drawing import hash_to_color\n", - "\n", "d = schematic.Drawing()\n", "\n", "coos = [\n", @@ -8436,15 +8493,25 @@ "\n", "for coo in coos:\n", " d.circle(\n", - " coo, \n", + " coo,\n", " radius=np.random.uniform(0.2, 0.3),\n", " color=hash_to_color(str(coo))\n", " )\n", - " \n", + "\n", "# dot is a simple alias circle\n", "d.dot((1.5, 1.5, 0))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Cubes\n", + "\n", + "[Drawing.cube](quimb.schematic.Drawing.cube) draws a cube with a given\n", + "'radius' and center coordinates, only for 3D coordinates." + ] + }, { "cell_type": "code", "execution_count": 5, @@ -8458,16 +8525,16 @@ "\n", "\n", - "\n", + "\n", " \n", " \n", " \n", " \n", - " 2023-05-04T18:32:42.561235\n", + " 2023-11-29T15:13:59.521609\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -8478,788 +8545,788 @@ " \n", " \n", " \n", - " \n", " \n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #7487d8; stroke: #4d5a90\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #7487d8; stroke: #4d5a90\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #7487d8; stroke: #4d5a90\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #7487d8; stroke: #4d5a90\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #7487d8; stroke: #4d5a90\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #7487d8; stroke: #4d5a90\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d04f56; stroke: #8b3539\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d04f56; stroke: #8b3539\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d04f56; stroke: #8b3539\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d77081; stroke: #8f4b56\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d77081; stroke: #8f4b56\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d77081; stroke: #8f4b56\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d77081; stroke: #8f4b56\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d77081; stroke: #8f4b56\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d77081; stroke: #8f4b56\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d04f56; stroke: #8b3539\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d04f56; stroke: #8b3539\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d04f56; stroke: #8b3539\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #54e358; stroke: #38973b\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #54e358; stroke: #38973b\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #54e358; stroke: #38973b\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #cee137; stroke: #899625\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #cee137; stroke: #899625\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #cee137; stroke: #899625\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e3b38a; stroke: #97775c\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e3b38a; stroke: #97775c\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e3b38a; stroke: #97775c\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e3b38a; stroke: #97775c\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e3b38a; stroke: #97775c\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e3b38a; stroke: #97775c\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #cee137; stroke: #899625\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #cee137; stroke: #899625\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #cee137; stroke: #899625\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #54e358; stroke: #38973b\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #54e358; stroke: #38973b\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #54e358; stroke: #38973b\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d581ad; stroke: #8e5673\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d581ad; stroke: #8e5673\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d581ad; stroke: #8e5673\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #8bdbbe; stroke: #5d927f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #8bdbbe; stroke: #5d927f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #8bdbbe; stroke: #5d927f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #ce54bf; stroke: #89387f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #ce54bf; stroke: #89387f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #ce54bf; stroke: #89387f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #3c30da; stroke: #282091\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #3c30da; stroke: #282091\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #3c30da; stroke: #282091\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #3c30da; stroke: #282091\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #3c30da; stroke: #282091\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #3c30da; stroke: #282091\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #ce54bf; stroke: #89387f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #ce54bf; stroke: #89387f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #ce54bf; stroke: #89387f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #8bdbbe; stroke: #5d927f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #8bdbbe; stroke: #5d927f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #8bdbbe; stroke: #5d927f\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d581ad; stroke: #8e5673\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d581ad; stroke: #8e5673\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #d581ad; stroke: #8e5673\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #37dcda; stroke: #259391\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #37dcda; stroke: #259391\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #37dcda; stroke: #259391\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #73ce6d; stroke: #4d8949\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #73ce6d; stroke: #4d8949\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #73ce6d; stroke: #4d8949\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #abcd37; stroke: #728925\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #abcd37; stroke: #728925\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #abcd37; stroke: #728925\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #abcd37; stroke: #728925\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #abcd37; stroke: #728925\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #abcd37; stroke: #728925\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #73ce6d; stroke: #4d8949\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #73ce6d; stroke: #4d8949\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #73ce6d; stroke: #4d8949\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #37dcda; stroke: #259391\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #37dcda; stroke: #259391\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #37dcda; stroke: #259391\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e1504f; stroke: #963535\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e1504f; stroke: #963535\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e1504f; stroke: #963535\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #38dd2d; stroke: #25931e\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #38dd2d; stroke: #25931e\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #38dd2d; stroke: #25931e\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #38dd2d; stroke: #25931e\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #38dd2d; stroke: #25931e\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #38dd2d; stroke: #25931e\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e1504f; stroke: #963535\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e1504f; stroke: #963535\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #e1504f; stroke: #963535\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #74e197; stroke: #4d9665\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #74e197; stroke: #4d9665\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #74e197; stroke: #4d9665\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #74e197; stroke: #4d9665\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #74e197; stroke: #4d9665\"/>\n", " \n", " \n", - " \n", + "\" clip-path=\"url(#pd410db2c11)\" style=\"fill: #74e197; stroke: #4d9665\"/>\n", " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", "\n" @@ -9275,9 +9342,6 @@ } ], "source": [ - "import numpy as np\n", - "from quimb.tensor.drawing import hash_to_color\n", - "\n", "d = schematic.Drawing()\n", "\n", "coos = [\n", @@ -9288,12 +9352,24 @@ "\n", "for coo in coos:\n", " d.cube(\n", - " coo, \n", + " coo,\n", " radius=np.random.uniform(0.2, 0.3),\n", " color=hash_to_color(str(coo))\n", " )" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Text\n", + "\n", + "[Drawing.text](quimb.schematic.Drawing.cube) places text in data coordinates \n", + "(including 3D). [Drawing.label_axes](quimb.schematic.Drawing.label_axes) and\n", + "[Drawing.label_fig](quimb.schematic.Drawing.label_fig) are the same but default\n", + "to axis and figure coordinates respectively." + ] + }, { "cell_type": "code", "execution_count": 6, @@ -9312,11 +9388,11 @@ " \n", " \n", " \n", - " 2023-05-04T18:32:42.745961\n", + " 2023-11-29T15:13:59.610192\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -9681,7 +9757,7 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " 2023-05-04T18:32:42.812657\n", + " 2023-11-29T15:13:59.669791\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -9911,67 +9997,67 @@ "L 302.595323 228.533996 \n", "L 335.62942 126.419272 \n", "z\n", - "\" clip-path=\"url(#p099ac41362)\" style=\"fill: url(#hca8ec82f45); opacity: 0.8; stroke: #4544d2; stroke-width: 2\"/>\n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#h11b0051b0d); opacity: 0.8; stroke: #4544d2\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#hbcea99df40); opacity: 0.8; stroke: #cb37df\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#hd4e9b408fa); opacity: 0.8; stroke: #6de569\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#h80032129ba); opacity: 0.8; stroke: #34ce97\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#h837c8df641); opacity: 0.8; stroke: #d9df8e\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#hd5790607b8); opacity: 0.8; stroke: #9adf88\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#h8fd2145e40); opacity: 0.8; stroke: #40d5a0\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p1ef792c3e8)\" style=\"fill: url(#he3fae655c4); opacity: 0.8; stroke: #453fe2\"/>\n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", "\n", - "\n", + "\n", " \n", " \n", " \n", " \n", - " 2023-05-04T18:32:42.854587\n", + " 2023-11-29T15:13:59.710987\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -10666,46 +10761,440 @@ " \n", " \n", " \n", - " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", "\n" @@ -10723,10 +11212,21 @@ "source": [ "d = schematic.Drawing()\n", "\n", - "d.line((0, 0, 0), (0, 0, 1))\n", - "d.line((0, 1, 0), (0, 1, 1), arrowhead=True)\n", - "d.line((1, 0, 0), (1, 0, 1), linewidth=4)\n", - "d.line((1, 1, 0), (1, 1, 1), linestyle=':')" + "for p in range(3, 10):\n", + " d.marker((p, 0), marker=p)\n", + " d.text((p, 0.5), f\"{p}-gon\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Lines and curves\n", + "\n", + "#### Lines\n", + "\n", + "The basic method for drawing lines between a pair of 2D or 3d points is \n", + "[Drawing.line](quimb.schematic.Drawing.line)." ] }, { @@ -10742,16 +11242,16 @@ "\n", "\n", - "\n", + "\n", " \n", " \n", " \n", " \n", - " 2023-05-04T18:32:42.896321\n", + " 2023-11-29T15:13:59.751301\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -10762,32 +11262,647 @@ " \n", " \n", " \n", - " \n", " \n", " \n", - " \n", - " \n", - " \n", " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ], + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "d = schematic.Drawing()\n", + "\n", + "d.line((0, 0, 0), (0, 0, 1))\n", + "d.line((0, 1, 0), (0, 1, 1), arrowhead=True)\n", + "d.line((1, 0, 0), (1, 0, 1), linewidth=4)\n", + "d.line((1, 1, 0), (1, 1, 1), linestyle=':')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Arrows and labels\n", + "\n", + "You can easily add text and arrows along lines:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " 2023-11-29T15:13:59.792583\n", + " image/svg+xml\n", + " \n", + " \n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ], + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "d = schematic.Drawing()\n", + "\n", + "pa, pb, pc = (0, 0), (1, 1), (2, 0.5)\n", + "\n", + "d.line(pa, pb, text=\"hello\\n\")\n", + "d.line(pb, pc, text=dict(text=\"world\\n\", color='red'), arrowhead=dict(center=1))\n", + "\n", + "# calling `line` with `text=` is a shortcut for `text_between`\n", + "d.text_between(pa, pc, \"Could this be a shortcut?\", color=\"green\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Curves\n", + "\n", + "If you want a line to pass through multiple points, you can use\n", + "[Drawing.curve](quimb.schematic.Drawing.curve) to draw a smooth curve." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " 2023-11-29T15:13:59.905442\n", + " image/svg+xml\n", + " \n", + " \n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -10807,17 +11922,24 @@ "d = schematic.Drawing()\n", "\n", "d.curve(\n", - " [(0, 0), (1, 1), (2.5, 0.5), (3.5, 1.5)], \n", + " [(0, 0), (1, 1), (2.5, 0.5), (3.5, 1.5)],\n", " linestyle='-.', linewidth=5,\n", ")\n", "\n", - "# you can draw just the arrowhead\n", + "# you can draw just the arrowhead separatel\n", "d.arrowhead((1, 1), (2.5, 0.5), linewidth=5, width=0.15)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Curves pass *exactly* through all points given, with the `smoothing` kwarg controlling... how smoothly they do this." + ] + }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": { "tags": [] }, @@ -10828,16 +11950,16 @@ "\n", "\n", - "\n", + "\n", " \n", " \n", " \n", " \n", - " 2023-05-04T18:32:43.257037\n", + " 2023-11-29T15:14:00.216540\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -10848,533 +11970,860 @@ " \n", " \n", " \n", - " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", "\n" @@ -11391,23 +12840,553 @@ ], "source": [ "import matplotlib as mpl\n", - "cm = mpl.colormaps.get_cmap('viridis_r')\n", "\n", "d = schematic.Drawing()\n", "\n", "rng = np.random.default_rng(1)\n", "pts = rng.normal(size=(20, 3))\n", + "cm = mpl.colormaps.get_cmap('RdPu')\n", "\n", "for pt in pts:\n", " d.dot(pt, color='black', radius=0.05)\n", "\n", - "for smoothing in np.linspace(0.0, 1.0, 11):\n", - " d.curve(pts, smoothing=smoothing, color=cm(smoothing))" + "for smoothing in np.linspace(0.0, 2.0, 11):\n", + " d.curve(pts, smoothing=smoothing, color=cm(smoothing / 2))\n", + "\n", + "d.label_ax(1.0, 0.60, \"smoothing=0.0\", color=cm(0.0))\n", + "d.label_ax(1.0, 0.65, \"smoothing=1.0\", color=cm(0.5))\n", + "d.label_ax(1.0, 0.70, \"smoothing=2.0\", color=cm(1.0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Multi-edges\n", + "\n", + "If you want to programmatically draw multiple lines from one place to the other ('multi-edges') you can use `line_offset`:" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " 2023-11-29T15:14:00.284766\n", + " image/svg+xml\n", + " \n", + " \n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ], + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "d = schematic.Drawing()\n", + "\n", + "pa, pb = (0, 0, 0), (0, 1, 1)\n", + "\n", + "green = schematic.get_wong_color(\"green\")\n", + "red = schematic.get_wong_color(\"red\")\n", + "blue = schematic.get_wong_color(\"blue\")\n", + "\n", + "d.circle(pa, color=green)\n", + "d.circle(pb, color=red)\n", + "\n", + "# you can still use arrowheads and text labels\n", + "d.line_offset(pa, pb, 0.2, arrowhead=dict(center=0.9), text='forwards\\n', color=blue)\n", + "d.line_offset(pa, pb, 0.0, arrowhead=dict(center=0.9, reverse=True), text='backwards\\n', color=blue)\n", + "d.line_offset(pa, pb, -0.2, arrowhead=dict(center=0.9, reverse=\"both\"), text='both ways!\\n', color=blue, midlength=0.4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Highlighting areas and groups of objects\n", + "\n", + "#### Patches around general areas\n", + "\n", + "In technical drawings it is often useful to highlight areas. The \n", + "[Drawing.patch](quimb.schematic.Drawing.patch) method does this by filling in\n", + "a curve, given by a sequence of 2D or 3D coordinates." + ] + }, + { + "cell_type": "code", + "execution_count": 14, "metadata": { "tags": [] }, @@ -11423,11 +13402,11 @@ " \n", " \n", " \n", - " 2023-05-04T18:34:02.522313\n", + " 2023-11-29T15:14:00.317250\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -11453,38 +13432,28 @@ "C 116.343279 205.55929 116.343279 30.60071 100.905757 15.163188 \n", "C 95.116686 9.374118 29.507219 9.374118 23.718148 15.163188 \n", "C 8.280627 30.60071 8.280627 205.55929 23.718148 220.996812 \n", - "\" clip-path=\"url(#p0ff8f72c11)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", + "\" clip-path=\"url(#p80cf460770)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -11503,8 +13472,8 @@ "source": [ "d = schematic.Drawing(figsize=(4, 4))\n", "\n", - "d.circle((0, 0), color=schematic.get_wong_color('red'))\n", - "d.circle((0, 1), color=schematic.get_wong_color('green'))\n", + "d.marker((0, 0), marker='s', color=schematic.get_wong_color('yellow'))\n", + "d.marker((0, 1), marker='s', color=schematic.get_wong_color('bluedark'))\n", "d.patch([\n", " (-.3, -.3),\n", " (+.3, -.3),\n", @@ -11513,6 +13482,17 @@ "], smoothing=0.3)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Patches around two circles\n", + "\n", + "If you want to specifically highlight two circles, you can use\n", + "[Drawing.patch_around_circles](quimb.schematic.Drawing.patch_around_circles),\n", + "and simply specify the two circles by their center coordinates and radii." + ] + }, { "cell_type": "code", "execution_count": 15, @@ -11531,11 +13511,11 @@ " \n", " \n", " \n", - " 2023-05-04T18:33:58.085558\n", + " 2023-11-29T15:14:00.345442\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -11569,7 +13549,7 @@ "C 210.430614 88.161741 207.074862 88.073614 193.744638 91.426727 \n", "C 164.427833 98.801139 160.826692 84.27461 131.408782 91.457358 \n", "C 99.901955 99.150141 102.939055 119.33225 72.143696 122.195684 \n", - "\" clip-path=\"url(#p1dc12ee4db)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", + "\" clip-path=\"url(#p5739301d44)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #808080; stroke-opacity: 0.75; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p5739301d44)\" style=\"fill: #cc79a7; stroke: #88516f; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p5739301d44)\" style=\"fill: #56b4e9; stroke: #39789b; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -11629,9 +13609,20 @@ ")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Patches around arbitrary collections of objects\n", + "\n", + "If you want to highlight an arbitrary collection of objects, you can call\n", + "[Drawing.patch_around](quimb.schematic.Drawing.patch_around), this computes\n", + "the convex hull of the objects and draws a patch around it." + ] + }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "metadata": { "tags": [] }, @@ -11647,11 +13638,11 @@ " \n", " \n", " \n", - " 2023-05-04T18:32:43.401009\n", + " 2023-11-29T15:14:00.388814\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -11682,7 +13673,7 @@ "C 256.990424 104.235142 257.356771 105.119583 258.008782 105.771594 \n", "C 258.660793 106.423605 259.545234 106.789952 260.467317 106.789952 \n", "z\n", - "\" clip-path=\"url(#p40e54edf9e)\"/>\n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #808080; fill-opacity: 0.25; stroke-dasharray: 1,1.65; stroke-dashoffset: 0; stroke: #ffa500; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #ffa500\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #ffa500\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #ffa500\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #ffa500\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #ffa500\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #ffa500\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\" style=\"fill: #ffa500\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#pd0cc52aaef)\"/>\n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -11970,9 +13961,17 @@ "d.patch_around(pts[:7], edgecolor='orange')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can control how much padding is added around the perimeter of the objects\n", + "using the `radius` kwarg." + ] + }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 17, "metadata": { "tags": [] }, @@ -11988,11 +13987,11 @@ " \n", " \n", " \n", - " 2023-05-04T18:32:43.901100\n", + " 2023-11-29T15:14:00.840064\n", " image/svg+xml\n", " \n", " \n", - " Matplotlib v3.7.1, https://matplotlib.org/\n", + " Matplotlib v3.8.1, https://matplotlib.org/\n", " \n", " \n", " \n", @@ -12032,7 +14031,7 @@ "C 51.562445 29.604683 39.128448 31.877341 34.046278 34.811534 \n", "C 28.964107 37.745726 19.796646 46.913187 16.862454 51.995358 \n", "C 13.928261 57.077528 10.572738 69.600512 10.572738 75.468897 \n", - "\" clip-path=\"url(#pd990c08898)\" style=\"fill: #d4d570; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #d4d570; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #50d0c2; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #96b5d9; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #76a3d6; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #6ad7c0; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #81df54; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #cee54f; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #7f40d4; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #31d651; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #c14bdb; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #39acd6; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #7930d2; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #a4de79; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #7355d7; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #80d749; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #8a5bcf; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #828fdd; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #50d0c2\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #45ce3d; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #45ce3d\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #80d749\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #74d649; opacity: 0.5; stroke: #808080; stroke-linejoin: miter\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #39acd6\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #828fdd\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #7930d2\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #a4de79\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #76a3d6\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #c14bdb\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #74d649\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #96b5d9\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #7355d7\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #81df54\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #6ad7c0\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #8a5bcf\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #9265d1\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #cee54f\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #7f40d4\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #31d651\"/>\n", " \n", " \n", " \n", + "\" clip-path=\"url(#p0c2bdd1da4)\" style=\"fill: #d4d570\"/>\n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -12690,8 +14689,8 @@ "\n", "for k in range(1, len(pts)):\n", " d.patch_around(\n", - " pts[:k], \n", - " radius=0.05 * k, \n", + " pts[:k],\n", + " radius=0.05 * k,\n", " facecolor=hash_to_color(str(k - 1)),\n", " linestyle='-',\n", " zorder=-k,\n", @@ -12702,9 +14701,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python [conda env:numpy]", + "display_name": "Python [conda env:py311]", "language": "python", - "name": "conda-env-numpy-py" + "name": "conda-env-py311-py" }, "language_info": { "codemirror_mode": { @@ -12716,7 +14715,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.11.3" } }, "nbformat": 4, diff --git a/docs/index_examples.md b/docs/index_examples.md index b6b329ac..194b9c0f 100644 --- a/docs/index_examples.md +++ b/docs/index_examples.md @@ -18,4 +18,5 @@ ./examples/ex_quimb_within_torch ./examples/ex_quimb_within_jax_flax_optax ./examples/ex_tn_tensor_fitting +./examples/schematic-demo ``` diff --git a/quimb/experimental/schematic.py b/quimb/schematic.py similarity index 73% rename from quimb/experimental/schematic.py rename to quimb/schematic.py index df1b930c..466c9165 100644 --- a/quimb/experimental/schematic.py +++ b/quimb/schematic.py @@ -10,14 +10,20 @@ class Drawing: - """Draw pseudo-3D diagrams using matplotlib. This handles the axonometric - projection and the z-ordering of the elements, as well as named preset - styles for repeated elements. + """Draw 2D or pseudo-3D diagrams using matplotlib. This handles the + axonometric projection and the z-ordering of the elements, as well as named + preset styles for repeated elements, and the automatic adjustment of the + figure limits. It also has basic support for drawing smooth curves and + shaded areas around certain elements automatically. Parameters ---------- - background : color + background : color, optional The background color of the figure, defaults to transparent. + drawcolor : color, optional + The default color to draw lines and text in. + shapecolor : color, optional + The default color to fill shapes with. a : float The axonometric angle of the x-axis in degrees. b : float @@ -40,6 +46,8 @@ class Drawing: def __init__( self, background=(0, 0, 0, 0), + drawcolor=(0.14, 0.15, 0.16, 1.0), + shapecolor=(0.45, 0.50, 0.55, 1.0), a=50, b=12, xscale=1, @@ -61,6 +69,9 @@ def __init__( self.ax.set_aspect("equal") self.ax.set_clip_on(False) + self.drawcolor = drawcolor + self.shapecolor = shapecolor + self._xmin = None self._xmax = None self._ymin = None @@ -128,8 +139,10 @@ def text(self, coo, text, preset=None, **kwargs): Specific style options passed to ``matplotlib.axes.Axes.text``. """ style = parse_style_preset(self.presets, preset, **kwargs) + style.setdefault("color", self.drawcolor) style.setdefault("horizontalalignment", "center") style.setdefault("verticalalignment", "center") + style.setdefault("clip_on", False) if len(coo) == 2: x, y = coo @@ -141,6 +154,54 @@ def text(self, coo, text, preset=None, **kwargs): self.ax.text(x, y, text, **style) self._adjust_lims(x, y) + def text_between(self, cooa, coob, text, preset=None, **kwargs): + """Place text between two coordinates. + + Parameters + ---------- + cooa, coob : tuple[int, int] or tuple[int, int, int] + The 2D or 3D coordinates of the text endpoints. If 3D, the + coordinates will be projected onto the 2D plane, and a z-order + will be assigned based on average z-order of the endpoints. + text : str + The text to place. + preset : str, optional + A preset style to use for the text. + kwargs + Specific style options passed to ``matplotlib.axes.Axes.text``. + """ + style = parse_style_preset(self.presets, preset, **kwargs) + style.setdefault("color", self.drawcolor) + style.setdefault("horizontalalignment", "center") + style.setdefault("verticalalignment", "center") + style.setdefault("clip_on", False) + + if len(cooa) == 2: + xa, ya = cooa + xb, yb = coob + style.setdefault("zorder", +0.02) + else: + style.setdefault( + "zorder", + mean(self._coo_to_zorder(*coo) for coo in [cooa, coob]) + 0.02, + ) + xa, ya = self._3d_project(*cooa) + xb, yb = self._3d_project(*coob) + + # compute midpoint + x = (xa + xb) / 2 + y = (ya + yb) / 2 + + # compute angle + if xa <= xb: + angle = atan2(yb - ya, xb - xa) * 180 / pi + else: + angle = atan2(ya - yb, xa - xb) * 180 / pi + style.setdefault("rotation", angle) + + self.ax.text(x, y, text, **style) + self._adjust_lims(x, y) + def label_ax(self, x, y, text, preset=None, **kwargs): """Place text at the specified location, using the axis coordinates rather than 2D or 3D data coordinates. @@ -157,6 +218,7 @@ def label_ax(self, x, y, text, preset=None, **kwargs): Specific style options passed to ``matplotlib.axes.Axes.text``. """ style = parse_style_preset(self.presets, preset, **kwargs) + style.setdefault("color", self.drawcolor) style.setdefault("horizontalalignment", "center") style.setdefault("verticalalignment", "center") style.setdefault("transform", self.ax.transAxes) @@ -179,31 +241,21 @@ def label_fig(self, x, y, text, preset=None, **kwargs): Specific style options passed to ``matplotlib.axes.Axes.text``. """ style = parse_style_preset(self.presets, preset, **kwargs) + style.setdefault("color", self.drawcolor) style.setdefault("horizontalalignment", "center") style.setdefault("verticalalignment", "center") style.setdefault("transform", self.fig.transFigure) self.ax.text(x, y, text, **style) self._adjust_lims(x, y) - def circle(self, coo, preset=None, **kwargs): - """Draw a circle at the specified coordinate. - - Parameters - ---------- - coo : tuple[int, int] or tuple[int, int, int] - The 2D or 3D coordinate of the circle. If 3D, the coordinate will - be projected onto the 2D plane, and a z-order will be assigned. - preset : str, optional - A preset style to use for the circle. - kwargs - Specific style options passed to ``matplotlib.patches.Circle``. - """ + def _parse_style_for_marker(self, coo, preset=None, **kwargs): style = parse_style_preset(self.presets, preset, **kwargs) if "color" in style: + # assume coloring whole shape style.setdefault("facecolor", style.pop("color")) - style.setdefault("facecolor", (0.4, 0.5, 0.6)) - style.setdefault("edgecolor", darken_color(style["facecolor"], 0.5)) - style.setdefault("linewidth", 2) + style.setdefault("facecolor", self.shapecolor) + style.setdefault("edgecolor", darken_color(style["facecolor"])) + style.setdefault("linewidth", 1) style.setdefault("radius", 0.25) if len(coo) == 2: @@ -213,10 +265,9 @@ def circle(self, coo, preset=None, **kwargs): x, y = self._3d_project(*coo) style.setdefault("zorder", self._coo_to_zorder(*coo) + 0.01) - circle = mpl.patches.Circle((x, y), **style) - self.ax.add_artist(circle) + return x, y, style - r = style["radius"] + def _adjust_lims_for_marker(self, x, y, r): for x, y in [ (x - 1.1 * r, y), (x + 1.1 * r, y), @@ -225,6 +276,59 @@ def circle(self, coo, preset=None, **kwargs): ]: self._adjust_lims(x, y) + def circle(self, coo, preset=None, **kwargs): + """Draw a circle at the specified coordinate. + + Parameters + ---------- + coo : tuple[int, int] or tuple[int, int, int] + The 2D or 3D coordinate of the circle. If 3D, the coordinate will + be projected onto the 2D plane, and a z-order will be assigned. + preset : str, optional + A preset style to use for the circle. + kwargs + Specific style options passed to ``matplotlib.patches.Circle``. + """ + x, y, style = self._parse_style_for_marker( + coo, preset=preset, **kwargs + ) + circle = mpl.patches.Circle((x, y), **style) + self.ax.add_artist(circle) + self._adjust_lims_for_marker(x, y, style["radius"]) + + def wedge(self, coo, theta1, theta2, preset=None, **kwargs): + """Draw a wedge at the specified coordinate. + + Parameters + ---------- + coo : tuple[int, int] or tuple[int, int, int] + The 2D or 3D coordinate of the wedge. If 3D, the coordinate will + be projected onto the 2D plane, and a z-order will be assigned. + theta1 : float + The angle in degrees of the first edge of the wedge. + theta2 : float + The angle in degrees of the second edge of the wedge. + preset : str, optional + A preset style to use for the wedge. + kwargs + Specific style options passed to ``matplotlib.patches.Wedge``. + """ + x, y, style = self._parse_style_for_marker( + coo, preset=preset, **kwargs + ) + + # wedge uses r, not radius + style["r"] = style.pop("radius") + # and is not filled by default + style.setdefault("fill", True) + + wedge = mpl.patches.Wedge( + (x, y), theta1=theta1, theta2=theta2, **style + ) + + self.ax.add_artist(wedge) + self._adjust_lims_for_marker(x, y, style["r"]) + def dot(self, coo, preset=None, **kwargs): """Draw a small circle with no border. Alias for circle with defaults `radius=0.1` and `linewidth=0.0`. @@ -244,6 +348,78 @@ def dot(self, coo, preset=None, **kwargs): style.setdefault("linewidth", 0.0) self.circle(coo, **style) + def regular_polygon(self, coo, preset=None, **kwargs): + """Draw a regular polygon at the specified coordinate. + + Parameters + ---------- + coo : tuple[int, int] or tuple[int, int, int] + The 2D or 3D coordinate of the polygon. If 3D, the coordinate will + be projected onto the 2D plane, and a z-order will be assigned. + n : int + The number of sides of the polygon. + orientation : float, optional + The orientation of the polygon in radians. Default is 0.0. + preset : str, optional + A preset style to use for the polygon. + kwargs + Specific style options passed to ``matplotlib.patches.Polygon``. + """ + x, y, style = self._parse_style_for_marker( + coo, preset=preset, **kwargs + ) + + n = style.pop("n", 3) + orientation = style.pop("orientation", 0.0) + + rpoly = mpl.patches.RegularPolygon( + (x, y), numVertices=n, orientation=orientation, **style + ) + self.ax.add_artist(rpoly) + self._adjust_lims_for_marker(x, y, style["radius"]) + + def marker(self, coo, preset=None, **kwargs): + """Draw a 'marker' at the specified coordinate. This is a shorthand for + creating polygons with shape specified by a single character. + + Parameters + ---------- + coo : tuple[int, int] or tuple[int, int, int] + The 2D or 3D coordinate of the marker. If 3D, the coordinate will + be projected onto the 2D plane, and a z-order will be assigned. + marker : str, optional + The marker shape to draw. One of ``"o.v^<>sDphH8"``. + preset : str, optional + A preset style to use for the marker. + kwargs + Specific style options. + """ + style = parse_style_preset(self.presets, preset, **kwargs) + marker = style.pop("marker", "s") + if marker in ("o", "."): + return self.circle(coo, preset=preset, **style) + + if isinstance(marker, int): + n = marker + orientation = 0.0 + else: + n, orientation = { + "v": (3, pi / 3), + "^": (3, 0), + "<": (3, pi / 2), + ">": (3, -pi / 2), + "s": (4, pi / 4), + "D": (4, 0), + "p": (5, 0), + "h": (6, 0), + "H": (6, pi / 2), + "8": (8, 0), + }[marker] + + self.regular_polygon( + coo, preset=preset, n=n, orientation=orientation, **style + ) + def cube(self, coo, preset=None, **kwargs): """Draw a cube at the specified coordinate, which must be 3D. @@ -288,9 +464,11 @@ def line(self, cooa, coob, preset=None, **kwargs): stretch : float Stretch the line by this factor. 1.0 is no stretch, 0.5 is half length, 2.0 is double length. Default is 1.0. - arrowhead : bool + arrowhead : bool or dict, optional Draw an arrowhead at the end of the line. Default is False. If a dict, it is passed as keyword arguments to the arrowhead method. + text_between : str, optional + Add text along the line. preset : str, optional A preset style to use for the line. kwargs @@ -301,10 +479,14 @@ def line(self, cooa, coob, preset=None, **kwargs): Drawing.arrowhead """ style = parse_style_preset(self.presets, preset, **kwargs) - style.setdefault("color", (0.25, 0.25, 0.25)) + style.setdefault("color", self.drawcolor) style.setdefault("solid_capstyle", "round") style.setdefault("stretch", 1.0) style.setdefault("arrowhead", None) + style.setdefault("text", None) + stretch = style.pop("stretch") + arrowhead = style.pop("arrowhead") + text = style.pop("text") if len(cooa) == 2: xs, ys = zip(*(cooa, coob)) @@ -316,27 +498,116 @@ def line(self, cooa, coob, preset=None, **kwargs): ) xs, ys = zip(*[self._3d_project(*coo) for coo in [cooa, coob]]) - stretch = style.pop("stretch") if stretch != 1.0: # shorten around center center = mean(xs), mean(ys) xs = [center[0] + stretch * (x - center[0]) for x in xs] ys = [center[1] + stretch * (y - center[1]) for y in ys] - arrowhead = style.pop("arrowhead") if arrowhead is not None: if arrowhead is True: arrowhead = {} else: arrowhead = dict(arrowhead) - self.arrowhead(cooa, coob, preset=preset, **style, **arrowhead) + self.arrowhead(cooa, coob, preset=preset, **(style | arrowhead)) line = mpl.lines.Line2D(xs, ys, **style) self.ax.add_artist(line) + if text: + if isinstance(text, str): + text = {"text": text} + else: + text = dict(text) + + # don't want to pass full style dict to text_between + text.setdefault("zorder", style["zorder"]) + self.text_between(cooa, coob, **text) + for x, y in zip(xs, ys): self._adjust_lims(x, y) + def line_offset( + self, cooa, coob, offset, midlength=0.5, preset=None, **kwargs + ): + """Draw a line between two coordinates, but curving out by a given + offset perpendicular to the line. + + Parameters + ---------- + cooa, coob : tuple[int, int] or tuple[int, int, int] + The 2D or 3D coordinates of the line endpoints. If 3D, the + coordinates will be projected onto the 2D plane, and a z-order + will be assigned based on average z-order of the endpoints. + offset : float + The offset of the curve from the line, as a fraction of the total + line length. This is always processed in the 2D projected plane. + midlength : float + The length of the middle straight section, as a fraction of the + total line length. Default is 0.5. + arrowhead : bool or dict, optional + Draw an arrowhead at the end of the line. Default is False. If a + dict, it is passed as keyword arguments to the arrowhead method. + text_between : str, optional + Add text along the line. + preset : str, optional + A preset style to use for the line. + kwargs + Specific style options passed to ``curve``. + """ + style = parse_style_preset(self.presets, preset, **kwargs) + style.setdefault("arrowhead", None) + style.setdefault("text", None) + arrowhead = style.pop("arrowhead") + text = style.pop("text") + + if len(cooa) == 2: + xs, ys = zip(*(cooa, coob)) + style.setdefault("zorder", +0.0) + else: + style.setdefault( + "zorder", + mean(self._coo_to_zorder(*coo) for coo in [cooa, coob]), + ) + xs, ys = zip(*[self._3d_project(*coo) for coo in [cooa, coob]]) + + cooa = xs[0], ys[0] + coob = xs[1], ys[1] + forward, inverse = get_rotator_and_inverse(cooa, coob) + R = forward(*coob)[0] + endlength = (1 - midlength) / 2 + cooml = inverse(endlength * R, offset * R) + coomm = inverse(R / 2, offset * R) + coomr = inverse((1 - endlength) * R, offset * R) + curve_pts = [cooa, cooml, coomm, coomr, coob] + + if arrowhead is not None: + if arrowhead is True: + arrowhead = {} + else: + arrowhead = dict(arrowhead) + + # want to correct center for midlength + center = arrowhead.pop("center", 0.5) + arrowhead["center"] = min( + max(0.0, 0.5 + (center - 0.5) / midlength), 1.0 + ) + self.arrowhead(cooml, coomr, preset=preset, **(style | arrowhead)) + + self.curve(curve_pts, preset=preset, **style) + + if text: + if isinstance(text, str): + text = {"text": text} + else: + text = dict(text) + # don't want to pass full style dict to text_between + text.setdefault("zorder", style["zorder"]) + self.text_between(cooml, coomr, **text) + + for coo in curve_pts: + self._adjust_lims(*coo) + def arrowhead(self, cooa, coob, preset=None, **kwargs): """Draw just a arrowhead on the line between ``cooa`` and ``coob``. @@ -346,8 +617,10 @@ def arrowhead(self, cooa, coob, preset=None, **kwargs): The coordinates of the start and end of the line. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints. - reverse : bool, optional - Reverse the direction by switching ``cooa`` and ``coob``. + reverse : bool or "both", optional + Reverse the direction by switching ``cooa`` and ``coob``. If + ``"both"``, draw an arrowhead in both directions. Default is + False. center : float, optional The position of the arrowhead along the line, where 0 is the start and 1 is the end. Default is 0.5. @@ -362,13 +635,15 @@ def arrowhead(self, cooa, coob, preset=None, **kwargs): Specific style options passed to ``matplotlib.lines.Line2D``. """ style = parse_style_preset(self.presets, preset, **kwargs) - style.setdefault("color", (0.25, 0.25, 0.25)) + style.setdefault("color", self.drawcolor) style.setdefault("center", 0.5) style.setdefault("width", 0.05) style.setdefault("length", 0.1) style.setdefault("reverse", False) reverse = style.pop("reverse") + if reverse == "both": + self.arrowhead(cooa, coob, preset=preset, **style) if reverse: cooa, coob = coob, cooa @@ -425,7 +700,7 @@ def curve(self, coos, preset=None, **kwargs): if "color" in style: # presume that edge color is being specified style.setdefault("edgecolor", style.pop("color")) - style.setdefault("edgecolor", (0.25, 0.25, 0.25)) + style.setdefault("edgecolor", self.drawcolor) style.setdefault("fill", False) style.setdefault("capstyle", "round") style.setdefault("smoothing", 1 / 2) @@ -494,9 +769,9 @@ def shape(self, coos, preset=None, **kwargs): style = parse_style_preset(self.presets, preset, **kwargs) if "color" in style: style.setdefault("facecolor", style.pop("color")) - style.setdefault("facecolor", (0.4, 0.5, 0.6)) - style.setdefault("edgecolor", darken_color(style["facecolor"], 0.5)) - style.setdefault("linewidth", 2) + style.setdefault("facecolor", self.shapecolor) + style.setdefault("edgecolor", darken_color(style["facecolor"])) + style.setdefault("linewidth", 1) style.setdefault("joinstyle", "round") if len(coos[0]) != 2: @@ -793,7 +1068,7 @@ def axonometric_project( x, y : float The 2D coordinates of the projected point. """ - i *= (xscale * 0.8) + i *= xscale * 0.8 j *= yscale k *= zscale return ( @@ -844,7 +1119,7 @@ def get_wong_color( return r, g, b -def darken_color(color, factor=0.5): +def darken_color(color, factor=2/3): """Take ``color`` and darken it by ``factor``.""" rgba = mpl.colors.to_rgba(color) return tuple(factor * c for c in rgba[:3]) + rgba[3:] @@ -899,8 +1174,9 @@ def get_rotator_and_inverse(pa, pb): def forward(x, y): """Rotate and translate a point.""" x, y = x - dx, y - dy - x, y = x * cos(-theta) - y * sin(-theta), x * sin(-theta) + y * cos( - -theta + x, y = ( + x * cos(-theta) - y * sin(-theta), + x * sin(-theta) + y * cos(-theta), ) return x, y