diff --git a/examples/graphical_circuit_visualization.ipynb b/examples/graphical_circuit_visualization.ipynb new file mode 100644 index 000000000..ed93f7402 --- /dev/null +++ b/examples/graphical_circuit_visualization.ipynb @@ -0,0 +1,796 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "87c9bc28", + "metadata": {}, + "source": [ + "# Graphical circuit visualization\n", + "\n", + "This notebook demonstrates the matplotlib-based circuit renderer exposed through `Circuit.show()`. Alongside the existing Unicode text diagram (`print(circuit)`), you can now render any `Circuit` as a matplotlib `Figure`.\n", + "\n", + "Highlights:\n", + "- Gates render as labelled rounded boxes\n", + "- Controls render as filled dots, anti-controls as open dots\n", + "- Multi-qubit gates draw a vertical connection line between their qubits\n", + "- SWAP renders as an `x` on each qubit, joined by a vertical line\n", + "- Barriers render as dashed vertical lines\n", + "- Global phase, additional result types, and unassigned parameters appear in a footer\n", + "\n", + "Requires `matplotlib` (installed as part of the SDK)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "888680f1", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from braket.circuits import Circuit, FreeParameter, Observable\n", + "from braket.circuits.graphical_diagram_builders import MatplotlibCircuitDiagram" + ] + }, + { + "cell_type": "markdown", + "id": "b91842d3", + "metadata": {}, + "source": [ + "## 1. Bell state\n", + "\n", + "The canonical two-qubit entangling circuit. `show()` returns a matplotlib `Figure` by default, so Jupyter will display it inline." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "75bb0c98", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │\n", + " ┌───┐ \n", + "q0 : ─┤ H ├───●───\n", + " └───┘ │ \n", + " ┌─┴─┐ \n", + "q1 : ───────┤ X ├─\n", + " └───┘ \n", + "T : │ 0 │ 1 │\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAggAAAEMCAYAAAChhU7oAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAEy9JREFUeJzt3QuQVfWd4PFfQ9NPmIZYkqJBQZGAYnDDCKWlUROjcWPFRBKmVMhm1CxZg4YxO1k2Wdc1WbPsrNmwRqEKhqSmLOJoIib4QrJEcZjEDIy4JuGRGNQIQgJRQR7dtHT31jlTUsDfTPHoe0/3vZ9PVdfte7rh/vvcfnzv/3/OvTXd3d3dAQBwiH6HXgEAEAgAwLsygwAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAACJ2nQT0Jfs3Lkz5s+fH+vXr48hQ4bE9ddfHxMnTix6WPSQNWvWxCOPPBIvvfRSjBkzJu644w77lrIwgwB93MKFC6OxsTEWLVoU06ZNi7lz5+bRQGVoamqKK6+8Mn+DchII0Ie1tbXF2rVrY8qUKdHQ0BDnnXdetLa25o86qQzjx4/P79eWlpaih0KVEQjQh23bti26u7tj+PDhceedd+bLDCNGjIgtW7YUPTSgjxMI0Ift378/6urqoqurKzZv3hy7du3Kp6Tb29uLHhrQxzlIEfqw+vr66OjoiNra2liwYEG+7bnnnovm5uaihwb0cWYQoA8bNmxY1NTUHLakkM0kZMsMACdCIEAflp29kJ3S+PDDD+fLDatXr46tW7fGpEmTih4aPSRbPspmiTo7O/PjTbL3Dxw4YP9ScjXd2Xcc0GdlpzTOmzcvNmzY4HkQKtDKlSvz57k41MUXXxwzZ84sbExUB4EAACQsMQAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkKhNNwE9YePGjbFp06bo6OiomB1aU1MTLS0tMWnSpBg4cGDRwwFKSCBAD3v00Udj9uzZsWHDhordt42NjXH11VfHggULhAJUqJru7u7uogcBleKJJ56IT3ziE9HY1Bz/9pOfirPPmRj19Q1RKbq6u+L1HdvjJ8sei+fX/DwuvPDCWLFiRdTX1xc9NKCHCQToQZMnT45169bH3z/xVIx+37iK3bfZ44qvz/6r+MHiv4ulS5fGVVddVfSQgB7mIEXoIVu2bIk1a9bEh664sqLj4J1jET53y5fy93/4wx8WPRygBAQC9JBXX301vxw/4d9UxT4dfsrIaBk8OF555ZWihwKUgECAHvL222/nlwMG1FXNPh1QV3/w6wYqi0AAABICAQBICAQAICEQAICEQAAAEgIBAEgIBAAgIRAAgIRAAAASAgEASAgEACAhEACARG26CYDeYv/+/fHyyy/H3r17Y9CgQXH66adHba1f3ZSeGYReaOPGjfGhD30ompqaYuTIkfHtb3+76CEBZZa9jPZXvvKVGDZsWJx55plx7rnnxtixY+PUU0+Nb3zjG/GHP/zBfUJJCYReZt++ffHRj340Dhw4EEuXLo0vfOELceutt8b3vve9oocGlMl9990XZ5xxRtx1113x5ptvHvaxbdu2xe233x6nnXZaLFu2zH1CyQiEXub++++P1157LR544IG47LLLYvbs2XHttdfGnDlzih4avcxrm38XZ7e2xK9eWHvY9mzbjx/7UWHj4sQsXrw4PvvZz0ZnZ2f+9m66urrypYePf/zjsWLFCruckhAIZTZ//vw45ZRTorm5OW688caYMWNGjBo16uDHf/KTn8TEiRNj+PDhB7dlvwTWrVuXP3I43iWLTZs29cj4gdL5/e9/HzfccMNRfW4WCd3d3TF16tRoa2tzt9DjBEIZZaU/c+bMmDJlSixZsiR2796dP1o41IsvvphPLWb27NmT/wJ453r2seORrV9eeumlPfAVAKW0aNGiPzlr8KciYefOnfHggw+WdFxUJ4FQRnfffXdMnjw5v7ziiivy4wqyo5IPtWvXrmhpaYnf/e53MXTo0Ljlllvy65nsFwFQmbIwmDdvXv5H/1j069fPgcyUhHNlyuiFF16Ia6655uD1AQMGxEUXXRRr1qxJPjf7WBYPQ4YMOeHbzWYhTlR7e3t+VDV/WhZ1RfjLqz8WNf2Ka/1sejtbxuLE/PGPf8yXGI5VFhTZ75YNGzZETU2Nu6FAo0aNioaGhoq5DwRCGW3fvj35g3/k9Wy24K233orW1taDpzGtXfsvB6G9M5NQhCwOpk+fXtjt9wXZklER/mbeohgz7syD1z92wcSy3XYWn7/+9a99b/SA7KDD45VFwrRp0/LZBIqzePHiGDduXMXcBQKhjE4++eTklKUjr48ZMyZ++9vfHrbtnevZx4os4yOPl+Bwq1evzo8+L7f3trbGqaeNLuTuyB6xZufm+944cdkS4vnnn39c/zabcczOgKJYow454LwSCIQymjBhQjzzzDMHr2fPdbBq1arDpqSygwkfeuih2Lp1az6LkHn00UfjrLPOOnj9WGXTv9kvkNGjj/+PSDbGSirjUqjWJ65pbGz0vdFDszHnnHNO/PKXvzym4xCyZ1XMjmny80lPMx9VRrNmzcofZWaXy5cvz6dlj5yWvu666/IQyI5VyM56yJ4oJXtkkD2j2vFyFgP0ftlszBe/+MVjPkgxe6Bx8803l2xcVC+BUEaXX3553HPPPfkpjtmpjtlTKWfrhofKtmXx0L9///z5D7LP/9a3vmWNF6pA9sAgO3sp+/k/2tmD7AHARz7ykZKPjepjiaHMstI/tPbfrfyzqcKnn366x26zJ85ioPcZfsrI+NXWXcn2d9tG35A9QHjyySfjgx/8YH7m0L/2nAhZHGQHOT/++OMOTqQkzCAA9CIf+MAH4tlnn81flClz5GzCO6/kOH78+PwU6ew1GaAUBAJAL/P+978/P3spezGm7DVZ3nHSSSfFpz71qfzg5ueffz5/tVcoFUsMBbv33nvzN4BDZc9pkJ2dkC03DBw48OCTcWWv4wLlYAYBAEgIBAAgIRAAgIRAAAASAgEASAgEACAhEACAhEAAABICAQBICAQAICEQAICEQAAAEgIBelh3d3f17NNq+lqhyggE6CENDQ35Zdu+vVUTQvv27YumpqaihwKUgECAHjJ27NgYMGBArP7ZqqrYp+t+8Xzs27snzj777KKHApSAQIAeMnjw4Ljsssvi2X94OpYtXVLR+3XP7rfirjv+S/7+1KlTix4OUAI13VW1YAql9Zvf/CYuueSS2LZtW5w+ZmxM+MC5MaC+rmJ2e3dXV7y+Y0f8fNXKaGvbF7NmzYq5c+dGTU1N0UOrWHv37o2BAwfm7+/Zsyeam5uLHhJVQiBAD9u0aVN885vfjCVLlsSOHTsqcv9eeOGFMX369JgxY4Y4KDGBQFEEApRINjmXPeLr6OiomH2czRRkj2br6ipnVqS3EwgUpbawW4YKl/0xHTRoUNHDADguDlIEABICAQBICAQAICEQAICEQAAAEgIBAEgIBAAgIRAAgIRAAAASAgEASAgEACAhEACAhEAAABJezRHgOLS3t8fPfvaz2L59e3R1dZVsH+7fv//g+9///vejvr4+Sql///7R2toa559/ftTW+hNRzWq6sxetB+CodHZ2xpe//OVYtGhR7N69u2L32kknnRS33nprfPWrX81fupzqIw8BjsHnP//5+M53vhPvO+vs+NwnPx0jRo6K/hX0SPvA22/Hy799MR5d8kDcdttt0dHREV/72teKHhYFMIMAcJReffXVGDlyZJx7/oWx8P6Ho67E0/1F2v3WrvjMJz4ar736SuzYsSOam5uLHhJl5iBFgKO0dOnS/HL65/5DRcdBZtCftcRffOaGaGtri+XLlxc9HAogEACOYQYhM/ass6tin40df/ZhXzfVRSAAHKUDBw7klwMG1FXFPqurqz/s66a6CAQAICEQAICEQAAAEgIBAEgIBAAgIRAAgIRAAAASAgEASAgEACAhEACAhEAAABICAQBICAQAICEQepmOjo6YPXt2XHDBBdHQ0BADBw4sekgAVCGB0Mvs27cvFi5cGIMHD45JkyYVPRwAqpRA6GVaWlri9ddfj8cffzwuvfTSoocDFOTVlzfFn5/+3li2dMlh2//dJ6+IW/7yWvcLJScQymz+/PlxyimnRHNzc9x4440xY8aMGDVq1MGP19TURL9+PXu3bNy4MTZt2tSj/ydQWqeeNjr+/S3/Mb759f8a+/btzbc98tAD8ZsN6+K2Of/b7qfkBEIZrVixImbOnBlTpkyJJUuWxO7du2Px4sUlv90zzzzTbAT0QTfO/KtoHjgwFvyfu2LP7rfiW3feHl+67Wvx3mGtRQ+NKlBb9ACqyd133x2TJ0/OLzPZEsKIESOKHhbQSw2oq4vb/2ZuzLj26nzJYdTpZ8TU6dcXPSyqhEAooxdeeCGuueaag9cHDBgQF110UaxZs6akt9vd3X3C/0d7e3u88sorPTIe6KveeOONst/mueddEJdcdkX8+LGl8aOnf54vQ5bb9u3b86VK/nXZcnF29lmlEAhl/iEbMmTIYduOvN5bZXEwffr0oocBhdq8eXPZb3PnG2/EPz/70xg46M9i5Y+XxRljzyz7GO6///546qmnyn67fc3ixYtj3LhxUSkEQhmdfPLJ8eabbx627cjrvbmMy3G8BPRmc+bMifvuu6+st/k//9t/jpGnnxEz//or+dkLH7v609E64tSyjuG6666LG264oay32ReNOuSA80ogEMpowoQJ8cwzzxy8fuDAgVi1alXJp6SyqcFsOWP06NHH/X9kY6ykMobj8Z73vKesO+6nK1fEk488HA/9eFU+c3D+xR+OObfNjnv+7u/LOo6hQ4f6+a9CzmIoo1mzZsXq1avzy+XLl+dT9tmZDEdatmxZPPTQQ7F+/fro7OzM38/eduzYcVy36ywG6HuyUxu/PvvW+Oznbz64rPDXt//3+MeVK2Ll/32y6OFRBQRCGV1++eVxzz335Kc4Zqc6NjU1xbRp05LPu+mmm2Lq1Knxgx/8ID84MHs/e1u3bl05hwsU6N7/9Y38gMSbbp19cNupo06Pz3zupphz25ejva3N/UNJCYQyu/nmm2PLli2xd+/e+O53vxt1dXXvekBgdubBkW+XXHLJcd1m9m+dgQB9y3+643/Ekz//RTQ0Nh62/Uu3fT2W/9Mvk+3Q0wQCAJAQCABAQiAU7N577zX9D0CvIxAAgIRAAAASAgEASAgEACAhEACAhEAAABICAQBICAQAICEQAICEQAAAEgIBAEgIBAAgIRAAjlF3d3dV7LNq+Tp5dwIB4Cg1Njbml/v27a2KfbZ3z+78sqmpqeihUACBAHCUzjnnnPxy9T/+Q1Xss3/66b98nRMmTCh6KBSgptscEsBR2bNnTwwdOjQGtQyOv33gRzH6feMqds/9v39eHTdN/3QMGtgcmzdvjn79PJ6sNgIB4Bg8+OCDMW3atOjs7Ixz/nxSjBh5WtTW1lbMPjzw9tvx0ou/jg2/+kW+pPLYY4/Fhz/84aKHRQEEAsAxeuqpp2LBggXxxBNP5LMKlWbIkCFx1VVXxcyZM2PSpElFD4eCCASAE9De3h5dXV0Vsw/79+8f9fX1RQ+DXkAgAAAJR50AAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAACJ2nQT0Jfs3Lkz5s+fH+vXr48hQ4bE9ddfHxMnTix6WPSQNWvWxCOPPBIvvfRSjBkzJu644w77lrIwgwB93MKFC6OxsTEWLVoU06ZNi7lz5+bRQGVoamqKK6+8Mn+DchII0Ie1tbXF2rVrY8qUKdHQ0BDnnXdetLa25o86qQzjx4/P79eWlpaih0KVEQjQh23bti26u7tj+PDhceedd+bLDCNGjIgtW7YUPTSgjxMI0Ift378/6urqoqurKzZv3hy7du3Kp6Tb29uLHhrQxzlIEfqw+vr66OjoiNra2liwYEG+7bnnnovm5uaihwb0cWYQoA8bNmxY1NTUHLakkM0kZMsMACdCIEAflp29kJ3S+PDDD+fLDatXr46tW7fGpEmTih4aPSRbPspmiTo7O/PjTbL3Dxw4YP9ScjXd2Xcc0GdlpzTOmzcvNmzY4HkQKtDKlSvz57k41MUXXxwzZ84sbExUB4EAACQsMQAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQEIgAAAJgQAAJAQCAJAQCABAQiAAAAmBAAAkBAIAkBAIAEBCIAAACYEAACQEAgCQEAgAQBzp/wMUuEUHM/P3GwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "bell = Circuit().h(0).cnot(0, 1)\n", + "print(bell)\n", + "bell.show()" + ] + }, + { + "cell_type": "markdown", + "id": "ac50b6f3", + "metadata": {}, + "source": [ + "## 2. Controls and anti-controls\n", + "\n", + "A controlled-Z with a positive control on qubit 0 and an anti-control on qubit 2 (open dot). Any gate can be wrapped with `.control` and `.control_state`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b7dceea9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │\n", + " \n", + "q0 : ───●───\n", + " │ \n", + " ┌─┴─┐ \n", + "q1 : ─┤ X ├─\n", + " └─┬─┘ \n", + " │ \n", + "q2 : ───◯───\n", + " \n", + "T : │ 0 │\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "controlled = Circuit().x(1, control=[0, 2], control_state=[1, 0])\n", + "print(controlled)\n", + "controlled.show()" + ] + }, + { + "cell_type": "markdown", + "id": "29408722", + "metadata": {}, + "source": [ + "## 3. Parallel gates in the same moment\n", + "\n", + "Independent gates that act on disjoint qubit ranges appear in the same column without their connection lines bridging." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1c63ba06", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │\n", + " \n", + "q0 : ───●───\n", + " │ \n", + " ┌─┴─┐ \n", + "q1 : ─┤ X ├─\n", + " └───┘ \n", + " \n", + "q2 : ───●───\n", + " │ \n", + " ┌─┴─┐ \n", + "q3 : ─┤ X ├─\n", + " └───┘ \n", + " ┌───┐ \n", + "q4 : ─┤ H ├─\n", + " └───┘ \n", + "T : │ 0 │\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "parallel = Circuit().cnot(0, 1).cnot(2, 3).h(4)\n", + "print(parallel)\n", + "parallel.show()" + ] + }, + { + "cell_type": "markdown", + "id": "f4f9d7fb", + "metadata": {}, + "source": [ + "## 4. GHZ state with a SWAP\n", + "\n", + "A three-qubit GHZ state followed by a SWAP to show the `x` markers joined by a connection line." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a15774e1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ 2 │ 3 │\n", + " ┌───┐ \n", + "q0 : ─┤ H ├───●────────────x─────\n", + " └───┘ │ │ \n", + " ┌─┴─┐ │ \n", + "q1 : ───────┤ X ├───●──────┼─────\n", + " └───┘ │ │ \n", + " ┌─┴─┐ │ \n", + "q2 : ─────────────┤ X ├────x─────\n", + " └───┘ \n", + "T : │ 0 │ 1 │ 2 │ 3 │\n" + ] + }, + { + "data": { + "image/png": "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fPLJ8eUvfzk6d+5cWo0A1BanvjYgzzzzTOy1117Rvn374uzllVdeWXZJQAW7/fbb49Of/nRcddVV7wkfyezZs+NrX/ta9OvXrwgqQHV46KGH1utysL4JIBtQ94n9998/li9fXhxUfOUrX4mvfvWrcdNNN5VdGhuQl16cE5/u1jn+7xMz13g+PXfvz39aWl2sf/fcc08MGTIkli5dWuw33k9zc3Px8+KLL8Yee+wRL7/8so8CNnBjxoyJAQMGxMUXX/w3l0uvp+XS8pCbALKB+NGPfhQvvfRS3HzzzbHffvvFGWecEV/84hfjwgsvLLs0oAJPWAwbNqy4nwLGB0kBZd68eTFq1KgM1QEtJbVonHfeecX9M88886+GkPR8ej1Jy2sJITcBpEKMHz8+tthii+jQoUMcf/zxMXLkyOjZs+eq1//nf/4ndtxxx+jevfuq5w455JB48skn45VXXlnnLl0vvPDCeqkfqBw//vGP45133okVK1Z86PekEPKzn/2saA0BNky77757XHTRRasev18IWT18JGn59D7ISQCpAPfff3+MHj266C4xadKkePfdd2PixIlrLPP888/HNttsU9xPfbnTWc2Vj9Nr62K77baLffbZZz38D4BKksaHrcvsVuk91157bYvUBOSRekj8tRDyfuEjLQ+5mQWrAlxxxRWxyy67FLdJCgU9evRYY5l0NjPNUjNnzpwiOKRZa0499dTitbfffruUutlwHTv4oKgz/WpVSmM+Hn/88XV6b1NTUzz44IPrvSYgr5WhYmXYSLeXXHJJvPnmm6uWET4okwBSAZ544okYPnz4qsdt2rQpBoROnz79Pcum1zp16hRdunT52Ov9MH3DP4zFixcXs+nw4b3fjEQ5XXz1DbFt3+1WPT5otx2z1/D6668X3QBZv956662P9f7XXnvN5wJV4POf/3yxn73sssuKx6uHj9NOO6143T648vXs2TMaGxuj2gggFSDtINYOFGs/Tq0ff/7zn6Nbt27FAUIyc+ZfZjIqe/7+FD5GjBhRag0bmmLK0/UUANfFpt26xZZb944ypQkVpk6dWmoN1eijjPt4P3PnzvX3DFWkdevWRevm6o8feOCB4ofKN3HixOjbt29UGwGkAnTt2vU9Zy3Xfrztttu+Z57+lY/Ta2Wn87XHrPC3pWmUH3r44ZreTKnV74QTTii7jKqU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qHwTJ06Mvn37RrURQCpA165d46233lrjubUfJ0uXLi3GibRv3z5uvvnmYidSKen8g8asANS6Y489Np559rns63146v1x9+Rb45Z7HyxaPvoP3DsuPOuMGHfjf5WyDb70pS9lX2+tuv7662PGjBlrPJfCyMCBA+PEE08srS4+vNUnJKomAkgF2GGHHdY4E7F8+fJ48MEH39PkdsIJJxTjPh555JH4xCc+8bHXm5peU3ev3r17f6x/J9VZjekcYH1KJ48i89CLhQsXxPlnfDWO+eeTVnW7Ov2cC+Lze/5jTL3v7mJcSE6bbbaZ74tM0mxXq3e/+ru/+7t48803i/vp+U022cQAdEpjFqwKcMoppxTX9Ei36cKCqTtTmglrdWPHji1aGc4+++x46aWXihCy8mddmQULoLpddcl/FAPOR331f2c62rJnrzjqhFFx4Vn/FosXLSq1PlrG+021m7pwrz1F7wddrBBaSl3z+hqJzMdy1VVXFTuG1PVq2LBhUV9fH/fee++qwd177rnnX+2vua4fYfpS2mqrrQwgB8hg7733jpmPPx4PP1l7k3ZM+9WD8eXD/ymuvvrq+MpXvlJ2OTUXPlafaveDXocctIBUiHSl0rlz58aCBQtiwoQJ0dDQsMbrU6dOLYLG+/2sq/Res1cBQPVcCf2DwsXa1wlJy6f3QU4CCABAFUgzZJ577rkf2LKxeghJy7sSOrkZhA4AUCXGjBkT++677weGihRCdtttN+GDUmgBqeAxIbpHAQAf1Ydt0dDyQVkEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAyaN26dTQtb6rJbb182bJV2wBAAAGADDbZZJOY/+6f440/zau57f3inD+s2gYAAggAZHDQQQcVtz+f9OOa2t4rVqyIO279STQ0NMTee+9ddjlABagvuwAAqAWHHHJIbLrppnH5f5xbHJT/05Ajouumm0W1am5ujqdmPR4Trr4iZk77dRx99NHRuXPnsssCKkBdc9pDAAAt7plnnom99torXn311eJx28bGaN26Os8FLl2yOJYvX76q9WfSpEnR2NhYdllABRBAACCjBQsWxB133BF33XVXvP7669HUVJ0D09u2bRvbbLNNfOELX4hdd901WrXS6xv4CwEEAADIxukIAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbOrzrQqoBG+//XaMHz8+nnrqqejSpUscd9xxseOOO5ZdFhlMnz49Jk+eHL///e9j2223jTFjxtjuNWD58uVx7bXXxqxZs2LRokXRrVu3GDFiRGy//fZll0YG3/rWt+LZZ5+NJUuWRNeuXWP48OGx00472faUSgCBGnPddddFu3bt4oYbbojHH388Lr/88hg3blxstNFGZZdGC2vfvn0cfPDBRQB57rnnbO8asWLFiuLA84ILLohPfvKT8eijj8Yll1wSV155ZXTu3Lns8mhhgwcPjh49ekRDQ0Pxt3/eeecVoST9LkBZdMGCGpLOfs6cOTOGDBkSjY2NseuuuxZnQ9OZcapfOuOdPnMHnbUlHXgeccQRRQipq6srfgfq6+tjzpw5ZZdGBr169Sp+B5qbm4vWsPTzyiuv2PaUSgsI1JD0pZO+hLp37x5jx44tgkg6MzZ37tyySwMy7gcWLlxY7AeoDanFe8qUKbFs2bLo3bt39OnTp+ySqHECCNSQ1Ac4nQlLXTJefPHFeOedd4puOYsXLy67NCCDdAB69dVXF91yNt54Y9u8RpxwwgnFeL/f/va3MW/evOJ7AMqkCxbUkLZt28bSpUuL7hdpUGr//v2LblmpOxZQ3dKJhzTuY7PNNouhQ4eWXQ6ZtW7dOvr16xczZsyIRx55xPanVAII1JDNN9+86AO+eper1BKSumEB1St1vbzmmmuKEDJq1KhiP0Dtmj17dtklUOMEEKghafarNOXurbfeWnTHmjZtWrz88sux8847l10aGaSDz9QC1tTUVByQpvtpQCq1MQYgTcF96qmnFmfCqQ2vvfZaTJ06tRjzk/7+04QjqRtW3759yy6NGlfXnL6FgJqRDkJSH/Cnn37adUBqTDoQSdeAWd3AgQNj9OjRpdVEy0t9/tNn3KZNm2jV6n/PO44cOTIGDBjgI6jyzz7t71NLdzrhkKbePfDAA2PQoEFll0aNE0AAAIBsdMECAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAACKX/wdJg4IliewnyAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ghz = Circuit().h(0).cnot(0, 1).cnot(1, 2).swap(0, 2)\n", + "print(ghz)\n", + "ghz.show()" + ] + }, + { + "cell_type": "markdown", + "id": "4c007897", + "metadata": {}, + "source": [ + "## 5. Barriers\n", + "\n", + "Barriers render as dashed vertical lines spanning the qubits they target. A barrier with no explicit target spans all qubits in the circuit." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4edff45a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ 2 │ 3 │\n", + " ┌───┐ \n", + "q0 : ─┤ H ├───▒──────●─────────\n", + " └───┘ │ \n", + " ┌───┐ ┌─┴─┐ \n", + "q1 : ─┤ H ├────────┤ X ├───●───\n", + " └───┘ └───┘ │ \n", + " ┌───┐ ┌─┴─┐ \n", + "q2 : ─┤ H ├───▒──────────┤ X ├─\n", + " └───┘ └───┘ \n", + "T : │ 0 │ 1 │ 2 │ 3 │\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "barriered = Circuit().h(0).h(1).h(2).barrier([0, 2]).cnot(0, 1).cnot(1, 2)\n", + "print(barriered)\n", + "barriered.show()" + ] + }, + { + "cell_type": "markdown", + "id": "md-barrier-all", + "metadata": {}, + "source": [ + "### Barrier spanning every qubit\n", + "\n", + "Calling `.barrier()` without a target argument adds a barrier that applies to every qubit in the circuit. The dashed vertical line spans the full height of the diagram." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "code-barrier-all", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ 2 │ 3 │\n", + " ┌───┐ \n", + "q0 : ─┤ H ├───▒──────●─────────\n", + " └───┘ │ │ \n", + " ┌───┐ │ ┌─┴─┐ \n", + "q1 : ─┤ H ├───▒────┤ X ├───●───\n", + " └───┘ │ └───┘ │ \n", + " ┌───┐ │ ┌─┴─┐ \n", + "q2 : ─┤ H ├───▒──────────┤ X ├─\n", + " └───┘ └───┘ \n", + "T : │ 0 │ 1 │ 2 │ 3 │\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# A barrier with no explicit target spans every qubit in the circuit.\n", + "barrier_all = Circuit().h(0).h(1).h(2).barrier().cnot(0, 1).cnot(1, 2)\n", + "print(barrier_all)\n", + "barrier_all.show()" + ] + }, + { + "cell_type": "markdown", + "id": "md-verbatim", + "metadata": {}, + "source": [ + "## 6. Verbatim boxes\n", + "\n", + "A verbatim box marks a subcircuit that the compiler must execute exactly as written, without optimization or rewriting. In the diagram, `StartVerbatim` and `EndVerbatim` render as labelled columns that bracket the protected region, connected by a vertical line across every qubit." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "code-verbatim", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │\n", + " ┌───┐ ┌───┐ ┌───┐ \n", + "q0 : ─┤ X ├───StartVerbatim───┤ H ├───●──────────────────EndVerbatim───┤ H ├─\n", + " └───┘ ║ └───┘ │ ║ └───┘ \n", + " ║ ┌─┴─┐ ┌──────────┐ ║ \n", + "q1 : ───────────────╨───────────────┤ X ├─┤ Rz(0.50) ├────────╨──────────────\n", + " └───┘ └──────────┘ \n", + "T : │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "inner = Circuit().h(0).cnot(0, 1).rz(1, 0.5)\n", + "verbatim = Circuit().x(0).add_verbatim_box(inner).h(0)\n", + "print(verbatim)\n", + "verbatim.show()" + ] + }, + { + "cell_type": "markdown", + "id": "3f1753d7", + "metadata": {}, + "source": [ + "## 7. Result types, global phase, and unassigned parameters\n", + "\n", + "Targeted result types get their own columns on the right. Additional (circuit-wide) result types, global phase, and unassigned free parameters appear in the footer below the wires." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "0f9a1f2d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ Result Types │\n", + "GP : │ 0.50 │0.50 │ 0.50 │ 0.50 │\n", + " ┌───────────┐ ┌────────────────┐ ┌─────────────┐ \n", + "q0 : ─┤ Rx(theta) ├───●───┤ Expectation(Z) ├─┤ Probability ├─\n", + " └───────────┘ │ └────────────────┘ └──────┬──────┘ \n", + " ┌─────────┐ ┌─┴─┐ ┌──────┴──────┐ \n", + "q1 : ──┤ Ry(phi) ├──┤ X ├────────────────────┤ Probability ├─\n", + " └─────────┘ └───┘ └─────────────┘ \n", + "T : │ 0 │ 1 │ Result Types │\n", + "\n", + "Global phase: 0.5\n", + "\n", + "Unassigned parameters: [phi, theta].\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "theta = FreeParameter(\"theta\")\n", + "phi = FreeParameter(\"phi\")\n", + "\n", + "annotated = (\n", + " Circuit()\n", + " .gphase(0.5)\n", + " .rx(0, theta)\n", + " .ry(1, phi)\n", + " .cnot(0, 1)\n", + " .expectation(Observable.Z(), target=0)\n", + " .probability()\n", + ")\n", + "print(annotated)\n", + "annotated.show()" + ] + }, + { + "cell_type": "markdown", + "id": "1f1b7be9", + "metadata": {}, + "source": [ + "## 8. Saving the figure\n", + "\n", + "`MatplotlibCircuitDiagram.build_diagram(circuit)` returns the `Figure` directly, which is handy for saving to disk or embedding in reports." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "b172559d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saved ghz_circuit.png\n" + ] + } + ], + "source": [ + "fig = MatplotlibCircuitDiagram.build_diagram(ghz)\n", + "fig.savefig(\"ghz_circuit_graphic_diagram.png\", dpi=150, bbox_inches=\"tight\")\n", + "plt.close(fig)\n", + "print(\"Saved ghz_circuit.png\")" + ] + }, + { + "cell_type": "markdown", + "id": "2bc8f4a1", + "metadata": {}, + "source": [ + "## 9. Customizing the renderer\n", + "\n", + "`Circuit.show(circuit_diagram_class=...)` accepts any class that implements `build_diagram(circuit)`. You can subclass `MatplotlibCircuitDiagram` and override the class-level style constants to change colors, sizes, and fonts without rewriting the layout logic." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "6531098a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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fPLJ8eUvfzk6d+5cWo0A1BanvjYgzzzzTOy1117Rvn374uzllVdeWXZJQAW7/fbb49Of/nRcddVV7wkfyezZs+NrX/ta9OvXrwgqQHV46KGH1utysL4JIBtQ94n9998/li9fXhxUfOUrX4mvfvWrcdNNN5VdGhuQl16cE5/u1jn+7xMz13g+PXfvz39aWl2sf/fcc08MGTIkli5dWuw33k9zc3Px8+KLL8Yee+wRL7/8so8CNnBjxoyJAQMGxMUXX/w3l0uvp+XS8pCbALKB+NGPfhQvvfRS3HzzzbHffvvFGWecEV/84hfjwgsvLLs0oAJPWAwbNqy4nwLGB0kBZd68eTFq1KgM1QEtJbVonHfeecX9M88886+GkPR8ej1Jy2sJITcBpEKMHz8+tthii+jQoUMcf/zxMXLkyOjZs+eq1//nf/4ndtxxx+jevfuq5w455JB48skn45VXXlnnLl0vvPDCeqkfqBw//vGP45133okVK1Z86PekEPKzn/2saA0BNky77757XHTRRasev18IWT18JGn59D7ISQCpAPfff3+MHj266C4xadKkePfdd2PixIlrLPP888/HNttsU9xPfbnTWc2Vj9Nr62K77baLffbZZz38D4BKksaHrcvsVuk91157bYvUBOSRekj8tRDyfuEjLQ+5mQWrAlxxxRWxyy67FLdJCgU9evRYY5l0NjPNUjNnzpwiOKRZa0499dTitbfffruUutlwHTv4oKgz/WpVSmM+Hn/88XV6b1NTUzz44IPrvSYgr5WhYmXYSLeXXHJJvPnmm6uWET4okwBSAZ544okYPnz4qsdt2rQpBoROnz79Pcum1zp16hRdunT52Ov9MH3DP4zFixcXs+nw4b3fjEQ5XXz1DbFt3+1WPT5otx2z1/D6668X3QBZv956662P9f7XXnvN5wJV4POf/3yxn73sssuKx6uHj9NOO6143T648vXs2TMaGxuj2gggFSDtINYOFGs/Tq0ff/7zn6Nbt27FAUIyc+ZfZjIqe/7+FD5GjBhRag0bmmLK0/UUANfFpt26xZZb944ypQkVpk6dWmoN1eijjPt4P3PnzvX3DFWkdevWRevm6o8feOCB4ofKN3HixOjbt29UGwGkAnTt2vU9Zy3Xfrztttu+Z57+lY/Ta2Wn87XHrPC3pWmUH3r44ZreTKnV74QTTii7jKqU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qHwTJ06Mvn37RrURQCpA165d46233lrjubUfJ0uXLi3GibRv3z5uvvnmYidSKen8g8asANS6Y489Np559rns63146v1x9+Rb45Z7HyxaPvoP3DsuPOuMGHfjf5WyDb70pS9lX2+tuv7662PGjBlrPJfCyMCBA+PEE08srS4+vNUnJKomAkgF2GGHHdY4E7F8+fJ48MEH39PkdsIJJxTjPh555JH4xCc+8bHXm5peU3ev3r17f6x/J9VZjekcYH1KJ48i89CLhQsXxPlnfDWO+eeTVnW7Ov2cC+Lze/5jTL3v7mJcSE6bbbaZ74tM0mxXq3e/+ru/+7t48803i/vp+U022cQAdEpjFqwKcMoppxTX9Ei36cKCqTtTmglrdWPHji1aGc4+++x46aWXihCy8mddmQULoLpddcl/FAPOR331f2c62rJnrzjqhFFx4Vn/FosXLSq1PlrG+021m7pwrz1F7wddrBBaSl3z+hqJzMdy1VVXFTuG1PVq2LBhUV9fH/fee++qwd177rnnX+2vua4fYfpS2mqrrQwgB8hg7733jpmPPx4PP1l7k3ZM+9WD8eXD/ymuvvrq+MpXvlJ2OTUXPlafaveDXocctIBUiHSl0rlz58aCBQtiwoQJ0dDQsMbrU6dOLYLG+/2sq/Res1cBQPVcCf2DwsXa1wlJy6f3QU4CCABAFUgzZJ577rkf2LKxeghJy7sSOrkZhA4AUCXGjBkT++677weGihRCdtttN+GDUmgBqeAxIbpHAQAf1Ydt0dDyQVkEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAyaN26dTQtb6rJbb182bJV2wBAAAGADDbZZJOY/+6f440/zau57f3inD+s2gYAAggAZHDQQQcVtz+f9OOa2t4rVqyIO279STQ0NMTee+9ddjlABagvuwAAqAWHHHJIbLrppnH5f5xbHJT/05Ajouumm0W1am5ujqdmPR4Trr4iZk77dRx99NHRuXPnsssCKkBdc9pDAAAt7plnnom99torXn311eJx28bGaN26Os8FLl2yOJYvX76q9WfSpEnR2NhYdllABRBAACCjBQsWxB133BF33XVXvP7669HUVJ0D09u2bRvbbLNNfOELX4hdd901WrXS6xv4CwEEAADIxukIAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbOrzrQqoBG+//XaMHz8+nnrqqejSpUscd9xxseOOO5ZdFhlMnz49Jk+eHL///e9j2223jTFjxtjuNWD58uVx7bXXxqxZs2LRokXRrVu3GDFiRGy//fZll0YG3/rWt+LZZ5+NJUuWRNeuXWP48OGx00472faUSgCBGnPddddFu3bt4oYbbojHH388Lr/88hg3blxstNFGZZdGC2vfvn0cfPDBRQB57rnnbO8asWLFiuLA84ILLohPfvKT8eijj8Yll1wSV155ZXTu3Lns8mhhgwcPjh49ekRDQ0Pxt3/eeecVoST9LkBZdMGCGpLOfs6cOTOGDBkSjY2NseuuuxZnQ9OZcapfOuOdPnMHnbUlHXgeccQRRQipq6srfgfq6+tjzpw5ZZdGBr169Sp+B5qbm4vWsPTzyiuv2PaUSgsI1JD0pZO+hLp37x5jx44tgkg6MzZ37tyySwMy7gcWLlxY7AeoDanFe8qUKbFs2bLo3bt39OnTp+ySqHECCNSQ1Ac4nQlLXTJefPHFeOedd4puOYsXLy67NCCDdAB69dVXF91yNt54Y9u8RpxwwgnFeL/f/va3MW/evOJ7AMqkCxbUkLZt28bSpUuL7hdpUGr//v2LblmpOxZQ3dKJhzTuY7PNNouhQ4eWXQ6ZtW7dOvr16xczZsyIRx55xPanVAII1JDNN9+86AO+eper1BKSumEB1St1vbzmmmuKEDJq1KhiP0Dtmj17dtklUOMEEKghafarNOXurbfeWnTHmjZtWrz88sux8847l10aGaSDz9QC1tTUVByQpvtpQCq1MQYgTcF96qmnFmfCqQ2vvfZaTJ06tRjzk/7+04QjqRtW3759yy6NGlfXnL6FgJqRDkJSH/Cnn37adUBqTDoQSdeAWd3AgQNj9OjRpdVEy0t9/tNn3KZNm2jV6n/PO44cOTIGDBjgI6jyzz7t71NLdzrhkKbePfDAA2PQoEFll0aNE0AAAIBsdMECAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAALIRQAAAgGwEEAAAIBsBBAAAyEYAAQAAshFAAACAbAQQAAAgGwEEAADIRgABAACyEUAAAIBsBBAAACAbAQQAAMhGAAEAACKX/wdJg4IliewnyAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "class DarkCircuitDiagram(MatplotlibCircuitDiagram):\n", + " GATE_FILL_COLOR = \"#1F2A44\"\n", + " GATE_EDGE_COLOR = \"#8AB4F8\"\n", + " GATE_TEXT_COLOR = \"#F8F9FA\"\n", + " WIRE_COLOR = \"#AAAAAA\"\n", + " CONNECTION_COLOR = \"#8AB4F8\"\n", + " CONTROL_DOT_COLOR = \"#8AB4F8\"\n", + "\n", + "\n", + "ghz.show(circuit_diagram_class=DarkCircuitDiagram)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a68f2cb3-0226-4aba-b8ec-5a3f81b8a407", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ 2 │ 3 │\n", + " ┌───┐ \n", + "q0 : ─┤ H ├───●────────────x─────\n", + " └───┘ │ │ \n", + " ┌─┴─┐ │ \n", + "q1 : ───────┤ X ├───●──────┼─────\n", + " └───┘ │ │ \n", + " ┌─┴─┐ │ \n", + "q2 : ─────────────┤ X ├────x─────\n", + " └───┘ \n", + "T : │ 0 │ 1 │ 2 │ 3 │\n" + ] + } + ], + "source": [ + "print(ghz)" + ] + }, + { + "cell_type": "markdown", + "id": "75376943", + "metadata": {}, + "source": [ + "## 10. A longer circuit: 5-qubit QFT\n", + "\n", + "A larger example showing how the renderer scales across many moments. This is a standard Quantum Fourier Transform on 5 qubits: Hadamards interleaved with controlled phase rotations, followed by bit-reversal swaps." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "2b8469fc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ 2 │ ╏\n", + " ┌───┐ ┌─────────────┐ ┌─────────────┐ ╏\n", + "q0 : ─┤ H ├─┤ PHASE(1.57) ├─┤ PHASE(0.79) ├─────── ╏\n", + " └───┘ └──────┬──────┘ └──────┬──────┘ ╏\n", + " │ │ ┌───┐ ╏\n", + "q1 : ──────────────●───────────────┼────────┤ H ├─ ╏\n", + " │ └───┘ ╏\n", + " │ ╏\n", + "q2 : ──────────────────────────────●────────────── ╏\n", + " ╏\n", + " ╏\n", + "q3 : ───────────────────────────────────────────── ╏\n", + " ╏\n", + " ╏\n", + "q4 : ───────────────────────────────────────────── ╏\n", + " ╏\n", + "T : │ 0 │ 1 │ 2 │ ╏\n", + " ╏ \n", + "╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸┻╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸┓\n", + " ╏\n", + "T : │ 3 │ 4 │ ╏\n", + " ┌─────────────┐ ┌─────────────┐ ╏\n", + "q0 : ─┤ PHASE(0.39) ├─────────────────┤ PHASE(0.20) ├─────────────────────── ╏\n", + " └──────┬──────┘ └──────┬──────┘ ╏\n", + " │ ┌─────────────┐ │ ┌─────────────┐ ╏\n", + "q1 : ────────┼────────┤ PHASE(1.57) ├────────┼────────┤ PHASE(0.79) ├─────── ╏\n", + " │ └──────┬──────┘ │ └──────┬──────┘ ╏\n", + " │ │ │ │ ┌───┐ ╏\n", + "q2 : ────────┼───────────────●───────────────┼───────────────┼────────┤ H ├─ ╏\n", + " │ │ │ └───┘ ╏\n", + " │ │ │ ╏\n", + "q3 : ────────●───────────────────────────────┼───────────────●────────────── ╏\n", + " │ ╏\n", + " │ ╏\n", + "q4 : ────────────────────────────────────────●────────────────────────────── ╏\n", + " ╏\n", + "T : │ 3 │ 4 │ ╏\n", + " ╏\n", + "╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸┫\n", + " ╏\n", + "T : │ 5 │ 6 │ 7 │ ╏\n", + " ╏\n", + "q0 : ─────────────────────────────────────────────────────────────────────── ╏\n", + " ╏\n", + " ┌─────────────┐ ╏\n", + "q1 : ─┤ PHASE(0.39) ├─────────────────────────────────────────────────────── ╏\n", + " └──────┬──────┘ ╏\n", + " │ ┌─────────────┐ ┌─────────────┐ ╏\n", + "q2 : ────────┼────────┤ PHASE(1.57) ├─┤ PHASE(0.79) ├─────────────────────── ╏\n", + " │ └──────┬──────┘ └──────┬──────┘ ╏\n", + " │ │ │ ┌───┐ ┌─────────────┐ ╏\n", + "q3 : ────────┼───────────────●───────────────┼────────┤ H ├─┤ PHASE(1.57) ├─ ╏\n", + " │ │ └───┘ └──────┬──────┘ ╏\n", + " │ │ │ ╏\n", + "q4 : ────────●───────────────────────────────●─────────────────────●──────── ╏\n", + " ╏\n", + "T : │ 5 │ 6 │ 7 │ ╏\n", + " ╏\n", + "╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸┳╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸╸┛\n", + " ┃ \n", + "T : │ 8 │ 9 │ ┃\n", + " ┃\n", + "q0 : ─────────────x───── ┃\n", + " │ ┃\n", + " │ ┃\n", + "q1 : ────x────────┼───── ┃\n", + " │ │ ┃\n", + " │ │ ┃\n", + "q2 : ────┼────────┼───── ┃\n", + " │ │ ┃\n", + " │ │ ┃\n", + "q3 : ────x────────┼───── ┃\n", + " │ ┃\n", + " ┌───┐ │ ┃\n", + "q4 : ──┤ H ├──────x───── ┃\n", + " └───┘ ┃\n", + "T : │ 8 │ 9 │ ┃\n", + " ┃\n", + "━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAC1QAAAIVCAYAAABs0V9lAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAmBpJREFUeJzs3QeYFOX9B/AfHY6iiAKCKFZAERUQG1UFCzZQrBh712iMEY3GbuwYazSWqBFjAURFhYAidlFUrIiCYEORKr3/nxn/d3Jiodyxu7efz/PMc7szs7vvvTf37uzsd35TbunSpUsDAAAAAAAAAAAAACAPlc90AwAAAAAAAAAAAAAAMkWgGgAAAAAAAAAAAADIWwLVAAAAAAAAAAAAAEDeEqgGAAAAAAAAAAAAAPKWQDUAAAAAAAAAAAAAkLcEqgEAAAAAAAAAAACAvCVQDQAAAAAAAAAAAADkLYFqAAAAAAAAAAAAACBvCVQDAAAAAAAAAAAAAHlLoBoAAAAAAAAAAAAAyFsC1QAAAAAAAAAAAABA3hKoBgAAAAAAAAAAAADylkA1AAAAAAAAAAAAAJC3BKoBAAAAAAAAAAAAgLwlUA0AAAAAAAAAAAAA5C2BagAAAAAAAAAAAAAgbwlUAwAAAAAAAAAAAAB5S6AaAAAAAAAAAAAAAMhbAtUAAAAAAAAAAAAAQN4SqAYAAAAAAAAAAAAA8pZANQAAAAAAAAAAAACQtwSqAQAAAAAAAAAAAIC8JVANAAAAAAAAAAAAAOQtgWoAAAAAAAAAAAAAIG8JVAMAAAAAAAAAAAAAeUugGgAAAAAAAAAAAADIWwLVAAAAAAAAAAAAAEDeEqgGAAAAAAAAAAAAAPKWQDUAAAAAAAAAAAAAkLcEqgEAAAAAAAAAAACAvCVQDQAAAAAAAAAAAADkLYFqAAAAAAAAAAAAACBvCVQDAAAAAAAAAAAAAHlLoBoAAAAAAAAAAAAAyFsC1QAAAAAAAAAAAABA3hKoBgAAAAAAAAAAAADylkA1AAAAAAAAAAAAAJC3BKoBAAAAAAAAAAAAgLwlUA0AAAAAAAAAAAAA5C2BagAAAAAAAAAAAAAgbwlUAwAAAAAAAAAAAAB5S6AaAAAAAAAAAAAAAMhbFTPdACA3TZ8+PW6//fb46KOPonbt2nHMMcdEy5YtM90syqg333wznnzyyRg3blxsvvnmcckll2S6ScAasGjRorjzzjvj/fffj7lz50aDBg2iZ8+esdVWW+l/IK/ccMMN8cknn8T8+fNjvfXWi0MPPTRat26d6WYBwAqbMWNGnHXWWdGsWbM499xz9RwAJSo5XjxmzJioUKFCej/53NS7d2+9DFACx+gffPDBePnll2PBggWx0UYbxeWXX65fIYtMnjw5/vSnPxWbl/y/7rHHHnHsscdmrF2UXRMmTIh77rkn/Vm9evXYd999Y6+99sp0s8giY8eOjXvvvTe+/PLLqFWrVvqdVtu2bTPdLFhhAtXAKvnXv/4V1apVi7vvvjvefffduPHGG+OWW26JtddeW49S4goKCqJr165poDo5MA7khyVLlqRfgCUHaNddd91444034tprr42bb7451lprrUw3D2CN6datW2ywwQZRuXLldH/o0ksvTUPWydgIALngvvvuS0+QBIDScsQRR6THkAEoOf/5z39i9OjRccUVV0S9evXS8ByQXZJjxMn/6rJh6pNOOil23nnnjLaLsivJBW299dbpSY1fffVVXHDBBbHpppvGFltskemmkSUnY11//fWxzz77pEH7UaNGpd/vb7LJJo4NkjPKZ7oBQO5JqoS+/fbb0b1796hatWrsuOOO6RtfUkUYSkNSjTbZzgQoIb8kwcGDDz44DVWXK1cuHQcqVqzooC2Qd5IDTcmYuHTp0vRgVDJNnDgx080CgBWSnIifXGVhm2220WMAAJAjklDm888/n16luH79+ukx+saNG2e6WcDveP3119OKsE2bNtVXlIrvv/8+dtpppyhfvnxsuOGG0ahRo7QSMSS++eabmD59ehqmTraR7bbbLt1/SMYmyBUqVAMrLQlvJGGOhg0bpmckJ8HqpGJecvYZAJTm+8+cOXPS9x+AfJNcGWbYsGGxcOHCtNpDkyZNMt0kAPhdSZD6/vvvj/POOy+GDx+uxwAoNf3794++ffvG+uuvH4cddlhaNQ+A1Tsen4SqP/vss/RKxcnJ/rvvvnvsv//+uhWy2HPPPRedOnXKdDMow/bdd980HJsUgvn666/TgHXz5s0z3SxyIGgNuUKgGlilL8OSD81LlixJzzSbMWNGFBQUxLx58/QmAKUiCRDedttt0a1bt6hTp45eBvLO8ccfn1YEeu+999IDlMn+OABku8ceeyy90kxyeXAAKC09e/ZMi74kFdBefPHF9JLSyWWmvf8ArLqkuElizJgxcdNNN8WUKVPioosuSquRJtUmgeyThFuT/9mzzjor002hDNt2223jn//8ZzzzzDPp1QuOPfZY+90UadCgQay99toxaNCg6NKlS/qd1oQJE2LdddfVS+SM8pluAJB7qlSpkp6RXLFixbjzzjvTy3nMnTs3qlatmummAVAGJSfw3HzzzellBXv06JHp5gBkTIUKFdIvrEaOHOnyaABkvS+++CLeeOONOOCAAzLdFADKuM022yz9fqKwemoS9nv33Xcz3SyAnP8+OLli8T777JOOscmVI1u1ahXvv/9+ppsG/EZ16m222SZq166tjyi1k22Sq9h37do1HnroobjhhhtiwIAB8dZbb+lxUkmO7JxzzonXXnstTjzxxBg8eHC0adMmLdIJuUKgGlhpySXzkjPNvvrqq6J5SaXqpAIEAJSk5IBtcpZzEqo+5ZRT0vcfACLGjx+vGwDIauPGjYvvvvsujjzyyDj44IOjb9++6RdsJ5xwQqabBkAZl1SqdgwJYPUkVf6NpZBbV3odPnx47LrrrpluCmXYN998k17RPtnOkn3upBrx1ltvHaNGjcp008gim266aVx++eVx7733xvnnnx/ffvttbLLJJpluFqwwgWpgpVWrVi1atmwZ/fv3T3eWRowYke44bb/99nqTUpEEKZOq6IsXL07DlcntRYsW6W3IA3fffXdMnz49vTxZUpkVIN8kQbQXXnghrfyQ7BO9+eab6SXSmjZtmummAcBv6tixYzz66KNF00EHHRStW7eOu+66S88BUGJmz54db7/9dtHx4xdffDE9ATWpzgjAqqtevXq0aNEiBg4cmI6xSRgqGW+T4ByQfZLMRhJwTXIcUFqSAHWlSpXS7yyS7yu+//77+OCDD6JRo0Y6nSJff/11miVLpqSC+eTJk2OXXXbRQ+SMckuTZBrASkrCbbfddlt8/PHH6SVjjjnmGDvnlJpkh/z2228vNq9Dhw5x2mmn6XUow5IP4cn/efLBPDkIVCi5PFC7du0y2jaANTkWJvvdyRVhki+v1l133dhrr72iS5cu/ggA5JQkVJ0E3M4999xMNwWAMuSHH36IK6+8MiZOnJhWUk2upHnYYYdF8+bNM900gJw3ZcqUuOOOO2L06NFRo0aN9JjUfvvtl+lmAb/gsssui8aNG8cf/vAH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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import math\n", + "\n", + "\n", + "def qft(num_qubits: int) -> Circuit:\n", + " circuit = Circuit()\n", + " for target in range(num_qubits):\n", + " circuit.h(target)\n", + " for control in range(target + 1, num_qubits):\n", + " angle = math.pi / (2 ** (control - target))\n", + " circuit.cphaseshift(control, target, angle)\n", + " for i in range(num_qubits // 2):\n", + " circuit.swap(i, num_qubits - 1 - i)\n", + " return circuit\n", + "\n", + "\n", + "qft5 = qft(5)\n", + "print(qft5)\n", + "qft5.show()" + ] + }, + { + "cell_type": "markdown", + "id": "19f33437", + "metadata": {}, + "source": [ + "## 11. A longer variational circuit: 4-qubit, 3-layer hardware-efficient ansatz\n", + "\n", + "A parameterized circuit with repeated layers of single-qubit rotations and entangling CNOTs, typical of VQE/QAOA workloads. Barriers between layers make the repeating structure easy to see, and the footer lists every unassigned free parameter." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "8d2b9ffc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Parameters: 24\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAACqQAAAHLCAYAAACkz2v+AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAA2wJJREFUeJzs3Qd0lEXXwPELBAIkJCFBWuhNegelFwEFpYiAdJWmiCKiggVRFEURC1JUwIaogICIdJEiKE2qNJHeS0IIhJBQv3PHL3mJJJvN9vL/nbMn7dndyfPM7s6duTOT6ebNmzcFAAAAAAAAAAAAAAAAAAAAsFFmW+8IAAAAAAAAAAAAAAAAAAAAKBJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABgFxJSAQAAAAAAAAAAAAAAAAAAYBcSUgEAAAAAAAAAAAAAAAAAAGAXElIBAAAAAAAAAAAAAAAAAABglwD77g7A150/f14mTpwou3btkty5c8tjjz0m1atXd3ex4EM2btwo8+bNkwMHDkjp0qXl9ddfd3eR4KGuXbsmn332mfz1119y+fJlKViwoHTv3l0qVKjg7qLByd5//335+++/JTExUe644w7p3Lmz1KxZk/PuJ2JjY2XQoEFSrlw5GTJkiLuLAxfQtsDevXslS5Ys5md93X/wwQece6TaNpg2bZqsWbNGrly5IkWLFpU333yTMwWHiYqKkmeffTbF77Su3XvvvdKrVy/ONFI4fPiwfP755+ZrUFCQtG7dWlq2bMlZ8gP79++XL774Qo4ePSohISEmXqlfv767iwUX9l/9+uuv8sMPP0h8fLyJVZ944gnJli0b18CHr/uNGzfk448/NnGLthdee+01+qeQZn3ZvHmzzJo1S44fPy7Zs2eX2rVrS48ePXifgMPek7Zs2WJiY30/0s+fqlWrmrG8nDlzcpb9mDVjb99//738+OOPMnr0aClWrJhbygnXXPedO3fKiBEjJDAwMPnYfv36SYMGDbgEPv5637Nnj3z99ddy7Ngx87nwyCOPSN26dd1aXjj/2k+aNElWr16dfJzGL9qXPnnyZNNvAbgCCakALNIPqxw5csiUKVNk69at8uGHH8q4ceMkLCyMMweH0Mbv/fffbxpK2okLpEUby5qUpIkmefLkkfXr15uOEh0ACA0N5cT5sAcffFAKFSpkOlT1vUI7TjRJVesBfN9XX31lEtDhX7p162baB4Al33zzjelUHTlypOTLl88kgQGOpG0NrWe3JqM+/vjjdNwjVdpXUqlSJdP5rwM9r7zyipQsWVLKlCnDGfNhOqAzZswYeeCBB0wC8rZt20ycWqJECdqwftJ/pT9/+eWXMmzYMClSpIi88847Mn36dOnZs6dbywvn91vqgG+rVq3krbfe4nTDYn1JSEiQTp06Sfny5U178r333pOZM2eaifaAI96T9PPnpZdekoiICLl69aoZ19MEVU02g/9Kb+xNJ1Npnwr857rr37SvHf5z3XWiwttvv23aHI0bNzbx64ULF9xaVrjm2msb4NZ2wNy5c82CTySjwpUyu/TZAHgVXYFQZ++2b9/ezNy9++67TWe6zrQAHEVXt9S6RUIh0qPJiNp5q0mpmTJlMvUmICCA5BM/oIO5ev1v3rxpAma9nTx50t3FggvoZBhdGbdKlSqcbwAp6EDu8uXLzaov+fPnN20DVvOAs61bt8503JYtW5aTjducPXtW6tSpI5kzZzZJAYULFzaDvPBtJ06cMLsLaTKqXvtq1aqZzyN9v4B/9F/98ccfZiU6/WzQwcA2bdqY1dvh29ddX+868KuTDrQdCliqL7oKmb5PaN9WcHCwaS/oTkCAo96TNBFVJ9Pp+9H169fNwg46QQr+zdLYm/az6yp5ulIifAtjrv4preu+cuVKM4mqRYsWph2i8Yr2o8K/XvP6nq+7ejRp0sSlZQNYIRVAmjTZRz+gIiMjzapDmpiqK9QRyALwlPco3Q5P36Pg+3Sl7hUrVphZ/rrS1J133unuIsHJNBFVt5J58cUXZdWqVZxvPzNnzhyzpWGBAgWkS5cuZsU54L/tAE1K3bdvn9nFQTtVmzVrJm3btuVEwWnovIUlrVu3NkmIOplKt+TVBNWKFSty0vw4URX+QV/vmoS8du1as5NL586dTZJyXFycSTwDgP/S1at08grgSLoK3nPPPWcWmsmSJYsMGDCAE4w0/fLLL2ZcRWMX+A9dsVt3fdGJNTVr1jQ7VOmCVPBdhw4dMhMWdNfBI0eOmLilb9++JKX6mZ07d5r4tHbt2u4uCvwMCakALCaC6MCuzqbUVT1iY2PNzBltsAKAO2lS4oQJE8xW7joDHL6vT58+ZhW87du3m8F9/XyCb/vhhx/MzE7dhhv+RbcQ0klQ2jn622+/mW1vdStc6gJupZNSkgZzx44dK9HR0TJ8+HAzsKur0wHOSDjS+jZo0CBOLlKlK5998sknsnDhQrM6Va9evfjs8gO6k1BYWJgsXrzYrDqj8crhw4fNoB/8p/80R44cJhFIPyu071Rp/ykJqQD+S3ef06SAd999l5MDh9K2h07sjomJMbuJ6ArOQGq0jvz0008yatQoTpAf0QTkDz74wCQinjlzRsaNGydTp05NsaU3fLP/dNu2bfLSSy+Zz4Vvv/1WPv74Y3n77bfdXTS40LJly6RevXqMq8LlMrv+KQF4i8DAQLPqkG6J/dlnn5mtZHR2JbOlALiTJslrwKSBc8eOHbkYfkRn92uS0aZNm9gC08fpbF1dXahdu3buLgrcoFSpUqa9mbTipSYYbt26lWuB22IV3c3hgQceMPVFO9Zr1Kghf/31F2cKTlsdtUqVKpI7d27OMFId5NGdZXT75u+++07ef/99mTt3rvz555+cLR+nfWbPP/+8WR1TB3OXLFliVh1JSkqEf7RJNPlUV0l+7733TN+pov8UwH/9/fffZgegoUOHmskMgDNovKJxC0nPSIsmLmu7JSQkhJPkR/RzRyfT6QIASWNrGzZscHex4GTav162bFkpX768iV1btWpldptKilng+y5cuGBe602bNnV3UeCHSEgFkCbdIlVX9Th27Fjy73SlVF2xCgDcQRNPdNUhTUrt37+/eY+C/241At914MABOX36tPTo0UM6depktm7XhA7dTgb+RztKeb/Hf+mKudQLuHJ1/lWrVtF5C4vbs+sqidrBr59bOtBXqVIlsxIJfF/JkiXlzTfflC+++MKsPHPq1Cm2P/UjOilGJ9Td2neqA/6sjgrgVgcPHjQr0+lq+2yRDVfQcb1r165xsnGbf/75x7Rbtc9Vb2rIkCGydOlSzpYfob/Vf3I94N+0P1NjVtqfcAcSUgGkSbebql69usyZM8cMrOjsCR1kqVWrFmcNDqOJhboS7/Xr102yoX5PRwnSoqsInD9/3nTe6mqZ8H2alLhy5Uqz6pS+X+jWZroNps7qhO9q3LixzJw5M/nWoUMHqVmzpkyePNndRYOTXbp0STZv3pzcNvjtt99MArqu7gHcKigoSCpXrizz58839UWTf7TuaAIY4GgaC+tgjcbHQGo0ATVr1qym3apt1rNnz8qOHTukcOHCnDA/oNu0a7+Z3nRlXN26XbfDg3/0X9WtW9ckn+vKhxq3/vzzz1K/fn13Fxcu6LfUCSv6s9Lf6fd6DPxXWvVFk9bfeecdM7m+XLly7i4mfLCOrVixwtQz/XtsbKzpS9PdZ3Q1PPivtOrLhAkTUvS7qtGjR0uLFi3cXWQ48brrjkJnzpwxv4uOjjYLQDDe7/vX/e6775adO3fKnj17zN8WL15sPh80BwT+kWexfPlyadKkiVvLCP+V6SYRMgALNPFLg5Pdu3ebrT4ee+wxBuHgUDpgN3HixBS/a9SokQwYMIAzjRR0UFfrhQ70akJAEt0WsUGDBpwtH77u+jmkq8xoIJUnTx5p2bIlHWR+RjtHNSlRZ+vD97eQeeutt+TkyZNm9Utdmb9Lly5SsWJFdxcNHkg70D/99FPTqaqrkOnnQ5s2bdxdLPigN954Q4oVKyY9e/Z0d1HgwXSA79tvvzWfYbpVt8YoXbt2TRG7wDfp5AidzK3JabrqiPad6XsG/Kf/6tdffzUxiyak6kS6J554QgIDA91WVrjmuutN+yxuNX78eMmbNy+XwE+lVV80ttXVqXTb3CR33HGHWTEVcEQd05XPNOEkJibG1DNNfNbYhfcj/2bt2JuukqoJqbRfffu6FylSRObNm2e2atdJ3pqoqH2uGrvCt1/vmoSqEyf12uvuHjqmmj9/freVFa679prfo7u5fPbZZ5IrVy5OPVyOhFQAAAAAAAAAAAAAAAAAAADYhSn6AAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALALCakAAAAAAAAAAAAAAAAAAACwCwmpAAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALALCakAAAAAAAAAAAAAAAAAAACwCwmpAAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALALCakAAAAAAAAAAAAAAAAAAACwCwmpAAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALALCakAAAAAAAAAAAAAAAAAAACwCwmpAAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALALCakAAAAAAAAAAAAAAAAAAACwCwmpAAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALALCakAAAAAAAAAAAAAAAAAAACwCwmpAAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALALCakAAAAAAAAAAAAAAAAAAACwCwmpAAAAAAAAAAAAAAAAAAAAsAsJqQAAAAAAAAAAAAAAAAAAALBLgH13B3xTbGysXLhwwd3FgIfKlCmThIaGSq5cuWx+jMuXL8u5c+fkxo0bDi0bfEfOnDkld+7ckjkzc0cAAMD/XLlyxbQjr169ymlBqrJlyyYRERESEGBbl4/GKFrHNGYBUpMlSxYJDw+X7Nmzc4IAAECymzdvmrGVixcvclaQ5thKWFiYBAcH23yG4uPjJSYmhrEVpCkoKMiMrWh9AwAAgHuQkAr8v8TERBk9erTMmDFDdu7cyXlBuqpVqyZdunSRZ5991urB3unTp8uUKVNkxYoVdJggXZGRkfLQQw/Jiy++KAUKFOCMAQDgx1avXi1jx46VhQsXkiiIdOkEujZt2shzzz0nVapUseqMHTt2TN555x2ZPXu2nDp1irOMdJNS77nnHunXr5+JWQAAgP/SBEFtR86cOVP+/vtvdxcHXqBWrVrSrVs3efrpp61ekOHrr7+WL774wsTGmvwMWFKkSBHp0KGDvPTSS5InTx5OFgAAgItlukmrHTDJqDqAsmDBAskdHiF1G99jvrIyIdJaMSj67Bn5feWvciH2vElKnTp1arpJqWPGjJEXXnhBsmbLJnUaNpFCRYrZvGoRfJt+NF+Kuygb/1gtRw8fkjJlysjKlStJSgUAwE8tWrRI2rVrZ1ZFrVbrbrmzfEXTpgRSk5BwWXZs3Sy7tm81ianLli2TmjVrWjxZR48elcaNG8uBAwekaImSUvPuepIzKJgVZZCqa9euydFDB2Td6pXmfWn8+PEyYMAAzhYAAH6ajPrAAw+YBRgi7sgrdRs1lbDc4bQjkebYytnTJ2XNil9N/3fv3r1l0qRJ6Y7Fvf766zJixAgJzJ5d6jZsKgUKFWZsBWmOrcRdvCDr1/wmJ44dkcqVK8uvv/5KUioAAICLkZAKiMiECRPkqaeekradusqIMeMIZGGVK4mJ8sKTveTXRfPlu+++M4mpadm3b5+ULl1aSt1ZTqbMnCd57sjLWYZVnSfffv6ZvDN8qPTs2dPMAgcAAP5Fk710pfRrN27IlOk/SblK1q12Caz9bYU89WhnKV2qlPz1118WT0inTp3khx9+kNdGfyQduj1KAgGscvrkCendsbUcOrDPJDUXKlSIMwcAgJ/RlVF1BcLOj/SRl0aONquoA+m5HB8vg/p0N4t+zJs3T1q3bp3msVu3bjW71ZWvVEUmfT9XwsLDOcGwamxlyvgPZOyoN8zkOZ1EBwAAANexbh8EwMfpwJvOrHzlrfdIRoXVsgUGyqujPjCzd7UOpVfH1HOvvkkyKqyWKVMm6d7nCdPZ9tNPP5nVnAEAgH/RlYaio6OlZ98BJKMiQ3RXhtYPPSw7duyQ3bt3W1zVSncLqV67jnTs/hjJqLBavgIF5ZmXhpvvZ8+ezZkDAMAPab93rpBQGTpiFMmosFqOnDnl1Xc+SK5D6dUxNfSNd0hGRYbGVvo8NViKlShlYpXr169z9gAAAFyIhFRARP7880+pVvMusyUhkBF58uYzW6Zu3Lgx3TqmAfDd9RtxgpFhdRo1ldjYWNm/fz9nDwAAP6PtSKVbXwIZlVRvNm3alOYxmqyqSanUMdgiqd6kFxMDAADfowlemzdvllp16kvWbNncXRx4mUJFiknREiWTY9606N9z5Mgp1Wrd7bKywTfomJzGK6dOnZITJ064uzgAAAB+JcDdBQA8waVLlyRXaKi7iwEvFRIWJiePHUm3jmmnCR1zsEVoaJj5GhcXxwkEAHitCxcumKQ3Z8iZM6eEhISIL0r6/NdVh4CMCrGiHamxCnUMtgoKzmVWQyNWAQB4O2fFK74cq1y+fNl8ZWwFttI4Nzb6rMVjtJ0ZlCuX2akOcEZMDACAp2NsBd6IhFTglplygC0yiZV1hzoGW1F3AAA+0GEyefJkuXbtmlMePyAgQPr27euzA72KeAXOrjfUMdiKugMA8HbOjFf8Ilaxtn8csDFeob0JmzG2AgDwcs4eW9GJ5v369fPpeAXuQUIqAAAAAMCpdKWhpA6TyMhIKVu2rMUBpaioKNm2bZtERERI5cqVLa6EcvLkSdm5c6d5DjpNAAAAANgar4SFhUn16tUtxh+xsbFmm/rg4GCpVq2aSThNy5kzZ2T79u3EKgAAAADsilU0/qhZs6bF+EN3wtq0aZM5pkaNGhIYGJjmsYmJibJx40ZJSEggXoFTkJAKAAAAAHAJTUatU6eOxWRUTTDVQdsCBQqYYy0NBp87d0727NnjpNICAAAA8CeajKqT4izFH1u2bDGJqw0aNJCsWbOmeezFixeJVQAAAAA4hCaj3nHHHRbjD41VNAm1cePGkj179jSP1STU9evXy40bN7g6cJq0R/YAAAAAAHCg9FZG1WTUP/74Q/Lnz29VMuqqVavMzGAAAAAAsJc18UdoaKhVyagrV660uHoRAAAAAFjLUmyRFH9ojGJNMqoee/XqVbOKKuAsJKQCAAAAAFzC0cmoOhis22QCAAAAgLPYkoyqxzDACwAAAMCZbE1G1WODgoK4OHAaElIBAAAAAG5lazKqDgaz6hAAAAAAT0tG1QFe3S4TAAAAADwtGTVXrlxcFDgVCakAAAAAAK9MRrU0GAwAAAAA7kpGtTQYDAAAAAD2IBkVno6EVAAAAACAW5CMCgAAAMATkYwKAAAAwBORjApvQEIqAAAAAMDlSEYFAAAA4IlIRgUAAADgiUhGhbcgIRUAAAAA4FIkowIAAADwRCSjAgAAAPBEJKPCmwS4uwAAAAAAAP9BMioAAAAATxQbGytbtmyR0NBQadCggWTNmtUhg8EAAAAAYI9Lly6ZWMWa+CMhIcHEKlevXjXH5sqVi5MPlyMhFQAAAADgElFRUbJ9+3bJnz+/1KlTRzJnzuyQlYkAAAAAwF6bN2+WsLAwklEBAAAAeJRNmzZJYGCgQ5NRr1275qTSAiJpj/4BAAAAAOBA27Ztc3gyqs4MBgAAAAB7BQcHOzQZNTExkYsCAAAAwG4BAQEOTUbVY3TFVcBZWCEVAAB4DW1IR0dHm+8jIiLYDg0AvIy+dzsyGVUHg3VmMAAA7nbjxg2JiYmRuLg4k9AUHh4umTJlcnexAAAZUK1aNYclo2ofFrEKAMBTXL582YytaIzC2AoAeJ8aNWo4NBl19erVpg8LcBZWSAUAAB7t5s2b8ttvv8nDDz9sBnYLFSpkbtqQ7ty5s2kw6zEAAM9XuXJlhyajageLzgwGAMBdoqKi5L333pNixYpJnjx5kr+WKlVKPvroI5OkCgDwDpZii4wmo+qxbIEJAHAnHTf59ddf5cEHHzRjK4ULFzZjKyEhIdKjRw9Zt24dYysA4CUCAwMdmowaGxsr1atXd1JpARJSvcaePXukSZMmkjNnTilatKh8/PHH7i4SAABOp4lJ2nBu1KiRzJkzR65fv578N+3Unz17tjRs2NAcw0AvAHg+Ryej6jE6MxgAAHeYOnWqFCxYUF588UU5evRoir8dPHhQBg8ebP4+a9YsLhAAeDFbklF1oJdYBQDgLmfOnJG77rpLmjVrJvPnzzc7OiTRz6jp06ebXYxatmxpPucAAN7J1mRUHXvXsRjAWVgh1QvEx8fLvffeaxJvfvrpJ3nyySfl2WeflW+//dbdRYOHemVQf5n08RjxVTHR0dKwUkk5deK4u4vit6hjcAVtDGtC0u+//25+Tm1ViaTf6TH169c39wEAeB9bk1G1g8XSzGB4JtqSoI7Zh5jYM0yaNEkeeeQR05l/6+DurasR6S0xMVE6deok3333nVvKCQBwTzKqHhsUFMTp9zLEKqCO2YdYxTNER0dL3bp1ZcuWLemOrSxbtkyaNm1q8hEAAP6TjBoeHu7SssL/kJDqBbTD+vjx42amUvPmzWXo0KHSpUsXGTVqlLuLBgepWDA0+dawcil5pnc3OXxgv02P9feuHbLyl0XSvfcTbrk+S37+UVrVqybVi+eVbq2by76/d2fo/jpYM270SJNwWqtUQXmhfy+5eCFlglnuiAhp3aGzTBjztoNL77uoY/9DHfMevXv3lr///jvFqqhp0WP02D59+rikbAAAz0hGtTQYDMfxlbZkYkKCDBv0pLRpVFsqRYbJWy8/n+HHoC3pHNQx6pi3+fPPP+WJJ6x7H0tKTNXk1d27M9ZHAgDw3mRUS4PBcBxfaUcuW/SzPPJgS6lbroi5Pd61vSlPRhCrOAd1jDrmjbp27SqHDh1KNRE1tbGVzZs3y9NPP+2SsgEAHINkVHg6ElI9wMSJE6Vw4cJmtqwm3/Tr10+KFSuW/Pdff/1VqlevLpGRkcm/a926tezcuVNOnjxp03Pu2bNH9u+3LSiHc7z+3seycutemfjNTImNiZH+PTqYzquM+u6Lz6RZy9aSMyhYXE07SIY82Vvad+4hMxevkvwFI+XJHp3kSmKi1Y8x/aspMnXSRBkxZpx8OXu+7N29U94Y+uxtx7Xt1FUW/PiDxMacc/B/4buoY/+ijnkH7SyZM2eOVcmoSfTY2bNny+HDh51aNgCA45CM6j18oS15/cZ1yZotqzz6xNNyZ/mKNj0GbUnnoY5Rx7zJ2LFjJUuWLBm+34QJE5xSHgCA45GM6j18oR25ZcM6aXJvK5kyY55Mm7dMQkLDpG/ndnL+nPXjH8QqzkMdo455E50Et3Tp0gyNreiOD1OnTpUzZ844tWwAAMcgGRXegIRUN9Nl8AcMGCDt27c3STTayTFt2rQUx/zzzz9SqlQp831cXJyZ5Zj0s/7NFuXKlZN77rnHAf8BHCUkNFTy5M0nFatUNwOkRw4ekIP79pq/9enURt58aXCK41cuXWRWEI2/FJf8Ow0uls7/SRo1uy/V55g741tzn83r10r7ZvXMKqatG9SUy/HxMvy5p6R/9w4pjtdkUF056NiRQ1b9D7O/myplK1aWPk8PllJ3lpPX3xsrZ06dkNXLf7H6PMyc9qU83LOX6XzRczF42BuydP7c2zpeypSrIHfkzSe/LPzZ6sf2d5bq2PGjh1PM9E26aZ25lT11TKX2HBPGWL/aM3XMv7a/zJw5480UvY/eFwDg+UhG9S6+EK/kzBkkr40eK+279JDgkFAbzgLxijP5QrxCHfMPUVFRZhcja1YbupUe/+WXX5q+PwCAZyMZ1bv4QqzywmtvmbKXr1xVSpQuI8NGvS/nos7K5g1rrT4PjK04jy/EKtQx//HJJ59IQEBAhu+nSalffPGFU8oEAHAcklHhLUhI9YAVFWrXrm2+3nffffLtt9/etpVLbGys2b5SV3zLmzevWTJff1bnz593U8nhLNoJsnTBT+b7wMB/twBq06mrLJn3Y4pZvfPnzJTm97dJMVt3764dZnv7ClWqpfn4169fk/dHviqDXxkhc5evle59+8tNuWlWHF372wqJjjqbfOyCOTOlxl11pVCR/63Ya8mu7VulWq27k3/OFRJqEkd3bt9i1f11JdX9f+9O8Rg1765rAvXdO7bddnzFqjXkz3W/W/XYsFzH8hcsZGaRJ93eHT9FArNnNx1gt7Knjqlbn+PzmfMkW2CgVK1Zy+rLQx3zHz/++GOGZvAm0fvoyqoAAM9GMqr38uZ4xV7EK67hzfGKvahj3jO5PKPJqEni4+Plt99+c3iZAACOQzKq9/KlWEXLokLCwqw6nnaka/hSrEId8+2xFVviFU1I1fsCADwXyajwJhmfHgOH2rZtm3Tu3Dn556xZs0rDhg1l48aNtx2rf9Nk1dy5c9v9vLrKqqPe8HRbZdjvpYGPyyuDnpTL8ZfMz+06dZOiJUqa75u3aiNvvfy8rFn+i1k59FLcRTOLd8LUGSke48Sxo5IpUya5I19+ix0Tz7w4XGrXa2h+LlL83+fQzpEChQrLormzpXufJ0wdWTh3tvQfPNTq/yHmXJTkDo+QXxbOkzeGDJKZS36TsPAIiYmOsur+52POmYBHH+Pd116STev/kJmLV0nWbNkkJjr6tuPzFSgoO7ZuFk+g5d6zZ0+af7906d/r6ql1TLca1Bm+6uzpUzJ6xMsydMQok1DsqDqmkp4jPv6SvPXKC9Kj75NSr3Ezq/8Hf65jSt9vQ0JCxB/YszWM3tfS6xEA4Hq3TqRzVjKqfk764oS96FTaKO7gC/GKvby5LXnq1Kk020c6+dUT+EK84s91THf08Zc2+K5du0w9s7VvbceOHVKy5P/qHQDA/ZLiCO3D3bJli1XxR0YGg301VvGEPm9fjVXGjnpDKlWrIdVr1/H5duTVa9cstiMvX74s7uaLsYo/1TF14MABc/79gfa72erkyZN+E9cBgLdIiiMSExNl/fr1VsUfeszq1avN4oeNGjWS8PBwi8/hq/GKNylWrJjF+NMbkZDqZpo0898E0//+rAO1Fy5ckIIFC8rp06fN7zZv/rcRn7RSqrvoG1P37t3dWgZf8dywN6Vuo6ay/vdVsvrXX+TVdz5I/luOnDmlxQNtZf6cGabTZNmi+SYJLykoTZKYkCABWbNa3OZaA65bVyC9VduOXc1zaKeJBpOa5Hdv63YZ/l+Cg3OZDhidoWmr8Dx5pEBkIYvH6OMnJLi/MyJplRNLr4V//vnHYYngzqhjt64u+UL/XlKnYRPp1KPXbX+3t44lGTFkkETckVcGDn3Vpv/FH+uYeu211yQoKEj8gT3bWOp9+WwCAM8SFhYmzZs3Nx0gOsDr6GRUNWzYMJ/sNDl+/Lh4Al+KVxzB29qSuk34/PnzU/2bp2wf7kvxir/VMQ11//zzT79pg0dFRdkV33/22Wfyww8/OLRMAADHxCubNm2SwMBAhyaj+nKsYsvuRs7ga7HKFxM+ko1r18h385dZLI8vtCOTkucstSP37t0rOW5ZzdYdfC1W8bc6poYMGSI5cuQQf6AJS7Y6e/as38R1AOCNsYpODnFkMqo+ni/HK95k2rRpUrZsWfElJKS62R133CExMTEpfvffn0uXLi379u1L8bukn/Vv7s7S1heGtytXrpy7iyB58uaVYiVLmdtfmzfJR6NGmFmUSXTbl8e7tpe4ixfMdi+tOzx822y+sPBwuXrlilyOjzcdLanJniOnmbGYmjYdO8vE90fJof37zHPc0/IBCQq23Jl2q9zheSTmXLQJuPWmzp+LlopVq1t1/7Dc4Sb41cfo+/Rz5nc6Y1n/p9wREbcdH3s+RsIj8ognyJkzp8XXQt++fWXzlq3iyXVMffzum2am6yfTZqX6GPbWMTXzmy9k/ZpVMmvpajN7OCP8uY6pESNGSOXKlcUfPPbYY7Jhw4bkhrC19PrWqFHDJF0AADyHdmboqqg6sU47UByZjJrU0T5y5Ejz2L7mww8/lEmTJrm7GD4Rr9jLm9uS2ra6dXeWW+kOLT179hR384V4xV/rmL7Ua9asKePHjxd/oHHKI488YvP933vvPalQIeWKWQAAz4hXAgICHJqMmrRlsq/GKrpCqrYB3M2XYpXpX02WLyaOlS9nL5CChYr4fDtSaZKEpbGVrl27yrETJ8WdfClW8cc6pkaPHu03uxR06tTJ7MqQ0Ul0Wqfq168v48aNc1rZAAC2xyoaWzRt2tShyajbt2/36XjFmxQrVkx8DQmpbqaJRfrmkUTfRPQN4tYOj3vuuUdmzZolJ06cMKukqp9//lnKly+f/HNG6XL7Orhrb+Nby+lrWdqe4LEnB8pDzetL1179pHDR4snbvuhWHt9/NdkEnC+9Ofq2+5Wt+G+i2v5/9kjFKtYl6N1Kg8+aderJj9O/kSXz58p7Ez/P0P3LV64qWzauS/754oVY2bt7pzw+aIhV99cZkyXvLGceQzts1J/r/jBBULmKVW47ft+e3aa8nkADcUuvBU9b1TK1OrZq2RKZ8fXn8t38X9PsELG3ju3+a5u8N2KYTPxmZvIWMxnhz3UsqSHiL++5gwcPNh0nGaWN5+eee85vzhMAeAvdLlzjnuDgYIcmo+pgsM4MTvqczJ8/7a3vvFVEKgM77uat8Yq9vLktqa+NtNpHunOLp/HWeMWf65i+v/tLG7xMmTLy+uuvm12DMjLIq/0GFStWlPbt2/vNdqEA4G3xik5ydlQyqh6ju0P4cqwSFxcnnsabY5U5338jH48eKZOnz5XSZcv7TTsya0CAxXakp61q6c2xir/WMVWiRAm/iVeeffZZ6dXr9lV606Or/D7//PN+c54AwBtjFUcmo65du1aio6N9Ol6Be2V8HX441DPPPGNWVtCvS5YsMcvg/3e7PJ39p4mnuprJsmXLzEoK3333nbz00kt2rQiqia7wTCXLlJXqte+Wzz4ak/w7HazQbV8mjBllAtfipW5fHVdnG2rC3ub1a21+7radusnXkyZItmyBcneDf1egtFb7Lj1kz47tMmXcB7Lv793y+gvPSN78BaVB0+ZWP0an7o/JjKlfyIolC2XHts3ywcjh0uKBdmb26K3i4y/Jrr+2Sv0mzTJURqRex86ePiUvP/O4DHjhZQkJDZWoM6fNLeHyZYfVMZ35O/jxR6RTj8ekeMnSyc8Rf8n6jkvqmP9o166d5MmTx6aVx9u2beuUMgEA7FetWjWHJqPqsUmrDsF1vDVeUfv37jExi7ZBdWUX/f7Iwf1W3594xTW8NV5R1DHfp4mlTz/9dIbvp539AwcOJBkVADxYYGCgw5JRdTDYExM2fZ23xirz58yUt195QUZ+MFHy5S+YZnvXEmIV1/DWWIU65j8efvhhCQkJydB99H2yaNGiZktoAIBnsrQAmi3JqJroWqXK7ZNKAEchIdXNWrRoYZa+nz17tlkhQbf97tatW4pj9HearKqzzFq3bm2O/+CDD0zyKnxXl8f6yfzZ0+XIoQMptn25dvWq3P9gxzTv17H7o7Lop9k2P2/z+9tI1oCscm/rBzO85UfZCpVk9MTPZfb3U6XjvQ3l1InjMmHqDDNz0lqdH+0jPfr2l+HPPSWPtb/fzNJ89Z0PbjtuxeKFZtaxzm6G/XXs4P5/JDYmRt4d/qI0rlom+bZ43hyH1bFz0Wfl6KGD8vVn41M8x5efWL/9B3XMf2gi0scff5zh+40dO9ZiohMAwL10C0xHJqNqR4vODIbreWO8ovp37ygdWjSQXdu3mraufj/8+YFW3594xXW8MV5R1DH/0KdPH7NykKXPtVvpcfp5pZPOAQDex5ZkVB0Mrl4946sgwj9jlVnffi0JCZdlYK+u6bZ300Ks4jreGKtQx/yH5hWMGfO/pHxr6XiMTr4DAHgXW5NR69ata9PiUIC1rOs1hVM99dRT5nbrz/+lndwrVqxw2HNmZEsxON+OE7G3/a55qzay9ci/S2QnOXPqlBnEaNWuQ5qPpTN9dYXSLRvXS7Vad6X4W7uHu5mbJRo4JyYmmA4aW2hni95spbPwBg591dwsmfb5J/KEldu0I/06VqRYiVSPcWQdiyxc1OrnsIQ65j+6dOkiZ8+eNauIa0eINpJTo3/Tz7WPPvrI3AcA4H1sTUbVY1kh1fl8KV5ZuuEvsQfxinP4UrxCHfMPmoi0dOlSadKkiRw8eNBsb5kWTUjRfr2FCxd63JazAADnJaPqYLC2HeFcvhKrfDV7gdiLWMU5fCVWoY75l759+0pUVJS8/PLL5r0hrbyApLGVyZMnS5s2bVxeTgCA+5JRCxQoIDExMVwCOA3TXAAvcCUxUU4eOyrjRr8pjVu0lDx586V5rK5G+tbYTyU25lyGP6x0a5GP3n7drEJZoXI18VQx0dEm4G/1YNqdR3AeW+uYN6GOeQ7d0nL+/Plmi2d16wpESd/r337++WdzLADAv5JRLQ0Gw3WIV1KiLelexCtwlUKFCsmGDRukX79+JtH01qSjpFglODjYTDz/448/JG/evFwcAPCjZFRLg8FwHWKVlIhV3ItYBa700ksvmR1aK1asmObYyt13320m2vXu3ZuLAwB+lowKOBsrpAJeYOHcWWYL+wpVqslbH32a7vE1766X4efYsnGd9OrwgBQvVUbGfPplir9pMmybxilna/7X5OlzpWrN2mn+ff6cmTJiyKA0/67Bz9o9R6wqa+6ICOk1IO3HgvPZUscsoY7Bkvvvv9/cNm3aJF9//bWMG/fvVkT9+/eXRx55hK2aAcCLkYzqG4hXUiJecT/iFbhK7ty5ZeLEifLuu+/K559/Ls8++6z5fdeuXaV+/frma1BQEBcEALwQyai+gVglJWIV9yNWgSu1b99eHnzwQTORburUqSZ2UTpprlevXlKpUiUuCAB4IZJR4Q1ISPVA48ePNzcgI9vB2Kt23QZpbvlxR/4CMvuX1Rbvn69ApMW/N2nRUipXq5H2AWxf5NeoY7BGjRo1zFaXSQmpo0aNYnAXALwYyai+g3gFvo54BenRFfN0W8ykhFQd6CURFQC8F8movoNYBb6OWAXp0Z0c7rrrLrNSalJC6siRI4lXAMBLkYwKb0FCKoD03ygCAqRI8ZJ2namg4FzmBlDHAAAAyahwJOIVOBt1DAAA/0EyKhyJdiScjToGAID/IBkV3oSEVAAAAACAy5CMCgAAAMATJSYmyvr1681Ab+PGjc0K2I4YDAYAAAAAe1y7ds3q+OPGjRuydu1aOXXqlNStW1cKFCjAyYfLkZAKAAAAAHCJS5cuyZYtWyRr1qxmgDd79uwOWZkIAAAAAOy1adMmM3hLMioAAAAAT6LjKjq+4shk1Js3bzqptIBIZk4CAAAAAMBVA7yOTkbVmcEAAAAAYC+NLRyZjKqDwQAAAABgr7i4OIcno+7Zs4cLA6chIRUAAAAA4BIBAQEOTUbVY3RmMAAAAADYq0aNGg5NRt2+fTsXBQAAAIDdqlev7tBk1M2bN8vx48e5MnAaElIBAAAAAC4b4HVkMqoOBuvMYAAAAACwV1BQkMOSUXUwODo6mosCAAAAwG6hoaEOTUY9cOCAlCtXjisDpyEhFQAAAADgEoGBgQ5NRtXBYJ0ZDAAAAADOYksyqg4GV6lShYsCAAAAwGlsTUatWbOmREZGcmXgNAHOe2gAAAAAANJnazKqDgZnypSJUwwAAADAo5JRdTDY0u4QAAAAAOCuZNTixYtLTEwMFwBOwwqpAAAAAACvTEa1NBgMAAAAAO5KRrU0GAwAAAAA7kxGBZyNhFQAAAAAgFuQjAoAAADAE5GMCgAAAMATkYwKb0BCKgAAAADA5UhGBQAAAOCJSEYFAAAA4IlIRoW3CHB3AQAAAAAA/uHChQvma2JiomzatEmuXbsmNWrUMF9jYmJSvY/+bcuWLRIXFyfVq1eXTJkypTg26TEBAAAAwN54Jb3447+Dwdu3b5fo6GipUqWKZM+enVgFAAAAgFNilfTij1vdvHlT9uzZI8ePH5dy5cpJWFjYbccytgJnIiEVAAAAAOBUOXPmlICAANmwYcNtf1u7dq3Vj7Nx48ZUf6+Prc8BAAAAAI6KV9KKP1KzdevWVH9PrAIAAADA0bFKWvFHanbv3m1uqSFegbOQkAqISJYsWeTa1WucC9hEZ81rHbJE/379OnUMttaxq8n1CAAAbxQSEiJ9+/aV+Pj4dI+9fPmy1K9f33y/Zs0ayZEjh1WdMvocvijp8z+pPQA4uh1JHYM9dGWG69evE6sAAPwiXiFWSb0deZVYBTa6dvWqVWMrehxgUx1jbAUA4OUYW4G3IiEVEJF8+fLJoQP7OBewafDt8MH9UqBAgXTrWGJCgpw8fkwKRBbiTCNDDh/Yb77mz5+fMwcA8OqOE2uSRi9duiQnTpww3+fNm1eCgoLEnyV9/h/av09Klinr7uLAyxzan347UmMVcywxMWxw5OABswVYejExAAC+EK8Qq6SkW4TqOTtMOxI2uHr1qhw/ekTKl7Mc52os8/vvv0tMdLTkjojgXCND9P0pU6ZMpn8JAABvxdgKvFFmdxcA8AQPPPCAHPjnb9m++U93FwVe5o9Vy+Xs6VOmDlmS9Pe5M751UcngK86fOycrly6UqlWrSmRkpLuLAwAAXOz+++83X3+a+Z1J+gIyMsD78+zpZpXhpk2bpnlcyZIl5c4775RfF/4sF2LPc4KRIT/OmGa+phcTAwAA36NJXhqv7Ni6Wfb9nfoWoEBaVixZYOIPa8ZWdGGQebO+52QiQ6LOnJbVy38xu/CEhYVx9gAAAFyIFVIBEendu7d89dVXMqBnJ3nmpeHS8J57JXdEHsmcmZxt3E47PzSQXbFkoXz87ptmi9iePXtaPFUtW7aUYsWKycT3R0liYoK0fuhhKVy0uGQJ4G0Yt9Nkk0txF2XD77/JJx+Oltjz5+XJJ5/kVAEA4Ie0DdmqVStZuHCBvPh0P+n6WD8pU66CZAsMdHfR4KESEy7LX1s2yVefjjPJAU888YTFlYY1kUDbms8884z06dRGHh80RGrVrS85g4LN34D/0i1Tjxw6YBLltZ6VKVNG7rnnHk4UAAB+qF+/fjJz5kzp27mdDBz6qjRo2lzCwiNoRyJVN65flzOnT8qvi+bLuHdHmtW+unbtavFstW3bVgoWLCgfjBwul+LipGXbhySycBHGVpDm2ErchQuydvUK+eT9dyTh8mXp378/ZwsAAMDFMt1kiRXAmD9/vnTo0EESExM5I7BacHCwqTuNGjVK99jDhw+blYkOHDjAGUaGjBw5Ul555RXO2v9vjaavOxUXF+f32zgDgC/ivT71c6KrwqxcudINVwTe7OGHH5Zp06ZJQDoT4bRraPjw4abdCWSEJqMuX76c3Rz4/AIAv0CskjpNSO3evbtZoR+wlq5YuXjxYrnrrrvSPXbv3r1mAtSxY8c4wbCaTrD88MMPzeRL8BkGAP6AeAWehIRU4Bbnz5+XefPmye+//y4XLlzg3CD1N85MmSQ0NNQkoWpiQFJynDW0U27FihWyaNEiOXPmjFltFUiNrrxbqVIlkyhfqFAhTtL/oyENAL6P9/q0Ewb//PNPmTt3rhw9epTBXqQpMDBQSpQoIQ899JBUqFAhQ2dKJ9HNmjVLdu3aJfHx8ZxlpCpLliySN29es0WvxsXpJTz7Cz6/AMD38V6ftnPnzplYZd26dXLx4kUXXhV429iKJqLqwh26E4j2gVvrypUrsmzZMlmyZIlERUUxtoI06Q4hVatWNTFxgQIFOFP/j88wAPB9vNfDk5CQCgAAvAYNaQDwfbzXAwC8EZ9fAOD7eK8HAHgrPsMAwPfxXg9PktndBQAAAAAAAAAAAAAAAAAAAIB3IyEVAAAAAAAAAAAAAAAAAAAAdiEhFQAAAAAAAAAAAAAAAAAAAHYhIRUAAAAAAAAAAAAAAAAAAAB2ISEVAAAAAAAAAAAAAAAAAAAAdiEhFQAAAAAAAAAAAAAAAAAAAHYhIRUAAAAAAAAAAAAAAAAAAAB2ISEVAAAAAAAAAAAAAAAAAAAAdiEhFQAAAAAAAAAAAAAAAAAAAHYhIRUAAAAAAAAAAAAAAAAAAAB2ISEVAAAAAAAAAAAAAAAAAAAAdiEhFQAAAAAAAAAAAAAAAAAAAHYhIRUAAAAAAAAAAAAAAAAAAAB2ISEVAAAAAAAAAAAAAAAAAAAAdiEhFQAAAAAAAAAAAAAAAAAAAHYJsO/ugO+4ceOGfP/99zJjxgz5/fff5cKFC+4uEjxUpkyZJCQkRBo1aiRdunSRhx56yPzOGn/88Yd8+eWXsmjRIjl79qypd0BqcuTIIZUrV5aOHTtK7969JTg42ONO1IkTJ2Ty5Mkye/Zs2b9/v1y5csWlzx8WFuaS58mWLZuULFnSvNb79u0rBQsWdMnzAgBwq71798qUKVNk7ty5cuzYMbl69SonCBbbLu3btzdtl8jISKvOVGxsrHz++efyww8/yM6dO+Xy5cucYaQqS5YskjdvXmnVqpX06tVLateu7XFn6ubNm+b98rvvvpOVK1ea+q2/87VYRfsicufOLU2bNpXu3bvL/fff75LnBQDgVtevX5dvvvlGZs6cKWvXrpW4uDhOENJsu2g7Sdsu3bp1k9atW1t9prRN9/XXX8uSJUskOjqasRWkKWfOnFKtWjUztqLxio61eJojR46YsZU5c+bIoUOHfHZsJTAwUMqUKSMdOnSQPn36mDgSAAD4h0w3XdkbC3goTQocMGCAfPrpp2ZgpWLVGpI7PEIyZ2YRYaReX6KjzsiOrZvNgNaLL74ob7/9drpJqdoh17VrV9NBV7JMWYksUlQCsjAvALfTehUfHyfbN/0ply/HS/369WXhwoWSK1cujzldhw8flsaNG5vOEn2/LF+5qgQGZhdflJiYILu2b5WYc9FSrFgx0/lZtGhRdxcLAHzWpUuXkidi6EBmUFCQ+LvNmzdLs2bNJCYmRvIXjJTSZctL1qzZ3F0seHDbZfdf2+RcdJQUKVLEtF2KFy9u8T6arNeiRQvZsGGD5AwKlsrVakiOnEFWT7yDf7l2/ZocPXhADu7/R7JmzWqSmNu2bSueFE8NHz5cRo4caepwhSrVJM8d+Xyyj0f7F86eOWXiFTVq1CjTRwEAcA5ildQ/ix599FGZNm2aBAQESOXqtSQ0LDftSKQ5tqJtl53btpif33zzTRk2bFi6Z0sX+dBFG7SdV7pcBSkYWdiM5QH/pXUkLu6ibN+8URITEqR58+by008/eVRSqk44btKkiVnwI+KOvFK2QiWfHVtJSLgsO7dtltjz5+XOO++UFStWSIECBdxdLADwWcQr8CQkpAIiZvZuz5495e4GjWX0xM8lPCIP5wXpOnPqpDzbt4ds27RRfv75Z3nggQfSPPb48eMmgU2Dywlfz5BylapwhpGuy/Hx8vG7b8o3kyeapPnx48d7zFlr2LChrFmzRl55e4x06Pao6XD2ZdeuXZNZ334lb738vEkQ/u2339xdJADwWXSa3D5gpxMizpw9K+9OmCJN773fJ5Oq4Pi2y4/Tv5E3hj4rd999t9mpwRJdqURXR+09YJD0H/yiZPegwTp4rr+2bJKnHnlYLsSeN4OpefJ4Rl/K4sWLpWXLllKpWg35aMo0yVfA93c4OH70sDz9aBfZu3unrF692sQsAADHI1a53cSJ//ZbNmnRSkZ+OEFCc4dT9ZCuk8eOysBeXWX3ju0mQU0XPkjLP//8YxLZChYqLBOmzpRSd5bjDCNd8Zfi5L0Rr8gP074yE7Z04panqF69umzfvl3eeH+8PPDQwz6fXH31yhX59ovPZMwbw8wuGwsWLHB3kQDAZxGvwJMwigWIyPTp000y1ZhPviQZFVbLm7+ASWBWM2bMsHisbmmus8WHjhhFMiqsliNnThny+ttSvGRpmTVrlqlDnkC3CdZBzhYPtJPOj/Tx+WRUpf+j/q/6P+v/rknmAAC4gm55efToUenep780a9maZFRY3Xbp2P0xadWug6lDuh1gWnRrQI1XdFWWQS+/TjIqrKYJn4NffVOuXr0qc+fO9ag+HqVJ/P6QjKoiCxeVt8d+alX/BAAAjv7c1clM706YTDIqrFagUGEZNW6SVW0XXY1fV70cNuoDklFhNd3549V3PjS7zGgd85QNY3V11C1btkjbTl3NzdeTUVXWbNnk0SeelgZNm8vSpUvl3Llz7i4SAABwARJSARGzyl+VGrUlLJzZu8j4oI9umaoJaunVMdXgnhacYmSIbjHZsNm9cvr0aTMb3BMkrbDVqPl94m/0Wqjff//d3UUBAPiJpHZmo3v+/QwCMqJRs/tSxCOp2bVrl5w/f9607bTtCWRE4/9vH6cXE7uS1vfipcpIkWIlxJ/cWaGSScC19HoHAMDRuzloH1mtOvVN8heQEbrSacFCRdJtR+rfswUGmh0OgYzQ3WV0TO7gwYNmRwdPkFTfk8YZ/EmjZvea3VzWr1/v7qIAAAAX8P0lzQArXLhwQXJHRHCuYBOtO3t3nki3juXIkVNy5gziLCPDwiPyJNcjT5BUjtzh/ve+6WnXAgC8ib53xsfHp3vc5cuXpWDBf1e0O3PmjOSwYuvwnDlzSkhIiPii5M/d//8MAjIiKc611Hb5X9uOOoaMCwnLbQZ6Y2NjPeb0aZ0uUqK0+BtNKNcYzZOuBQD4WrxCrJKSni9NSiVWgT3xyoVzUem+NkNCQiVr1qycaNjVnx8ZGen2M5gUf4f7Yfyd9FnB2AoAZBxjK/BGJKQC/08HUABbZM5kXd3JRB2DjTy17mTO7H8raPnj/wwAjqAdJpMnTzYrIVhj4MCB5uvMmTOt3p68b9++PpuUqohX4Ox6Qx2DrUmQnlh3PDWGcjZPvBYA4GvxCrGK7f3jgK1tF39t28F+mTz0/ckf6zSxCgDYhrEVeCsSUgEAAAAATl85Rwd3a9eunSJp9ObNm7Jnzx45fvy4lCtXLt3VKg4cOGBuJUqUMLekDpkNGzaY5/DlhFQAAAAAro1XUos/0qIxze7du01MU7ZsWTNpg1gFAAAAgDNildTij7RERUXJtm3bJCIiQipXrpw8SYB4Bc5EQioAAAAAwCW0wyR37tzJyaibN282HSc1a9aU4sWLW7zvrl27zGBwhQoVpHz58lwxAAAAAE6LVzISfxw8eNAMBmvSavXq1S0OBgMAAACAPbFKRuKPkydPyvbt26VAgQJSp04dVqyGy/jfevAAAAAAALdKSkbVAV5rk1F37txJMioAAAAAp8tI/KGDwX/++SfJqAAAAACcLiPxhyaj/vHHH5I/f36SUeFyJKQCAAAAAFyGZFQAAAAAnopkVAAAAACeiGRUeJMAdxcAAAAAAOAfSEYFAAAA4Kl0Bwe9sTIqAAAAAE9y/Phx2b17NyujwmuQkAoAAAAAcIk9e/aYjpOaNWtK8eLFHbYyEQAAAADYi2RUAAAAAJ7IGcmosbGxTiotIJJ2zQMAAAAAwIGckYyqjwkAAAAA9tIB3vTij4xskxkVFcVFAQAAAGC3yMhIhyajnjt3TjZv3syVgdOQkAoAAAAAcIly5co5NBlVB4N1ZjAAAAAA2EuTTB2VjKqDwdu2beOiAAAAALBb2bJlHZqMumrVKgkODubKwGlISAUAAAAAuGwWryOTUXUwOL3HBAAAAAB7ZTQZVQeDIyIiOPEAAAAA7OboZNTQ0FCpVq0aVwZOQ0IqAAAAAMDtbElG1cFgnRkMAAAAAJ6UjKqDwZUrV+aiAAAAAHAaW5NRGzRoIAEBAVwZOA0JqQAAAAAAr0xGTW8wGAAAAADckYya3mAwAAAAALgrGTVr1qycfDgV0TAAAAAAwG1IRgUAAADgiUhGBQAAAOCJSEaFpyMhFQAAAF7h5s2b7i4CAAcjGRUAAPgCYhXA95CMCgAAfAXxCuBbSEaFNyAhFQAAAB7p/PnzMnbsWClXrpwEBgZKQECA5M6dWx577DHZuHGju4sHwE4kowIAAG8e0F2zZo106dLFbHensUqOHDmkcuXK8tlnn0lcXJy7iwjADiSjAgAAbxYdHS1jxoyR0qVLJ4+thIeHS79+/WTr1q3uLh4AO5CMCm9BQqoXuHLligwdOlTq1asn2bNnl+DgYHcXCQAAwKmDux988IEUKFBAnn32Wfn7779Ne+jGjRsmSXXatGlSu3ZtqVu3rgm8AHgfklEBAIA3J6pVq1ZNGjRoILNmzZILFy6YWCUhIUF27Ngh/fv3l3z58smUKVPcXVQANiAZFQAAePPYyltvvSUFCxY0+SX79u1LHluJiYmRL7/80sQyTZo0kaioKHcXF0AGkYwKb0JCqheIj4+XSZMmSVhYmNSqVcvdxYEXeGVQf5n08RjxVTHR0dKwUkk5deK4u4vit6hjAJz6HvPKK/Lcc8+ZAV3tQPnvdjLXrl0zX3WVVG0bHT/O5wHgTUhGBW1JOBt1DICz6ICuxiA7d+5MEZskSYpftD+3b9++ZlUiAN5D+xf+/PNPKVGihFSvXl0yZcrkkMFgeA/akaCO2YfxO8B9NA4ZOHCgDBs2LDkJ9b+S4pfVq1fLXXfdJWfOnHFDSQHYQpPIrY0/zp07J6tWrTI7uuhk2qxZs3LS4XJEyF5A3yR0WfUFCxbIPffc4+7iwAkqFgxNvjWsXEqe6d1NDh/Yb9Nj/b1rh6z8ZZF07/2EuMOSn3+UVvWqSfXieaVb6+ay7+/dGbr//r17ZFCf7nJPjXLmfCydP/e2Y3JHREjrDp1lwpi3HVhy30Yd+x/qmHc6cnC/1CiRTxb9NDvF73u2u0+efrSL28oFx/v2229l1KhRVh2rnSenT5+WVq1apdq5AsDzHDhwwCRwVKhQQcqXL++wlYngXL7SlkxMSJBhg56UNo1qS6XIMHnr5ecz/Bi0JZ2DOkYd82bEKv4jMTFRWrRoIbGxsbcloqblhRdekIULFzq9bAAcY/fu3SSjehlfaUcuW/SzPPJgS6lbroi5Pd61vSlPRhCrOAd1jDrm7YhX/MfkyZNl/PjxVh17/fp1OXLkiLRr1+62BUEAeKZt27Y5PBn10qVLTiotQEKqR5g4caIULlxYgoKCpHfv3tKvXz8pVqxY8t914NXRs2v37Nkj+/fbFpTDOV5/72NZuXWvTPxmpsTGxEj/Hh3k6tWrGX6c7774TJq1bC05g4LF1bSDZMiTvaV95x4yc/EqyV8wUp7s0UmuJCZa/Rjxly5JoSLFZOgIy8lIbTt1lQU//iCxMeccUHL/QB37F3XMOxUpXlL6Pv2cjHnjVYmP/7dxPG/WdNm7e6cMG/W+u4sHB9GOj5EjR2Yo6UwHgrdv3y6//PIL1wHwkoRURyejsr2Ua/hCW/L6jeuSNVtWefSJp+XO8hVtegzaks5DHaOOeStiFf8xZ84c00axNhlVaZ/u228zoRrwFpGRkQ5dGVUT2OF8vtCO3LJhnTS5t5VMmTFPps1bJiGhYdK3czs5f8768Q9iFeehjlHHvBnxin/QBFMdW8kIjWvWrl1r2jUAPF9ERIRDk1EvXrwomzZtclJpARJS3W7ZsmUyYMAAad++vcyePdu86KdNm+b05y1XrhyrrXqYkNBQyZM3n1SsUt0MkB45eEAO7ttr/tanUxt586XBKY5fuXSR1CpVUOIvxaVobC6d/5M0anZfqs8xd8a35j6b16+V9s3qmVVMWzeoKZfj42X4c09J/+4dUhyviV66ctCxI4es+h9mfzdVylasLH2eHiyl7iwnr783Vs6cOiGrl1ufJFSpWg15fvhIafFAO4vHlSlXQe7Im09+Wfiz1Y/t7yzVseNHD6eY6Zt00zpzK3vqmErtOSaMsW4lREUd82+9BwySoOBg+eyj9yTu4gX5YORwGTxshOQrUNDdRYODrFmzxkyayeiM3ICAAKtn/gJwL00wdWQyqg4G68xgOJ8vxCs5cwbJa6PHSvsuPSQ4JNSGs0C84ky+EK9Qx/wXsYp/GDduXIYXDdCdHH7//XfZsSNjq9wBcI+yZcs6LBlVB4M3b97spJLC12KVF157y5S9fOWqUqJ0GTMB/1zUWdm8Ya3VF5uxFefxhViFOubfiFd835IlS+To0aMZvp+OrUyYMMEpZQLgWJUrV3ZoMurKlSvNewDgLI5ddhMZNnbsWKldu7b5et9995ltanPlysWZ9GPaCbJ0wU/m+8DA7OZrm05dZcm8H1PM6p0/Z6Y0v79Nitm6e3ftkIsXYqVClWppPv7169fk/ZGvyuBXRsjc5Wule9/+clNumhVH1/62QqKjziYfu2DOTKlxV12zYqk1dm3fKtVq3Z38c66QUJM4unP7FnGGilVryJ/rfnfKY/tbHctfsJCZRZ50e3f8FAnMnt10gN3Knjqmbn2Oz2fOk2yBgVK1Zi2ry04d829Zs2WT4e9+KN9MniivDh4gxUqUko7dH3N3seBAP/zwg03Bj87k1W0w4/+/gxaA59IkU0cmo+pgsM4Mhut4c7ziasQr/hevuBp1zHMQq/g+bXfo6kGaYJpRGuNorAPA8zkyGVUHg4ODXb/Spj/zpVhFy6JCwsLEGWhH2saXYhXqmH8hXvF99oytzJo1y6Y4B4BrOToZVY+pUaOGk0oLiJDu7Ga6mk/nzp2Tf9YXfcOGDWXjxo1Ofd6MrjyWloSEBDl0yLoZnrDspYGPyyuDnpTL/78VdbtO3aRoiZLm++at2shbLz8va5b/YrZtuRR30czinTB1RorHOHHsqOk0uyNf/jSf50piojzz4nCpXa9h8lYNSjtHChQqLIvmzpbufZ4wdWTh3NnSf/BQqy9dzLkoyR0eIb8snCdvDBkkM5f8JmHhERITHeWUy6+rIu7Y6hmzzLWhrqv6peXSpX+vq6fWsSxZspgZvurs6VMyesTLMnTEKJNQ7Kg6ppKeQ7dcf+uVF6RH3yelXuNmVv8P/lzHlL7fhoSEuLsYpgPeXWreXU8aN7/PzCafu2JdhrZ2d/Q5sPSah2327dtnc8eH3m/Dhg1mYAiA5zl//ny6x9iSjKqveV3FaPny5eZz0prn8TbR0dHiCXwhXnE1T2pLnjp1Ks22y+HDh8UT+EK84s91LC4uzmPax7r6lD/HKppw4ynXwpf8/fffdt1/7969XBfAg6UXR9iSjKqDwZUqVTKDvb4aq3hCn7evxipjR71hVjytXruO+Ho78uq1axY/Iy9fvizu5ouxij/VMXXgwAG3tc9vdfr0abc9t6fEK8ePH6dd7KQ6rsmltsaQ2ifrCeOPAG6XXhxhazJq48aNk9tZvhqveJNixYpJ9uz/TnjyFSSkutmZM2ckd+7cKX733589mb4xde/e3d3F8AnPDXtT6jZqKut/XyWrf/1FXn3ng+S/5ciZU1o80Fbmz5lhOk2WLZpvkvCSgtIkiQkJEpA1q8UOMQ0wbl3F9FZtO3Y1z6GdJpvW/2GS/O5t3S7D/0twcC7TAaMzNJ1JHz8hwf2dEUpX5bP0Wvjnn38clgjujDp268DdC/17SZ2GTaRTj163/d3eOpZkxJBBEnFHXhk49FWb/hd/rGPqtddek6CgIHcXQ6KinJMAbI3z587Jn2t/l+BcIabzuNSd5dxSjs8//1x++unf2fBwHE1Gs2cm7jPPPGMx0ALgPmFhYdK8eXOHJ6PqYHBs7L8rxwwbNswnO020o94T+FK84iqe1Jb88ssvZf78+Wl2RHoCX4pX/K2Oaair7+Ge0j/krjrtKbHK2bNnPeZa+BJ7kmH0vevXX381fUMAvC9esTUZVQeDdcKGL8cq7poE4uuxyhcTPpKNa9fId/OXWSyPL7Qjk143ltouOqkjxy2r2bqDr8Uq/lbH1JAhQyRHjhx+nZDqKfHK+PHj5bvvvnPLc/v6Yh/2ePzxx02CPQDvilXsSUbV5Mekvg5fjVe8ybRp08ziK76EhFQ3u+OOOyQmJibF7/77s6dnaesLw9uVK+eeRvet8uTNK8VKljK3vzZvko9GjTCzKJPoti+Pd20vcRcvmO1eWnd4+LaB+rDwcLl65Ypcjo83HS2pyZ4jp9maITVtOnaWie+PkkP795nnuKflAxIUnMvq/yF3eB6JORdtAm69qfPnoqVi1eriDLHnYyQ8Io94gpw5c1p8LfTt21c2b9kqnlzH1MfvvinnY87JJ9NmpfoY9tYxNfObL2T9mlUya+nqDAc3/lzH1IgRI6Ry5coesfXH8OHD3fLc77z2ohQtUUoGPP+SPP1oF2n1YAcpWKiIy8vRu3dv6dixo8uf19e9//77JmHGlgGNbNmyyTfffGO+AvA82pmhHSOOTka9deBk5MiRpnPG13z44YcyadIkdxfDJ+IVV/OktuRjjz2WYneWW+kOLT179hR384V4xV/rmL7Ua9asaQYWPUG9evX8OlbRvkZf6KvzxLaM1i1bJtDp56G+z/bp08cpZQPgvHjFnmTUWweDfTVW0RVStQ3gbr4Uq0z/arJ8MXGsfDl7gVPbEZ7SjlTh4eEW2y5du3aVYyfct2OXr8Uq/ljH1OjRo6Vkyf+tOOsuX331lbz77rt+Ha889dRT0qpVK5c/r6974403ZObMmTaNregYtyYJe8IqwgCsj1XsTUa9la/GK96kWLFi4mtISHUzTSy69c1Dl1JfvXq105fi1e0v9M3G3sa3ltPXsrQ9wWNPDpSHmteXrr36SeGixZO3fdGtPL7/arIJOF96c/Rt9ytb8d9Etf3/7JGKVTKeoKeBR8069eTH6d/Ikvlz5b2Jn2fo/uUrV5UtG9cl/3zxQqzs3b1THh80RJxh357dpryeQDsjLb0WPGFVy/Tq2KplS2TG15/Ld/N/TbNDxN46tvuvbfLeiGEy8ZuZyVvMZIQ/17GkhognvOcWKFDALc/7+8plsnjeHNPhprN36zRqKqOGDZVxX33vlnPgCdfC1wwePFimTJmS4fsFBASYlRQ8IWEbQNrbhafWaeKoZNSkz0n9m6+JiIgQT+Ot8YqreVJbUl8babVddOcWT+Ot8Yo/17Hg4GCPaR+7I5HYk2IV7e/zlGvha1q3bi0LFiywaSvMZ599ViIjI51SLgDOiVcclYzqy7FK0gqwnsSbY5U5338jH48eKZOnz5XSZcuLv7QjswYEWGy7eMKqlr4Sq/hrHVPa7+QJbeR8+dwTZ3pSvKJtYk+4Fr5G443vv//epvhZF1XyhMW7AFgfqzgyGdWX4xW4l3PW4UeGtpbdsGGD+bpkyRKTTJHa1mKLFi2SWbNmya5du8zMFv1eb7oNly20UXHPPfdwpTxUyTJlpXrtu+Wzj8Yk/04H53XblwljRpnAtXip0rfdT2cbasLe5vVrbX7utp26ydeTJki2bIFyd4N/V6C0VvsuPWTPju0yZdwHsu/v3fL6C89I3vwFpUHTtLdn/S+dIaqPoTd1/OgR833UmZTbWMTHX5Jdf22V+k2aZaiMSL2OnT19Sl5+5nEZ8MLLEhIaas633hL+syWdPXVMZ/4OfvwR6dTjMSlesnTyc8Rfsr7jkjrmv/Q1/8bQZ+WRx59K3krm+eFvypqVy2TlL4vdXTw4iLZPGjZsmOGtonRAeMCAAVwHwMs4MhkVruWt8Yrav3ePiS+0Daor7+v3Rw7ut/r+xCuu4a3xiqKO+R9iFf+hqzllNBlVB3jbtm1LMirgZRyZjArX8tZYZf6cmfL2Ky/IyA8mSr78BdNs71pCrOIa3hqrUMf8F/GKf6hVq5ZUrVo1w32mmnfSv39/p5ULgOM5OhkVcBZG8dysRYsWMm7cOJk9e7a0b9/eLInerVu3247ThoBuDazbJCckJJjv9bZz5063lBvO1+WxfjJ/9nQ5cuhAim1frl29Kvc/mPY20R27PyqLfppt8/M2v7+NZA3IKve2fjDDq4qUrVBJRk/8XGZ/P1U63ttQTp04LhOmzpBsgYFWP8aZ0yelQ4sG5qbef/NV8/2MqV+kOG7F4oVm1rHObob9dezg/n8kNiZG3h3+ojSuWib5pjMmHVXHzkWflaOHDsrXn41P8RxffjLO6segjvmv8aPfMp3H/Z8dmvy7IsVKSI8+/WXUsBcy1DkLz6bbQmSk00SPffDBB00yGwDvQTKq9/PGeEX1797RxBe7tm81bV39fvjzA62+P/GK63hjvKKoY/6HWMV/NG3a1AzgWPv5ozGs7uYwfPhwp5cNgOOQjOr9vDFWmfXt15KQcFkG9uqabns3LcQqruONsQp1zH8Rr/iPd955R27evJmhsZWePXvKnXfe6dRyAXAcklHhTQLcXQD8O7teb0lu/T7JoUOHHHqqMtIYgfPtOBF72++at2ojW49Ep/jdmVOnTEd2q3Yd0nwsnemrK5Ru2bheqtW6K8Xf2j3czdws0cA5MTHBdNDYQjtb9GaryMJFUz0f/zXt80/kCSdt0+6PdUwT+6w57/bUMWuvbXqoY/5pyOtvm9t/DR72hrnBd+hsvqlTp0qPHj3kxo0bFtss2mFSr149mTZtmkvLCMA+JKN6H1+KV5Zu+EvsQbziHL4Ur1DH/A+xiv/Q+GPu3LnSpEkT2b59u1lNyNKxmoykixDoSkUAvENUVJR5fbMyqvfwlVjlq9kLxF7EKs7hK7EKdcx/Ea/4j3vvvVcmTZok/fr1Mz9bGlvRyXPNmjUzxwPwDrGxsbJlyxZWRoXXYIVUwAtcSUyUk8eOyrjRb0rjFi0lT958aR6rq5G+NfZTiY05l6HnuHr1qtla5KO3XzerUFaoXE08VUx0tAn4Wz2YducRnMfWOuZNqGOAe3Xp0kUWL14s5cqVMz/rgMGtHSV6020lBg4cKL/88otZYR6Adzh+/Lj8+eefUqJECbOysb6eHbEyEdyLeCUl2pLuRbwCwJl0S7zVq1dLr169JFu2bLe1T5JiF01C1W3x7r//fi4I4EW2bdtGMqqPIVZJiVjFvYhVADhbnz595Oeff5ZSpUqlObYSFBQkQ4YMkfnz50tgBnY5BeBemzdvdngyamJiopNKC7BCKuAVFs6dJcOfe0oqVKkmb330abrH17y7XoafY8vGddKrwwNSvFQZGfPplyn+psmwbRqnnK35X5Onz5WqNWun+ff5c2bKiCGD0vy7NojX7jliVVlzR0RIrwFpPxacz5Y6Zgl1DMB/6ezcHTt2yNq1a2XixIny7bffmt/rakTt27c3K6iGhIRw4gAvs3v3bocno+rMYLgX8UpKxCvuR7wCwJl0AFdXEtItMb/66isz4KuDPap79+4yYMAAqVmzJhcB8EIRERHpxh8Z2Sbz0qVLTioprEWskhKxivsRqwBwNp0U16pVK9Ne+eyzz2T69Onm902bNpVOnTpJ165dJTg4mAsBeBl93ToyGTUhIUE2bdrkpNICJKR6pPHjx5sbkJHtYOxVu26DNLf8uCN/AZn9y2qL989XINLi35u0aCmVq9VI+wALCQnwfdQxAKnRZLW6detKlSpVkhNS582bZwaAAXinyMhIhyaj6mCwzgyGexGvwNcRrwBITXh4uAwePFgef/zx5AFd7dMlXgG8V+XKlR2WjKqDwQzwuh+xCnwdsQqA1Gjfqyaj1apVKzkh9aeffiJWAbxYtWrVHJqMqsdeu3bNSaUFSEgFYAVdvbRI8ZJ2naug4FzmBlDHAADwX2XLlnVoMqoOBmsCCKuk+jfiFVDHAACAIzgyGVUHeLWdeuXKFS6OHyNWAXUMAAA4ql3pyGTUq1evSo0aNcxOlYAzpB1dAwAAAADgQI5ORtXBYJ0ZDAAAAADOYksyqh6jA7wAAAAA4Cy2JqPqsezwAmciIRUAAAAA4Fa2JqPqYLClmcEAAAAA4I5kVB3gDQwM5OQDAAAA8Lhk1Fy52N0YzkVCKgAAAADAK5NRLQ0GAwAAAIC7klEtDQYDAAAAgD1IRoWnIyEVAAAAAOAWJKMCAAAA8EQkowIAAADwRCSjwhuQkAoAAAAAcDmSUQEAAAB4IpJRAQAAAHgiklHhLUhIBQAAAAC4FMmoAAAAADwRyagAAAAAPBHJqPAmAe4uAAAAAADAf5CMCgAAAMATxcbGypYtWyQ0NFQaNGggWbNmdchgMAAAAADY49KlSyZWsSb+SEhIMLHK1atXzbG5cuXi5MPlSEgFAAAAALhEVFSUbN++XfLnzy916tSRzJkzO2RlIgAAAACw1+bNmyUsLIxkVAAAAAAeZdOmTRIYGOjQZNRr1645qbSASNqjfwAAAAAAONC2bdscnoyqM4MBAAAAwF7BwcEOTUZNTEzkogAAAACwW0BAgEOTUfUYXXEVcBYSUgEAAAAALhEREeHQZFQdDNaZwQAAAABgr2rVqjksGVUHg4lVAAAAADhCjRo1HJqMunr1aomLi+PiwGlISAUAAAAAuETlypUdmoyqHSw6MxgAAAAA7GUptshoMqoeyxaYAAAAABwhMDDQocmosbGxUr16dS4OnIaROwAAAACAS+iM27QSUrUDZPPmzWabzEqVKlmcnXvp0iWz2pAOGN95551sLQMAAADAbhcuXEg3/qhatapcvnzZ3FKTmJhojtVk1LJly8r27du5MgAAAACcEqvcGn/oKqr6NSYmJtVj9W9btmwxYy+ajJopUyauCpyGhFRAlwrOnFmuX7/OuYBNrl2/bnGlr6Q6duMGdQy2uX79WnI98gRJ5bh+/Yb4m6T/2VOuBQB4i5w5c5rB2w0bNqR7rCam6mxea1y5csV0oOhj63P4ov997tKWRMYlrcplqe2SXMeIV2CDmzdvmvcnT2ofm/jbT98zremfAADYHq9o/KGrCVlLk1H9IlahHQkbWdOO9Oe2HXx3bMUfxwut6Z8AANg3trJ27VqrT+HGjRvNV1+OV+BeJKQCIhIeHi4njx3lXMCmwbdTx49Knjx50q1jCZcvy7noKAmPsHws8F8n/v/9KSIiwiNOjtZndfK4/71vnjh2xKOuBQB4i5CQEOnbt6/Ex8ene6yuNFS/fn3z/Zo1ayRHjhzp3kc7TPQ5fFHSZ87J40ekROky7i4OvExSe81S2yW5bUdMDBucOn7MxMXpxcSupHVaYygtlz+t9KAJHadPHpeyZfisAABnxSvEKilprJY9e3bakbDJjRs35PSJ41K0SGGLx2kscz7mnFyKuyhBwWlvPwtYGltJinvdLSk213LVuEv8SlKfA2MrAJAxjK3AW5GQCojIvffeK99++60c2r9PipUsxTmB1XZs3SzHjhyWp59+2qo6tvinOdK1Vz/OMKyWmJAgK5YslNKlS0uxYsU84sw1btxYsmbNKovn/SidevTym0FeHdBe8vNcyZYtmzRq1MjdxQEAr+w4sSZpVLfDPHHihPk+b968EhQUJP5M25Fq0U8/Sr3GzdxdHHhZ20XjD53l3qRJkzSPK1eunBQuXFiWLfxZnn35dcmaLZtLywnvtmjenBTvVZ5Ay/LRRx/J1j83SLVa/jPKu271SomNiZEWLVq4uygA4LPxCrFKStonqJ878+fPl1Mnjkv+gpFOvUbwLRv/WC3RUWelX98+6bbtfvrpJ/llwTxp93A3l5UP3i/+Upys/nWp2ZL4jjvuEE/QrFkz896psfoD7Tv5zdiKJqAvmT9XgoODpU6dOu4uDgB4HcZW4I1YEx0QkUceecSchyd7djQd+EnbBgBpuXrlivz261IZ1Ke72V6ie/fuFk9WmzZtJHfu3PL+yFdl1rdfS9zFC5xcpJtAsGv7Vnnq0c4Sdea0PProox7TOREWFiYPPvig6TQcMeQZOXr4oPg6/R9ff2Gg+Z/1f9dzAACAK5QvX15q1aolc2dMk3GjR8rZ06c48UjXsSOH5I0Xn5V1a1ZJ27ZtLa4Go21MjYl1Jfhn+nSXv3ftMG1RwJILsedl+tdTZNy7b5rB3ZYtW3rMCdP4PEuWLPLc44/IqmVLTPzu65MYly36WV58qq+ZONilSxd3FwkA4Ee0z1ITjZ7o9pBsXLvGrNgNpNd2Wb54gQx5sreZPNe1a1eLx7dv394ksb39ygsyb9Z0k2QIWKLx7F9bNkn/7h1N3KLvU54if/78JnZatWyxjHp1aPKObL5MF4N6aeDjsnPbFuncubNVOyEBAADvl+kmowyA8emnn0r//v3N9zly5JSQsDDJlImcbdzu5s0bZosY7TjRZNRp06ZZNeCzefNmM/sxJibGdLTkjsgjWbKwUDVSc1MuxcXJxQux5qfevXvLpEmTTH3zFLoiRKtWreS3334zP+cOj5DA7L7ZkZCYcFlizkWb7xs2bCgLFy70+9X63FHftONZxcXFcf4BH8dr/nanTp2Spk2byu7du03yYHhEHsmaLdANVwfe1napX7++abvkymV5a0tNHNBBOo1tVEhomOQ0qxN7xoQoeJZr165KTHSUqTd58uSRFStWSMWKFcWTzJw50yQ3aBkDs2eXsNzhPtnHc+PGddM/cSUx0SSjzpkzRx544AF3F8vv0HYB/Aev99SNGTNGXnjhBfN9zpxBZmyFdiTSa7voGMmsWbPMBLr0/PHHH2alVO0X1DZPWHgEYytIw02Ju3gxeVGYZ555Rj788EOPWexDnT9/3tTnDRs2mJ+1jydbYHbxPTclIeGynD93zvx03333yY8//ijZs/vi/+q5aLsA/oXXPDwJCanALXbt2iU//PCD/P777xIb+28iGHDbG2emTBIaGmq2Le/YsaOUKlXK6pN09uxZM0C0aNEiOXPmDDPGkSbdnrhSpUqmjtWtW9ejklGTXLlyRX755ReZPXu27Nu3TxITE8UXBQYGmtf5Qw89JM2bN5dsbGPrcgRQgH/hNZ/2eVmwYIHMnTtXjhw5IlevXnXxlYE3tV1KlixpVhLSLVT1Z2voylarV682MfHOnTslPj7e6WWFd9LVR/Plyyf333+/tGvXziSleqL9+/eb+rxy5Uoz6OuLc/LNJIXwcDNpQWPHokWLurtIfom2C+A/eL2nbfv27eZzd+3atXLx4kUXXhV4W9tFd5LTtkuHDh2kePHiVt/35MmTZmxl8eLFEhUVZeIXIDW6sEHVqlVN+/iuu+7yqGTUJAkJCaYua4LmwYMHfXZsRZNPy5QpY17v+rrXhHK4Fm0XwL/wmocnISEVAAAAHo0ACvAvvOYBAIA3oe0C+A9e7wAAwJvQdgH8C695eBLPW24NAAAAAAAAAAAAAAAAAAAAXoWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYJcC+uwO+Ze3atTJjxgxZs2aNXLhwwd3FgYfKlCmThIaGSqNGjaRz585So0YNq+978OBBmT59uixatEjOnDkjN27ccGpZ4b1y5swplStXlo4dO0rLli0lIICPbHiG69evy9KlS+WHH36QLVu2yKVLl5z+nLe+V1apUkUyZ3b+nCp9zRUoUEBat24tDz/8sPkeANwpOjravPfOnTtXjh49KlevXuWCIFXZsmWTkiVLykMPPSTt27eX4OBgq86U1qkFCxaYerZjxw65fPkyZxipypIli+TLl09atWplYuIiRYpwpuAxjhw5YvpdFi5cKKdPnzbxiy/GK/reXqtWLenUqZM0bdrU9FUBgLvcvHlTVq9eLTNnzjRjLBcvXuRiIFX6eZU7d27z2aXtSO3/tta+ffvk+++/lyVLlkhUVBRjK0hTUFCQVKtWzYyt3HvvvS5pmwHWuHbtmhkf1n6X7du3S3x8vM+OrRQqVEjatGlj4pW8efM6/TkBAJ4n002NFAHIO++8Iy+99JI5E3ny5pPc4RGSiSAFqbh544ZEnz0j56KjzM+ffPKJPPHEE+meK+2U08RCTd4KCs4l+QtGShaSDJFaHbt5U+LjLsrxo0fMz9px8t1335GUCrfTwdw+ffrIV199ZX4uWKiIBOXK5ZODn9euXpWTx47K5cvxkidPHlmxYoVUrFjR3cUC/IK2lZIS6OLi4sxAgr87fPiwNG7cWA4dOiTZAgMlsnBRyZotm7uLBQ+VmHBZjh0+ZD63dRBu2bJlEh4ebvE+V65cMW3OefPmmZ8LFSkqOYKCffIzHva7fu2anDx+TOIvxUlISIiZrHTXXXdxauF269evlxYtWphJ5jmDgqVAZCGf7HfRPoOL58/LqZPHzc/PPPOMfPjhh7xnAy5ArJL6e9Krr74qb731lvk5b/4CEpo7nPckpDm2cvb0KTkfc87UkalTp0r37t3TPVva3mzbtq0kJCRIrpBQU8988TMejnlPunTxopw49u/YymOPPSZTpkwhKRVup5OAu3XrZpJRVWThIpIz2DfHVq5euWJeg4kJCVKwYEFZuXKllC5d2t3FAvwC8Qo8CQmpgIj8/PPPZpZOmXIV5M0PJ0j5SlV9sgEIx84o2775T3n5mcflyMED8ttvv0mDBg0srmhVtGhRuSmZ5K2PJkrj5i1JIkC6jh05JGPeGCbLFv4sr7zyiowcOZKzBrd699135cUXX5QGTZvLS2++K0WKl/TpK3I5Pl4Wzp0lI18aLBERESYhTFedA+BcdJrcPpiiq8bs3LlTnnv1TenQ7REJzhVCNYRFMdHR8tWnH8vnEz4yk+J0pUBLnn/+eXn//felZduHZPArI6RAocKcYVh0JTFRli36WYY/95QEZstmVm7OlSsXZw1uo6vxFS5cWBKvXJE33h8vzVq2NpM4fNn+vXvkzRcHy5/rfpfPPvtM+vXr5+4iAT6PWOV2OoleE2wqVq0uI8aMM2MsjK0gvbGVTev/kJcHPiGnThyTjRs3WtyF7vjx41KqVCkJzJ5d3vroU6nXpJlkzZqVkwyLDh/YL+8MHyqrl/9iFiQaOnQoZwxuNWzYMDN5o1mr1vL88JFSqEgxn74iOoF13g/fy6hXh5pdVXSVa1YrBpyPeAWehDXqARH55ptvzHmY8PUMqVC5Gh0mSP/NM3NmqVqztnw4+d+68+2331o8XrdW1QbAkNfflub3tyUZFVbRgPS9T76U/AULybRp00xCCuDuz0tdQfyjKdN8PhlV5ciZUx7q2lMeHzRETp06JcuXL3d3kQD4oW3btpnt0zv17CWPPvE0yaiwSu6ICHn2lRHSsNm9ZkvLM2fOpHmsrqSq8UyR4iXknfGTSUaFVTTRr1W7DvLsyyMkNjZW5s+fz5mD2yeba13UOql109eTUVXJMmVl/NfTJXuOHKbPAADc1VekW/NO/OYHubN8RcZWYNXYSq069WX0xM9Nf/f3339v8fhZs2aZlVFfeft9adyiJcmosErREiVNH3ZY7nDaSXA7fa/T9nqByMJmzM/Xk1GV7ljR+dG+0rPfADl48KD88ccf7i4SAMDFSEgFROTXX3+VStVqMPCGDNNONh241W0w06tjqvn9bTjLyBCd7d2kRUuzMuP+/fs5e3Cb06dPm9X5GjW7z6xI4E901rJK770eAJwhuR3ZinYkMk7rja5ApNujpWX37t1m4sU99z0gWbJk4TQjY3Xs/2Nc2knwlM/LFg+0FX+iq6bXadBE1qxZY5J1AMDVCTY6ebfG3XUlPCIPJx8Zogt+3JEvv1VjK//2kbfiDCNDtA+7UfP7zCRf7dsG3EXH9nSMT8f6/G2FZ12kSdFnAAD+J8DdBQA8QUxMjFS7q667iwEvla9ApOzfszPdOqYrVoSG5XZZueA78hUomFyPAHdJqn95CxTwu4vAaxBwjAsXLkh8fHy6x12+fFkKFvz3s09XdcyRI0e698mZM6eEhPjmNvbnzp0zX/Pm//ecAI7+DPvfZzx1DBmnSQS6yhWxCjzh81LrYp68+cQf3+s1KUxXiM3uZ5MHAVfHK8QqKen5unLlCrEKbJIpUybTloyJ+TfmtfQZHxIaZnYyAuyJifPl8792IjxDcr9LfsZWANiGsRV4IxJSgf+fyctKMLBVlsyZzapD6dWxzJlZbQi2yfz/K1VpPQLcJan++eN7WVIbIb33egCWO0wmT54s165ds+o0DRw40HydOXOmVcfrFpF9+/b1yaTUpPdf4hXYIosV7cjkOuaHn/FwTCKBJgHSToK7/dvvktkvt4qmzwBwbbxCrPI/tCPhiHglvT5v8xnPTg6wUVJfNmMr8IixFT98L7OmXwqAZYytwFuRkAoAAAAAcPrKOTq4q6t2adJSjRo1JCgoKM3j9dgtW7ZIXFycVK9eXUJDQ9M8VlcD27hxo3kOX0xIBQAAAOCaeEUT2zVWsRR/aDyzfft2iY6OlipVqkiePHksDh5v2LCBWAUAAACAXbGKTsBNL/7Q5O89e/bI8ePHpVy5chIZGWnxsXfv3m2OZWwFzkBCKgAAAADAJXTwtmnTppIrV640j7l69aqsXr1aLl26JI0bN5bw8HCLj7d161YnlRYAAACAP9Fk1GLFilmMP9auXWu2EK9Xr54UKFDA4mCwDvACAAAAgL00GbV06dIW44/NmzebBNOaNWtK8eLFLT7erl27zLGAs2R22iMDAAAAAPCfAV5rklF11dNGjRqlm4yqg8G6MhEAAAAA2Cu9lVE1/jh16pTUrVs33WTUpMFgAAAAALBXeiujavxx4MABq5NRd+7cKSVKlODCwGlISAUAAAAAuERQUJBDk1F1MFhnBgMAAACAs9iSjKqDwbpNJgAAAAA4i63JqBUqVCAhFU5FQioAAAAAwK1sTUbVwWBLM4MBAAAAwB3JqDoYHBkZyckHAAAA4HHJqOXLl+eqwKlISAUAAAAAeGUyqqXBYAAAAABwVzJqeoPBAAAAAGArklHh6UhIBQAAAAC4BcmoAAAAADwRyagAAAAAPBHJqPAGJKQCAAAAAFyOZFQAAAAAnohkVAAAAACeiGRUeAsSUgEAAAAALkUyKgAAAABPRDIqAAAAAE9EMiq8CQmpAAAAAACXIRkVAAAAgCciGRUAAACAJyIZFd4mwN0FAAAAAAD4h2vXrsnq1aslNjZWGjVqJOHh4Q4ZDAYAAAAAe23fvl3OnTuXbvyR0cFgAAAAALDHnj175Pjx41bFH7t27ZKdO3dKhQoVpHz58px4uAUJqQAAAAAAl9iyZYtcunTJocmoOhgMAAAAAPaKjo6WevXqkYwKAAAAwKM4IxlVHxNwlsxOe2QAAAAAAG4RFxfn8GRUnRkMAAAAAPaqUqWKQ5NR9TgAAAAAsFe5cuUcmox68OBB2b17NxcGTkNCKgAAAACP8ueff0qvXr1MwFykSBGpWLGiDBgwQHbs2OHuosFO1atXd2gyqg4GM4sXAAAArhIbGyvjx483bVUdDCxZsqQ0adJEvvnmG0lISOBCeLk8efI4LBlVB4NJSAUAAICraHtV+9Z79Ohhkhd1bKVSpUoyaNAg+fvvv7kQXi4yMtKhyag6DpfeYwL2ICEVAAAAgEf466+/TMJirVq1zICuzs48evSoCaInTZpkOk8aNGjAoJ4XCw0NdWgyqg7waucaAAAA4EzXr1+Xl156SfLnzy8DBw6UdevWyaFDh0x79LfffpOePXuav40dO9a0VeFbbElG1Ti2RIkSLisjAAAA/JcmF1auXNn0q0+fPt3sKqZjK7rIh06oK1u2rNxzzz1y7NgxdxcVTmBLMqrGKlovAGchIdULLFu2TNq2bWuy03PlyiW1a9eW+fPnu7tY8GCvDOovkz4eI74qJjpaGlYqKadOHHd3UfwWdQwA4GiaiFinTh3Zvn27+fnatWsp/p70sx6nCasaXMN32JqMqoPBzOL1PrQlQR2zDzExALiWxiIdO3aUd99916yCqu3RW5NOtS2btHqqrj40ePBgklJ9iK3JqDoYTEKq9yFWAXXMPsQqAOB6y5cvNwt5JG2//t+xFZ1cp3QinbZn9+3bx2XyIbYmo+riMJkyZXJZOeF/SEj1Al988YVkyZJFPvjgA5k7d65Uq1ZNWrduLUuWLHF30eAgFQuGJt8aVi4lz/TuJocP7Lfpsf7etUNW/rJIuvd+wi3XZ8nPP0qretWkevG80q11c9n3978NH2t9NvY9ebBpHalVsoA0qXanDH/uKRPA3ip3RIS07tBZJox528Gl913Usf+hjgHe48jB/VKjRD5Z9NPsFL/v2e4+efrRLm4rFxxPZ+q2atXKDO4mdY6kRf+uA73NmzeXc+fOcTn8PBk1vcFgOIavtCUTExJk2KAnpU2j2lIpMkzeevn5DD8GbUnnoI5RxwBvRLziP1544QXTL2/tyqcfffSRWYUI/p2Mmt5gMBzDV9qRyxb9LI882FLqlitibo93bW/KkxHEKs5BHaOOAd6IWMV//PPPP9KmTRu5cuVKumMrmqgaHR0tLVq0kLi4OJeVEc5DMio8GQmpXmDcuHEyZ84cefjhh80y2p999plUrVrVdGzBd7z+3seycutemfjNTImNiZH+PTrI1atXM/w4333xmTRr2VpyBgWLq2kHyZAne0v7zj1k5uJVkr9gpDzZo5NcSUy0+jG2bdoovQYMkhmLV8lHU6bJzm1b5fn+j952XNtOXWXBjz9IbAyJKNaijlHHAG9TpHhJ6fv0czLmjVclPv6S+d28WdNl7+6dMmzU++4uHhzc3r148WK6HSZJ9LjTp0+biVvwbiSjeg9faEtev3FdsmbLKo8+8bTcWb6iTY9BvOI81DHqGOBtiFf8g8YdmlxqbTJqktdff90MCsN7kYzqPXyhHbllwzppcm8rmTJjnkybt0xCQsOkb+d2cj4DE3GJVZyHOkYdA7wNsYr/0EXtEhMTk3dtSI8mpR46dEi+/fZbp5cNzkUyKjwdCakeYOLEiVK4cGEJCgqS3r17S79+/aRYsWLJf4+IiLjtPnfeeaf5oLDVnj17ZP9+22aJwjlCQkMlT958UrFKdTNAeuTgATm4b6/5W59ObeTNlwanOH7l0kVSq1RBib8UlyI5Y+n8n6RRs/tSfY65M74199m8fq20b1bPrGLaukFNuRwfb1Yi7d+9Q4rjNeFHVw46dsS6ujb7u6lStmJl6fP0YCl1Zzl5/b2xcubUCVm9/Berz8PEqTOl9UMPS4nSZaRKjVrS/7mhsn7Nb3LxQmyK48qUqyB35M0nvyz82erH9neW6tjxo4dTzPRNummduZU9dUyl9hwTxoyy+n+gjgH+p/eAQRIUHCyfffSexF28IB+MHC6Dh42QfAUKurtocJDLly/LpEmTrE5GTaIdLJrIam1HCzwPyajexRfilZw5g+S10WOlfZceEhwSasNZIF5xJl+IV6hjgP8hXvF9n3/+uU0xh+7moItMwDuRjOpdfCFWeeG1t0zZy1euasZGdCL2uaizsnnDWqvPA2MrzuMLsQp1DPA/xCq+78KFC/LVV1+ZJNOMGjt2bIYn3cFzkIwKb0BCqpstW7ZMBgwYIO3bt5fZs2eblaGmTZtmVWeIbvtiq3LlypnVVuF5tBNk6YKfzPeBgdnN1zadusqSeT+mmNU7f85MaX5/mxSzdffu2mESNytUqZbm41+/fk3eH/mqDH5lhMxdvla69+0vN+WmWXF07W8rJDrqbPKxC+bMlBp31ZVCRf6XIG3Jru1bpVqtu5N/zhUSahJHd27fIra6GBsr2bPnkGzZAm/7W8WqNeTPdb/b/Nj+KrU6lr9gITOLPOn27vgpEpg9u+kAu5U9dUzd+hyfz5wn2QIDpWrNWlaXnToG+J+s2bLJ8Hc/lG8mT5RXBw+QYiVKScfuj7m7WHCgxYsXS2xsyokn1jpy5IjZ6h3eh2RU7+XN8YozEK84njfHK85AHQM8G/GK79NdGWxJSM2cObN8/fXXTikTnItkVO/lS7FK0gIdIWFhNt3fPAZjKw7nS7EKdQzwfcQqvm/u3LmSkJBgU3t39+7dsn37dqeUC85FMiq8RYC7C+DvdOZB7dq1zVelSaKFChWyeJ8vv/xS9u3b5xEdWvoBZ89KrfiflwY+Lq8MelIu//+WxO06dZOiJUqa75u3aiNvvfy8rFn+i9m25VLcRTOLd8LUGSlO4YljRyVTpkxyR778aZ7aK4mJ8syLw6V2vYbJS/Yr7RwpUKiwLJo7W7r3ecI0RBbOnS39Bw+1+jLFnIuS3OER8svCefLGkEEyc8lvEhYeITHRUTYH91PGfyCdH+1jAvj/0tXxdmzdLJ5AO6Z15eG0XLr073X11DqWJUsWM8NXnT19SkaPeFmGjhhlEoodVcdU0nPo1ttvvfKC9Oj7pNRr3Mzq/8Gf65jS99uQkBB3FwN+6sCBA2577pp315PGze8zqwjMXbHOvA+5gyZNWnqvh210opVeU1tn427cuDHVHQXgWc6fP+/0ZFT9nLz1eXxFdHS0eAJfiFcczZvakvp6S+sz7PDhw+IJfCFe8ec6FhcXRzsJbq+D/h6v/PPPPz7ZFnK3EydO2HQ/bfNqHz4xpHdIeu04KxnVV2MVT+jz9tVYZeyoN6RStRpSvXYdn29HXr12zeJ7pe6s426+GKv4Ux1T+r7urjYa4M5cCk+JVWJiYmgXO8G2bdvM51BGd59Lsn79egkMvH1RMHiWW+MIZyWj+mq84k2KFSsm2VNpU3kzElI94EOic+fOyT9nzZpVGjZsaAbWU6MzFQYNGiTPP/+81KljW5CgHLX8tr4xde/e3SGP5e+eG/am1G3UVNb/vkpW//qLvPrOB8l/y5Ezp7R4oK3MnzPDdJosWzTfJOElBaVJEhMSJCBrVjMDPy36QXPrKqa3atuxq3kO7TTZtP4Pk+R3b+t2Gf5fgoNzmQ4YnaFpK11afsiTfeSOfAVMAJ4affyEBPd3Rqj4+HiLrwUdFHD3sveW6lgSbbC+0L+X1GnYRDr16HXb3+2tY0lGDBkkEXfklYFDX7Xpf/HHOqZee+01CQoKcncx4Kfc2fl7/tw5+XPt7xKcK8QMGpS6s5xbyvHbb7/R7nGCM2fO2PUZ+fHHH6e7wwDcLywsTJo3b+7UlVGHDRvmk50mx48fF0/gS/GKI3hbW1Ints6fPz/Vv+lOLZ7Al+IVf6tj+jGuHdz0D8GdNPHPXd0unhKvPPXUU6ZvGY6VmJho832PHTvGe6OXxSuaFKftb0cmo/pyrGJr8oOj+Vqs8sWEj2Tj2jXy3fxlFsvjC+1Ide7cOYvvlXv37pUct6xm6w6+Fqv4Wx1TQ4YMkRw5cri7GPBT7pzA4SmxypIlS0yeCxzr5MmTdrXH3nvvPZk0aZJDywTnxSo6TqI3Ryej+nK84k2mTZsmZcuWFV9CQqoHDMDnzp07xe/++/OtK+O0bt1a6tevL6NGjRJPydL2hQSAcuXc0/i6VZ68eaVYyVLm9tfmTfLRqBFmFmUS3fbl8a7tJe7iBbPdS+sOD9/2wREWHi5Xr1yRy/HxpqMlNdlz5DRL9KemTcfOMvH9UXJo/z7zHPe0fECCgnNZ/T/kDs8jMeeiTcCtN3X+XLRUrFpdMkITFV4e+LicPXPKbD2SVnljz8dIeEQe8QQ5c+a0+Fro27evbN6yVTy5jqmP331Tzseck0+mzUr1MeytY2rmN1/I+jWrZNbS1WbWVkb4cx1TI0aMkMqVK7u7GPBT+/fvlwceeMAtz/3Oay9K0RKlZMDzL8nTj3aRVg92kIKFiri8HDpp6O2333b58/o67YzSCVe2ev31182OA/Bs2pmxatUqsw2QDjY5OhlVjRw50nTO+JoPP/zQIzoGfSFecRRvbEs+9thjKSbD3konxPbs2VPczRfiFX+tY/pS1/fq8ePHu7so8GOajKltDX+OV/Q1eMcdd7j8eX1ds2bNbJogpAk+1apVky+++MIp5YJz4hVnJKP6cqyiCTZ6vtzNl2KV6V9Nli8mjpUvZy+w6bPE29qRKjw83OLYSteuXeXYiZPiTr4Uq/hjHVOjR4+WkiX/t+Is4EraH/rwww/7daxy7733yiuvvOLy5/V1c+bMseu8vvPOO6Y9C++IVZyRjBoVFeXT8Yo3KVasmPgaElLdTDsJdYnyW/33Z3XlyhVp3769SXqbPn262wZF/kuXDPa1LG1P8NiTA+Wh5vWla69+Urho8eRtX3Qrj++/mmwCzpfeHH3b/cpW/DdRbf8/e6RilYwl6CltgNasU09+nP6NLJk/V96b+HmG7l++clXZsnFd8s8XL8TK3t075fFBQ6x+DE0+GD74Kdm/92/54od5ZsZWWvbt2W3K6wm0k9nSa8HTVrVMrY6tWrZEZnz9uXw3/9c0O0TsrWO7/9om740YJhO/mZm8xUxG+HMdS2qI8J4Ld3HXKs+/r1wmi+fNMR2tOnu3TqOmMmrYUBn31fcuL0toaCivQScoXLiw6TSxZaa4JjTqwERAAGGNp9MVUbXTRCfZ1atXz6HJqHpc0udk/vxpb33nrSIiIsTTeGu84gje2pbU10Za7UidKOtpvDVe8ec6FhwcTDsJbq+D/h6vlC5d2ifbQu7Wu3dveeuttzK88pAm7Dz++OO8N3pZvKILVzgyGTUpmdlXY5W4uDjxNN4cq8z5/hv5ePRImTx9rpQum36is6+0I7MGBFh8r/S0VS29OVbx1zqmNCmHsRW4y4ULF8TfYxVdkI3XoOM98cQTZjEjzSXKCE1Q1PdFzT9Kb+VMeE6sotfMkcmousKu7ujty/EK3Cvj6/DDoXSlu1tn7+s2B6tXr77tuD59+pitpxYsWCAhIWk38K2lW8/oSmfwTCXLlJXqte+Wzz4ak/w7/bDQbV8mjBllAtfipUrfdj+dbagJe5vXr7X5udt26iZfT5og2bIFyt0N/l2B0lrtu/SQPTu2y5RxH8i+v3fL6y88I3nzF5QGTZtb/RhvDB0k63//Td4ZP0muXr0qUWdOm9t/O33j4y/Jrr+2Sv0mzTJURqRex86ePiUvP/O4DHjhZQkJDU0+7wn/2aLbnjqmM38HP/6IdOrxmBQvWTr5OeIvWd9xSR0D/Iu+178x9Fl55PGnkreSeX74m7Jm5TJZ+ctidxcPDqKTNnSQN6NJpToZZMCAASSjepkqVao4NBlVB4OTElLhOt4ar6j9e/eYmEXboLryvn5/5KD1sTHximt4a7yiqGOA/yBe8Q+665EtEzR1QmOnTp2cUiY4T2RkpMOSUXUwmK1pXc9bY5X5c2bK26+8ICM/mCj58hdMs71rCbGKa3hrrEIdA/wLsYp/0FXGbV2wY+DAgSSjehlNMnVkMuoff/zhkYthwHeQkOpmzzzzjGzYsMF81e1Ku3fvLhcvXkxxjC6PrNtVvPrqq2ZG7bp165JvttKZvvfcc48D/gM4S5fH+sn82dPlyKEDKbZ9uXb1qtz/YMc079ex+6Oy6KfZNj9v8/vbSNaArHJv6wczvBJv2QqVZPTEz2X291Ol470N5dSJ4zJh6gzJFhho9WP8MO0rOXn8qDzYtI40rlom+XbqxLEUx61YvNDMOtbZzbC/jh3c/4/ExsTIu8NfTHHedeaco+rYueizcvTQQfn6s/EpnuPLT8ZZ/RjUMcC/jB/9lgmY+j87NPl3RYqVkB59+suoYS9kqFMenk07P7Jly2aSTK2hbRTdPkQHh+Fd8uTJ49BkVB0MTq8jBs7hjfGK6t+9o3Ro0UB2bd9q2rr6/fDnB1p9f+IV1/HGeEVRxwD/QbziHwoVKiS9evWyOlZJMnToUI9b1Q/2yWgyqg4Gp5fgCufwxlhl1rdfS0LCZRnYq2u67d20EKu4jjfGKtQxwL8Qq/iP559/3rQ7rF3pVI/VlTB79uzp9LLBdWxJRtV6oAsoAs7C3pZu1qJFCxk3bpy88847MmXKFHn44YelW7dusnTp0uRjli1bZgZn+/fv7zHb58KxdpyIve13zVu1ka1HolP87sypU2aGS6t2HdJ8LJ3pqyuUbtm4XqrVuivF39o93M3cLNHAOTExwXTQ2EI7W/TmyHORmmmffyJPZGCbdn+XXh3TBC9rz72tdSyycFGrn8MS6hjgP4a8/ra5/dfgYW+YG3xHyZIl5aeffpL777/f7Big21ta6jDRgd3FixdL3rx5XVpOOI+tyag6GKwrrrJKqnP5UryydMNfYg/iFefwpXiFOgb4D+IV/zF+/HjT3ly5cqXFWCXJo48+Ki+++KJLygbPTUbVwWCNa3SRETiPr8QqX81eIPYiVnEOX4lVqGOAfyFW8R/aPp05c6Y89NBDJlaxFK9oWyg4ONgslKcLfsC/k1Hr1KkjsbH294UCaWGFVA/w1FNPybFjx+TSpUvyxRdfmNWhbqUdXTpAm9rNVnrfQ4cOOaD0cIUriYly8thRGTf6TWncoqXkyZsvzWN1NdK3xn4qsTHnMvQcV69eNVuLfPT262YVygqVq4mniomONgF/qwfT7jyC89hax7wJdQwAXK9Zs2ayatUqKVq0qPn5v6uJJG07c+edd8ratWulVq1aXCYfYU8yanqDwXAN4pWUaEu6F/EKAMDRAgMDZdGiRWaHBo1T/rtaqg746S179uzy2muvyeeff872lz7E1mTU9AaD4RrEKikRq7gXsQoAwBnatGljFrxLWp0/rbGVihUryvr166VSpUpcCB9hTzJqRncBATKKFVIBL7Bw7iwZ/txTUqFKNXnro0/TPb7m3fUy/BxbNq6TXh0ekOKlysiYT79M8TdNhm3TOOVszf+aPH2uVK1ZO82/z58zU0YMGZTm37UhtHbPEavKmjsiQnoNSPux4Hy21DFLqGMAAHX33XfLvn37ZPny5TJ27FiZP3+++b2ugNmoUSMzkatu3boM6vkQklF9A/FKSsQr7ke8AgBwNF1E4tNPP5XXX3/d7HQ2depU+eeff8zfNFFRk1V120tWGvItJKN6P2KVlIhV3I9YBQDgDE2aNDHJibr6qe7QrDvMqYIFC5rFQAYMGGAW+WDClO8gGRWejoRUwAtYsx2MvWrXbZDmlh935C8gs39ZbfH++Qr8O+MmLU1atJTK1WqkfQCzxf0adQwAkERnZWoHic7Q1O1jlA70BgUFcZJ8DMmovoN4Bb6OeAUAkERXkxk2bJg8++yzyfHKunXriFd8EMmovoFYBb6OWAUAkERXRm3VqpVZ3CMpVtm7dy+xig8iGRXegIRUDzR+/HhzAzyFrl5apHhJux4jKDiXuQHUMQAAQDIqHIl4Bc5GHQMAwL+QjApHoR0JZ6OOAQDgX0hGhbfI7O4CAAAAAAD8B8moAAAAADwVyagAAAAAPBHJqPAmrJAKAAAAAHAJklEBAAAAeKoDBw6YW4UKFaR8+fIOGwwGAAAAAHscP35cdu/ebVX8cfLkSfnjjz8kf/78UqdOHcmcmbUq4XokpAIAAAAAXGLPnj2m46RmzZpSvHhxh61MBAAAAAD2IhkVAAAAgCdyRjJqbGysk0oLiJAGDQAAAABwCWcko+pjAgAAAIC9dIDXkSujRkVFcVEAAAAA2C0yMtKhyajnzp2TzZs3c2XgNCSkAgAAAABcoly5cg5NRtXBYJ0ZDAAAAAD20iRTRyWj6mDwtm3buCgAAAAA7Fa2bFmHJqOuWrVKgoODuTJwGhJSAQAAAAAum8XryGRUHQxO7zEBAAAAwF4ZTUbVweCIiAhOPAAAAAC7OToZNTQ0VKpVq8aVgdOQkAoAAAAAcDtbklF1MFhnBgMAAACAJyWj6mBw5cqVuSgAAAAAnMbWZNQGDRpIQEAAVwZOQ0IqAAAAAMArk1HTGwwGAAAAAHcko6Y3GAwAAAAA7kpGzZo1KycfTkU0DAAAAABwG5JRAQAAAHgiklEBAAAAeCKSUeHpSEgFAAAAALgFyagAAAAAPBHJqAAAAAA8Ecmo8AYkpAIAAAAAXI5kVAAAAACeiGRUAAAAAJ6IZFR4iwB3FwAAAAAA4B8uXLhgvh44cMDcSpQoIQUKFJCYmJg073P8+HHZvXu3REZGSvHixeX8+fOpPiYAAAAA2BuvpBd/3CoqKkq2bdsmERERUrZsWYmNjSVWAQAAAOCUWCW9+ONW+rfNmzdLcHCwVKpUSeLi4lJ9TMBZSEgFRCRTpkxy48YNzgVscuPmDVOHLNG/36SOwUZJdSe9egY4U1L9u3nT/z4vk9oIvAYB2+XMmVMCAgJkw4YNKX6flJhqDR0Y1ltq9LH1OXxR0nsP8Qqc9RlGHYM9bt68aeoZ7SR4St+e1kl/q4/0GQDOiVcsxR//pQPDy5cv999YxQ/7iuAY1rQjGVuBPZL6sv2tfQgPHVvxw3FixlYA58QqluKP1BJTV65cmebffTlegXuRkAqISGhoqESdOcO5gE3Onj4tYWFh6daxy5fjJe7iBQnOFcKZRsbq2JnTyfUIcJek+hf1//XR397nVXrv9QDSFhISIn379pX4+Ph0T9Ply5elfv365vs1a9ZIjhw50r2Pdpjoc/iipPeeqLOnpXip0u4uDnywHZn8GX/W/z7jYb9z0VFmgIl2EtxN66DWxZhz0RIekUf8ydkzp8xXX20LAZ4UrxCrpKSxmg5g+2NfEeynk0iiz5yRO/KEp/sZHxt7XhITEiQwe3ZOPTLk7Ol/20mMrcCd/tfv4n+5CEmxCq9BwHaMrcBbkZAKiEjjxo1l3rx5puMkT958nBNY7eC+f+Tgvr3Sq1evdOvYjBkzZMXSRdL6oYc5w7CaDqit+mWR2SasVKlSnDm4Tf78+aVMmTKyatkSuXbtmhlw8BcrlixIfi8HYF/HiTWJEpcuXZITJ06Y7/PmzStBQUF+fdqT3ntWLFkoter8m6gLZOQzTFfiaNiwYZrHlC9fXvLkyWPq2DMvDmflGNjUTmrSpAlnDm7/vPzqq69k+eL50qHbo35zNS7Hx8sfq1bI3XffbdUkHgD2xSvEKillzpxZGjVqJL+tXi0XYs9LSCgTeWG93X9tk1Mnj0unjg+l+xm/YMECWbNimdzT8gFOMaymfdjal33nnXeavm3AXXRsr2DBgrJy6UJ54bW3zOenv1ixeKH5Sp8BYB/GVuCN/OfTDrCga9euJunrmd7d5Ojhg5wrWGX/P3/Lc48/Yr7v0qWLxWPbt28vgYGB8s7wobJu9Uq2XIVVYqKjZfjgp+To4UPSuXNnvwpS4Xk0mUU/L3XyxotP9fWL2bzaafnLwnky8YN3JDw8XFq0aOHuIgHwQzVr1jQd199+/qnM+f4buXrliruLBC9JUPp8/Ifyy4J5ZgBXBz7SopNMHn74Ydm/d4+88eKzEhtzzqVlhXfSPhRNCnj/zeFmleo2bdq4u0jwc23btjV1Ueuk1s2krSF92emTJ2Tw449I/KW4dPulAMBZtK9IY5RBfbrLiWNHONGwamXUv3ftkCFP9jY/a7+3JR07djQxy5svPiub16819wfSo33X2ocdffaMaSclbZkOuIOO7Wk91LE+HfPTsT9fd/XqVVn44yz5fOJHpk/K0kRpAIBvynSTljtgAtiXX35Z3nnnHXM2ipcqY7b3ykTyF1Jx88YNs53l4QP7zc9ab4YOHZruuVq8eLG0a9dOEhMTJW/+AhJZuKhk8aMVBpEBN2/KpbiLsnf3Trl+/brcd9998uOPP0p2tiSCB3QiaCfxnDlzTCdK6bIVJJeuHuKDHXo6mHLk4H6z5afOPFy6dKncdddd7i6WX9GVZ4KDg833cXFxfr9Kpj/h2t9uz549ZiWBU6dOmVWHipcqLVmzBbrh6sAbJCZcln17dsvly/FmJZgVK1ZIgQIFLN5Ht6dt3bq1LF++3Az2lilXQXIGBfvkZzzsd+3qVTl25JCZqKQrMs6fP1+aNm3KqYXb/frrr+a9TLfU1h2QChUpJgFZs4rPuXnTbF38z+6d5sfHHntMpkyZwiRWF6PN6p+47qmPrTz99NMyYcIE83PJMmUld3gE7Uik6sb163L29EmTlKXGjx8vAwYMSPdszZ492/RJ6uTx/AUipUChwoytIHU3b8rFCxfknz07zQQlXSxm+vTpktUX24TwKgkJCfLggw+aseIsWbKYfpeg4Fw+O7Zy6MA/EhsTIxERESZOq1KliruL5Vdos/ovrj08CQmpwC0dJ9oI1G3V16xZIxcuXODcIPU3zkyZJDQ01GxHpDPaMjLwtmPHDvnmm29k0aJFcubMGb9YsQO20ZVdKlWqJJ06dTKzwElGhSclpc6aNUtmzpwpW7duNcGNL9JkHN3KSVf76tGjh5QsWdLdRfI7BM7+i2ufumPHjsm0adNk7ty5cvToUfN+DKRGd2YoUaKEPPTQQ9KtWzfT+W8NTeDSePiHH36QnTt3miRVIDU6eJY3b165//77TTupXLlynCh4jN27d5t+F93aV/tddJKnL9KJW7Vq1TL9BZpowY4qrkeb1T9x3dMeW5k3b57pK1q3bp1cvHjRxVcG3jS2EhYWZsZUdHXdBg0aWH3fLVu2mJh4yZIlEhUVxdgK0hQUFCRVq1Y1YysdOnQgGRUelZSqfS76efnXX3/5bL+Ljq1ERkaaXSy0z6Bo0aLuLpLfoc3qv7j28CQkpAIAAADwOATO/otrDwAAAE9Hm9U/cd0BAADg6Wiz+i+uPTxJZncXAAAAAAAAAAAAAAAAAAAAAN6NhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2IWEVAAAAAAAAAAAAAAAAAAAANiFhFQAAAAAAAAAAAAAAAAAAADYhYRUAAAAAAAAAAAAAAAAAAAA2CXAvrsDvuXYsWMye/Zs+f333+XChQvuLg48VKZMmSQkJEQaNWok7du3l/z581t937i4OJk/f74sWrRIzp49Kzdu3HBqWeG9cuTIIZUrV5aOHTtKhQr/1959gFlV3A8D/im9KCjYURE0ig0FNCqiYCH23rvGXhKjETUae4sldhP/lhhjomJDNCpiFMSGCiqxEGNXlKiAIF2Q75mTbwkouyx77+5t7/s8+7DsbWfOmblnym9m1snyHUAhjR07Nh588MEYOnRoVk+aM2dOvX7e7Nmz5/6+2267RaNGjaK+pe/apZZaKrbeeuvsM9u1a1fvnwm19d1338XTTz8dAwYMyNot6f+wIE2bNo3OnTtnbZWePXvG4ovXbi5y+l4fNWpU3HffffHWW2/FtGnTnGAWKN2Tl1122dhhhx2yn1atWjlTQEGltsOzzz4bDz30UHz00Ucxc+bMBvnMhm6vNGvWLNZcc83Ya6+9YqONNtJXRFH5+OOP4/77748XX3wx6wOH6vpd2rZtG1tttVXsvvvu0b59+1qfqNQXNXDgwBg0aFCMGzfO2ArVatmyZWy44YbZ2Mpaa63lTAEFN2bMmCwG5bnnnmuQGJRCtFVS/+PSSy8dffv2jV122SW73wOVbbE59T2SDCXi7rvvjoMOOmhuI7ZFi5axWC0H7qgsc77/PqZNm5r93qRJkyw4Z6eddlro60aPHh19+vTJAnqSZs2bR6NG5gWwoEw2J6ZPnzb3++jUU0+NK664wkADUDBpMkUKbKoKgGuoetKcOf/9HlxssYapk33//eyY/v8DsFJwTZpA0qtXrwb5bP5nypQp0bp16+z3NJAp0CliwoQJse2228aIESOy89KkadNo0qSpbMMCzZwxPWbNmpX9vt1222XBOc2bN6/xbKWuoZNOOiluvPHGuZ3IzZu3SF/AzjI/Mnv2rJgxfXr2e4cOHWLIkCFZEDRAoeqOO+64YzZxrqqvrknTZg3y2Q3dXpkxfdrcweX9998/7rzzzmjcWN9iQ9JWWbBbb701jjrqqLn/b9mylXokCx1bSQsyPPLII9mk4IV54403suelQNSkeYsWsfji9R9cQwmaMyfLY1XhD+edd16ce+65hT4qoIL1798/DjjggLn1+EoYW2nTpk089dRT0aNHjwb5bP5He4ViIiAVImLYsGHRu3fvWHb5FaLfeZdEr636RouWLZ0bqjVl8rcx5Mkn4rJzTs9+f/nll6Nr167VPj8FU6yxxhrx9ddfxy/PPDd22mOfWGa52q+sSuVJDZMRLz0f1152Ybwx4uW4+uqr4+STTy70YQEV6PXXX4+NN944Wi+xZJxxwe+id9/tolXrJaJcTfxmQgz++8C4/LzfxGIxJ958883o2LFjoQ+roug0+bHUVklBFvsfdlQccMQxsdrqaxTgylAq0sDbv976Z9x24zXx+MMPxMEHH5wFrNTk0ksvjd/85jfRY5OecWK/s2LDjTZpkNUTKF3/+eLzGHj/3XH97y6KlVZaKd59992FBj4D1Ie0wl5aQX63fQ6MQ489MVZfs0vZTuhN9/h/vjYi/njN5fHsU4PilFNOiauuuqrQh1VRtFV+7Iknnojtt98+Vl61Y5x27iXRs/fW2UIMUJ1vJ02Mfzz+aPzu3DNj1nczs36nn/zkJ9U+PwWhpse/nTw5Tj37wth+tz2jXftlnGCqlSbUv/LCsLjmkvPi7X++kQXN//znP3fGgAb3wgsvxBZbbBHtllk2Tj//0ui1dd//TtwpUxPGjYtBjz4UV15wdjRr2jRbrGtRdpold9orFBMBqRARhx9+eNxxxx3xwFPPx5prr+ucUGuvvPhcHL7njgvtAL7nnnuylQtO/e2Fcfhxv3CGqbUU8LzdJl1jheWXy7ZOBWho6R6XguLvePCxLFCpUjz56IA45ehDsyCtM844o9CHU1F0mszv3//+dzb4tsNue8XlN91WoKtCKUqr7R+2xw7x5usj4ssvv8xWJ6guuCWtbjll2vT4+3MjTc5kkfzh97+LG6+8JB5++OFsSzaAhvSf//wnVlxxxdhsy63iD3fdX7aBqAsKtNlr281jwtdfZjsxpVVhaRjaKj+21157ZTuI/f35kbFKx06yIrU29KlBccIh+8Q555wT559//kJX4P3tZb+PfQ8RVMiiTTrfdqN1Y71114mXXnrJqQMaXLp/pfvYfYOejS7rVb+wVbkZcO9f4+xfHR/XX399nHjiiYU+nIqivUIxsR85RGTbsf5k7XUFo7LIUmDO8it2yPJQTaoeTyujwqJIqxButd2O8fbbb8fHH3/s5AENLt3D0r2u+083q6iz36fvDtl38MLu8VDfqvLgjuqRLKLFF188dth9r5g5c2Y888wz1T4vrWz54YcfxjY77CIYlUW2057/beO6XwKF8OSTT2YTMFI9qVKCUZMUgLrdLnvE+PHjs12boFDSxKZUB+jafWPBqCyytJpu26WWrtXYStq9Yftd93SWWSRt2i4VW2zdN4YPH56ttAvQ0NI9rPNP1qqoYNSk7067RpOmTfUVQYUTkAoR8dVXX0WHVWzFyqJLnd0dVu2YrTi0sDyWtipaZjnL0rPoUh6rykcADS3d49L3UCUN8Capw2T5FVda6D0e6ltVHqyqD8CiWHnV1ebLRwtSVcdM26zColpp5VWzOoL7JVDQelIF9uuu3HHh93iob9OmTYupU6dqq1AnjRs3jhU7rLzQ77Fst4e2S8WSbdo609T5fvn11187e0CDS31uK62yasWd+ZatWke79stqq0CFa1zoA4BikGbSN27cqNCHQYlq3KhRzJ49e6F5rFEjX7nUTVXeSfkIoCD1pEaVWU9q1LhxzP5uRqEPo2xMmjQpG6yszaBm2nq1auCpRYsWC31Ny5YtY8kll4xyVHX/b6wuSR0HeefNRzXlMe0V6roSb6NatIkB6rWe9P/vd5Ukffcm+ooatr2irTI/bRXy0e+ysO+xbGylAr/nyQ9jK0Dhx1Yq8x6WYm+0VfLH2AqlqDK//QAAAGjQDpNbbrklZs2aVavn/+IXv8j+7d+/f62en4IQjjrqqLINSgUAAIqjvaKtAgAANBRjK5QqAakAAADUq7TSUBrc3XjjjecLGp04cWKMHDkyWrduHRtuuGGNq1tNmTIlRowYkT2ne/fu0axZs7kdMi+//HL2GQJSAQCAfLRXqmt/LMiMGTOy56b3SM9t1aqVtgoAAFAvbZXq2h8Lkp7z2muvxeTJk6Nbt27Rpk2buY8ZW6E+CUgFAACgQaQOk6WWWir7ffz48VlHSNu2baNXr17RpEmTal/37bffZs9Ng8C9e/eO5s2bu2IAAEC9tFcWpf0xffr0GD58eLYl6VZbbRVLLLGEqwIAANRLW2VR2h/fffddDBs2LJtsl9o1Sy+9tKtCg1m84T4KAAAA/huMOnTo0Gw2bm2CUYcMGZI9RzAqAABQnxal/ZEGg9Nz00Bveq5gVAAAoL4sSvujKhg17VK35ZZbCkalwVkhFQAAgAYjGBUAAChGaeWgtDKqYFQAAKCYzJgxI1sZVTAqpUJAKgAAAA0izcZNA7xWRgUAAIrNiBEjolmzZlZGBQAAiq6t8v333+d1ZdT0flBfFq+3dwYAAIB5jBw5Mu/BqGlmMAAAQK4aN26c12DUWbNmuSgAAEDOUtsi38Goo0aNcmWoNwJSAQAAaBCtW7fOazBqGgxOM4MBAABy1b1797wFo6bnpN0hAAAA8tFWyWcw6osvvhjjxo1zYag3AlIBAABoEBtuuGFeg1HTc606BAAA5EOzZs3yFoyaBoMnT57swgAAADlr1apVXoNRx44dG127dnVlqDcCUgEAAGiwLTDzGYyaOlrSzGAAAID6Updg1DQY3K1bNxcFAACoN3UNRt1ss82iffv2rgz1pvrRQAAAAGgAdQ1GTc+1QioAAFBswahpMHixxRZzYQAAgKILRl1hhRViwoQJrgz1xgqpAAAAlGQwak2DwQAAAIUKRq1pMBgAAKCQwahQ3wSkAgAAUBCCUQEAgGIkGBUAAChGglEpBQJSAQAAaHCCUQEAgGIkGBUAAChGglEpFQJSAQAAaFCCUQEAgGIkGBUAAChGglEpJQJSS8D9998fPXv2jHbt2kXr1q2je/fu0b9//0IfFkXsrJOPi/+77sooVxPGjYst1uscYz8fU+hDqVjyGABQV4JRUZekvsljAEBdzJgxI4YMGZIN9Pbu3TuWWGKJvAwGUzrUI5HHcmP8DgDqx6xZs2rd/vj+++/jxRdfjLFjx8Zmm20WK6ywgstCgxOQWgLSl8QWW2wRt9xySwwcODD69OkT++67bzzwwAOFPjTyZN0V28z92WL91eOXPz8wPv7g/Tq917/efjOGDH48Dvr5sQW5PoMeeSh26LlhdFtt2Thw523jvX+9s0ivv/HKS2PnXj2iR6fls3Nx+olHxVf/GTvfc5Zq1y523mu/uPHKS/J89OVLHvsfeQyguH3y4fvRvdNy8fjD89d1D9ltuzjpsP0Ldlzkx5QpU7IB3iZNmmQDvM2bN8/LykTUr3KpS86YPj3OPvn42GXLjWO9ldrGxb/59SK/h7pk/ZDH5DGAUqG9Ut5GjBghGLXElEs98qnHH4lDd98+NuuySvZzzAF7ZMezKLRV6oc8Jo8BlAptlfL22muv5T0Ydc6cOfV0tCAgtSSceOKJcemll8Yee+wRW221VVx55ZVZgOptt91W6EMjj8674roY8vq7cdNf+sfECRPiuIP3yjq/FtXfbr85ttl+52jZqnWDX5/UQdLv+J/HHvsdHP2fGBrLr7hSHH/wPjFzxoxav0eHVTvG2ZdeFQOGvBQ3//WB+HLsF3HK0Yf+6Hm77nNA/P2h+2LihPF5TkX5ksf+Sx4DKG6rrNY5jjrp1Ljygt/G1KlTsr8NvP+eePedt7I6AqU/wJvvYNQ0M5j6Vw51ydnfz44mTZvEYceeFGuuvW6d3kNdsv7IY/IYQCnQXilvqW2Rz5VR02Aw9a8c6pGvvfxS9PnZDnHrvQPjroFPxZJt2sZR++0W34yv/fiHtkr9kcfkMYBSoK1S3iZPnpz3YNTRo0fX09GCgNSicNNNN8XKK68crVq1ip///Odx9NFHR8eOHWt8TZs2bWLSpEl1/sz0xfL++3WbJUr9WLJNm2i/7HKxbtdu2QDpJx9+EB++92722JH77BIXnnnKfM8f8uTjsdHqK8bUKZPn/m327Nnx5KMPx5bbbLfAzxhw71+z14wc/mLssU3PbBXTtBrptKlT45xTT4zjDtprvuenwI+0ctBnn3xUqzQ88Lc7Y611148jTzolVl+zS5x3xbXx5djPY9jTg2t9Hnbde//46eZbRodVOkaX9brGoUefEK+/OjxbzWheP+myTiyz7HIx+LFHav3ela6mPDbm04/nm+lb9ZPyzLxyyWPJgj4jzdyuLXkMoDL8/ISTo1Xr1nHzNVfE5G8nxe8vOidOOfv8WG6FFQt9aOSocePGeQ1GTc9JM4Opf+XQXmnZslWce/m1scf+B0frJdvU4Sxor9SncmivyGMAlUF7pXx17949r8Goo0aNqqcjpdzaKqede3F27Guvv0F0WuMn2YTc8V9/FSNffrHWF9vYSv0ph7aKPAZQGbRVyle3bt3yGow6cuTIGDNmTD0dLQhILbinnnoqTjjhhGz10wceeCC+/fbbuOuuuxb43NRYSUGo6fHHH388DjvssDp/bpcuXWLrrbfO4cipL6kT5Mm/P5z93qzZfwfqd9nngBg08KH5ZvU++mD/2HbHXeabrfvu22/Gt5MmxjpdN6z2/WfPnhVXXfTbOOWs82PA0y/GQUcdF3NiTrbi6IvPPhPjvv5q7nP//mD/6P7TzbLg0Np4e9TrseFGm8z9/xJLtskCR98aVbcggbT66cD7747V11o7mi0gaGHdDbrHqy89X6f3rmQLymPLr9ghm0Ve9fO7G27NznnqAJtXLnksmfczbus/MJo2axYb9Nio1scujwFUhiZNm8Y5v7s6/nLLTfHbU06Ijp1Wj70POrzQh0WeBnjzGYyaBoPTzGAaTim3V/JNe6V+lHJ7Jd/kMYDipL1SvtKiIfkKRk2DwePGjaunI6Xc2yrpWJIl27at0+vVI+tHObVV5DGA8qStUr7SooX5DEb94IMPsrgxqC+N6+2dqZVrr702Nt544+zfJAWJdujQodovmClTpkSjRo3immuuiSOPPLLgZzkNGH/0Ue1meFKzM39xTJx18vEx7f9vTbvbPgfGqp06Z79vu8MucfFvfh3PPT0427ZlyuRvs1m8N95573zv8flnn8Ziiy0Wyyy3fLWfM3PGjPjlGefExj23mLt0e5I6R1bosHI8PuCBOOjIY7Mb0WMDHojjTjm91pduwvivY6ml28XgxwbGBf1Ojv6Dno22S7eLCeO+XqTLP2TwE3HacUdk56Jr943ilrsfWuDz0ippb74+MopBusnXtKR5KrvFnMfS90qa4Zt89Z+xcfn5v4nTz780CyjOVx5Lqj4jbcF88VmnxcFHHR89e29T6zRUch5L0vftkksuWejDACpMobYY7LFJz+i97XbZ6hEDnnkpu/8UwsyZM21bkgfffPNN9m+zZs3yGoyaBoPTzOBXXnklu09WfU45KZZB7HJor+RLKdYlU2dkde2Vjz/+OIpBObRXKjmPpckBtvkCGtqXX35ZsJNeLO2VtKKN79/cLawdUZdg1FT/6tq1a7z++utl21Yphj7vcm2rXHvpBbHeht2j28abln098rtZs2r8Hps2bVqDHk+ltFUqKY8lKeimUPdqgEptq6T+fm2V3C2sHVHXYNQePXpE27Zt45133inb9kop6dixY42LuZQiAakF9sYbb8R+++039/9NmjSJLbbYIhtQ/aGqDo9BgwbFaaedln2R7LnnnnX63PRFkw/pi+mggw7Ky3tVulPPvjA223KrGP780Bj2j8Hx28t+P/exFi1bRt+ddo1HH7w36zR56vFHsyC8qkZplbStfeMmTWLxxRev9nNShWPeVUznteveB2SfkTpNRgx/IQvy+9nOuy1yWlq3XiLrgEkzNOti45694v4nh8UXYz6NG664JC797elx1c13/Oh56f2nTy98Z0QyderUGsvCv//977yVu/rIY/OuxJw6Ezbdok/sc/ARP3o81zxW5fx+J0e7ZZaNX5z+2zqlpRLzWHLuuefWuFIDQH3d4wrhm/Hj49UXn4/WSyyZDRatvmZhZmqmRrz6bu5Sx8a2226b92DUNBhc1aF29tlnl2WnSbFsm1NO7ZVclWJd8k9/+lM8+uijC3ws7dRSDMqpvVJpeSw1dV999VX3S6AgdfVCKZb2Slro4s477yzIZ1dKe6WuwahpMLhqQLFc2yqpblYMyq2tcvuN18QrLz4Xf3v0qRqPpxzqkcn48eNrrEe+++670WKe1WwLodzaKpWWx5J+/fpFixYtCn0YQIUpVF2pGNoqqa9ILFH9t1VyCUZdbbXVYsKECWXdXikld911V6y11lpRTgSkFsEs7qWWWmq+v/3w/1U23PC/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5YVhMX3atGjeokU9XBnK1UfvvxefffxRHHHEETU+L9UzBw0aFK+++Fxs0qt3gx0f5THZPNUROnToECuuWDl9mkDxSPewwYMHZwtftFlq6agUr7/6cjaZpKb+SBaNtgqlaPFCHwAUgxRM+N3MmfHbU07IVrGE2kgVqbN/dfzcPFSTvfbaK/v3ivN/E598VLtl0iHN+r7pqsvi3++8FXvssUc0adLESQEaXNU97qyTj8vufZVg/Liv47zTflGrezzUt169esXyyy8fd95yU7z8wjAnnFoPvA165KH4+4P9o1u3btG5c+dqn9u8efPYdddd45+vjYjbbrg6W+0SauPD9/4dv7/43CwYJbVXABpa165dY4011oj7//bnGDL4iYrYFjKtNnTfXX/KAmy22WabaNeuXaEPiQqX2sxpTOXc036RBaVCbaTAnDQeV5WHarL33ntn/15y1mnxxZjPnGBq5bvvvovfX3ROjPn0kywPpTYLQENL97g01nvWycfH1CmTK+ICpEU+LjrzlOx3YytQ2RabUwm9NLAQqSJwyCGHxN13353N4t1o081jqXbtY/HFNFD4se/nfB9ff/mfePWl52PmjBlx7LHHxo033rjQBu2tt96abf2UtjHq2n3j6LBqx2jcyELV/NicmBNTJn8bI156IdtmdcMNN4ynnnoqWyUVoBADnscff3zcfPPN0bRZs+ixSc9ov+xyZVlPmv397PjPF2Ni5PAXs/rh2WefHRdccEF274ZCGjZsWGy//fYxZcqUWH3NLvGTLutE06bNXBQWaPr0afHWGyPj048/imWXXTaeeeaZbBXUmnz55Zex9dZbx5tvvhnt2i8T3X66abRs1ToWC99//Nh3s76LTz/6IEaNfDW7R955551x0EEHOVVAQYwcOTILzJwwYUJ07LR6dFmvazRr1rws+4qmT5sab4x4JduxqWPHjjFkyJBYddVVC31oVLiZM2dmwV4DBw6Mli1bRY/NNo+llm6nHkm1/S5fjf0iRgx/IQsYPPXUU+OKK65YaL/LNddcE7/61a+yMZgNN9okVuiwsrEVqr1ffjtpUox46bmY+M032eqETzzxhB17gIJIk74PO+ywuOuuu8o+BiXd49PEkddefjFL96WXXhpnnHFGoQ8LKCABqfD/paCDFGhx7733xvPPP58FX0B1GjduHFtssUXsv//+2ZYytZ1dmRq+t912Wzz++ONZQAHUJAUOpNljJ510kmBUoKBSvej222/PJu88++yzWb2pXDVt2jQLykqBNek+LxiVYvHaa6/FH/7whxgwYEB89dVXhT4cilzaknDPPfeME088MVZfffVavSblq+uvvz7uu+++GD16dL0fI6WtdevWseOOO8aRRx6ZBYIBFNI777yTTRZ/8MEH44svvijri9GpU6dsJ6bUV5Tu91AsQampDPbv3z+GDx9eEasVU3dpF7A+ffrEgQceGAcffHCt+10efvjhuOOOO2LQoEExzWq8LMT6668/d2wlbXMMUCgpOLMqBuW5554r6xiUtAvTtttuG4ceemjWLwlUNgGpsACpIjB16lTnhgV/cS62WLRs2TKnAJXUKZc6Tcq50knulfYU+AxQbNI9LNWTynGAKR/3eGgIM2bMyFaTgeoC69NPLtLEg+nTpzvBLFCjRo2y9or7JVCsgXHppxw1a9YsC+SCYmZshZoYW6EhtGjRImuzABSbcq4npcW70vevviKgioBUAAAAAAAAAAAAAHJSuz2mAQAAAAAAAAAAAKAaAlIBAAAAAAAAAAAAyImAVAAAAAAAAAAAAAByIiAVAAAAAAAAAAAAgJwISAUAAAAAAAAAAAAgJwJSAQAAAAAAAAAAAMiJgFQAAAAAAAAAAAAAciIgFQAAAAAAAAAAAICcCEgFAAAAAAAAAAAAICcCUgEAAAAAAAAAAADIiYBUAAAAAAAAAAAAAHIiIBUAAAAAAAAAAACAnAhIBQAAAAAAAAAAACAnAlIBAAAAAAAAAAAAyImAVAAAAAAAAAAAAAByIiAVAAAAAAAAAAAAgJwISAUAAAAAAAAAAAAgJwJSAQAAAAAAAAAAAMiJgFQAAAAAAAAAAAAAciIgFQAAAAAAAAAAAICcCEgFAAAAAAAAAAAAICcCUgEAAAAAAAAAAADIiYBUAAAAAAAAAAAAAHLSOLeXA+Xum2++iZtuuinefvvtWGqppeLwww+Pbt26FfqwKCOvvPJKDBw4MD744INYY4014rzzziv0IVGkZs2aFTfffHP885//jGnTpsWKK64YBx10UKyzzjqFPjTq2VVXXRX/+te/YsaMGbHMMsvEfvvtFz169HDeK8TEiRPj5JNPji5dukS/fv0KfTg0gFQXePfdd6NRo0bZ/1O5//3vf+/cs8C6wV133RXPPfdczJw5M1ZdddW48MILnSny5uuvv45f/epX8/0t5bWf/exnccQRRzjTzOfjjz+O2267Lfu3VatWsfPOO8f222/vLFWA999/P26//fb49NNPY8kll8zaK5tvvnmhD4sG7L/6xz/+Effdd19MnTo1a6see+yx0bRpU9egjK/7999/H9ddd13Wbkn1hXPPPVf/FNXml5EjR8b9998fY8aMiebNm8fGG28cBx98sO8J8vad9Nprr2Vt4/R9lO4/G2ywQTaW17JlS2e5gtVm7O3uu++Ohx56KC6//PLo2LFjQY6Thrnub731Vpx//vnRrFmzuc89+uijo1evXi5BmZf30aNHx5///Of47LPPsvvCoYceGptttllBj5f6v/b/93//F8OGDZv7vNR+SX3pt9xyS9ZvAQ1BQCpQo3SzatGiRdx6663x+uuvx9VXXx3XX399tG3b1pkjL1Lld8cdd8wqSqkTF6qTKsspKCkFmrRv3z6GDx+edZSkAYA2bdo4cWVs9913jw4dOmQdqum7InWcpCDVlA8of3fccUcWgE5lOfDAA7P6AdTkL3/5S9apetFFF8Vyyy2XBYFBPqW6Rspn8wajHnPMMTruWaDUV7Leeutlnf9poOess86Kzp07x09+8hNnrIylAZ0rr7wydtpppywA+Y033sjaqZ06dVKHrZD+q/T/P/3pT3H22WfHKqusEpdddlncc889ccghhxT0eKn/fss04LvDDjvExRdf7HRTY36ZPn167LPPPrH22mtn9ckrrrgi+vfvn020h3x8J6X7z5lnnhnt2rWL7777LhvXSwGqKdiMyrWwsbc0mSr1qVA51z09lvraqZzrniYqXHLJJVmdo3fv3ln7ddKkSQU9Vhrm2qc6wLz1gAEDBmQLPglGpSEt3qCfBpSUtAJhmr27xx57ZDN3N9lkk6wzPc20gHxJq1umvCWgkIVJwYip8zYFpS622GJZvmncuLHgkwqQBnPT9Z8zZ07WYE4/X3zxRaEPiwaQJsOklXG7du3qfAPzSQO5Tz/9dLbqy/LLL5/VDazmQX176aWXso7btdZay8nmR7766qvYdNNNY/HFF8+CAlZeeeVskJfy9vnnn2e7C6Vg1HTtN9xww+x+lL4vqIz+qxdeeCFbiS7dG9Jg4C677JKt3k55X/dU3tPAb5p0kOqhUFN+SauQpe+J1LfVunXrrL6QdgKCfH0npUDUNJkufR/Nnj07W9ghTZCistU09pb62dMqeWmlRMqLMdfKVN11HzJkSDaJqm/fvlk9JLVXUj8qlVXm03d+2tWjT58+DXpsYIVUoFop2CfdoFZaaaVs1aEUmJpWqNOQBYrlOypth5e+oyh/aaXuZ555Jpvln1aaWnPNNQt9SNSzFIiatpI544wzYujQoc53hXnwwQezLQ1XWGGF2H///bMV5+CH9YAUlPree+9luzikTtVtttkmdt11VyeKeqPzlprsvPPOWRBimkyVtuRNAarrrruuk1bBgapUhlTeUxDyiy++mO3kst9++2VBypMnT84CzwB+KK1elSavQD6lVfBOPfXUbKGZRo0axQknnOAEU63Bgwdn4yqp7ULlSCt2p11f0sSaHj16ZDtUpQWpKF8fffRRNmEh7Tr4ySefZO2Wo446SlBqhXnrrbey9unGG29c6EOhwghIBWoMBEkDu2k2ZVrVY+LEidnMmVRhBSikFJR44403Zlu5pxnglL8jjzwyWwVv1KhR2eB+uj9R3u67775sZmfahpvKkrYQSpOgUufos88+m217m7bClReYV5qUUjWYe+2118a4cePinHPOyQZ20+p0UB8BRym/nXzyyU4uC5RWPvvDH/4Qjz32WLY61RFHHOHeVQHSTkJt27aNJ554Ilt1JrVXPv7442zQj8rpP23RokUWCJTuFanvNEn9pwJSgR9Ku8+loIDf/e53Tg55leoeaWL3hAkTst1E0grOsCApjzz88MNx6aWXOkEVJAUg//73v88CEb/88su4/vrr484775xvS2/Ks//0jTfeiDPPPDO7L/z1r3+N6667Li655JJCHxoN6KmnnoqePXsaV6XBLd7wHwmUimbNmmWrDqUtsW+++eZsK5k0u9JsKaCQUpB8ajClhvPee+/tYlSQNLs/BRmNGDHCFphlLs3WTasL7bbbboU+FApg9dVXz+qbVStepgDD119/3bXgR22VtJvDTjvtlOWX1LHevXv3+Oc//+lMUW+ro3bt2jWWWmopZ5gFDvKknWXS9s1/+9vf4qqrrooBAwbEq6++6myVudRn9utf/zpbHTMN5g4aNChbdaQqKJHKqJOk4NO0SvIVV1yR9Z0m+k+BH/rXv/6V7QB0+umnZ5MZoD6k9kpqtwh6pjopcDnVW5ZcckknqYKk+06aTJcWAKgaW3v55ZcLfVjUs9S/vtZaa8Xaa6+dtV132GGHbLepqjYL5W/SpElZWd9qq60KfShUIAGpQLXSFqlpVY/PPvts7t/SSqlpxSqAQkiBJ2nVoRSUetxxx2XfUVTuViOUrw8++CD+85//xMEHHxz77LNPtnV7CuhI28lQeVJHqe97fiitmCtf0JCr8w8dOlTnLTVuz55WSUwd/Om+lQb61ltvvWwlEspf586d48ILL4zbb789W3lm7Nixtj+tIGlSTJpQN2/faRrwtzoqMK8PP/wwW5kurbZvi2waQhrXmzVrlpPNj/z73//O6q2pzzX9JP369Ysnn3zS2aog+lsrJ9aDypb6M1ObVf2TQhCQClQrbTfVrVu3ePDBB7OBlTR7Ig2ybLTRRs4aeZMCC9NKvLNnz86CDdPvOkqoTlpF4Jtvvsk6b9NqmZS/FJQ4ZMiQbNWp9H2RtjZL22CmWZ2Ur969e0f//v3n/uy1117Ro0ePuOWWWwp9aNSzKVOmxMiRI+fWDZ599tksAD2t7gHzatWqVay//vrx6KOPZvklBf+kvJMCwCDfUls4Ddak9jEsSApAbdKkSVZvTXXWr776Kt58881YeeWVnbAKkLZpT/1m6SetjJu2bk/b4VEZ/VebbbZZFnyeVj5M7dZHHnkkNt9880IfLg3Qb5kmrKT/J+lv6ff0HCpXdfklBa1fdtll2eT6Ll26FPowKcM89swzz2T5LD0+ceLErC8t7T6TVsOjclWXX2688cb5+l2Tyy+/PPr27VvoQ6Yer3vaUejLL7/M/jZu3LhsAQjj/eV/3TfZZJN46623YvTo0dljTzzxRHZ/SDEgVEacxdNPPx19+vQp6DFSuRabo4UM1CAFfqXGyTvvvJNt9XH44YcbhCOv0oDdTTfdNN/fttxyyzjhhBOcaeaTBnVTvkgDvSkgoEraFrFXr17OVhlf93QfSqvMpIZU+/btY/vtt9dBVmFS52gKSkyz9Sn/LWQuvvji+OKLL7LVL9PK/Pvvv3+su+66hT40ilDqQP/jH/+YdaqmVcjS/WGXXXYp9GFRhi644ILo2LFjHHLIIYU+FIpYGuD761//mt3D0lbdqY1ywAEHzNd2oTylyRFpMncKTkurjqS+s/SdQeX0X/3jH//I2iwpIDVNpDv22GOjWbNmBTtWGua6p5/UZzGvG264IZZddlmXoEJVl19S2zatTpW2za2yzDLLZCumQj7yWFr5LAWcTJgwIctnKfA5tV18H1W22o69pVVSU0Cq+mt5X/dVVlklBg4cmG3VniZ5p0DF1Oea2q6Ud3lPQahp4mS69ml3jzSmuvzyyxfsWGm4a5/ie9JuLjfffHMsscQSTj0NTkAqAAAAAAAAAAAAADkxRR8AAAAAAAAAAACAnAhIBQAAAAAAAAAAACAnAlIBAAAAAAAAAAAAyImAVAAAAAAAAAAAAAByIiAVAAAAAAAAAAAAgJwISAUAAAAAAAAAAAAgJwJSAQAAAAAAAAAAAMiJgFQAAAAAAAAAAAAAciIgFQAAAAAAAAAAAICcCEgFAAAAAAAAAAAAICcCUgEAAAAAAAAAAADIiYBUAAAAAAAAAAAAAHIiIBUAAAAAAAAAAACAnAhIBQAAAAAAAAAAACAnAlIBAAAAAAAAAAAAyImAVAAAAAAAAAAAAAByIiAVAAAAAAAAAAAAgJwISAUAAAAAAAAAAAAgJwJSAQAAAAAAAAAAAMiJgFQAAAAAAAAAAAAAciIgFQAAAAAAAAAAAICcCEgFAAAAAAAAAAAAICcCUgEAAAAAAAAAAADIiYBUAAAAAAAAAAAAAHIiIBUAAAAAAAAAAACAnAhIBQAAAAAAAAAAACAnAlIBAAAAAAAAAAAAyImAVAAAAAAAAAAAAAByIiAVAAAAAAAAAAAAgJwISAUAAAAAAAAAAAAgJwJSAQAAAAAAAAAAAMiJgFQAAAAAAAAAAAAAciIgFQAAAAAAAAAAAICcCEgFAAAAAAAAAAAAICcCUgEAAAAAAAAAAADIiYBUAAAAAAAAAAAAAHIiIBUAAAAAAAAAAACAnAhIBQAAAAAAAAAAACAnAlIBAAAAAAAAAAAAyImAVAAAAAAAAAAAAAByIiAVAAAAAAAAAAAAgJwISAUAAAAAAAAAAAAgJwJSAQAAAAAAAAAAAMiJgFQAAAAAAAAAAAAAciIgFQAAAAAAAAAAAICcCEgFAAAAAAAAAAAAICcCUil7Y8eOjV69esXkyZML8vlDhgyJnXfeuSCfDQAAAAAAAAAAAA1BQCo5+/zzz6NHjx7x7bffzv3beeedF1dddVVRnN3ll18+hg0bFq1bty70oZS1FHSbgm8r3bhx4+IXv/hF9OzZM3bbbbd47rnnGuS1hZLLMaf8csQRR2SvPfroo6MU1DW9s2bNyr4Xd9hhh9hyyy3jkEMOiVdffTXK+fr269cvfvazn2Xp3W+//WLo0KFR7HLJk6VYfnNJbymW37oec6mW31yuUamV31yvUamV31zTW2rlN5f0lmL5zfWYS638JurP6s/lUn4T9eeGOVeFov4cZV1+1Z/Vn+sjbxSC+nP5158BAACg2DUu9AEAlJNLLrkkWrVqFU899VS88MILceaZZ8aAAQOiXbt29fraQsnlmFOQ+AEHHBD/+te/4o033ohSUNf0zp49O1ZYYYW47bbbsiD5p59+Ok499dR46KGHYumll45yvL5psKZjx47RvHnzeOedd+LYY4+Ne++9N0t/scolT5Zi+c0lvaVYfut6zKVafnO5RqVWfnO9RqVWfnNNb6mV31zSW4rlN9djLrXym6g/qz+XS/lN1J8b5lwVivpz7ZRq+VV/Vn+uj7xRCOrP5V9/BgAAgGJnhVTqXZqR3Lt377jjjjti6623jh133DGGDx8+9/G77rordt9999h8882zx/7617/O9/rHHnssdt1119hiiy2yfwcNGjT3sYkTJ8avfvWr6NOnT2y11VZZh9H3338/9/F99tkne98fruCafPTRR3HYYYdFr1694uyzz4599903HnnkkVod86RJk+L888/PZk+nFR9uueWWmDNnTvZY+vcPf/hD9O3bN3baaacYNWpUrc9V+vx0HOm9U3oPPfTQ+PDDD2t9rqqO+4knnsg+O6Xt+uuvX+hr0+qmp5xySmy77bZZmtP/07mZPn36QtN7+umnZ58zduzYOOuss7Lf999//1qdq4Ud88Kub5I6CPfcc89an+OFfe57772XnaOpU6fOfW4aIKvNZ0yZMiVb1SV1ZLZo0SLLO6usskqtVo7N5bWlmN4klcttttkmllpqqci3Yktvs2bN4phjjskG5RZbbLHstY0bN4533303yjG9yVprrZV15qfynlbn+O677+KTTz6JYk1vLnmyFMtvrmWw1MpvLsdciuU312tUauU3l2tUiuU31zxZauU3l/SWYvnN9ZgLUX6T3/3ud9n/q3423njjuW2rcqs/Fyq9hSq/hUpvocpvodJbiuW3FOvPhUpvrq8ttfSWYvktxfpzLuktxfpzodJbiuW3FOvPhUpvfZdfAAAAqFRWSKVBpMHYRo0axZNPPhk333xzXHvttfG3v/0teyytiHHl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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def hardware_efficient_ansatz(num_qubits: int, num_layers: int) -> Circuit:\n", + " circuit = Circuit()\n", + " for layer in range(num_layers):\n", + " for q in range(num_qubits):\n", + " circuit.ry(q, FreeParameter(f\"ry_{layer}_{q}\"))\n", + " circuit.rz(q, FreeParameter(f\"rz_{layer}_{q}\"))\n", + " for q in range(num_qubits - 1):\n", + " circuit.cnot(q, q + 1)\n", + " circuit.barrier()\n", + " return circuit\n", + "\n", + "\n", + "ansatz = hardware_efficient_ansatz(num_qubits=4, num_layers=3)\n", + "print(f\"Parameters: {len(ansatz.parameters)}\")\n", + "ansatz.show()" + ] + }, + { + "cell_type": "markdown", + "id": "789bff99", + "metadata": {}, + "source": [ + "## Text diagram remains available\n", + "\n", + "The graphical renderer is additive. The Unicode text diagram you get from `print(circuit)` or `str(circuit)` is unchanged, which is useful in terminals, logs, and CI output." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "57acff31", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ Result Types │\n", + "GP : │ 0.50 │0.50 │ 0.50 │ 0.50 │\n", + " ┌───────────┐ ┌────────────────┐ ┌─────────────┐ \n", + "q0 : ─┤ Rx(theta) ├───●───┤ Expectation(Z) ├─┤ Probability ├─\n", + " └───────────┘ │ └────────────────┘ └──────┬──────┘ \n", + " ┌─────────┐ ┌─┴─┐ ┌──────┴──────┐ \n", + "q1 : ──┤ Ry(phi) ├──┤ X ├────────────────────┤ Probability ├─\n", + " └─────────┘ └───┘ └─────────────┘ \n", + "T : │ 0 │ 1 │ Result Types │\n", + "\n", + "Global phase: 0.5\n", + "\n", + "Unassigned parameters: [phi, theta].\n" + ] + } + ], + "source": [ + "print(annotated)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/setup.py b/setup.py index 8a86cbb52..9fb0aedff 100644 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ "openqasm3", "sympy", "backports.entry-points-selectable", + "matplotlib", ], extras_require={ "test": [ diff --git a/src/braket/circuits/circuit.py b/src/braket/circuits/circuit.py index 9b627a6a9..db26b322c 100644 --- a/src/braket/circuits/circuit.py +++ b/src/braket/circuits/circuit.py @@ -30,6 +30,9 @@ from braket.circuits.free_parameter import FreeParameter from braket.circuits.free_parameter_expression import FreeParameterExpression from braket.circuits.gate import Gate +from braket.circuits.graphical_diagram_builders.matplotlib_circuit_diagram import ( + MatplotlibCircuitDiagram, +) from braket.circuits.instruction import Instruction from braket.circuits.measure import Measure from braket.circuits.moments import Moments, MomentType @@ -1653,6 +1656,9 @@ def to_unitary(self) -> np.ndarray: return calculate_unitary_big_endian(self.instructions, qubits) return np.zeros(0, dtype=complex) + def show(self, circuit_diagram_class: type = MatplotlibCircuitDiagram) -> None: + circuit_diagram_class.build_diagram(self) + @property def qubits_frozen(self) -> bool: """bool: Whether the circuit's qubits are frozen, that is, cannot be remapped. diff --git a/src/braket/circuits/graphical_diagram_builders/__init__.py b/src/braket/circuits/graphical_diagram_builders/__init__.py new file mode 100644 index 000000000..d3fa8b05c --- /dev/null +++ b/src/braket/circuits/graphical_diagram_builders/__init__.py @@ -0,0 +1,18 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from braket.circuits.graphical_diagram_builders.matplotlib_circuit_diagram import ( + MatplotlibCircuitDiagram, +) + +__all__ = ["MatplotlibCircuitDiagram"] diff --git a/src/braket/circuits/graphical_diagram_builders/graphical_circuit_diagram.py b/src/braket/circuits/graphical_diagram_builders/graphical_circuit_diagram.py new file mode 100644 index 000000000..d9b309875 --- /dev/null +++ b/src/braket/circuits/graphical_diagram_builders/graphical_circuit_diagram.py @@ -0,0 +1,336 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from __future__ import annotations + +from abc import abstractmethod +from functools import reduce + +import braket.circuits.circuit as cir +from braket.circuits.circuit_diagram import CircuitDiagram +from braket.circuits.compiler_directive import CompilerDirective +from braket.circuits.gate import Gate +from braket.circuits.graphical_diagram_builders.graphical_diagram_utils import ( + BarrierMarker, + CircuitLayout, + Connection, + ControlDot, + GateBox, + SwapMarker, + _categorize_result_types, + _compute_moment_global_phase, + _group_items, + _has_global_phase, +) +from braket.circuits.instruction import Instruction +from braket.circuits.result_type import ResultType +from braket.registers.qubit import Qubit +from braket.registers.qubit_set import QubitSet + + +class GraphicalCircuitDiagram(CircuitDiagram): + """Abstract base class for graphical circuit diagrams. + + Subclasses must implement ``_render_layout`` which converts a + :class:`CircuitLayout` into a visual output (e.g. a matplotlib Figure). + + The layout-computation pipeline mirrors + ``TextCircuitDiagram._build()`` so that maintainers familiar with + the text path can follow along easily. + """ + + @classmethod + @abstractmethod + def _render_layout(cls, layout: CircuitLayout) -> object: + """Convert a CircuitLayout into a visual output.""" + + @classmethod + def _compute_layout(cls, circuit: cir.Circuit) -> CircuitLayout: + """Compute a :class:`CircuitLayout` for *circuit*. + + Pipeline (parallel to ``TextCircuitDiagram._build``): + 1. Collect qubit labels and initialise metadata. + 2. Walk time-slices and convert each moment into layout primitives. + 3. Append result-type columns. + 4. Return a ``CircuitLayout`` ready for rendering. + """ + circuit_qubits = circuit.qubits + circuit_qubits.sort() + + qubit_labels = [f"q{int(q)}" for q in circuit_qubits] + qubit_index = {q: i for i, q in enumerate(circuit_qubits)} + + global_phase: float | None = 0 if _has_global_phase(circuit) else None + + elements: list = [] + moment_labels: list[str] = [] + col = 0 # current column index + + # --- moment columns --- + time_slices = circuit.moments.time_slices() + for time, instructions in time_slices.items(): + global_phase = _compute_moment_global_phase(global_phase, instructions) + + groupings = _group_items(circuit_qubits, instructions) + for grouping in groupings: + cls._compute_column_elements( + col, circuit_qubits, qubit_index, grouping[1], global_phase, elements + ) + moment_labels.append(str(time)) + col += 1 + + # --- result-type columns --- + additional_result_types, target_result_types = _categorize_result_types( + circuit.result_types + ) + if target_result_types: + groupings = _group_items(circuit_qubits, target_result_types) + for grouping in groupings: + cls._compute_column_elements( + col, circuit_qubits, qubit_index, grouping[1], global_phase, elements + ) + moment_labels.append("Result Types") + col += 1 + + # --- unassigned parameters --- + unassigned = ( + [str(p) for p in sorted(circuit.parameters, key=lambda p: p.name)] + if circuit.parameters + else [] + ) + + return CircuitLayout( + num_qubits=len(circuit_qubits), + num_moments=col, + qubit_labels=qubit_labels, + moment_labels=moment_labels, + elements=elements, + global_phase=global_phase, + additional_result_types=additional_result_types, + unassigned_parameters=unassigned, + ) + + @classmethod + def _compute_column_elements( + cls, + col: int, + circuit_qubits: QubitSet, + qubit_index: dict[Qubit, int], + items: list[Instruction | ResultType], + global_phase: float | None, # noqa: ARG003 + elements: list, + ) -> None: + """Populate *elements* with layout primitives for one column. + + This mirrors ``UnicodeCircuitDiagram._create_diagram_column`` but + emits dataclass primitives instead of characters. + """ + symbols: dict[Qubit, str | None] = dict.fromkeys(circuit_qubits) + connections: dict[Qubit, str] = dict.fromkeys(circuit_qubits, "none") + + # Track per-item qubit ranges for emitting separate Connection elements + item_qubit_ranges: list[tuple[int, int]] = [] + + for item in items: + ( + target_qubits, + control_qubits, + qubits, + connections, + ascii_symbols, + map_control_qubit_states, + ) = cls._build_parameters(circuit_qubits, item, connections) + + # Record this item's qubit span for connection drawing + if len(qubits) > 1: + item_rows = [qubit_index[q] for q in qubits if q in qubit_index] + item_qubit_ranges.append((min(item_rows), max(item_rows))) + + cls._assign_qubit_symbols( + qubits, + target_qubits, + control_qubits, + ascii_symbols, + map_control_qubit_states, + item, + symbols, + ) + + cls._emit_symbol_elements(col, circuit_qubits, qubit_index, symbols, elements) + + # Emit connections - one per item so independent gates don't bridge + for row_start, row_end in item_qubit_ranges: + elements.append(Connection(col=col, row_start=row_start, row_end=row_end)) + + cls._emit_barrier_elements(col, items, qubit_index, circuit_qubits, elements) + + @classmethod + def _assign_qubit_symbols( + cls, + qubits: QubitSet, + target_qubits: QubitSet, + control_qubits: QubitSet, + ascii_symbols: list, + map_control_qubit_states: dict, + item: Instruction | ResultType, + symbols: dict[Qubit, str | None], + ) -> None: + """Assign a symbol string to each qubit involved in an item.""" + for qubit in qubits: + if qubit in target_qubits: + item_qubit_index = next( + index for index, q in enumerate(target_qubits) if q == qubit + ) + power_string = ( + f"^{power}" + if ( + (power := getattr(item, "power", 1)) != 1 + and ascii_symbols[item_qubit_index] != "C" + ) + else "" + ) + symbol = ( + f"{ascii_symbols[item_qubit_index]}{power_string}" + if power_string + else ascii_symbols[item_qubit_index] + ) + symbols[qubit] = symbol + elif qubit in control_qubits: + symbols[qubit] = "C" if map_control_qubit_states[qubit] else "N" + # Qubits inside the gate span but not involved (pass-through) are + # left with symbols[qubit] = None. The Connection primitive + # emitted for the item handles drawing the wire across them; + # no per-row primitive is needed or wanted. + + @classmethod + def _emit_symbol_elements( + cls, + col: int, + circuit_qubits: QubitSet, + qubit_index: dict[Qubit, int], + symbols: dict[Qubit, str | None], + elements: list, + ) -> None: + """Convert symbols into layout primitives.""" + for qubit in circuit_qubits: + row = qubit_index[qubit] + symbol = symbols[qubit] + if symbol is None: + continue + + if symbol in {"C", "N"}: + elements.append(ControlDot(col=col, row=row, filled=(symbol == "C"))) + elif symbol == "SWAP": + elements.append(SwapMarker(col=col, row=row)) + elif symbol != "||": + elements.append(GateBox(col=col, row=row, label=symbol)) + + @classmethod + def _emit_barrier_elements( + cls, + col: int, + items: list[Instruction | ResultType], + qubit_index: dict[Qubit, int], + circuit_qubits: QubitSet, + elements: list, + ) -> None: + """Emit barrier marker elements for barrier instructions. + + A barrier is represented as one ``BarrierMarker`` per targeted + qubit (or every qubit when no target is given). Rendering is per + qubit, so qubits not included in the barrier's target get no + marker, making the scope unambiguous. + """ + for item in items: + if not ( + isinstance(item, Instruction) + and isinstance(item.operator, CompilerDirective) + and item.operator.name == "Barrier" + ): + continue + + target = item.target or circuit_qubits + elements.extend(BarrierMarker(col=col, row=qubit_index[q]) for q in target) + + @classmethod + def _build_parameters( + cls, + circuit_qubits: QubitSet, + item: ResultType | Instruction, + connections: dict[Qubit, str], + ) -> tuple: + map_control_qubit_states: dict = {} + + if isinstance(item, ResultType) and not item.target: + target_qubits = circuit_qubits + control_qubits = QubitSet() + qubits = circuit_qubits + ascii_symbols = [item.ascii_symbols[0]] * len(qubits) + cls._update_connections(qubits, connections) + elif isinstance(item, Instruction) and isinstance(item.operator, CompilerDirective): + if item.operator.name == "Barrier": + if not item.target: + target_qubits = circuit_qubits + qubits = circuit_qubits + ascii_symbols = [item.ascii_symbols[0]] * len(circuit_qubits) + cls._update_connections(circuit_qubits, connections) + else: + target_qubits = item.target + qubits = target_qubits + ascii_symbols = [item.ascii_symbols[0]] * len(target_qubits) + control_qubits = QubitSet() + else: + target_qubits = circuit_qubits + control_qubits = QubitSet() + qubits = circuit_qubits + ascii_symbols = [item.ascii_symbols[0]] * len(qubits) + cls._update_connections(qubits, connections) + elif ( + isinstance(item, Instruction) + and isinstance(item.operator, Gate) + and item.operator.name == "GPhase" + ): + target_qubits = circuit_qubits + control_qubits = QubitSet() + qubits = circuit_qubits + # GPhase does not draw on any qubit wire — use None as sentinel + ascii_symbols = [None] * len(circuit_qubits) + else: + if isinstance(item.target, list): + target_qubits = reduce(QubitSet.union, map(QubitSet, item.target), QubitSet()) + else: + target_qubits = item.target + control_qubits = getattr(item, "control", QubitSet()) + control_state = getattr(item, "control_state", "1" * len(control_qubits)) + map_control_qubit_states = dict(zip(control_qubits, control_state, strict=True)) + + target_and_control = target_qubits.union(control_qubits) + qubits = QubitSet(range(min(target_and_control), max(target_and_control) + 1)) + ascii_symbols = item.ascii_symbols + cls._update_connections(qubits, connections) + + return ( + target_qubits, + control_qubits, + qubits, + connections, + ascii_symbols, + map_control_qubit_states, + ) + + @staticmethod + def _update_connections(qubits: QubitSet, connections: dict[Qubit, str]) -> None: + if len(qubits) > 1: + connections |= dict.fromkeys(qubits[1:-1], "both") + connections[qubits[-1]] = "above" + connections[qubits[0]] = "below" diff --git a/src/braket/circuits/graphical_diagram_builders/graphical_diagram_utils.py b/src/braket/circuits/graphical_diagram_builders/graphical_diagram_utils.py new file mode 100644 index 000000000..cced2b0b1 --- /dev/null +++ b/src/braket/circuits/graphical_diagram_builders/graphical_diagram_utils.py @@ -0,0 +1,182 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from __future__ import annotations + +from dataclasses import dataclass, field +from functools import reduce +from typing import TYPE_CHECKING + +from braket.circuits.compiler_directive import CompilerDirective +from braket.circuits.gate import Gate +from braket.circuits.instruction import Instruction +from braket.circuits.moments import MomentType +from braket.circuits.quantum_operator import QuantumOperator +from braket.circuits.result_type import ResultType +from braket.registers.qubit_set import QubitSet + +if TYPE_CHECKING: + from braket.circuits import Circuit + + +@dataclass +class GateBox: + """A gate drawn as a labelled box.""" + + col: int + row: int + label: str + + +@dataclass +class ControlDot: + """A control qubit indicator (filled = control, open = anti-control).""" + + col: int + row: int + filled: bool + + +@dataclass +class SwapMarker: + """A SWAP gate drawn as an 'x' on a qubit wire.""" + + col: int + row: int + + +@dataclass +class Connection: + """A vertical wire connecting qubits of a multi-qubit gate.""" + + col: int + row_start: int + row_end: int + + +@dataclass +class BarrierMarker: + """A barrier indicator on a single qubit wire.""" + + col: int + row: int + + +@dataclass +class CircuitLayout: + """Complete layout description produced by GraphicalCircuitDiagram._compute_layout().""" + + num_qubits: int + num_moments: int + qubit_labels: list[str] + moment_labels: list[str] + elements: list = field(default_factory=list) + global_phase: float | None = None + additional_result_types: list[str] = field(default_factory=list) + unassigned_parameters: list[str] = field(default_factory=list) + + +def _compute_moment_global_phase( + global_phase: float | None, items: list[Instruction] +) -> float | None: + moment_phase = sum( + item.operator.angle + for item in items + if ( + isinstance(item, Instruction) + and isinstance(item.operator, Gate) + and item.operator.name == "GPhase" + ) + ) + return global_phase + moment_phase if global_phase is not None else None + + +def _get_qubit_range_for_item(item: Instruction | ResultType, circuit_qubits: QubitSet) -> QubitSet: + if ( + isinstance(item, Instruction) + and isinstance(item.operator, Gate) + and item.operator.name == "GPhase" + ): + return QubitSet() + + if isinstance(item, ResultType) and not item.target: + return circuit_qubits + + if isinstance(item, Instruction) and isinstance(item.operator, CompilerDirective): + return _get_compiler_directive_qubit_range(item, circuit_qubits) + + return _get_standard_qubit_range(item) + + +def _get_compiler_directive_qubit_range(item: Instruction, circuit_qubits: QubitSet) -> QubitSet: + if item.operator.name == "Barrier": + if not item.target or len(item.target) == 0: + return circuit_qubits + return QubitSet(item.target) + return circuit_qubits + + +def _get_standard_qubit_range(item: Instruction | ResultType) -> QubitSet: + if isinstance(item.target, list): + target = reduce(QubitSet.union, map(QubitSet, item.target), QubitSet()) + else: + target = item.target + control = getattr(item, "control", QubitSet()) + target_and_control = target.union(control) + return QubitSet(range(min(target_and_control), max(target_and_control) + 1)) + + +def _group_items( + circuit_qubits: QubitSet, + items: list[Instruction | ResultType], +) -> list[tuple[QubitSet, list[Instruction]]]: + groupings = [] + for item in items: + if isinstance(item, Instruction) and not isinstance( + item.operator, CompilerDirective | QuantumOperator + ): + continue + + qubit_range = _get_qubit_range_for_item(item, circuit_qubits) + + found_grouping = False + for group in groupings: + qubits_added = group[0] + instr_group = group[1] + if not qubits_added.intersection(set(qubit_range)): + instr_group.append(item) + qubits_added.update(qubit_range) + found_grouping = True + break + + if not found_grouping: + groupings.append((qubit_range, [item])) + + return groupings + + +def _categorize_result_types( + result_types: list[ResultType], +) -> tuple[list[str], list[ResultType]]: + additional_result_types = [] + target_result_types = [] + for result_type in result_types: + if hasattr(result_type, "target"): + target_result_types.append(result_type) + else: + additional_result_types.extend(result_type.ascii_symbols) + return additional_result_types, target_result_types + + +def _has_global_phase(circuit: Circuit) -> bool: + return any(m.moment_type == MomentType.GLOBAL_PHASE for m in circuit._moments) diff --git a/src/braket/circuits/graphical_diagram_builders/matplotlib_circuit_diagram.py b/src/braket/circuits/graphical_diagram_builders/matplotlib_circuit_diagram.py new file mode 100644 index 000000000..cb62b2cc5 --- /dev/null +++ b/src/braket/circuits/graphical_diagram_builders/matplotlib_circuit_diagram.py @@ -0,0 +1,394 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from __future__ import annotations + +import matplotlib.patches as mpatches +import matplotlib.pyplot as plt +from matplotlib.axes import Axes +from matplotlib.figure import Figure + +import braket.circuits.circuit as cir +from braket.circuits.graphical_diagram_builders.graphical_circuit_diagram import ( + GraphicalCircuitDiagram, +) +from braket.circuits.graphical_diagram_builders.graphical_diagram_utils import ( + BarrierMarker, + CircuitLayout, + Connection, + ControlDot, + GateBox, + SwapMarker, +) +from braket.circuits.moments import MomentType + + +class MatplotlibCircuitDiagram(GraphicalCircuitDiagram): + """Renders circuit diagrams as matplotlib Figures. + + The visual style mirrors the Unicode text diagram: + - Gates are drawn as labelled boxes + - Control qubits are filled/open circles + - Multi-qubit connections are vertical lines + - SWAP gates are drawn as ``x`` markers + - Barriers are hatched markers on each targeted qubit wire + """ + + # Layout parameters + COL_WIDTH = 1.4 # default/minimum column width, used as a lower bound + COL_GAP = 0.2 # horizontal gap between adjacent column boxes + ROW_HEIGHT = 0.8 + WIRE_EXTEND = 0.5 # extra wire length before first / after last column + + # Gate box style + GATE_BOX_HEIGHT = 0.5 + GATE_BOX_MIN_WIDTH = 0.6 + GATE_BOX_PADDING = 0.3 # horizontal padding inside the box around the label + GATE_FONT_SIZE = 10 + GATE_FILL_COLOR = "#D4E6F1" + GATE_EDGE_COLOR = "black" + GATE_TEXT_COLOR = "black" + + # Wire style + WIRE_COLOR = "#333333" + WIRE_LW = 1.0 + + # Control dot style + CONTROL_DOT_RADIUS = 0.08 + CONTROL_DOT_COLOR = "black" + + # Connection / barrier style + CONNECTION_LW = 1.5 + CONNECTION_COLOR = "black" + BARRIER_COLOR = "#888888" + BARRIER_FILL_COLOR = "#DDDDDD" + BARRIER_LW = 1.0 + BARRIER_WIDTH = 0.25 # horizontal width of the per-qubit barrier marker + BARRIER_HEIGHT_FRAC = 0.6 # fraction of ROW_HEIGHT covered by the marker + BARRIER_HATCH = "///" + + # Label style + QUBIT_LABEL_FONT_SIZE = 11 + MOMENT_LABEL_FONT_SIZE = 9 + FOOTER_FONT_SIZE = 9 + + # Marker sizes + SWAP_MARKER_SIZE = 8 + + @staticmethod + def build_diagram(circuit: cir.Circuit) -> Figure: + """Build a matplotlib Figure for *circuit*. + + Args: + circuit: The circuit to visualise. + + Returns: + A ``matplotlib.figure.Figure``. + """ + if not circuit.instructions: + fig, ax = plt.subplots(figsize=(2, 1)) + ax.text(0.5, 0.5, "(empty circuit)", ha="center", va="center", fontsize=12) + ax.axis("off") + return fig + + if all(m.moment_type == MomentType.GLOBAL_PHASE for m in circuit._moments): + fig, ax = plt.subplots(figsize=(3, 1)) + ax.text( + 0.5, + 0.5, + f"Global phase: {circuit.global_phase}", + ha="center", + va="center", + fontsize=12, + ) + ax.axis("off") + return fig + + layout = MatplotlibCircuitDiagram._compute_layout(circuit) + return MatplotlibCircuitDiagram._render_layout(layout) + + @classmethod + def _gate_box_width(cls, label: str) -> float: + """Return the width of a gate box rendered with *label*.""" + char_width = cls.GATE_FONT_SIZE * 0.012 + text_width = len(label) * char_width + return max(cls.GATE_BOX_MIN_WIDTH, text_width + cls.GATE_BOX_PADDING) + + @classmethod + def _compute_column_x(cls, layout: CircuitLayout) -> tuple[list[float], list[float]]: + """Compute the x center and width of each column based on box sizes. + + Columns are sized to fit the widest gate box they contain, plus a + fixed gap. Columns with no boxes fall back to the default width. + + Returns: + Tuple of ``(centers, widths)`` lists of length ``num_moments``. + """ + n_cols = max(layout.num_moments, 1) + widths = [cls.COL_WIDTH] * n_cols + for elem in layout.elements: + if isinstance(elem, GateBox): + widths[elem.col] = max( + widths[elem.col], cls._gate_box_width(elem.label) + cls.COL_GAP + ) + centers: list[float] = [] + cursor = 0.0 + for w in widths: + centers.append(cursor + w / 2) + cursor += w + return centers, widths + + @classmethod + def _render_layout(cls, layout: CircuitLayout) -> Figure: + n_rows = max(layout.num_qubits, 1) + + col_x, col_w = cls._compute_column_x(layout) + total_width = sum(col_w) + right_edge = total_width + + fig_width = max(4, cls.WIRE_EXTEND * 2 + total_width + 1.5) + fig_height = max(2, n_rows * cls.ROW_HEIGHT + 1.5) + fig, ax = plt.subplots(figsize=(fig_width, fig_height)) + + left_wire = col_x[0] - col_w[0] / 2 - cls.WIRE_EXTEND + right_wire = right_edge + cls.WIRE_EXTEND + + cls._draw_qubit_wires(ax, layout, left_wire, right_wire) + + label_y_top = cls.ROW_HEIGHT * 0.8 + label_y_bottom = -(n_rows - 1) * cls.ROW_HEIGHT - cls.ROW_HEIGHT * 0.8 + cls._draw_moment_labels(ax, layout, col_x, label_y_top, label_y_bottom) + + cls._draw_elements(ax, layout, col_x) + + footer_lines = cls._build_footer_lines(layout) + if footer_lines: + cls._draw_footer(ax, footer_lines, left_wire, label_y_bottom) + + cls._configure_axes(ax, left_wire, right_wire, label_y_top, label_y_bottom, footer_lines) + fig.tight_layout() + return fig + + @classmethod + def _draw_qubit_wires( + cls, ax: Axes, layout: CircuitLayout, left_wire: float, right_wire: float + ) -> None: + for row_idx, label in enumerate(layout.qubit_labels): + y = -row_idx * cls.ROW_HEIGHT + ax.plot( + [left_wire, right_wire], + [y, y], + color=cls.WIRE_COLOR, + lw=cls.WIRE_LW, + zorder=1, + ) + ax.text( + left_wire - 0.15, + y, + f"{label} :", + ha="right", + va="center", + fontsize=cls.QUBIT_LABEL_FONT_SIZE, + fontfamily="monospace", + ) + + @classmethod + def _draw_moment_labels( + cls, + ax: Axes, + layout: CircuitLayout, + col_x: list[float], + label_y_top: float, + label_y_bottom: float, + ) -> None: + moment_col_ranges: list[tuple[str, int, int]] = [] + for col_idx, label in enumerate(layout.moment_labels): + if moment_col_ranges and moment_col_ranges[-1][0] == label: + moment_col_ranges[-1] = (label, moment_col_ranges[-1][1], col_idx) + else: + moment_col_ranges.append((label, col_idx, col_idx)) + + for label, col_start, col_end in moment_col_ranges: + cx = (col_x[col_start] + col_x[col_end]) / 2 + for y_pos in (label_y_top, label_y_bottom): + ax.text( + cx, + y_pos, + label, + ha="center", + va="center", + fontsize=cls.MOMENT_LABEL_FONT_SIZE, + fontfamily="monospace", + color="#555555", + ) + + @classmethod + def _draw_elements(cls, ax: Axes, layout: CircuitLayout, col_x: list[float]) -> None: + for elem in layout.elements: + if isinstance(elem, GateBox): + cls._draw_gate_box(ax, elem, col_x[elem.col]) + elif isinstance(elem, ControlDot): + cls._draw_control_dot(ax, elem, col_x[elem.col]) + elif isinstance(elem, SwapMarker): + cls._draw_swap_marker(ax, elem, col_x[elem.col]) + elif isinstance(elem, Connection): + cls._draw_connection(ax, elem, col_x[elem.col]) + elif isinstance(elem, BarrierMarker): + cls._draw_barrier(ax, elem, col_x[elem.col]) + + @classmethod + def _build_footer_lines(cls, layout: CircuitLayout) -> list[str]: + footer_lines: list[str] = [] + if layout.global_phase: + footer_lines.append(f"Global phase: {layout.global_phase}") + if layout.additional_result_types: + footer_lines.append( + f"Additional result types: {', '.join(layout.additional_result_types)}" + ) + if layout.unassigned_parameters: + footer_lines.append(f"Unassigned parameters: {', '.join(layout.unassigned_parameters)}") + return footer_lines + + @classmethod + def _draw_footer( + cls, ax: Axes, footer_lines: list[str], left_wire: float, label_y_bottom: float + ) -> None: + footer_y = label_y_bottom - cls.ROW_HEIGHT * 0.7 + for i, line in enumerate(footer_lines): + ax.text( + left_wire, + footer_y - i * cls.ROW_HEIGHT * 0.5, + line, + ha="left", + va="top", + fontsize=cls.FOOTER_FONT_SIZE, + fontfamily="monospace", + color="#333333", + ) + + @classmethod + def _configure_axes( + cls, + ax: Axes, + left_wire: float, + right_wire: float, + label_y_top: float, + label_y_bottom: float, + footer_lines: list[str], + ) -> None: + ax.set_xlim(left_wire - 1.5, right_wire + 0.5) + y_top = label_y_top + 0.4 + y_bottom = label_y_bottom - 0.4 + if footer_lines: + y_bottom -= len(footer_lines) * cls.ROW_HEIGHT * 0.5 + ax.set_ylim(y_bottom, y_top) + ax.set_aspect("equal") + ax.axis("off") + + @classmethod + def _draw_gate_box(cls, ax: Axes, elem: GateBox, x: float) -> None: + y = -elem.row * cls.ROW_HEIGHT + + box_width = cls._gate_box_width(elem.label) + + rect = mpatches.FancyBboxPatch( + (x - box_width / 2, y - cls.GATE_BOX_HEIGHT / 2), + box_width, + cls.GATE_BOX_HEIGHT, + boxstyle=mpatches.BoxStyle.Round(pad=0.05), + facecolor=cls.GATE_FILL_COLOR, + edgecolor=cls.GATE_EDGE_COLOR, + linewidth=1.2, + zorder=3, + ) + ax.add_patch(rect) + ax.text( + x, + y, + elem.label, + ha="center", + va="center", + fontsize=cls.GATE_FONT_SIZE, + fontfamily="monospace", + color=cls.GATE_TEXT_COLOR, + zorder=4, + ) + + @classmethod + def _draw_control_dot(cls, ax: Axes, elem: ControlDot, x: float) -> None: + y = -elem.row * cls.ROW_HEIGHT + if elem.filled: + circle = plt.Circle( + (x, y), + cls.CONTROL_DOT_RADIUS, + color=cls.CONTROL_DOT_COLOR, + zorder=4, + ) + else: + circle = plt.Circle( + (x, y), + cls.CONTROL_DOT_RADIUS, + facecolor="white", + edgecolor=cls.CONTROL_DOT_COLOR, + linewidth=1.5, + zorder=4, + ) + ax.add_patch(circle) + + @classmethod + def _draw_swap_marker(cls, ax: Axes, elem: SwapMarker, x: float) -> None: + y = -elem.row * cls.ROW_HEIGHT + ax.plot( + x, + y, + "x", + markersize=cls.SWAP_MARKER_SIZE, + color=cls.CONNECTION_COLOR, + markeredgewidth=2, + zorder=4, + ) + + @classmethod + def _draw_connection(cls, ax: Axes, elem: Connection, x: float) -> None: + y_start = -elem.row_start * cls.ROW_HEIGHT + y_end = -elem.row_end * cls.ROW_HEIGHT + ax.plot( + [x, x], + [y_start, y_end], + color=cls.CONNECTION_COLOR, + lw=cls.CONNECTION_LW, + zorder=2, + ) + + @classmethod + def _draw_barrier(cls, ax: Axes, elem: BarrierMarker, x: float) -> None: + """Draw a barrier marker on a single qubit wire. + + Rendered as a small hatched rectangle centered on the qubit wire. + One marker per targeted qubit; qubits not in the barrier's target + get no marker. + """ + y = -elem.row * cls.ROW_HEIGHT + half_h = cls.ROW_HEIGHT * cls.BARRIER_HEIGHT_FRAC / 2 + half_w = cls.BARRIER_WIDTH / 2 + rect = mpatches.Rectangle( + (x - half_w, y - half_h), + cls.BARRIER_WIDTH, + half_h * 2, + facecolor=cls.BARRIER_FILL_COLOR, + edgecolor=cls.BARRIER_COLOR, + hatch=cls.BARRIER_HATCH, + linewidth=cls.BARRIER_LW, + zorder=2, + ) + ax.add_patch(rect) diff --git a/test/unit_tests/braket/circuits/test_circuit.py b/test/unit_tests/braket/circuits/test_circuit.py index 435051ea5..8377470c0 100644 --- a/test/unit_tests/braket/circuits/test_circuit.py +++ b/test/unit_tests/braket/circuits/test_circuit.py @@ -2514,6 +2514,13 @@ def test_to_unitary_with_global_phase(): assert np.allclose(circuit.to_unitary(), 1j * circuit_unitary) +def test_show_invokes_build_diagram(): + diagram_cls = Mock() + circ = Circuit().h(0) + circ.show(circuit_diagram_class=diagram_cls) + diagram_cls.build_diagram.assert_called_once_with(circ) + + @pytest.mark.parametrize( "circuit,expected_unitary", [ diff --git a/test/unit_tests/braket/circuits/test_matplotlib_circuit_diagram.py b/test/unit_tests/braket/circuits/test_matplotlib_circuit_diagram.py new file mode 100644 index 000000000..ccfd48f02 --- /dev/null +++ b/test/unit_tests/braket/circuits/test_matplotlib_circuit_diagram.py @@ -0,0 +1,767 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +"""Tests for MatplotlibCircuitDiagram. + +Each test mirrors a corresponding test in test_unicode_circuit_diagram.py. +Since graphical output cannot be compared as strings we verify: + - build_diagram() returns a matplotlib Figure + - _compute_layout() produces the correct layout primitives +""" + +import numpy as np +import pytest +from matplotlib.figure import Figure + +from braket.circuits import Circuit, FreeParameter, Gate, Instruction, Noise, Observable, Operator +from braket.circuits.compiler_directives import Barrier +from braket.circuits.graphical_diagram_builders.graphical_circuit_diagram import ( + GraphicalCircuitDiagram, +) +from braket.circuits.graphical_diagram_builders.graphical_diagram_utils import ( + BarrierMarker, + CircuitLayout, + Connection, + ControlDot, + GateBox, + SwapMarker, +) +from braket.circuits.graphical_diagram_builders.matplotlib_circuit_diagram import ( + MatplotlibCircuitDiagram, +) +from braket.pulse import Frame, Port, PulseSequence + + +def _layout(circ: Circuit) -> CircuitLayout: + return MatplotlibCircuitDiagram._compute_layout(circ) + + +def _fig(circ: Circuit) -> Figure: + return MatplotlibCircuitDiagram.build_diagram(circ) + + +def _elements_of_type(layout: CircuitLayout, cls): + return [e for e in layout.elements if isinstance(e, cls)] + + +def _gate_labels(layout: CircuitLayout) -> list[str]: + return [e.label for e in layout.elements if isinstance(e, GateBox)] + + +def test_empty_circuit(): + fig = _fig(Circuit()) + assert isinstance(fig, Figure) + + +def test_only_gphase_circuit(): + fig = _fig(Circuit().gphase(0.1)) + assert isinstance(fig, Figure) + + +def test_one_gate_one_qubit(): + layout = _layout(Circuit().h(0)) + assert layout.qubit_labels == ["q0"] + assert layout.num_moments == 1 + gates = _elements_of_type(layout, GateBox) + assert len(gates) == 1 + assert gates[0] == GateBox(col=0, row=0, label="H") + assert isinstance(_fig(Circuit().h(0)), Figure) + + +def test_one_gate_one_qubit_rotation(): + layout = _layout(Circuit().rx(angle=3.14, target=0)) + gates = _elements_of_type(layout, GateBox) + assert len(gates) == 1 + assert gates[0].label == "Rx(3.14)" + + +def test_one_gate_one_qubit_rotation_with_parameter(): + theta = FreeParameter("theta") + layout = _layout(Circuit().rx(angle=theta, target=0)) + gates = _elements_of_type(layout, GateBox) + assert len(gates) == 1 + assert gates[0].label == "Rx(theta)" + assert layout.unassigned_parameters == ["theta"] + + +@pytest.mark.parametrize("target", [0, 1]) +def test_one_gate_with_global_phase(target): + layout = _layout(Circuit().x(target=target).gphase(0.15)) + assert layout.global_phase == 0.15 + gates = _elements_of_type(layout, GateBox) + assert any(g.label == "X" for g in gates) + + +def test_one_gate_with_zero_global_phase(): + layout = _layout(Circuit().gphase(-0.15).x(target=0).gphase(0.15)) + assert layout.global_phase == pytest.approx(0.0) + + +def test_one_gate_one_qubit_rotation_with_unicode(): + theta = FreeParameter("\u03b8") + layout = _layout(Circuit().rx(angle=theta, target=0)) + gates = _elements_of_type(layout, GateBox) + assert gates[0].label == "Rx(θ)" + assert layout.unassigned_parameters == ["θ"] + + +def test_one_gate_with_parametric_expression_global_phase(): + theta = FreeParameter("\u03b8") + circ = Circuit().x(target=0).gphase(2 * theta).x(0).gphase(1) + layout = _layout(circ) + assert layout.global_phase is not None + assert layout.unassigned_parameters == ["θ"] + + +def test_one_gate_one_qubit_rotation_with_parameter_assigned(): + theta = FreeParameter("theta") + circ = Circuit().rx(angle=theta, target=0) + new_circ = circ.make_bound_circuit({"theta": np.pi}) + layout = _layout(new_circ) + gates = _elements_of_type(layout, GateBox) + assert gates[0].label == "Rx(3.14)" + assert layout.unassigned_parameters == [] + + +def test_qubit_width(): + layout = _layout(Circuit().h(0).h(100)) + assert layout.qubit_labels == ["q0", "q100"] + assert layout.num_qubits == 2 + gates = _elements_of_type(layout, GateBox) + assert len(gates) == 2 + assert all(g.label == "H" for g in gates) + + +def test_different_size_boxes(): + layout = _layout(Circuit().cnot(0, 1).rx(2, 0.3)) + gates = _elements_of_type(layout, GateBox) + gate_labels = [g.label for g in gates] + assert "X" in gate_labels + assert "Rx(0.30)" in gate_labels + controls = _elements_of_type(layout, ControlDot) + assert len(controls) == 1 + assert controls[0].filled is True + + +def test_swap(): + layout = _layout(Circuit().swap(0, 2).x(1)) + swaps = _elements_of_type(layout, SwapMarker) + assert len(swaps) == 2 + assert {s.row for s in swaps} == {0, 2} + gates = _elements_of_type(layout, GateBox) + assert any(g.label == "X" for g in gates) + + +def test_gate_width(): + class Foo(Gate): + def __init__(self): + super().__init__(qubit_count=1, ascii_symbols=["FOO"]) + + def to_ir(self, target): + return "foo" + + circ = Circuit().h(0).h(1).add_instruction(Instruction(Foo(), 0)) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert "FOO" in gate_labels + assert gate_labels.count("H") == 2 + + +def test_time_width(): + circ = Circuit() + num_qubits = 8 + for qubit in range(num_qubits - 1): + circ.cnot(qubit, qubit + 1) + layout = _layout(circ) + assert layout.num_qubits == 8 + assert layout.num_moments == 7 + gates = _elements_of_type(layout, GateBox) + assert all(g.label == "X" for g in gates) + controls = _elements_of_type(layout, ControlDot) + assert len(controls) == 7 + connections = _elements_of_type(layout, Connection) + assert len(connections) == 7 + + +def test_connector_across_two_qubits(): + layout = _layout(Circuit().cnot(4, 3).h(range(2, 6))) + connections = _elements_of_type(layout, Connection) + # q3 → row 1, q4 → row 2 + assert any(c.row_start == 1 and c.row_end == 2 for c in connections) + + +def test_neg_control_qubits(): + layout = _layout(Circuit().x(1, control=[0, 2], control_state=[0, 1])) + controls = _elements_of_type(layout, ControlDot) + filled_states = {c.row: c.filled for c in controls} + # q0 has control_state=0 → anti-control (not filled) + # q2 has control_state=1 → control (filled) + assert filled_states[0] is False + assert filled_states[2] is True + + +def test_only_neg_control_qubits(): + layout = _layout(Circuit().x(2, control=[0, 1], control_state=0)) + controls = _elements_of_type(layout, ControlDot) + assert len(controls) == 2 + assert all(c.filled is False for c in controls) + + +def test_connector_across_three_qubits(): + layout = _layout(Circuit().x(control=(3, 4), target=5).h(range(2, 6))) + controls = _elements_of_type(layout, ControlDot) + assert len(controls) == 2 + + +def test_overlapping_qubits(): + circ = Circuit().cnot(0, 2).x(control=1, target=3).h(0) + layout = _layout(circ) + # CNOT(0,2) and CX(1,3) overlap → need separate columns + assert layout.num_moments >= 3 + gates = _elements_of_type(layout, GateBox) + assert any(g.label == "H" for g in gates) + + +def test_overlapping_qubits_angled_gates(): + circ = Circuit().zz(0, 2, 0.15).x(control=1, target=3).h(0) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert "ZZ(0.15)" in gate_labels + assert "H" in gate_labels + + +def test_connector_across_gt_two_qubits(): + layout = _layout(Circuit().h(4).x(control=3, target=5).h(4).h(2)) + connections = _elements_of_type(layout, Connection) + # q3 (control) and q5 (target) are spanned by a Connection that crosses q4. + # We don't emit a per-row primitive for the pass-through qubit; the + # Connection line is what indicates the gate crosses over it. + assert any( + conn.row_start <= 2 <= conn.row_end for conn in connections + ) # rows: q2=0, q3=1, q4=2, q5=3; q4 is row 2 + + +def test_connector_across_non_used_qubits(): + layout = _layout(Circuit().h(4).cnot(3, 100).h(4).h(101)) + assert layout.num_qubits == 4 # q3, q4, q100, q101 + + +def test_verbatim_1q_no_preceding(): + layout = _layout(Circuit().add_verbatim_box(Circuit().h(0))) + gate_labels = _gate_labels(layout) + assert "StartVerbatim" in gate_labels + assert "EndVerbatim" in gate_labels + assert "H" in gate_labels + + +def test_verbatim_1q_preceding(): + layout = _layout(Circuit().h(0).add_verbatim_box(Circuit().h(0))) + gate_labels = _gate_labels(layout) + assert gate_labels.count("H") == 2 + assert "StartVerbatim" in gate_labels + assert "EndVerbatim" in gate_labels + + +def test_verbatim_1q_following(): + layout = _layout(Circuit().add_verbatim_box(Circuit().h(0)).h(0)) + gate_labels = _gate_labels(layout) + assert gate_labels.count("H") == 2 + assert "StartVerbatim" in gate_labels + assert "EndVerbatim" in gate_labels + + +def test_verbatim_2q_no_preceding(): + layout = _layout(Circuit().add_verbatim_box(Circuit().h(0).cnot(0, 1))) + gate_labels = _gate_labels(layout) + assert "StartVerbatim" in gate_labels + assert "EndVerbatim" in gate_labels + assert "H" in gate_labels + assert "X" in gate_labels + + +def test_verbatim_2q_preceding(): + layout = _layout(Circuit().h(0).add_verbatim_box(Circuit().h(0).cnot(0, 1))) + gate_labels = _gate_labels(layout) + assert gate_labels.count("H") == 2 + + +def test_verbatim_2q_following(): + layout = _layout(Circuit().add_verbatim_box(Circuit().h(0).cnot(0, 1)).h(0)) + gate_labels = _gate_labels(layout) + assert gate_labels.count("H") == 2 + + +def test_verbatim_3q_no_preceding(): + layout = _layout(Circuit().add_verbatim_box(Circuit().h(0).cnot(0, 1).cnot(1, 2))) + gate_labels = _gate_labels(layout) + assert "StartVerbatim" in gate_labels + assert "EndVerbatim" in gate_labels + + +def test_verbatim_3q_preceding(): + layout = _layout(Circuit().h(0).add_verbatim_box(Circuit().h(0).cnot(0, 1).cnot(1, 2))) + assert isinstance( + _fig(Circuit().h(0).add_verbatim_box(Circuit().h(0).cnot(0, 1).cnot(1, 2))), Figure + ) + + +def test_verbatim_3q_following(): + layout = _layout(Circuit().add_verbatim_box(Circuit().h(0).cnot(0, 1).cnot(1, 2)).h(0)) + assert isinstance( + _fig(Circuit().add_verbatim_box(Circuit().h(0).cnot(0, 1).cnot(1, 2)).h(0)), Figure + ) + + +def test_verbatim_different_qubits(): + circ = Circuit().h(1).add_verbatim_box(Circuit().h(0)).cnot(3, 4) + layout = _layout(circ) + assert layout.num_qubits == 4 # q0, q1, q3, q4 + + +def test_verbatim_qubset_qubits(): + circ = Circuit().h(1).cnot(0, 1).cnot(1, 2).add_verbatim_box(Circuit().h(1)).cnot(2, 3) + layout = _layout(circ) + assert layout.num_qubits == 4 + + +def test_ignore_non_gates(): + class Foo(Operator): + @property + def name(self) -> str: + return "foo" + + def to_ir(self, target): + return "foo" + + circ = Circuit().h(0).h(1).cnot(1, 2).add_instruction(Instruction(Foo(), 0)) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert "foo" not in gate_labels + assert "H" in gate_labels + + +def test_single_qubit_result_types_target_none(): + layout = _layout(Circuit().h(0).probability()) + gate_labels = _gate_labels(layout) + assert "Probability" in gate_labels + + +def test_result_types_target_none(): + layout = _layout(Circuit().h(0).h(100).probability()) + gate_labels = _gate_labels(layout) + assert gate_labels.count("Probability") == 2 + + +def test_result_types_target_some(): + circ = ( + Circuit() + .h(0) + .h(1) + .h(100) + .expectation(observable=Observable.Y() @ Observable.Z(), target=[0, 100]) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert any("Expectation" in g for g in gate_labels) + + +def test_additional_result_types(): + circ = Circuit().h(0).h(1).h(100).state_vector().amplitude(["110", "001"]) + layout = _layout(circ) + assert "StateVector" in layout.additional_result_types + assert "Amplitude(110,001)" in layout.additional_result_types + + +def test_multiple_result_types(): + circ = ( + Circuit() + .cnot(0, 2) + .cnot(1, 3) + .h(0) + .variance(observable=Observable.Y(), target=0) + .expectation(observable=Observable.Y(), target=2) + .sample(observable=Observable.Y()) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert any("Variance" in g for g in gate_labels) + assert any("Expectation" in g for g in gate_labels) + assert any("Sample" in g for g in gate_labels) + + +def test_multiple_result_types_with_state_vector_amplitude(): + circ = ( + Circuit() + .cnot(0, 2) + .cnot(1, 3) + .h(0) + .variance(observable=Observable.Y(), target=0) + .expectation(observable=Observable.Y(), target=3) + .expectation( + observable=Observable.Hermitian(np.array([[1.0, 0.0], [0.0, 1.0]])), + target=1, + ) + .amplitude(["0001"]) + .state_vector() + ) + layout = _layout(circ) + assert "Amplitude(0001)" in layout.additional_result_types + assert "StateVector" in layout.additional_result_types + + +def test_multiple_result_types_with_custom_hermitian_ascii_symbol(): + herm_matrix = (Observable.Y() @ Observable.Z()).to_matrix() + circ = ( + Circuit() + .cnot(0, 2) + .cnot(1, 3) + .h(0) + .variance(observable=Observable.Y(), target=0) + .expectation(observable=Observable.Y(), target=3) + .expectation( + observable=Observable.Hermitian( + matrix=herm_matrix, + display_name="MyHerm", + ), + target=[1, 2], + ) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert any("MyHerm" in g for g in gate_labels) + + +def test_noise_1qubit(): + layout = _layout(Circuit().h(0).x(1).bit_flip(1, 0.1)) + gate_labels = _gate_labels(layout) + assert "BF(0.1)" in gate_labels + + +def test_noise_2qubit(): + layout = _layout(Circuit().h(1).kraus((0, 2), [np.eye(4)])) + gate_labels = _gate_labels(layout) + assert gate_labels.count("KR") == 2 + + +def test_noise_multi_probabilities(): + layout = _layout(Circuit().h(0).x(1).pauli_channel(1, 0.1, 0.2, 0.3)) + gate_labels = _gate_labels(layout) + assert "PC(0.1,0.2,0.3)" in gate_labels + + +def test_noise_multi_probabilities_with_parameter(): + a = FreeParameter("a") + c = FreeParameter("c") + d = FreeParameter("d") + layout = _layout(Circuit().h(0).x(1).pauli_channel(1, a, c, d)) + gate_labels = _gate_labels(layout) + assert "PC(a,c,d)" in gate_labels + assert sorted(layout.unassigned_parameters) == ["a", "c", "d"] + + +def test_pulse_gate_1_qubit_circuit(): + circ = ( + Circuit() + .h(0) + .pulse_gate(0, PulseSequence().set_phase(Frame("x", Port("px", 1e-9), 1e9, 0), 0)) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert "PG" in gate_labels + + +def test_pulse_gate_multi_qubit_circuit(): + circ = ( + Circuit() + .h(0) + .pulse_gate([0, 1], PulseSequence().set_phase(Frame("x", Port("px", 1e-9), 1e9, 0), 0)) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert gate_labels.count("PG") == 2 + + +def test_circuit_with_nested_target_list(): + circ = ( + Circuit() + .h(0) + .h(1) + .expectation( + observable=(2 * Observable.Y()) @ (-3 * Observable.I()) + - 0.75 * Observable.Y() @ Observable.Z(), + target=[[0, 1], [0, 1]], + ) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert any("Hamiltonian" in g for g in gate_labels) + + +def test_hamiltonian(): + circ = ( + Circuit() + .h(0) + .cnot(0, 1) + .rx(0, FreeParameter("theta")) + .adjoint_gradient( + 4 * (2e-5 * Observable.Z() + 2 * (3 * Observable.X() @ (2 * Observable.Y()))), + [[0], [1, 2]], + ) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert any("AdjointGradient" in g for g in gate_labels) + assert layout.unassigned_parameters == ["theta"] + + +def test_power(): + class Foo(Gate): + def __init__(self): + super().__init__(qubit_count=1, ascii_symbols=["FOO"]) + + class CFoo(Gate): + def __init__(self): + super().__init__(qubit_count=2, ascii_symbols=["C", "FOO"]) + + class FooFoo(Gate): + def __init__(self): + super().__init__(qubit_count=2, ascii_symbols=["FOO", "FOO"]) + + circ = Circuit().h(0, power=1).h(1, power=0).h(2, power=-3.14) + circ.add_instruction(Instruction(Foo(), 0, power=-1)) + circ.add_instruction(Instruction(CFoo(), (0, 1), power=2)) + circ.add_instruction(Instruction(CFoo(), (1, 2), control=0, power=3)) + circ.add_instruction(Instruction(FooFoo(), (1, 3), control=[0, 2], power=4)) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert "H" in gate_labels + assert "H^0" in gate_labels + assert "H^-3.14" in gate_labels + assert "FOO^-1" in gate_labels + assert "FOO^2" in gate_labels + assert "FOO^3" in gate_labels + assert "FOO^4" in gate_labels + + +def test_unbalanced_ascii_symbols(): + class FooFoo(Gate): + def __init__(self): + super().__init__(qubit_count=2, ascii_symbols=["FOOO", "FOO"]) + + circ = Circuit().add_instruction(Instruction(FooFoo(), (1, 3), control=[0, 2], power=4)) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert "FOOO^4" in gate_labels + assert "FOO^4" in gate_labels + + +def test_measure(): + circ = Circuit().h(0).cnot(0, 1).cnot(1, 2).cnot(2, 3).measure([0, 2, 3]) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert gate_labels.count("M") == 3 + + +def test_measure_with_multiple_measures(): + circ = Circuit().h(0).cnot(0, 1).cnot(1, 2).cnot(2, 3).measure([0, 2]).measure(3).measure(1) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert gate_labels.count("M") == 4 + + +def test_measure_multiple_instructions_after(): + circ = ( + Circuit() + .h(0) + .cnot(0, 1) + .cnot(1, 2) + .cnot(2, 3) + .measure(0) + .measure(1) + .h(3) + .cnot(3, 4) + .measure([2, 3]) + ) + layout = _layout(circ) + assert layout.num_qubits == 5 + gate_labels = _gate_labels(layout) + assert gate_labels.count("M") == 4 + + +def test_measure_with_readout_noise(): + circ = ( + Circuit() + .h(0) + .cnot(0, 1) + .apply_readout_noise(Noise.BitFlip(probability=0.1), target_qubits=1) + .measure([0, 1]) + ) + layout = _layout(circ) + gate_labels = _gate_labels(layout) + assert "BF(0.1)" in gate_labels + assert gate_labels.count("M") == 2 + + +def test_barrier_circuit_visualization_without_other_gates(): + layout = _layout(Circuit().barrier(target=[0, 100])) + barriers = _elements_of_type(layout, BarrierMarker) + # One marker per targeted qubit. + assert sorted(b.row for b in barriers) == [0, 1] + + +def test_barrier_circuit_visualization_with_other_gates(): + layout = _layout(Circuit().x(0).barrier(target=[0, 100]).h(3)) + barriers = _elements_of_type(layout, BarrierMarker) + # Circuit qubits are {0, 3, 100} → rows 0, 1, 2. Barrier targets q0 and q100. + assert sorted(b.row for b in barriers) == [0, 2] + gate_labels = _gate_labels(layout) + assert "X" in gate_labels + assert "H" in gate_labels + + +def test_barrier_single_qubit(): + layout = _layout(Circuit().x(0).x(1).barrier(target=[0]).h(2)) + barriers = _elements_of_type(layout, BarrierMarker) + assert len(barriers) == 1 + assert barriers[0].row == 0 + + +def test_barrier_multiple_qubits_with_gates(): + layout = _layout(Circuit().x(0).x(1).barrier(target=[0, 1]).h(0).h(2)) + barriers = _elements_of_type(layout, BarrierMarker) + assert sorted(b.row for b in barriers) == [0, 1] + gate_labels = _gate_labels(layout) + assert "X" in gate_labels + assert "H" in gate_labels + + +def test_barrier_global_marks_all_qubits(): + circ = Circuit().x(0).x(1) + circ.add_instruction(Instruction(Barrier([]), [])) + circ.h(2) + layout = _layout(circ) + barriers = _elements_of_type(layout, BarrierMarker) + # Global barrier puts a marker on every qubit row. + assert sorted(b.row for b in barriers) == [0, 1, 2] + + +def test_barrier_non_contiguous_target_marks_only_targeted_rows(): + # q0, q1, q2 all present; barrier targets q0 and q2 but skips q1. + # Each targeted qubit gets its own marker; q1 is explicitly not marked, + # so it's visually obvious the barrier does not apply there. + circ = Circuit().h(0).h(1).h(2).barrier([0, 2]).cnot(0, 1).cnot(1, 2) + layout = _layout(circ) + barriers = _elements_of_type(layout, BarrierMarker) + assert sorted(b.row for b in barriers) == [0, 2] + + +def test_barrier_contiguous_target_marks_each_targeted_row(): + circ = Circuit().h(0).h(1).h(2).barrier([0, 1]).cnot(0, 1) + layout = _layout(circ) + barriers = _elements_of_type(layout, BarrierMarker) + assert sorted(b.row for b in barriers) == [0, 1] + + +def test_barrier_target_not_mutated_by_diagram(): + circ = Circuit() + circ.h(0) + circ.h(1) + circ.h(2) + circ.barrier([0, 1]) + circ.rx(2, 0.5) + circ.cnot(0, 1) + + barrier_instr = circ.instructions[3] + original_target = list(barrier_instr.target) + assert len(original_target) == 2 + assert 0 in original_target + assert 1 in original_target + assert 2 not in original_target + + # Build diagram should not mutate barrier target + _fig(circ) + + assert len(barrier_instr.target) == 2 + assert 0 in barrier_instr.target + assert 1 in barrier_instr.target + assert 2 not in barrier_instr.target + + +@pytest.mark.parametrize( + "circ", + [ + Circuit().h(0), + Circuit().cnot(0, 1), + Circuit().h(0).cnot(0, 1).cnot(1, 2), + Circuit().swap(0, 2).x(1), + Circuit().x(1, control=[0, 2], control_state=[0, 1]), + Circuit().h(0).h(1).h(100).state_vector(), + Circuit().h(0).cnot(0, 1).measure([0, 1]), + ], + ids=[ + "single_h", + "cnot", + "chain", + "swap_and_x", + "neg_control", + "state_vector", + "measure", + ], +) +def test_build_diagram_returns_figure(circ): + fig = _fig(circ) + assert isinstance(fig, Figure) + # Verify figure has axes + assert len(fig.axes) == 1 + + +def test_build_diagram_with_global_phase_footer(): + # Covers _build_footer_lines global-phase branch when build_diagram runs end-to-end. + circ = Circuit().h(0).gphase(0.25) + fig = _fig(circ) + assert isinstance(fig, Figure) + + +def test_build_diagram_with_unassigned_parameters_footer(): + # Covers _build_footer_lines unassigned-parameters branch in the render path. + circ = Circuit().rx(angle=FreeParameter("theta"), target=0) + fig = _fig(circ) + assert isinstance(fig, Figure) + + +def test_build_diagram_with_barrier_and_following_gate(): + # Exercises _draw_elements loop continuing past a BarrierMarker to another element, + circ = Circuit().x(0).barrier(target=[0, 1]).h(0) + fig = _fig(circ) + assert isinstance(fig, Figure) + + +def test_draw_elements_ignores_unknown_element(): + # Feeds an unrecognised layout element straight into _render_layout so the + # final elif in _draw_elements falls through. + class UnknownElement: + col = 0 + row = 0 + + layout = CircuitLayout( + num_qubits=1, + num_moments=1, + qubit_labels=["q0"], + moment_labels=["0"], + elements=[GateBox(col=0, row=0, label="H"), UnknownElement()], + global_phase=None, + additional_result_types=[], + unassigned_parameters=[], + ) + fig = MatplotlibCircuitDiagram._render_layout(layout) + assert isinstance(fig, Figure) diff --git a/test/unit_tests/conftest.py b/test/unit_tests/conftest.py new file mode 100644 index 000000000..998a8eee9 --- /dev/null +++ b/test/unit_tests/conftest.py @@ -0,0 +1,25 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +"""Shared pytest configuration for unit tests. + +Forces matplotlib to use the non-interactive ``Agg`` backend before any +test imports matplotlib. This avoids failures on CI runners (notably +Windows hosted runners) where the default ``TkAgg`` backend cannot +initialise because Tcl/Tk is not properly installed in the Python +distribution used by the runner. +""" + +import matplotlib + +matplotlib.use("Agg")