diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 0000000..34b359d --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: a0c892ca1128a7a36da4fb498739b03d +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/apiref/apiref.doctree b/.doctrees/apiref/apiref.doctree new file mode 100644 index 0000000..a29593e Binary files /dev/null and b/.doctrees/apiref/apiref.doctree differ diff --git a/.doctrees/contribute.doctree b/.doctrees/contribute.doctree new file mode 100644 index 0000000..7e85d0d Binary files /dev/null and b/.doctrees/contribute.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle new file mode 100644 index 0000000..038e7ee Binary files /dev/null and b/.doctrees/environment.pickle differ diff --git a/.doctrees/examples/fim_workflow_combined.doctree b/.doctrees/examples/fim_workflow_combined.doctree new file mode 100644 index 0000000..d7f8d8d Binary files /dev/null and b/.doctrees/examples/fim_workflow_combined.doctree differ diff --git a/.doctrees/examples/fim_workflow_indiv_steps.doctree b/.doctrees/examples/fim_workflow_indiv_steps.doctree new file mode 100644 index 0000000..7cddb02 Binary files /dev/null and b/.doctrees/examples/fim_workflow_indiv_steps.doctree differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 0000000..cde3986 Binary files /dev/null and b/.doctrees/index.doctree differ diff --git a/.doctrees/nbsphinx/examples/fim_workflow_combined.ipynb b/.doctrees/nbsphinx/examples/fim_workflow_combined.ipynb new file mode 100644 index 0000000..57b0e56 --- /dev/null +++ b/.doctrees/nbsphinx/examples/fim_workflow_combined.ipynb @@ -0,0 +1,483 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Fluvial flood inundation mapping quick start" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/passah2o/pygeoflood/blob/master/doc/examples/fim_workflow_combined.ipynb)\n", + "\n", + "On Google Colab, run the following command to install pygeoflood:\n", + "\n", + "```bash\n", + "%pip install git+https://github.com/passah2o/pygeoflood\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bs031yHfIwQK" + }, + "source": [ + "### Import libraries\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from pygeoflood import PyGeoFlood" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Instantiate **pygeoflood** model class\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "pgf = PyGeoFlood(dem_path=\"data/OC1mTest.tif\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Set paths to input datasets\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "pgf.flowline_path = \"data/Flowline.shp\"\n", + "pgf.catchment_path = \"data/Catchment.shp\"\n", + "\n", + "# # we are not using these datasets for this example\n", + "# pgf.streamflow_forecast_path = \"data/prod_nwm.t00z.analysis_assim.channel_rt.tm00.conus.nc\"\n", + "# pgf.custom_flowline_path = Path(data_dir, \"NHDPlus_H_1209_HU4_GDB.gdb\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download example input datasets if necessary\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# make data directory if it doesn't exist\n", + "if not Path(\"data\").is_dir():\n", + " Path(\"data\").mkdir()\n", + "# download input datasets if they doesn't exist\n", + "# DEM from USGS 3DEP\n", + "if not pgf.dem_path.is_file():\n", + " !curl https://utexas.box.com/shared/static/id0in7w8yn38o59sexa50aqunsr7mzk0.tif -Lso data/OC1mTest.tif\n", + "# flowlines and catchments from NFIE (NHD MR) dataset\n", + "# https://www.arcgis.com/home/webmap/viewer.html?webmap=9766a82973b34f18b43dafa20c5ef535\n", + "if not pgf.flowline_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/s1vlnymonbidnhul52oja7s83ky1212j.tgz | tar -xz -C data\n", + "if not pgf.catchment_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/jzawwvmb2tjl4yqtnitgvfjcc4ho4tg5.tgz | tar -xz -C data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Run full fluvial flood inundation mapping workflow\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running apply_nonlinear_filter with parameters:\n", + " custom_dem = None\n", + " custom_path = None\n", + " method = PeronaMalik2\n", + " smoothing_quantile = 0.9\n", + " time_increment = 0.1\n", + " n_iter = 50\n", + " sigma_squared = 0.05\n", + "Computing slope of raw DTM\n", + "DEM slope array shape: (3378, 4750)\n", + "Computing lambda = q-q-based nonlinear filtering threshold\n", + "DEM smoothing Quantile: 0.9\n", + "Edge Threshold Value: 0.34356024861335754\n", + "Filtered DEM written to data/OC1mTest_filtered.tif\n", + "apply_nonlinear_filter completed in 10.7802 seconds\n", + "\n", + "Running calculate_slope with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " slope statistics\n", + " min angle: 0.0\n", + " max angle: 54.863846043721324\n", + " mean slope: 0.13960592\n", + " stdev slope: 0.15432632\n", + "Slope raster written to data/OC1mTest_slope.tif\n", + "calculate_slope completed in 1.2883 seconds\n", + "\n", + "Running calculate_curvature with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " method = geometric\n", + " using geometric curvature\n", + " curvature statistics\n", + " non-nan curvature cell number: 16045500\n", + " non-nan finite curvature cell number: mean: -0.00031314598\n", + " standard deviation: 0.112147875\n", + "Curvature raster written to data/OC1mTest_curvature.tif\n", + "calculate_curvature completed in 1.3863 seconds\n", + "\n", + "Running fill_depressions with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"FillDepressions\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filtered.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --fix_flats -v --compress_rasters=True\n", + "\n", + "******************************\n", + "* Welcome to FillDepressions *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "******************************\n", + "Reading data...\n", + "Fixing flow on flats...\n", + "Flats increment value: 0.000002\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.190s\n", + "Filled DEM written to data/OC1mTest_filled.tif\n", + "fill_depressions completed in 8.0148 seconds\n", + "\n", + "Running calculate_mfd_flow_accumulation with parameters:\n", + " custom_filled_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"QuinnFlowAccumulation\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_mfd_fac.tif' --out_type=cells --exponent=1.0 -v --compress_rasters=True\n", + "\n", + "************************************\n", + "* Welcome to QuinnFlowAccumulation *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "************************************\n", + "Saving data...\n", + "Output file written\n", + "\n", + "Elapsed Time (Including I/O): 4.702s\n", + "MFD flow accumulation raster written to data/OC1mTest_mfd_fac.tif\n", + "calculate_mfd_flow_accumulation completed in 4.7655 seconds\n", + "\n", + "Running calculate_d8_flow_direction with parameters:\n", + " custom_filled_dem = None\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"D8Pointer\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_d8_fdr.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to D8Pointer *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.251s\n", + "D8 flow direction raster written to data/OC1mTest_d8_fdr.tif\n", + "calculate_d8_flow_direction completed in 1.9938 seconds\n", + "\n", + "Running find_outlets with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "Outlets raster written to data/OC1mTest_outlets.tif\n", + "find_outlets completed in 0.2224 seconds\n", + "\n", + "Running delineate_basins with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Basins\" --d8_pntr='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_d8_fdr.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_basins.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Basins *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.465s\n", + "Basins raster written to data/OC1mTest_basins.tif\n", + "delineate_basins completed in 1.0381 seconds\n", + "\n", + "Running define_skeleton with parameters:\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_path = None\n", + " fac_threshold = 3000\n", + " write_flow_skeleton = False\n", + " write_curvature_skeleton = False\n", + "Curvature mean: -0.00031413726\n", + "Curvature standard deviation: 0.11232527\n", + "Curvature Projection: EPSG:6343\n", + "Mean upstream flow: 2617.3564\n", + "Combined skeleton written to data/OC1mTest_combined_skeleton.tif\n", + "define_skeleton completed in 0.7782 seconds\n", + "\n", + "Running find_endpoints with parameters:\n", + " custom_flowline = None\n", + " custom_path = None\n", + "Endpoints csv written to data/OC1mTest_endpoints.csv\n", + "find_endpoints completed in 0.0330 seconds\n", + "\n", + "Running calculate_binary_hand with parameters:\n", + " custom_dem = None\n", + " custom_flowline = None\n", + " custom_path = None\n", + "Binary HAND raster written to data/OC1mTest_binary_hand.tif\n", + "calculate_binary_hand completed in 4.9416 seconds\n", + "\n", + "Running extract_channel_network with parameters:\n", + " custom_flowline = None\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_endpoints = None\n", + " custom_binary_hand = None\n", + " custom_path = None\n", + " retrace_flowline = True\n", + " vector_extension = shp\n", + " write_cost_function = False\n", + " use_custom_flowline = False\n", + " no_flowline = False\n", + " custom_weight_curvature = None\n", + " custom_weight_mfd_fac = None\n", + " custom_weight_binary_hand = None\n", + " custom_weight_custom_flowline = None\n", + "Retracing flowline...\n", + "Cost function weights:\n", + "curvature 0.2520 (mean flow accumulation)\n", + "mfd_fac 1.0000\n", + "binary_hand 0.7500\n", + "custom_flowline 0.0000\n", + "0.25195235 1 0.75 0\n", + "Cost min: 0.5028838188775905\n", + "Cost max: inf\n", + "cost shape: (3378, 4750)\n", + "Creating path 1/1: RAM usage: 12.00/16.00 GB (75.0%)\n", + "Number of endpoints: 1\n", + "Channel network raster written to data/OC1mTest_channel_network_raster.tif\n", + "Channel network vector written to data/OC1mTest_channel_network.shp\n", + "extract_channel_network completed in 2.0418 seconds\n", + "\n", + "Running calculate_hand with parameters:\n", + " custom_filled_dem = None\n", + " custom_channel_network_raster = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"ElevationAboveStream\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --streams='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_HAND.tif' -v --compress_rasters=True\n", + "\n", + "***********************************\n", + "* Welcome to ElevationAboveStream *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "***********************************\n", + "Reading DEM data...\n", + "Reading streams data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.644s\n", + "**********************************************************************************\n", + "WARNING: Interior pit cells were found within the input DEM. It is likely that the\n", + "DEM needs to be processed to remove topographic depressions and flats prior to\n", + "running this tool.\n", + "**********************************************************************************\n", + "HAND raster written to data/OC1mTest_HAND.tif\n", + "calculate_hand completed in 5.1220 seconds\n", + "\n", + "Running segment_channel_network with parameters:\n", + " custom_channel_network_vector = None\n", + " custom_path = None\n", + " vector_extension = shp\n", + " segment_length = 1000\n", + "Segmented channel network written to data/OC1mTest_segmented_channel_network.shp\n", + "segment_channel_network completed in 0.7907 seconds\n", + "\n", + "Running delineate_segment_catchments with parameters:\n", + " custom_segmented_channel_network = None\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Watershed\" --d8_pntr='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_d8_fdr.tif' --pour_pts='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_segmented_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_segment_catchments.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Watershed *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.841s\n", + "Segment catchments written to data/OC1mTest_segment_catchments.tif\n", + "delineate_segment_catchments completed in 1.5538 seconds\n", + "\n", + "Running calculate_src with parameters:\n", + " custom_dem = None\n", + " custom_segmented_channel_network = None\n", + " custom_segment_catchments_raster = None\n", + " custom_catchments = None\n", + " custom_hand = None\n", + " custom_path = None\n", + " min_slope = 1e-06\n", + " max_stage = 20\n", + " incr_stage = 0.1\n", + " custom_roughness_path = None\n", + "River attributes written to data/OC1mTest_river_attributes.csv\n", + "Synthetic rating curves written to data/OC1mTest_src.csv\n", + "calculate_src completed in 3.4749 seconds\n", + "\n", + "Running calculate_flood_stage with parameters:\n", + " custom_src = None\n", + " custom_streamflow_forecast_path = None\n", + " custom_path = None\n", + " custom_Q = 500\n", + "Applying custom streamflow to each segment: 500 cms\n", + "Flood stages written to data/OC1mTest_flood_stage.csv\n", + "calculate_flood_stage completed in 0.0042 seconds\n", + "\n", + "Running inundate with parameters:\n", + " custom_hand = None\n", + " custom_flood_stage = None\n", + " custom_segment_catchments_raster = None\n", + " custom_path = None\n", + "Flood inundation raster written to data/OC1mTest_fim.tif\n", + "inundate completed in 0.9615 seconds\n", + "\n", + "run_fim_workflow completed in 49.1919 seconds\n", + "\n" + ] + } + ], + "source": [ + "# set constant flowrate since we don't have a streamflow forecast\n", + "# see docs for `PyGeoFlood.config` and `PyGeoFlood.calculate_flood_stage`\n", + "\n", + "pgf.config = {\"calculate_flood_stage\": {\"custom_Q\": 500}}\n", + "\n", + "pgf.run_fim_workflow()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot flood inundation map\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import rasterio as rio\n", + "\n", + "with rio.open(pgf.fim_path) as ds:\n", + " fim = ds.read(1)\n", + " fim[fim == ds.nodata] = np.nan\n", + "\n", + "plt.imshow(fim, cmap=\"Blues\")\n", + "plt.colorbar()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All output files are saved in the `data` directory and can be downloaded for viewing with a GIS software such as QGIS\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Paths written to data/paths.txt\n" + ] + } + ], + "source": [ + "# save output data file paths we can load our PyGeoFlood instance later with\n", + "# pgf = PyGeoFlood.from_paths(\"data/paths.txt\")\n", + "pgf.to_paths(\"data/paths.txt\")" + ] + } + ], + "metadata": { + "colab": { + "authorship_tag": "ABX9TyMNCi84+7QiD4ra1kbkEbpz", + "include_colab_link": true, + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/.doctrees/nbsphinx/examples/fim_workflow_indiv_steps.ipynb b/.doctrees/nbsphinx/examples/fim_workflow_indiv_steps.ipynb new file mode 100644 index 0000000..6903323 --- /dev/null +++ b/.doctrees/nbsphinx/examples/fim_workflow_indiv_steps.ipynb @@ -0,0 +1,1021 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "view-in-github" + }, + "source": [ + "# Fluvial flood inundation mapping detailed workflow\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/passah2o/pygeoflood/blob/master/doc/examples/fim_workflow_combined.ipynb)\n", + "\n", + "On Google Colab, run the following command to install pygeoflood:\n", + "\n", + "```bash\n", + "%pip install git+https://github.com/passah2o/pygeoflood\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import libraries\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from pygeoflood import PyGeoFlood" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Instantiate **pygeoflood** model class\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "pgf = PyGeoFlood(dem_path=\"data/OC1mTest.tif\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Set paths to input datasets\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "pgf.flowline_path = \"data/Flowline.shp\"\n", + "pgf.catchment_path = \"data/Catchment.shp\"\n", + "\n", + "# # we are not using these datasets for this example\n", + "# pgf.streamflow_forecast_path = \"data/prod_nwm.t00z.analysis_assim.channel_rt.tm00.conus.nc\"\n", + "# pgf.custom_flowline_path = Path(data_dir, \"NHDPlus_H_1209_HU4_GDB.gdb\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download input datasets if necessary\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# make data directory if it doesn't exist\n", + "if not Path(\"data\").is_dir():\n", + " Path(\"data\").mkdir()\n", + "# download input datasets if they doesn't exist\n", + "# DEM from USGS 3DEP\n", + "if not pgf.dem_path.is_file():\n", + " !curl https://utexas.box.com/shared/static/id0in7w8yn38o59sexa50aqunsr7mzk0.tif -Lso data/OC1mTest.tif\n", + "# flowlines and catchments from NFIE (NHD MR) dataset\n", + "# https://www.arcgis.com/home/webmap/viewer.html?webmap=9766a82973b34f18b43dafa20c5ef535\n", + "if not pgf.flowline_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/s1vlnymonbidnhul52oja7s83ky1212j.tgz | tar -xz -C data\n", + "if not pgf.catchment_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/jzawwvmb2tjl4yqtnitgvfjcc4ho4tg5.tgz | tar -xz -C data" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bs031yHfIwQK" + }, + "source": [ + "### Fluvial inundation mapping steps\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running apply_nonlinear_filter with parameters:\n", + " custom_dem = None\n", + " custom_path = None\n", + " method = PeronaMalik2\n", + " smoothing_quantile = 0.9\n", + " time_increment = 0.1\n", + " n_iter = 50\n", + " sigma_squared = 0.05\n", + "Computing slope of raw DTM\n", + "DEM slope array shape: (3378, 4750)\n", + "Computing lambda = q-q-based nonlinear filtering threshold\n", + "DEM smoothing Quantile: 0.9\n", + "Edge Threshold Value: 0.34356024861335754\n", + "Filtered DEM written to data/OC1mTest_filtered.tif\n", + "apply_nonlinear_filter completed in 10.6132 seconds\n", + "\n" + ] + } + ], + "source": [ + "# apply nonlinear filter to DEM\n", + "pgf.apply_nonlinear_filter()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_slope with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " slope statistics\n", + " min angle: 0.0\n", + " max angle: 54.8638\n", + " mean slope: 0.13960592\n", + " stdev slope: 0.15432632\n", + "Slope raster written to data/OC1mTest_slope.tif\n", + "calculate_slope completed in 1.6471 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate slope\n", + "pgf.calculate_slope()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_curvature with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " method = geometric\n", + " using geometric curvature\n", + " curvature statistics\n", + " non-nan curvature cell number: 16045500\n", + " non-nan finite curvature cell number: mean: -0.00031314598\n", + " standard deviation: 0.112147875\n", + "Curvature raster written to data/OC1mTest_curvature.tif\n", + "calculate_curvature completed in 1.8044 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate curvature\n", + "pgf.calculate_curvature()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running fill_depressions with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"FillDepressions\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filtered.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --fix_flats -v --compress_rasters=True\n", + "\n", + "******************************\n", + "* Welcome to FillDepressions *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "******************************\n", + "Reading data...\n", + "Fixing flow on flats...\n", + "Flats increment value: 0.000002\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.188s\n", + "Filled DEM written to data/OC1mTest_filled.tif\n", + "fill_depressions completed in 11.2731 seconds\n", + "\n" + ] + } + ], + "source": [ + "# fill depressions on filtered DEM\n", + "pgf.fill_depressions()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_mfd_flow_accumulation with parameters:\n", + " custom_filled_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"QuinnFlowAccumulation\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_mfd_fac.tif' --out_type=cells --exponent=1.0 -v --compress_rasters=True\n", + "\n", + "************************************\n", + "* Welcome to QuinnFlowAccumulation *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "************************************\n", + "Saving data...\n", + "Output file written\n", + "\n", + "Elapsed Time (Including I/O): 4.602s\n", + "MFD flow accumulation raster written to data/OC1mTest_mfd_fac.tif\n", + "calculate_mfd_flow_accumulation completed in 4.6753 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate MFD flow accumulation\n", + "pgf.calculate_mfd_flow_accumulation()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_d8_flow_direction with parameters:\n", + " custom_filled_dem = None\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"D8Pointer\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_d8_fdr.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to D8Pointer *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.158s\n", + "D8 flow direction raster written to data/OC1mTest_d8_fdr.tif\n", + "calculate_d8_flow_direction completed in 2.2877 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate D8 flow directions\n", + "pgf.calculate_d8_flow_direction()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running find_outlets with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "Outlets raster written to data/OC1mTest_outlets.tif\n", + "find_outlets completed in 0.3229 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate outlets\n", + "pgf.find_outlets()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running delineate_basins with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Basins\" --d8_pntr='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_d8_fdr.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_basins.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Basins *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.459s\n", + "Basins raster written to data/OC1mTest_basins.tif\n", + "delineate_basins completed in 1.1284 seconds\n", + "\n" + ] + } + ], + "source": [ + "# delineate basins\n", + "pgf.delineate_basins()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running define_skeleton with parameters:\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_path = None\n", + " fac_threshold = 3000\n", + " write_flow_skeleton = False\n", + " write_curvature_skeleton = False\n", + "Curvature mean: -0.00031413726\n", + "Curvature standard deviation: 0.11232527\n", + "Curvature Projection: EPSG:6343\n", + "Mean upstream flow: 2617.36\n", + "Combined skeleton written to data/OC1mTest_combined_skeleton.tif\n", + "define_skeleton completed in 1.2861 seconds\n", + "\n" + ] + } + ], + "source": [ + "# define channel skeletons\n", + "pgf.define_skeleton()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# geodesic distance (not needed for GeoFlood workflow)\n", + "# pgf.calculate_geodesic_distance(write_cost_function=True) # uncomment this if identifying channel heads" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# get channel heads (not needed for GeoFlood workflow)\n", + "# pgf.identify_channel_heads() # uncomment this if identifying channel heads" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running find_endpoints with parameters:\n", + " custom_flowline = None\n", + " custom_path = None\n", + "Endpoints csv written to data/OC1mTest_endpoints.csv\n", + "find_endpoints completed in 0.1257 seconds\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/markwang/micromamba/envs/test-env/lib/python3.12/site-packages/pyogrio/raw.py:198: UserWarning: Measured (M) geometry types are not supported. Original type 'Measured 3D LineString' is converted to 'LineString Z'\n", + " return ogr_read(\n" + ] + } + ], + "source": [ + "# get flowline endpoints\n", + "pgf.find_endpoints()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_binary_hand with parameters:\n", + " custom_dem = None\n", + " custom_flowline = None\n", + " custom_path = None\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/markwang/micromamba/envs/test-env/lib/python3.12/site-packages/pyogrio/raw.py:198: UserWarning: Measured (M) geometry types are not supported. Original type 'Measured 3D LineString' is converted to 'LineString Z'\n", + " return ogr_read(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Binary HAND raster written to data/OC1mTest_binary_hand.tif\n", + "calculate_binary_hand completed in 6.7015 seconds\n", + "\n" + ] + } + ], + "source": [ + "# get binary HAND array\n", + "pgf.calculate_binary_hand()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# # get custom flowline from NHD HR dataset (optional)\n", + "# pgf.rasterize_custom_flowline(layer=\"NHDFlowline\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running extract_channel_network with parameters:\n", + " custom_flowline = None\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_endpoints = None\n", + " custom_binary_hand = None\n", + " custom_path = None\n", + " retrace_flowline = True\n", + " vector_extension = shp\n", + " write_cost_function = False\n", + " use_custom_flowline = False\n", + " no_flowline = False\n", + " custom_weight_curvature = None\n", + " custom_weight_mfd_fac = None\n", + " custom_weight_binary_hand = None\n", + " custom_weight_custom_flowline = None\n", + "Retracing flowline...\n", + "Cost function weights:\n", + "curvature 0.2520 (mean flow accumulation)\n", + "mfd_fac 1.0000\n", + "binary_hand 0.7500\n", + "custom_flowline 0.0000\n", + "0.25195235 1 0.75 0\n", + "Cost min: 0.5028838188775905\n", + "Cost max: inf\n", + "cost shape: (3378, 4750)\n", + "Creating path 1/1: RAM usage: 10.95/16.00 GB (68.5%)\n", + "Number of endpoints: 1\n", + "Channel network raster written to data/OC1mTest_channel_network_raster.tif\n", + "Channel network vector written to data/OC1mTest_channel_network.shp\n", + "extract_channel_network completed in 2.7061 seconds\n", + "\n" + ] + } + ], + "source": [ + "# extract channel network\n", + "pgf.extract_channel_network()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_hand with parameters:\n", + " custom_filled_dem = None\n", + " custom_channel_network_raster = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"ElevationAboveStream\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --streams='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_HAND.tif' -v --compress_rasters=True\n", + "\n", + "***********************************\n", + "* Welcome to ElevationAboveStream *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "***********************************\n", + "Reading DEM data...\n", + "Reading streams data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.658s\n", + "**********************************************************************************\n", + "WARNING: Interior pit cells were found within the input DEM. It is likely that the\n", + "DEM needs to be processed to remove topographic depressions and flats prior to\n", + "running this tool.\n", + "**********************************************************************************\n", + "HAND raster written to data/OC1mTest_HAND.tif\n", + "calculate_hand completed in 7.1866 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate HAND\n", + "pgf.calculate_hand()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running segment_channel_network with parameters:\n", + " custom_channel_network_vector = None\n", + " custom_path = None\n", + " vector_extension = shp\n", + " segment_length = 1000\n", + "Segmented channel network written to data/OC1mTest_segmented_channel_network.shp\n", + "segment_channel_network completed in 1.1774 seconds\n", + "\n" + ] + } + ], + "source": [ + "# segment flowline\n", + "pgf.segment_channel_network()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running delineate_segment_catchments with parameters:\n", + " custom_segmented_channel_network = None\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Watershed\" --d8_pntr='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_d8_fdr.tif' --pour_pts='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_segmented_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_segment_catchments.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Watershed *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.914s\n", + "Segment catchments written to data/OC1mTest_segment_catchments.tif\n", + "delineate_segment_catchments completed in 1.8000 seconds\n", + "\n" + ] + } + ], + "source": [ + "# delineate channel network segment catchments\n", + "pgf.delineate_segment_catchments()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_src with parameters:\n", + " custom_dem = None\n", + " custom_segmented_channel_network = None\n", + " custom_segment_catchments_raster = None\n", + " custom_catchments = None\n", + " custom_hand = None\n", + " custom_path = None\n", + " min_slope = 1e-06\n", + " max_stage = 20\n", + " incr_stage = 0.1\n", + " custom_roughness_path = None\n", + "River attributes written to data/OC1mTest_river_attributes.csv\n", + "Synthetic rating curves written to data/OC1mTest_src.csv\n", + "calculate_src completed in 4.7793 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate synthetic rating curves table\n", + "pgf.calculate_src()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_flood_stage with parameters:\n", + " custom_src = None\n", + " custom_streamflow_forecast_path = None\n", + " custom_path = None\n", + " custom_Q = 500\n", + "Applying custom streamflow to each segment: 500 cms\n", + "Flood stages written to data/OC1mTest_flood_stage.csv\n", + "calculate_flood_stage completed in 0.0102 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate flood stage from synthetic rating curves\n", + "# pgf.streamflow_forecast_path must be set or custom_Q must be provided\n", + "pgf.calculate_flood_stage(custom_Q=500)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running inundate with parameters:\n", + " custom_hand = None\n", + " custom_flood_stage = None\n", + " custom_segment_catchments_raster = None\n", + " custom_path = None\n", + "Flood inundation raster written to data/OC1mTest_fim.tif\n", + "inundate completed in 1.4405 seconds\n", + "\n" + ] + } + ], + "source": [ + "# create flood depth grid (FIM)\n", + "pgf.inundate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot flood inundation map\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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xZg7dy6vv/76iDT9/f1ccsklJBIJampquOKKK8hkMiPSrFmzhve9731Eo1Ha2tq46aabDvatldzy5cs544wzqKqqoqmpiY9+9KNs2LBhRBrLsli8eDH19fVUVlZy8cUX093dPSLN9u3bWbhwIfF4nKamJr7yla/ged6INI899hinnnoqkUiEY445Zr/ncZ9IbrnlFubMmVOcNbCjo4M//vGPxePyLA/cjTfeiKZpXH311cV98jzLSxunPyWnDjN33nmnCofD6he/+IVat26d+vznP69qampUd3d3uYtWVvfff7/6+7//e/Xb3/5WAeruu+8ecfzGG29U1dXV6p577lEvvfSS+j//5/+o6dOnq3w+X0xz0UUXqZNOOkk9/fTT6n//93/VMcccoz796U8XjyeTSdXc3KwuueQStXbtWvXrX/9axWIx9ZOf/KRUt1kS8+fPV7fddptau3atWr16tfrgBz+o2tvbVSaTKaa58sorVVtbm3rkkUfU888/r84++2z1nve8p3jc8zx1wgknqLlz56oXX3xR3X///aqhoUEtW7asmGbz5s0qHo+rpUuXqvXr16sf/ehHyjAM9cADD5T0fg+23//+9+q+++5Tr732mtqwYYP6u7/7OxUKhdTatWuVUvIsD9Szzz6rpk2bpubMmaO+9KUvFffL8yyPZDKpAPXa9l7VOeiMaXtte68CVDKZLFn5D7tg4cwzz1SLFy8ufvZ9X7W2tqrly5eXsVSHlrcGC0EQqJaWFvWd73ynuG9wcFBFIhH161//Wiml1Pr16xWgnnvuuWKaP/7xj0rTNLVr1y6llFI//vGPVW1trbJtu5jm2muvVTNmzDjId1RePT09ClCPP/64Uqrw7EKhkPrNb35TTPPKK68oQK1cuVIpVQjedF1XXV1dxTS33HKLSiQSxef31a9+Vc2ePXvEtT75yU+q+fPnH+xbKrva2lr1s5/9TJ7lAUqn0+rYY49VK1asUO9///uLwYI8z/IpBgs7elVn0hnT9tqO0gcLh1UzhOM4rFq1irlz5xb36brO3LlzWblyZRlLdmjbsmULXV1dI55bdXU1Z511VvG5rVy5kpqaGk4//fRimrlz56LrOs8880wxzbnnnks4HC6mmT9/Phs2bGBgYKBEd1N6yWQSeGOl01WrVuG67ojnOXPmTNrb20c8zxNPPJHm5uZimvnz55NKpVi3bl0xzZvzGE5zOP9b9n2fO++8k2w2S0dHhzzLA7R48WIWLlz4tnuW51l+2jhtpXZYdXDs7e3F9/0R/8gBmpubefXVV8tUqkNfV1cXwF6f2/Cxrq4umpqaRhw3TZO6uroRaaZPn/62PIaP1dbWHpTyl1MQBFx99dWcc845nHDCCUDhXsPhMDU1NSPSvvV57u15Dx/bV5pUKkU+nycWix2MWyqLl19+mY6ODizLorKykrvvvptZs2axevVqeZajdOedd/LCCy/w3HPPve2Y/NsUB+qwChaEKLXFixezdu1annzyyXIXZUKbMWMGq1evJplM8t///d8sWrSIxx9/vNzFmnB27NjBl770JVasWEE0Gi13ccReyGiIQ0BDQwOGYbytZ293dzctLS1lKtWhb/jZ7Ou5tbS00NPTM+K453n09/ePSLO3PN58jcPJkiVLuPfee/nTn/7ElClTivtbWlpwHIfBwcER6d/6PN/tWb1TmkQicdh9cwuHwxxzzDGcdtppLF++nJNOOokf/OAH8ixHadWqVfT09HDqqadimiamafL444/zwx/+ENM0aW5uludZZhN1NMRhFSyEw2FOO+00HnnkkeK+IAh45JFH6OjoKGPJDm3Tp0+npaVlxHNLpVI888wzxefW0dHB4OAgq1atKqZ59NFHCYKAs846q5jmiSeewHXdYpoVK1YwY8aMw6oJQinFkiVLuPvuu3n00Uff1vRy2mmnEQqFRjzPDRs2sH379hHP8+WXXx4RgK1YsYJEIsGsWbOKad6cx3CaI+HfchAE2LYtz3KULrzwQl5++WVWr15d3E4//XQuueSS4s/yPMtsonZaKFlXyhK58847VSQSUbfffrtav369+sIXvqBqampG9Ow9EqXTafXiiy+qF198UQHqu9/9rnrxxRfVtm3blFKFoZM1NTXqd7/7nVqzZo36yEc+stehk6eccop65pln1JNPPqmOPfbYEUMnBwcHVXNzs7r00kvV2rVr1Z133qni8fhhN3TyqquuUtXV1eqxxx5TnZ2dxS2XyxXTXHnllaq9vV09+uij6vnnn1cdHR2qo6OjeHx4eNq8efPU6tWr1QMPPKAaGxv3OjztK1/5inrllVfUzTfffFgOT/vbv/1b9fjjj6stW7aoNWvWqL/9279Vmqaphx56SCklz3Ks3jwaQil5nuUyPBpi064+1ZN2x7Rt2tUnQyfHw49+9CPV3t6uwuGwOvPMM9XTTz9d7iKV3Z/+9CcFvG1btGiRUqowfPIf/uEfVHNzs4pEIurCCy9UGzZsGJFHX1+f+vSnP60qKytVIpFQn/3sZ1U6nR6R5qWXXlLvfe97VSQSUZMnT1Y33nhjqW6xZPb2HAF12223FdPk83n1//7f/1O1tbUqHo+rv/iLv1CdnZ0j8tm6datasGCBisViqqGhQX35y19WruuOSPOnP/1JnXzyySocDqujjjpqxDUOF5dffrmaOnWqCofDqrGxUV144YXFQEEpeZZj9dZgQZ5neQwHC5t39ak9aXdM2+YyBAuaUkqVvj5DCCGEOHKkUimqq6vZsruPqkRiTHmlUymmt9aTTCZJjDGv/XVY9VkQQgghxPiToZNCCCFEyYzHaIbS93CUYEEIIYQoEZlnQQghhBCHJQkWhBBCCLFP0gwhhBBClIg0QwghhBDisCQ1C0IIIUSJjMfaDuVYG0KCBSGEEKJEJmozhAQLQgghRImMxzpQ5VhHSvosCCGEEGKfpGZBCCGEKJUJWrUgwYIQQghRIhO1g6M0QwghhBBin6RmQQghhCgRGQ0hhBBCiH2aoF0WpBlCCCGEEPsmNQtCCCFEqUzQqgUJFoQQQogSkdEQQgghhDgsSc2CEEIIUSLpdGrMoxnS6dT4FGYUJFgQQgghDrJwOExLSwvHTm8bl/xaWloIh8Pjktf+0JRSqmRXE0IIIY5QlmXhOM645BUOh4lGo+OS1/6QYEEIIYQQ+yQdHIUQQgixTxIsCCGEEGKfJFgQQgghxD5JsCCEEEKIfZJgQQghhBD7JMGCEEIIIfZJggUhhBBC7NP/D+dkQs5i4jMSAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import rasterio as rio\n", + "\n", + "with rio.open(pgf.fim_path) as ds:\n", + " fim = ds.read(1)\n", + " fim[fim == ds.nodata] = np.nan\n", + "\n", + "plt.imshow(fim, cmap=\"Blues\")\n", + "plt.colorbar()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Paths written to data/paths.txt\n" + ] + } + ], + "source": [ + "# save output data file paths we can load our PyGeoFlood instance later with\n", + "# pgf = PyGeoFlood.from_paths(\"data/paths.txt\")\n", + "pgf.to_paths(\"data/paths.txt\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Temporary workaround to obtain Dinf HAND (optional)\n", + "- Dinf HAND creates more realistic FIM than D8 HAND\n", + "- The previous workflow uses D8 HAND as input to the FIM step\n", + "- Dinf HAND is not yet supported in pygeoflood (coming soon)\n", + "- This is a workaround to use TauDEM to obtain Dinf HAND\n", + "\n", + "**Note**: TauDEM must be installed on your system for the following steps to work." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "vscode": { + "languageId": "shellscript" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PitRemove version 5.3.9\n", + "Input file data/OC1mTest.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -340282346638528859811704183484516925440.000000\n", + "Nodata value recast to float used in partition raster: -340282346638528859811704183484516925440.000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This run may take on the order of 1 minutes to complete.\n", + "This estimate is very approximate. \n", + "Run time is highly uncertain as it depends on the complexity of the input data \n", + "and speed and memory of the computer. This estimate is based on our testing on \n", + "a dual quad core Dell Xeon E5405 2.0GHz PC with 16GB RAM.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Processes: 8\n", + "Header read time: 0.144063\n", + "Data read time: 0.022310\n", + "Compute time: 1.109974\n", + "Write time: 0.450810\n", + "Total time: 1.727157\n", + "DinfFlowDir version 5.3.9\n", + "Input file data/OC1mTest_fel.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -300000000549775575777803994281145270272.000000\n", + "Nodata value recast to float used in partition raster: -300000000549775575777803994281145270272.000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This run may take on the order of 3 minutes to complete.\n", + "This estimate is very approximate. \n", + "Run time is highly uncertain as it depends on the complexity of the input data \n", + "and speed and memory of the computer. This estimate is based on our testing on \n", + "a dual quad core Dell Xeon E5405 2.0GHz PC with 16GB RAM.\n", + "All slopes evaluated. 539517 flats to resolve.\n", + "Draining flats towards lower adjacent terrain\n", + "..................................................................................................................................................................................................................................................................................................................................................................................................................\n", + "Draining flats away from higher adjacent terrain\n", + ".....................................................\n", + "Setting directions\n", + "Iteration complete. Number of flats remaining: 13592\n", + "Draining flats towards lower adjacent terrain\n", + "...................................\n", + "Draining flats away from higher adjacent terrain\n", + ".........\n", + "Setting directions\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Processors: 8\n", + "Header read time: 0.019067\n", + "Data read time: 0.047244\n", + "Compute Slope time: 1.134700\n", + "Write Slope time: 0.411829\n", + "Resolve Flat time: 9.764547\n", + "Write Flat time: 0.463723\n", + "Total time: 11.841111\n", + "DinfDistDown -v version 5.3.9\n", + "Input file data/OC1mTest_ang.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -340282346638528859811704183484516925440.000000\n", + "Nodata value recast to float used in partition raster: -340282346638528859811704183484516925440.000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This run may take on the order of 1 minutes to complete.\n", + "This estimate is very approximate. \n", + "Run time is highly uncertain as it depends on the complexity of the input data \n", + "and speed and memory of the computer. This estimate is based on our testing on \n", + "a dual quad core Dell Xeon E5405 2.0GHz PC with 16GB RAM.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Input file data/OC1mTest_fel.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -300000000549775575777803994281145270272.000000\n", + "Nodata value recast to float used in partition raster: -300000000549775575777803994281145270272.000000\n", + "Input file data/OC1mTest_channel_network.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -32768.000000\n", + "Nodata value recast to int16_t used in partition raster: -32768\n", + "Processors: 8\n", + "Read time: 0.106575\n", + "Compute time: 4.125068\n", + "Write time: 0.363995\n", + "Total time: 4.595638\n" + ] + } + ], + "source": [ + "%%bash\n", + "\n", + "# bash script to generate Dinf HAND with TauDEM\n", + "\n", + "# Notes before running this cell:\n", + "# - Open taudem_hand.sh and update the first two blocks as necessary\n", + "# - Ensure the TauDEM executables pitremove, dinfflowdir, and dinfdistdown are on your path\n", + "\n", + "bash taudem_hand.sh" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running inundate with parameters:\n", + " custom_hand = data/OC1mTest_HAND_taudem.tif\n", + " custom_flood_stage = None\n", + " custom_segment_catchments_raster = None\n", + " custom_path = data/OC1mTest_HAND_taudem_fim\n", + "Flood inundation raster written to data/OC1mTest_HAND_taudem_fim.tif\n", + "inundate completed in 1.3339 seconds\n", + "\n" + ] + } + ], + "source": [ + "# create FIM with Dinf HAND written in previous step\n", + "pgf.inundate(\n", + " custom_hand=\"data/OC1mTest_HAND_taudem.tif\",\n", + " custom_path=\"data/OC1mTest_HAND_taudem_fim\", # output FIM path\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot flood inundation map (Dinf HAND based)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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oSnHGBgYYMOGDaRSKbq6uvjkJz9JEART9rn//vt505vehOM4LF26lFtvvfXw36EQQghxrNCmaZthhxQszJ8/ny9+8Yts3ryZxx57jLe//e387u/+Lk899RQAn/jEJ/iP//gPvve97/HAAw+we/du3vve9zafH4YhGzZswPM8fvnLX/LNb36TW2+9lc985jPNfbZv386GDRu48MILefzxx7nmmmv44z/+Y+6+++5pestCCCGEOBSaOsK1K9va2vjrv/5rfv/3f5/Ozk5uu+02fv/3fx+AZ599lpUrV7Jp0ybOPfdcfvzjH/Pbv/3b7N69m+7ubgBuvvlmrrvuOvbu3Ytt21x33XXceeedbNmypfka73//+5mYmOCuu+466PMqFovk83mGRgvkcrkjeYtCCCGOc8Vike72PIXC0blmTF6THnxyJ5nskR2/XCpy/mnzj9q57s9hJziGYch3vvMdKpUKa9euZfPmzfi+z7p165r7rFixggULFrBp0yYANm3axGmnndYMFADWr19PsVhsjk5s2rRpyjEm95k8xutxXZdisThlE0IIIY4lk9UQR7rNtEMOFp588kkymQyO43DllVfygx/8gFWrVjE4OIht27S0tEzZv7u7m8HBQQAGBwenBAqTj08+dqB9isUitVrtdc/rxhtvJJ/PN7f+/v5DfWtCCCHEUTVHUxYOPVhYvnw5jz/+OA8//DBXXXUVl19+OU8//fTROLdDcv3111MoFJrbjh07ZvuUhBBCiOPCIZdO2rbN0qVLATjrrLN49NFH+cpXvsL73vc+PM9jYmJiyujC0NAQPT09APT09PDII49MOd5ktcQr93l1BcXQ0BC5XI5kMvm65+U4Do7jHOrbEUIIIWbOHK2dPOKmTFEU4bouZ511FpZlcd999zUf27p1KwMDA6xduxaAtWvX8uSTTzI8PNzc55577iGXy7Fq1armPq88xuQ+k8cQQggh5iptmn7NtEMaWbj++uu5+OKLWbBgAaVSidtuu43777+fu+++m3w+zxVXXMG1115LW1sbuVyOP/mTP2Ht2rWce+65AFx00UWsWrWKD37wg3zpS19icHCQT3/602zcuLE5KnDllVfyv/7X/+JTn/oUH/3oR/npT3/Kd7/7Xe68887pf/dCCCGEeEOHFCwMDw/zoQ99iD179pDP51m9ejV3330373znOwH48pe/jK7rXHrppbiuy/r16/na177WfL5hGNxxxx1cddVVrF27lnQ6zeWXX87nP//55j6LFy/mzjvv5BOf+ARf+cpXmD9/Pv/yL//C+vXrp+ktCyGEELNjrq4NccR9Fo5V0mdBCCHEwZqpPgubnt41LX0W1q6aNzf6LAghhBDixCALSQkhhBAzZY5WQ0iwIIQQQsyQ6ahmmI1qCJmGEEIIIcQByciCEEIIMUPmajWEBAtCCCHEDJmjKQsSLAghhBAzZo5GC5KzIIQQQogDkpEFIYQQYobM1WoICRaEEEKIGTJXExxlGkIIIYQQByQjC0IIIcQMmaP5jRIsCCGEEDNmjkYLMg0hhBBCiAOSkQUhhBBihszVaggZWRBCCCFmiravIuJwt0ONFR588EHe85730NfXh6Zp3H777Yd82hIsCCGEEMexSqXC6aefzle/+tXDPoZMQwghhBAzZDbyGy+++GIuvvjiI3pNCRaEEEKImTKN0UKxWJxyt+M4OI5zhAffP5mGEEIIIWaINk2/APr7+8nn883txhtvPGrnLSMLQgghxBy0Y8cOcrlc8/bRGlUACRaEEEKIGTOda0PkcrkpwcLRJMGCEEIIMUPmaANHCRaEEEKI41m5XOb5559v3t6+fTuPP/44bW1tLFiw4KCOcdwGC0opAEqvyhYVQgghXm3yWjF57ThqZmFo4bHHHuPCCy9s3r722msBuPzyy7n11lsP6hjHbbAwOjoKwNLF/bN8JkIIIeaKUqlEPp8/asefjXbPF1xwwREHQcdtsNDW1gbAwMDAUf2LPxEUi0X6+/tfk3krDo98ntNHPsvpdSJ/nkopSqUSfX19s30qx6TjNljQ9biFRD6fP+H+0R8tM5l5eyKQz3P6yGc5vU7Uz3MmvlhqTEM1xLScyaE5boMFIYQQ4lgzV6shpIOjEEIIIQ7ouB1ZcByHz372s0e1o9WJQj7L6SWf5/SRz3J6yed59E1nU6aZpKmjXicihBBCnNiKxSL5fJ6nX9pL9gjzQUrFIqsWdVIoFKSDoxBCCHG8masjC5KzIIQQQogDkpEFIYQQYobM1WoICRaEEEKIGSLTEMeQr371qyxatIhEIsGaNWt45JFHZvuUZt2DDz7Ie97zHvr6+tA0jdtvv33K40opPvOZz9Db20symWTdunVs27Ztyj5jY2Ncdtll5HI5WlpauOKKKyiXy1P2eeKJJzjvvPNIJBL09/fzpS996Wi/tRl34403cs4555DNZunq6uKSSy5h69atU/ap1+ts3LiR9vZ2MpkMl156KUNDQ1P2GRgYYMOGDaRSKbq6uvjkJz9JEART9rn//vt505vehOM4LF269KD7uM8lN910E6tXr242Alq7di0//vGPm4/LZ3n4vvjFL6JpGtdcc03zPvk8xWFRx5nvfOc7yrZt9Y1vfEM99dRT6mMf+5hqaWlRQ0NDs31qs+pHP/qR+ou/+Av1/e9/XwHqBz/4wZTHv/jFL6p8Pq9uv/129Zvf/Eb9zu/8jlq8eLGq1WrNfd71rnep008/XT300EPqZz/7mVq6dKn6wAc+0Hy8UCio7u5uddlll6ktW7aob3/72yqZTKp/+qd/mqm3OSPWr1+vbrnlFrVlyxb1+OOPq3e/+91qwYIFqlwuN/e58sorVX9/v7rvvvvUY489ps4991z1W7/1W83HgyBQp556qlq3bp369a9/rX70ox+pjo4Odf311zf3efHFF1UqlVLXXnutevrpp9U//uM/KsMw1F133TWj7/do++EPf6juvPNO9dxzz6mtW7eqP//zP1eWZaktW7YopeSzPFyPPPKIWrRokVq9erX60z/90+b98nnOjkKhoAD13MCI2jPhHdH23MCIAlShUJix8z/ugoU3v/nNauPGjc3bYRiqvr4+deONN87iWR1bXh0sRFGkenp61F//9V8375uYmFCO46hvf/vbSimlnn76aQWoRx99tLnPj3/8Y6Vpmtq1a5dSSqmvfe1rqrW1Vbmu29znuuuuU8uXLz/K72h2DQ8PK0A98MADSqn4s7MsS33ve99r7vPMM88oQG3atEkpFQdvuq6rwcHB5j433XSTyuVyzc/vU5/6lDrllFOmvNb73vc+tX79+qP9lmZda2ur+pd/+Rf5LA9TqVRSy5YtU/fcc49629ve1gwW5POcPc1gYceI2lPwjmh7bsfMBwvH1TSE53ls3ryZdevWNe/TdZ1169axadOmWTyzY9v27dsZHByc8rnl83nWrFnT/Nw2bdpES0sLZ599dnOfdevWoes6Dz/8cHOf888/H9u2m/usX7+erVu3Mj4+PkPvZuYVCgVg3+Jlmzdvxvf9KZ/nihUrWLBgwZTP87TTTqO7u7u5z/r16ykWizz11FPNfV55jMl9jud/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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import rasterio as rio\n", + "\n", + "with rio.open(\"data/OC1mTest_HAND_taudem_fim.tif\") as ds:\n", + " fim = ds.read(1)\n", + " fim[fim == ds.nodata] = np.nan\n", + "\n", + "plt.imshow(fim, cmap=\"Blues\")\n", + "plt.colorbar()\n", + "plt.show()" + ] + } + ], + "metadata": { + "colab": { + "authorship_tag": "ABX9TyMNCi84+7QiD4ra1kbkEbpz", + "include_colab_link": true, + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/.doctrees/nbsphinx/examples_fim_workflow_combined_13_0.png b/.doctrees/nbsphinx/examples_fim_workflow_combined_13_0.png new file mode 100644 index 0000000..da9b790 Binary files /dev/null and b/.doctrees/nbsphinx/examples_fim_workflow_combined_13_0.png differ diff --git a/.doctrees/nbsphinx/examples_fim_workflow_indiv_steps_33_0.png b/.doctrees/nbsphinx/examples_fim_workflow_indiv_steps_33_0.png new file mode 100644 index 0000000..1a57f5c Binary files /dev/null and b/.doctrees/nbsphinx/examples_fim_workflow_indiv_steps_33_0.png differ diff --git a/.doctrees/nbsphinx/examples_fim_workflow_indiv_steps_39_0.png b/.doctrees/nbsphinx/examples_fim_workflow_indiv_steps_39_0.png new file mode 100644 index 0000000..51dbf89 Binary files /dev/null and b/.doctrees/nbsphinx/examples_fim_workflow_indiv_steps_39_0.png differ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/_images/examples_fim_workflow_combined_13_0.png b/_images/examples_fim_workflow_combined_13_0.png new file mode 100644 index 0000000..da9b790 Binary files /dev/null and b/_images/examples_fim_workflow_combined_13_0.png differ diff --git a/_images/examples_fim_workflow_indiv_steps_33_0.png b/_images/examples_fim_workflow_indiv_steps_33_0.png new file mode 100644 index 0000000..1a57f5c Binary files /dev/null and b/_images/examples_fim_workflow_indiv_steps_33_0.png differ diff --git a/_images/examples_fim_workflow_indiv_steps_39_0.png b/_images/examples_fim_workflow_indiv_steps_39_0.png new file mode 100644 index 0000000..51dbf89 Binary files /dev/null and b/_images/examples_fim_workflow_indiv_steps_39_0.png differ diff --git a/_sources/apiref/apiref.rst.txt b/_sources/apiref/apiref.rst.txt new file mode 100644 index 0000000..0b139a6 --- /dev/null +++ b/_sources/apiref/apiref.rst.txt @@ -0,0 +1,7 @@ +pygeoflood +========== + +.. autoclass:: src.pygeoflood.PyGeoFlood + :members: + + \ No newline at end of file diff --git a/_sources/contribute.rst.txt b/_sources/contribute.rst.txt new file mode 100644 index 0000000..4e2b0f4 --- /dev/null +++ b/_sources/contribute.rst.txt @@ -0,0 +1,32 @@ +Contributing +============ + +Bug reports +----------- + +We welcome contributions to **pygeoflood**. Please file bug reports on the `GitHub issue tracker `_. + +Development +----------- + +Clone and install in editable mode: + +.. code-block:: bash + + git clone https://github.com/passah2o/pygeoflood + cd pygeoflood + pip install -e . + +To contribute: fork, create a new branch with your changes, and submit a pull request. + +Building the docs +----------------- + +To build the documentation, use the provided environment: + +.. code-block:: bash + + conda env create -f doc/pgfdocs-env.yml + conda activate pgfdocs-env + cd doc + make html \ No newline at end of file diff --git a/_sources/examples/fim_workflow_combined.ipynb.txt b/_sources/examples/fim_workflow_combined.ipynb.txt new file mode 100644 index 0000000..57b0e56 --- /dev/null +++ b/_sources/examples/fim_workflow_combined.ipynb.txt @@ -0,0 +1,483 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Fluvial flood inundation mapping quick start" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/passah2o/pygeoflood/blob/master/doc/examples/fim_workflow_combined.ipynb)\n", + "\n", + "On Google Colab, run the following command to install pygeoflood:\n", + "\n", + "```bash\n", + "%pip install git+https://github.com/passah2o/pygeoflood\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bs031yHfIwQK" + }, + "source": [ + "### Import libraries\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from pygeoflood import PyGeoFlood" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Instantiate **pygeoflood** model class\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "pgf = PyGeoFlood(dem_path=\"data/OC1mTest.tif\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Set paths to input datasets\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "pgf.flowline_path = \"data/Flowline.shp\"\n", + "pgf.catchment_path = \"data/Catchment.shp\"\n", + "\n", + "# # we are not using these datasets for this example\n", + "# pgf.streamflow_forecast_path = \"data/prod_nwm.t00z.analysis_assim.channel_rt.tm00.conus.nc\"\n", + "# pgf.custom_flowline_path = Path(data_dir, \"NHDPlus_H_1209_HU4_GDB.gdb\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download example input datasets if necessary\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# make data directory if it doesn't exist\n", + "if not Path(\"data\").is_dir():\n", + " Path(\"data\").mkdir()\n", + "# download input datasets if they doesn't exist\n", + "# DEM from USGS 3DEP\n", + "if not pgf.dem_path.is_file():\n", + " !curl https://utexas.box.com/shared/static/id0in7w8yn38o59sexa50aqunsr7mzk0.tif -Lso data/OC1mTest.tif\n", + "# flowlines and catchments from NFIE (NHD MR) dataset\n", + "# https://www.arcgis.com/home/webmap/viewer.html?webmap=9766a82973b34f18b43dafa20c5ef535\n", + "if not pgf.flowline_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/s1vlnymonbidnhul52oja7s83ky1212j.tgz | tar -xz -C data\n", + "if not pgf.catchment_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/jzawwvmb2tjl4yqtnitgvfjcc4ho4tg5.tgz | tar -xz -C data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Run full fluvial flood inundation mapping workflow\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running apply_nonlinear_filter with parameters:\n", + " custom_dem = None\n", + " custom_path = None\n", + " method = PeronaMalik2\n", + " smoothing_quantile = 0.9\n", + " time_increment = 0.1\n", + " n_iter = 50\n", + " sigma_squared = 0.05\n", + "Computing slope of raw DTM\n", + "DEM slope array shape: (3378, 4750)\n", + "Computing lambda = q-q-based nonlinear filtering threshold\n", + "DEM smoothing Quantile: 0.9\n", + "Edge Threshold Value: 0.34356024861335754\n", + "Filtered DEM written to data/OC1mTest_filtered.tif\n", + "apply_nonlinear_filter completed in 10.7802 seconds\n", + "\n", + "Running calculate_slope with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " slope statistics\n", + " min angle: 0.0\n", + " max angle: 54.863846043721324\n", + " mean slope: 0.13960592\n", + " stdev slope: 0.15432632\n", + "Slope raster written to data/OC1mTest_slope.tif\n", + "calculate_slope completed in 1.2883 seconds\n", + "\n", + "Running calculate_curvature with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " method = geometric\n", + " using geometric curvature\n", + " curvature statistics\n", + " non-nan curvature cell number: 16045500\n", + " non-nan finite curvature cell number: mean: -0.00031314598\n", + " standard deviation: 0.112147875\n", + "Curvature raster written to data/OC1mTest_curvature.tif\n", + "calculate_curvature completed in 1.3863 seconds\n", + "\n", + "Running fill_depressions with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"FillDepressions\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filtered.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --fix_flats -v --compress_rasters=True\n", + "\n", + "******************************\n", + "* Welcome to FillDepressions *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "******************************\n", + "Reading data...\n", + "Fixing flow on flats...\n", + "Flats increment value: 0.000002\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.190s\n", + "Filled DEM written to data/OC1mTest_filled.tif\n", + "fill_depressions completed in 8.0148 seconds\n", + "\n", + "Running calculate_mfd_flow_accumulation with parameters:\n", + " custom_filled_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"QuinnFlowAccumulation\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_mfd_fac.tif' --out_type=cells --exponent=1.0 -v --compress_rasters=True\n", + "\n", + "************************************\n", + "* Welcome to QuinnFlowAccumulation *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "************************************\n", + "Saving data...\n", + "Output file written\n", + "\n", + "Elapsed Time (Including I/O): 4.702s\n", + "MFD flow accumulation raster written to data/OC1mTest_mfd_fac.tif\n", + "calculate_mfd_flow_accumulation completed in 4.7655 seconds\n", + "\n", + "Running calculate_d8_flow_direction with parameters:\n", + " custom_filled_dem = None\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"D8Pointer\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_d8_fdr.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to D8Pointer *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.251s\n", + "D8 flow direction raster written to data/OC1mTest_d8_fdr.tif\n", + "calculate_d8_flow_direction completed in 1.9938 seconds\n", + "\n", + "Running find_outlets with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "Outlets raster written to data/OC1mTest_outlets.tif\n", + "find_outlets completed in 0.2224 seconds\n", + "\n", + "Running delineate_basins with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Basins\" --d8_pntr='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_d8_fdr.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_basins.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Basins *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.465s\n", + "Basins raster written to data/OC1mTest_basins.tif\n", + "delineate_basins completed in 1.0381 seconds\n", + "\n", + "Running define_skeleton with parameters:\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_path = None\n", + " fac_threshold = 3000\n", + " write_flow_skeleton = False\n", + " write_curvature_skeleton = False\n", + "Curvature mean: -0.00031413726\n", + "Curvature standard deviation: 0.11232527\n", + "Curvature Projection: EPSG:6343\n", + "Mean upstream flow: 2617.3564\n", + "Combined skeleton written to data/OC1mTest_combined_skeleton.tif\n", + "define_skeleton completed in 0.7782 seconds\n", + "\n", + "Running find_endpoints with parameters:\n", + " custom_flowline = None\n", + " custom_path = None\n", + "Endpoints csv written to data/OC1mTest_endpoints.csv\n", + "find_endpoints completed in 0.0330 seconds\n", + "\n", + "Running calculate_binary_hand with parameters:\n", + " custom_dem = None\n", + " custom_flowline = None\n", + " custom_path = None\n", + "Binary HAND raster written to data/OC1mTest_binary_hand.tif\n", + "calculate_binary_hand completed in 4.9416 seconds\n", + "\n", + "Running extract_channel_network with parameters:\n", + " custom_flowline = None\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_endpoints = None\n", + " custom_binary_hand = None\n", + " custom_path = None\n", + " retrace_flowline = True\n", + " vector_extension = shp\n", + " write_cost_function = False\n", + " use_custom_flowline = False\n", + " no_flowline = False\n", + " custom_weight_curvature = None\n", + " custom_weight_mfd_fac = None\n", + " custom_weight_binary_hand = None\n", + " custom_weight_custom_flowline = None\n", + "Retracing flowline...\n", + "Cost function weights:\n", + "curvature 0.2520 (mean flow accumulation)\n", + "mfd_fac 1.0000\n", + "binary_hand 0.7500\n", + "custom_flowline 0.0000\n", + "0.25195235 1 0.75 0\n", + "Cost min: 0.5028838188775905\n", + "Cost max: inf\n", + "cost shape: (3378, 4750)\n", + "Creating path 1/1: RAM usage: 12.00/16.00 GB (75.0%)\n", + "Number of endpoints: 1\n", + "Channel network raster written to data/OC1mTest_channel_network_raster.tif\n", + "Channel network vector written to data/OC1mTest_channel_network.shp\n", + "extract_channel_network completed in 2.0418 seconds\n", + "\n", + "Running calculate_hand with parameters:\n", + " custom_filled_dem = None\n", + " custom_channel_network_raster = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"ElevationAboveStream\" --dem='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_filled.tif' --streams='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_HAND.tif' -v --compress_rasters=True\n", + "\n", + "***********************************\n", + "* Welcome to ElevationAboveStream *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "***********************************\n", + "Reading DEM data...\n", + "Reading streams data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.644s\n", + "**********************************************************************************\n", + "WARNING: Interior pit cells were found within the input DEM. It is likely that the\n", + "DEM needs to be processed to remove topographic depressions and flats prior to\n", + "running this tool.\n", + "**********************************************************************************\n", + "HAND raster written to data/OC1mTest_HAND.tif\n", + "calculate_hand completed in 5.1220 seconds\n", + "\n", + "Running segment_channel_network with parameters:\n", + " custom_channel_network_vector = None\n", + " custom_path = None\n", + " vector_extension = shp\n", + " segment_length = 1000\n", + "Segmented channel network written to data/OC1mTest_segmented_channel_network.shp\n", + "segment_channel_network completed in 0.7907 seconds\n", + "\n", + "Running delineate_segment_catchments with parameters:\n", + " custom_segmented_channel_network = None\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Watershed\" --d8_pntr='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_d8_fdr.tif' --pour_pts='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_segmented_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/examples/data/OC1mTest_segment_catchments.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Watershed *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.841s\n", + "Segment catchments written to data/OC1mTest_segment_catchments.tif\n", + "delineate_segment_catchments completed in 1.5538 seconds\n", + "\n", + "Running calculate_src with parameters:\n", + " custom_dem = None\n", + " custom_segmented_channel_network = None\n", + " custom_segment_catchments_raster = None\n", + " custom_catchments = None\n", + " custom_hand = None\n", + " custom_path = None\n", + " min_slope = 1e-06\n", + " max_stage = 20\n", + " incr_stage = 0.1\n", + " custom_roughness_path = None\n", + "River attributes written to data/OC1mTest_river_attributes.csv\n", + "Synthetic rating curves written to data/OC1mTest_src.csv\n", + "calculate_src completed in 3.4749 seconds\n", + "\n", + "Running calculate_flood_stage with parameters:\n", + " custom_src = None\n", + " custom_streamflow_forecast_path = None\n", + " custom_path = None\n", + " custom_Q = 500\n", + "Applying custom streamflow to each segment: 500 cms\n", + "Flood stages written to data/OC1mTest_flood_stage.csv\n", + "calculate_flood_stage completed in 0.0042 seconds\n", + "\n", + "Running inundate with parameters:\n", + " custom_hand = None\n", + " custom_flood_stage = None\n", + " custom_segment_catchments_raster = None\n", + " custom_path = None\n", + "Flood inundation raster written to data/OC1mTest_fim.tif\n", + "inundate completed in 0.9615 seconds\n", + "\n", + "run_fim_workflow completed in 49.1919 seconds\n", + "\n" + ] + } + ], + "source": [ + "# set constant flowrate since we don't have a streamflow forecast\n", + "# see docs for `PyGeoFlood.config` and `PyGeoFlood.calculate_flood_stage`\n", + "\n", + "pgf.config = {\"calculate_flood_stage\": {\"custom_Q\": 500}}\n", + "\n", + "pgf.run_fim_workflow()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot flood inundation map\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import rasterio as rio\n", + "\n", + "with rio.open(pgf.fim_path) as ds:\n", + " fim = ds.read(1)\n", + " fim[fim == ds.nodata] = np.nan\n", + "\n", + "plt.imshow(fim, cmap=\"Blues\")\n", + "plt.colorbar()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All output files are saved in the `data` directory and can be downloaded for viewing with a GIS software such as QGIS\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Paths written to data/paths.txt\n" + ] + } + ], + "source": [ + "# save output data file paths we can load our PyGeoFlood instance later with\n", + "# pgf = PyGeoFlood.from_paths(\"data/paths.txt\")\n", + "pgf.to_paths(\"data/paths.txt\")" + ] + } + ], + "metadata": { + "colab": { + "authorship_tag": "ABX9TyMNCi84+7QiD4ra1kbkEbpz", + "include_colab_link": true, + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_sources/examples/fim_workflow_indiv_steps.ipynb.txt b/_sources/examples/fim_workflow_indiv_steps.ipynb.txt new file mode 100644 index 0000000..6903323 --- /dev/null +++ b/_sources/examples/fim_workflow_indiv_steps.ipynb.txt @@ -0,0 +1,1021 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "view-in-github" + }, + "source": [ + "# Fluvial flood inundation mapping detailed workflow\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/passah2o/pygeoflood/blob/master/doc/examples/fim_workflow_combined.ipynb)\n", + "\n", + "On Google Colab, run the following command to install pygeoflood:\n", + "\n", + "```bash\n", + "%pip install git+https://github.com/passah2o/pygeoflood\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import libraries\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from pygeoflood import PyGeoFlood" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Instantiate **pygeoflood** model class\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "pgf = PyGeoFlood(dem_path=\"data/OC1mTest.tif\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Set paths to input datasets\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "pgf.flowline_path = \"data/Flowline.shp\"\n", + "pgf.catchment_path = \"data/Catchment.shp\"\n", + "\n", + "# # we are not using these datasets for this example\n", + "# pgf.streamflow_forecast_path = \"data/prod_nwm.t00z.analysis_assim.channel_rt.tm00.conus.nc\"\n", + "# pgf.custom_flowline_path = Path(data_dir, \"NHDPlus_H_1209_HU4_GDB.gdb\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download input datasets if necessary\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# make data directory if it doesn't exist\n", + "if not Path(\"data\").is_dir():\n", + " Path(\"data\").mkdir()\n", + "# download input datasets if they doesn't exist\n", + "# DEM from USGS 3DEP\n", + "if not pgf.dem_path.is_file():\n", + " !curl https://utexas.box.com/shared/static/id0in7w8yn38o59sexa50aqunsr7mzk0.tif -Lso data/OC1mTest.tif\n", + "# flowlines and catchments from NFIE (NHD MR) dataset\n", + "# https://www.arcgis.com/home/webmap/viewer.html?webmap=9766a82973b34f18b43dafa20c5ef535\n", + "if not pgf.flowline_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/s1vlnymonbidnhul52oja7s83ky1212j.tgz | tar -xz -C data\n", + "if not pgf.catchment_path.is_file():\n", + " !curl -sL https://utexas.box.com/shared/static/jzawwvmb2tjl4yqtnitgvfjcc4ho4tg5.tgz | tar -xz -C data" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bs031yHfIwQK" + }, + "source": [ + "### Fluvial inundation mapping steps\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running apply_nonlinear_filter with parameters:\n", + " custom_dem = None\n", + " custom_path = None\n", + " method = PeronaMalik2\n", + " smoothing_quantile = 0.9\n", + " time_increment = 0.1\n", + " n_iter = 50\n", + " sigma_squared = 0.05\n", + "Computing slope of raw DTM\n", + "DEM slope array shape: (3378, 4750)\n", + "Computing lambda = q-q-based nonlinear filtering threshold\n", + "DEM smoothing Quantile: 0.9\n", + "Edge Threshold Value: 0.34356024861335754\n", + "Filtered DEM written to data/OC1mTest_filtered.tif\n", + "apply_nonlinear_filter completed in 10.6132 seconds\n", + "\n" + ] + } + ], + "source": [ + "# apply nonlinear filter to DEM\n", + "pgf.apply_nonlinear_filter()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_slope with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " slope statistics\n", + " min angle: 0.0\n", + " max angle: 54.8638\n", + " mean slope: 0.13960592\n", + " stdev slope: 0.15432632\n", + "Slope raster written to data/OC1mTest_slope.tif\n", + "calculate_slope completed in 1.6471 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate slope\n", + "pgf.calculate_slope()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_curvature with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + " method = geometric\n", + " using geometric curvature\n", + " curvature statistics\n", + " non-nan curvature cell number: 16045500\n", + " non-nan finite curvature cell number: mean: -0.00031314598\n", + " standard deviation: 0.112147875\n", + "Curvature raster written to data/OC1mTest_curvature.tif\n", + "calculate_curvature completed in 1.8044 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate curvature\n", + "pgf.calculate_curvature()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running fill_depressions with parameters:\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"FillDepressions\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filtered.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --fix_flats -v --compress_rasters=True\n", + "\n", + "******************************\n", + "* Welcome to FillDepressions *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "******************************\n", + "Reading data...\n", + "Fixing flow on flats...\n", + "Flats increment value: 0.000002\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.188s\n", + "Filled DEM written to data/OC1mTest_filled.tif\n", + "fill_depressions completed in 11.2731 seconds\n", + "\n" + ] + } + ], + "source": [ + "# fill depressions on filtered DEM\n", + "pgf.fill_depressions()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_mfd_flow_accumulation with parameters:\n", + " custom_filled_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"QuinnFlowAccumulation\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_mfd_fac.tif' --out_type=cells --exponent=1.0 -v --compress_rasters=True\n", + "\n", + "************************************\n", + "* Welcome to QuinnFlowAccumulation *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "************************************\n", + "Saving data...\n", + "Output file written\n", + "\n", + "Elapsed Time (Including I/O): 4.602s\n", + "MFD flow accumulation raster written to data/OC1mTest_mfd_fac.tif\n", + "calculate_mfd_flow_accumulation completed in 4.6753 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate MFD flow accumulation\n", + "pgf.calculate_mfd_flow_accumulation()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_d8_flow_direction with parameters:\n", + " custom_filled_dem = None\n", + " custom_filtered_dem = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"D8Pointer\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_d8_fdr.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to D8Pointer *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.158s\n", + "D8 flow direction raster written to data/OC1mTest_d8_fdr.tif\n", + "calculate_d8_flow_direction completed in 2.2877 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate D8 flow directions\n", + "pgf.calculate_d8_flow_direction()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running find_outlets with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "Outlets raster written to data/OC1mTest_outlets.tif\n", + "find_outlets completed in 0.3229 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate outlets\n", + "pgf.find_outlets()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running delineate_basins with parameters:\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Basins\" --d8_pntr='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_d8_fdr.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_basins.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Basins *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.459s\n", + "Basins raster written to data/OC1mTest_basins.tif\n", + "delineate_basins completed in 1.1284 seconds\n", + "\n" + ] + } + ], + "source": [ + "# delineate basins\n", + "pgf.delineate_basins()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running define_skeleton with parameters:\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_path = None\n", + " fac_threshold = 3000\n", + " write_flow_skeleton = False\n", + " write_curvature_skeleton = False\n", + "Curvature mean: -0.00031413726\n", + "Curvature standard deviation: 0.11232527\n", + "Curvature Projection: EPSG:6343\n", + "Mean upstream flow: 2617.36\n", + "Combined skeleton written to data/OC1mTest_combined_skeleton.tif\n", + "define_skeleton completed in 1.2861 seconds\n", + "\n" + ] + } + ], + "source": [ + "# define channel skeletons\n", + "pgf.define_skeleton()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# geodesic distance (not needed for GeoFlood workflow)\n", + "# pgf.calculate_geodesic_distance(write_cost_function=True) # uncomment this if identifying channel heads" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# get channel heads (not needed for GeoFlood workflow)\n", + "# pgf.identify_channel_heads() # uncomment this if identifying channel heads" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running find_endpoints with parameters:\n", + " custom_flowline = None\n", + " custom_path = None\n", + "Endpoints csv written to data/OC1mTest_endpoints.csv\n", + "find_endpoints completed in 0.1257 seconds\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/markwang/micromamba/envs/test-env/lib/python3.12/site-packages/pyogrio/raw.py:198: UserWarning: Measured (M) geometry types are not supported. Original type 'Measured 3D LineString' is converted to 'LineString Z'\n", + " return ogr_read(\n" + ] + } + ], + "source": [ + "# get flowline endpoints\n", + "pgf.find_endpoints()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_binary_hand with parameters:\n", + " custom_dem = None\n", + " custom_flowline = None\n", + " custom_path = None\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/markwang/micromamba/envs/test-env/lib/python3.12/site-packages/pyogrio/raw.py:198: UserWarning: Measured (M) geometry types are not supported. Original type 'Measured 3D LineString' is converted to 'LineString Z'\n", + " return ogr_read(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Binary HAND raster written to data/OC1mTest_binary_hand.tif\n", + "calculate_binary_hand completed in 6.7015 seconds\n", + "\n" + ] + } + ], + "source": [ + "# get binary HAND array\n", + "pgf.calculate_binary_hand()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# # get custom flowline from NHD HR dataset (optional)\n", + "# pgf.rasterize_custom_flowline(layer=\"NHDFlowline\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running extract_channel_network with parameters:\n", + " custom_flowline = None\n", + " custom_curvature = None\n", + " custom_mfd_fac = None\n", + " custom_endpoints = None\n", + " custom_binary_hand = None\n", + " custom_path = None\n", + " retrace_flowline = True\n", + " vector_extension = shp\n", + " write_cost_function = False\n", + " use_custom_flowline = False\n", + " no_flowline = False\n", + " custom_weight_curvature = None\n", + " custom_weight_mfd_fac = None\n", + " custom_weight_binary_hand = None\n", + " custom_weight_custom_flowline = None\n", + "Retracing flowline...\n", + "Cost function weights:\n", + "curvature 0.2520 (mean flow accumulation)\n", + "mfd_fac 1.0000\n", + "binary_hand 0.7500\n", + "custom_flowline 0.0000\n", + "0.25195235 1 0.75 0\n", + "Cost min: 0.5028838188775905\n", + "Cost max: inf\n", + "cost shape: (3378, 4750)\n", + "Creating path 1/1: RAM usage: 10.95/16.00 GB (68.5%)\n", + "Number of endpoints: 1\n", + "Channel network raster written to data/OC1mTest_channel_network_raster.tif\n", + "Channel network vector written to data/OC1mTest_channel_network.shp\n", + "extract_channel_network completed in 2.7061 seconds\n", + "\n" + ] + } + ], + "source": [ + "# extract channel network\n", + "pgf.extract_channel_network()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_hand with parameters:\n", + " custom_filled_dem = None\n", + " custom_channel_network_raster = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"ElevationAboveStream\" --dem='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_filled.tif' --streams='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_HAND.tif' -v --compress_rasters=True\n", + "\n", + "***********************************\n", + "* Welcome to ElevationAboveStream *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "***********************************\n", + "Reading DEM data...\n", + "Reading streams data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.658s\n", + "**********************************************************************************\n", + "WARNING: Interior pit cells were found within the input DEM. It is likely that the\n", + "DEM needs to be processed to remove topographic depressions and flats prior to\n", + "running this tool.\n", + "**********************************************************************************\n", + "HAND raster written to data/OC1mTest_HAND.tif\n", + "calculate_hand completed in 7.1866 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate HAND\n", + "pgf.calculate_hand()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running segment_channel_network with parameters:\n", + " custom_channel_network_vector = None\n", + " custom_path = None\n", + " vector_extension = shp\n", + " segment_length = 1000\n", + "Segmented channel network written to data/OC1mTest_segmented_channel_network.shp\n", + "segment_channel_network completed in 1.1774 seconds\n", + "\n" + ] + } + ], + "source": [ + "# segment flowline\n", + "pgf.segment_channel_network()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running delineate_segment_catchments with parameters:\n", + " custom_segmented_channel_network = None\n", + " custom_d8_fdr = None\n", + " custom_path = None\n", + "./whitebox_tools --run=\"Watershed\" --d8_pntr='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_d8_fdr.tif' --pour_pts='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_segmented_channel_network_raster.tif' --output='/Users/markwang/repos/pygeoflood/doc/examples/data/OC1mTest_segment_catchments.tif' -v --compress_rasters=True\n", + "\n", + "****************************\n", + "* Welcome to Watershed *\n", + "* Powered by WhiteboxTools *\n", + "* www.whiteboxgeo.com *\n", + "****************************\n", + "Reading data...\n", + "Saving data...\n", + "Output file written\n", + "Elapsed Time (excluding I/O): 0.914s\n", + "Segment catchments written to data/OC1mTest_segment_catchments.tif\n", + "delineate_segment_catchments completed in 1.8000 seconds\n", + "\n" + ] + } + ], + "source": [ + "# delineate channel network segment catchments\n", + "pgf.delineate_segment_catchments()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_src with parameters:\n", + " custom_dem = None\n", + " custom_segmented_channel_network = None\n", + " custom_segment_catchments_raster = None\n", + " custom_catchments = None\n", + " custom_hand = None\n", + " custom_path = None\n", + " min_slope = 1e-06\n", + " max_stage = 20\n", + " incr_stage = 0.1\n", + " custom_roughness_path = None\n", + "River attributes written to data/OC1mTest_river_attributes.csv\n", + "Synthetic rating curves written to data/OC1mTest_src.csv\n", + "calculate_src completed in 4.7793 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate synthetic rating curves table\n", + "pgf.calculate_src()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running calculate_flood_stage with parameters:\n", + " custom_src = None\n", + " custom_streamflow_forecast_path = None\n", + " custom_path = None\n", + " custom_Q = 500\n", + "Applying custom streamflow to each segment: 500 cms\n", + "Flood stages written to data/OC1mTest_flood_stage.csv\n", + "calculate_flood_stage completed in 0.0102 seconds\n", + "\n" + ] + } + ], + "source": [ + "# calculate flood stage from synthetic rating curves\n", + "# pgf.streamflow_forecast_path must be set or custom_Q must be provided\n", + "pgf.calculate_flood_stage(custom_Q=500)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running inundate with parameters:\n", + " custom_hand = None\n", + " custom_flood_stage = None\n", + " custom_segment_catchments_raster = None\n", + " custom_path = None\n", + "Flood inundation raster written to data/OC1mTest_fim.tif\n", + "inundate completed in 1.4405 seconds\n", + "\n" + ] + } + ], + "source": [ + "# create flood depth grid (FIM)\n", + "pgf.inundate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot flood inundation map\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgsAAAGFCAYAAABzDbD7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABvBklEQVR4nO3deZxddX34/9dZ7jozd/Ylk8wkYUtIIOzLiCJLTIjRr1a0ailEQf3CN/EnxCpNaxG0GoqtaxG0KthWpNgKKiAQQKBI2AIhJIFA9m2WzHb3s39+f9yZCwMhZDKTezPJ+5nHeTD3nM/5nM85CXPe97NqSimFEEIIIcQ70MtdACGEEEIc2iRYEEIIIcQ+SbAghBBCiH2SYEEIIYQQ+yTBghBCCCH2SYIFIYQQQuyTBAtCCCGE2Cez3AUQQgghjgSWZeE4zrjkFQ6HiUaj45LX/pBgQQghhDjILMsiVlUPXm5c8mtpaWHLli0lCxgkWBBCCCEOMsdxwMsRmbUIjPDYMvMdutb/EsdxJFgQQgghDjtmFG2MwYLSSt/dUIIFIYQQolQ0QNPGnkeJyWgIIYQQQuyT1CwIIYQQpaLphW2seZSYBAtCCCFEqWjaODRDlL4dQpohhBBCCLFPUrMghBBClIo0QwghhBBin6QZQgghhBCHI6lZEEIIIUpmHJohyvA9X4IFIYQQolQmaDOEBAtCCCFEqUzQDo7SZ0EIIYQQ+yQ1C0IIIUSpSDOEEEIIIfZJmiGEEEIIcTiSmgUhhBCiVKQZQgghhBD7JM0QQgghhDjUTJs2DU3T3rYtXrx4v/OQmgUhhBCiVDRtHGoWRtcM8dxzz+H7fvHz2rVr+cAHPsAnPvGJ/c5DggUhhBCiVHStsI01j1FobGwc8fnGG2/k6KOP5v3vf/9+5yHBghBCCDEBpVKpEZ8jkQiRSGSf5ziOw3/+53+ydOlStFHUUEifBSGEEKJUhjs4jnUD2traqK6uLm7Lly9/18vfc889DA4O8pnPfGZUxZaaBSGEEKJUxnHo5I4dO0gkEsXd71arAPDzn/+cBQsW0NraOqpLSrAghBBClMo4Dp1MJBIjgoV3s23bNh5++GF++9vfjvqS0gwhhBBCHAFuu+02mpqaWLhw4ajPlZoFIYQQolTKNINjEATcdtttLFq0CNMc/atfggUhhBCiVMo0g+PDDz/M9u3bufzyyw/okhIsCCGEEIe5efPmoZQ64PMlWBBCCCFKRRaSEkIIIcQ+yUJSQgghhDgcSc2CEEIIUSrSDCGEEEKIfRuHZogyNApIsCCEEEKUygStWZA+C0IIIYTYJ6lZEEIIIUpF08ZhNIT0WRBCCCEOXzJ0cvzdfPPNTJs2jWg0yllnncWzzz5b7iIJIYQQR5xDNlj4r//6L5YuXcrXv/51XnjhBU466STmz59PT09PuYsmhBBCHJjhDo5j3UrskA0Wvvvd7/L5z3+ez372s8yaNYtbb72VeDzOL37xi3IXTQghhDgww80QY91K7JDss+A4DqtWrWLZsmXFfbquM3fuXFauXLnXc2zbxrbt4ucgCOjv76e+vh6tDFGYEEKIiUMpRTqdprW1FV0/ZL9Hl80hGSz09vbi+z7Nzc0j9jc3N/Pqq6/u9Zzly5dzww03lKJ4QgghDlM7duxgypQpB+8CE3SehUMyWDgQy5YtY+nSpcXPyWSS9vZ2duzYQSKRKGPJhBBClMLG7hyOF+D6AZ6vcIMAx1d4qrDP9gNyrkfW80nmfZa+/6jiualUira2Nqqqqg5uISfoaIhDMlhoaGjAMAy6u7tH7O/u7qalpWWv50QiESKRyNv2JxIJCRaEEOIwt6knTyReieYF6L7CDBSB56F7AboKwA+wbJd+2yDn+3RZDhf+6AWe+/vzRuQjzdZ7d0g2zITDYU477TQeeeSR4r4gCHjkkUfo6OgoY8mEEEIcajbvyeP6AX6g8AOF5wdYno8fKJzAJ+V49FsOfTmPtO2Tsny29WTo6kyWvrATdDTEIVmzALB06VIWLVrE6aefzplnnsn3v/99stksn/3sZ8tdNCGEEIeQ4SBheHMDhe0HWL5HxvXJOB4ZJ8DxFAB70javvNrDYO9gycuqadrYay8kWHjDJz/5Sfbs2cN1111HV1cXJ598Mg888MDbOj0KIYQ4cu3oL4yCGw4UgkI8gKIQNFieT8YJyFg+th/Qk3Z4/uUu+rv7ydz1mZKXV4KFg2DJkiUsWbKk3MUQQghxiFKAUm/dp/CCNzo4+kM1DX1Zl9Wv9bJ7WzcViYqylHeiOqSDBSGEEGJflFIo3uiYGKhCkOCrAC9QBEORRN4N2NGbZffOfnRdp/tnnyhPgbWhbax5lJgEC0IIISak7pRb/FkphVLgBaq4KaXwA0hZPlt6MuzYlSKfydM6talsZZZmCCGEEKKElCr0UQiG+iooCk0QSoETBOzJeexKOnQnLXoH8/T2JAlHw5wyS/q+jZYEC0IIISYkRSFQcP0A2/XJuT4px6XfduhMOXSlXQYyDsmsQ2dnhnwmz6yT2mmujpatzBO1ZuGQnGdBCCGEeDcZyyNteeQdn7zn02879Fk2vVmXlOXjeAF5x2PT1gH6u/tpaWtkZnstUVPj249sLEuZh4OFsW6lJjULQgghJoTt/TZ5x8fzA5QC1w/IOT45z8Mdmt456wTknADbVwxmHV5c101fVz+1TbUcf2wDk2uj1MVMauMm96zp5KNzJpX7tiYECRaEEEIc8jbvyRdnZ3S8AMsNcPyAQClybiFgGLA8BvM+g5bP5u40L7y0m/RgmvqWOmYe28DxrVU0xE2aK8PURyNUR0K8uC3FKVNLtyTARG2GkGBBCCFESXWnXDw/IBiqHXC8gKztM2g56Gg0VUUwdA3LDfD8AF3TMHQNTStMvuR4AWnHJed5hHSdrOeRsj36cx5daYe12wZ4Ze0uAj9g8tQmprXVcFxrgpaqMC2VYZrjURKRECFT58QplaW9eRk6KYQQQuy/QA2v5VAY5mhqOj15i1f60/iBIucG5J2AaEinqdKkJhKmMmQSKBh0HPKeT8TQsf2AtO2ztd/i2bVd7NjSTTQeZepRTUydVEVTdYzJ1WGmVkdpiceIhQ1MQ2P25BIHChOYBAtCCCFKKnjTlIuFavnhn6EmEiKs66Rdj5DhYegavRmXDd1ZkjmX6niIuoow/lAeiahB1NTZ0J1j5erddO/cQ01jDe3ttUxprKA6HmZKTZhja+NMq6kgEtLRNY3jWuLluHVphhBCCCH2x6TqMADb+iyg8AI1dI2IoaOjoWsaMdOgPhpGQ8Op8+nN22wdsNk1aLOhM0Uq6xAEimjURCnYtKmPgZ4BGibV09ZWTVNNjOp4mMnVEWY3VjK9toKqWAhT12iri5Tt3guLRo41WBifsoyGBAtCCCHKYmp9lO1DC0HpGoQMHT9QxALjjT4NQYDhQ0MsgqFpVEUMGivDdKdsNnel6exM09udJJ/NM6m9ieOOricRDxELm7TXRjihqZJpNRVUx0NMrS/f/ArDNMZj6KPULAghhDiCtNdF2DXo4Psa3vAS077C8zVcX6H7YGgapqajFMXmh0CB7QV0daXJpXPUtdRxzPQ6JtXGMHWdhkqT4+rjTK2uYE5bVZnvcuKTYEEIIURZTa4JsyftFgMFQw/wdA1DD3A00HyFrmm4QYCp67h+ofPj5l1JunbsobqhmhNnNdPeUEl1zKAubjK9JsaUyjgntR9agYL0WRBCCCEOUGNViD1pt7DWg9IIFGhBoS+DHygCwNA1TF2jL+vxys5BXlu/i3hVnJnHNzOzNUFd3KSxIsTkyhh10TCV0UPwFSdDJ4UQQogD1zlo4XgBnq/Ie4WJliw/IO/5OL5PoGBLv82f13ezbUsvtY01zJrRyEnt1TTETWpjJpMr4yQiIWJhgxNKPYfCYUyCBSGEEGW3ensa1yvMymj5Po4fDC01HWB5PinLpz/vsfL1Xtat3grA7BNbOXN6LZMSISrDJjXhMBUhk2ioDJMt7a9xaIZQ0gwhhBDiSNCdcrFdH9dX2F4AFJridU3D0LShUQOFlSW9QGF5AZ1Jm9c29ODZDrXN9cTCJrGwTm00TE0kRNwsBAph89BdI3E8+iyUYyGpQ/eJCiGEOGw1J0LoQ1M469obzfCFJn0NQy/8N1AKyw3IuQGpnEs2lcUIhZh2VAONiSiWG5AIm1RHQlREDE6ZmmDmpIpy3tohadeuXfz1X/819fX1xGIxTjzxRJ5//vn9Pl9qFoQQQpSFphUmYCr8PPytWxVrFqBQq2D7w0MqA3zPp7K6kua6ONXxENGQjh/A6dOry3kr+60cNQsDAwOcc845nH/++fzxj3+ksbGR119/ndra2v3OQ4IFIYQQZaEP1SoUFonS0HhjGmg19MdXCqUKaTw/IPADwtEwkZBBXcykuSJEzDTKeBejVIbREP/0T/9EW1sbt912W3Hf9OnTR5WHNEMIIYQoi2KQMPRNOVCqMNlS4GN5AbYf4AcKQwdT04hHTDRNw/d8dF2jNm4UhkhGjszvvalUasRm2/Ze0/3+97/n9NNP5xOf+ARNTU2ccsop/Nu//duoriXBghBCiLJoqgrtdX4hpQqBgxsEhVqFocWmDL2QOJ/NA1ARNqgKhzhtWqKUxR6T4eBorBtAW1sb1dXVxW358uV7vebmzZu55ZZbOPbYY3nwwQe56qqr+P/+v/+PX/7yl/td7iMzHBNCCHFI0IcWkQoZGkrpQEBMGTh+UOzPEAylG16s0rEccrZHzDQmVhME49tnYceOHSQSbwRKkcjeF8gKgoDTTz+db3/72wCccsoprF27lltvvZVFixbt1zUlWBBCCFE2IUPDDzT8oUWkDL3QtVHTCjUKAH6gyLk+sbDBpKnNALTUxKgwTc44amJ0bBw2nsFCIpEYESy8k0mTJjFr1qwR+44//nj+53/+Z7+vKcGCEEKIsmmsCrF70MHQCyMjdE3DNHRipoHt+5iGxo5Bh1Wv9ZDLeWRSOVzHZf32SmY2xcpd/AnhnHPOYcOGDSP2vfbaa0ydOnW/85BgQQghRFmZhobnU5x3AQqrS3qBYuegw+pNvaRSNrmcS7IviVKKfN6jN+eVt+AHoBxDJ6+55hre85738O1vf5u//Mu/5Nlnn+WnP/0pP/3pT/c7DwkWhBBClFVP0mb7YI5Bx2FP1mUg59Gf9+jL2PSlbDwvwDQNQqEA3dDxbIdUyqI6avDIq71cOLOh3Lew/8owdPKMM87g7rvvZtmyZXzjG99g+vTpfP/73+eSSy7Z7zwkWBBCCFFWmwcyDNouKdsrrgGRzrtkLQ9naJikaero+tD8z0qRHMgQNfWJFSiU0Yc+9CE+9KEPHfD5EiwIIYQoude7c6TyHhm70JSgURjxEDY1oqZOVh+e2VFD1zUMQ8N1fTzPA02jMlFBa1W0jHdwYGRtCCGEEGI/HdscLwyZ1DVCuk7UNIgOBQohQyt2eDT0QrAAkOxPQRBghEJMnVrDxSdNKvNdjN54zrNQSuMeLFx//fVvu6mZM2cWj1uWxeLFi6mvr6eyspKLL76Y7u7uEXls376dhQsXEo/HaWpq4itf+UohmhRCCHHYGF4hMmYaRIxCwBAyCgFEYTGpwmaaOsmkRTaVBaWorKnkvJmN5S7+EeWgNEPMnj2bhx9++I2LmG9c5pprruG+++7jN7/5DdXV1SxZsoSPfexj/PnPfwbA930WLlxIS0sLTz31FJ2dnVx22WWEQqHihBJCCCEmvrBZCBaivoGlBxiaX5ja2XhToGDoZPMufd2D4PtgGLRPa+BDxzWVu/gHZKI2QxyUYME0TVpaWt62P5lM8vOf/5w77riDCy64AIDbbruN448/nqeffpqzzz6bhx56iPXr1/Pwww/T3NzMySefzDe/+U2uvfZarr/+esLh8MEoshBCiBIziwFBYQZHU9fR0TCHl64ean7o7EwXahU0jer6ak45tpFELFTm0h+gMoyGGA8Hpc/C66+/TmtrK0cddRSXXHIJ27dvB2DVqlW4rsvcuXOLaWfOnEl7ezsrV64EYOXKlZx44ok0NzcX08yfP59UKsW6deve8Zq2bb9tUQ0hhBCHLl1/Uw2CpmNoYOgU14EwNI2uPVm6dvSACognKpl2VCM/+cRsjpYJmUpq3IOFs846i9tvv50HHniAW265hS1btvC+972PdDpNV1cX4XCYmpqaEec0NzfT1dUFQFdX14hAYfj48LF3snz58hELarS1tY3vjQkhhBhX2lAHRk0rBAYab1TRhw2NwZzD1k3deLZDOBalZUo9T//t+8tc6rGZqB0cx70ZYsGCBcWf58yZw1lnncXUqVO56667iMUOXiS4bNkyli5dWvycSqUkYBBCiEPZ0MpQaui/w+9AXYOM7bN+wx4ygxnMcJjmKY20T5lY60DszUTts3DQh07W1NRw3HHHsXHjRlpaWnAch8HBwRFpuru7i30cWlpa3jY6Yvjz3vpBDItEIsVFNfZ3cQ0hhBCl0Zd9+4i2nf15OpMWO1I5+iybQdsl7wZYrmLVhj10buvCMA0aWhuYMiXB2UfXlaHk42u49mRMWxk6LRz0SZkymQybNm3i0ksv5bTTTiMUCvHII49w8cUXA7Bhwwa2b99OR0cHAB0dHXzrW9+ip6eHpqZCb9cVK1aQSCTetmqWEEKIiSGZc9nVnydn+9h+gBP4pB2PQduhP+/Tl3XZ2W8xkLXJOz6vrduBUopJU5tpb69hdlsN50+rL/dtHLHGPVj4m7/5Gz784Q8zdepUdu/ezde//nUMw+DTn/401dXVXHHFFSxdupS6ujoSiQRf/OIX6ejo4OyzzwZg3rx5zJo1i0svvZSbbrqJrq4uvva1r7F48eJ3XKtbCCHEoS3v+AzmXXZmcuxOO0SGRkCkbZ+sHbB70Ob1nYNs3bwHgFhFjMrqSk6c2UR7Q5zZzXHOPe4wqFmYoM0Q4x4s7Ny5k09/+tP09fXR2NjIe9/7Xp5++mkaGwsTaHzve99D13UuvvhibNtm/vz5/PjHPy6ebxgG9957L1dddRUdHR1UVFSwaNEivvGNb4x3UYUQQpSIHyjcIMDyfLb0WaTzLq01hemaU5bPtp40Gzd0kh1Mg6bTNKWJ005q5ZjmStprw7RWTrypnfdqgg6dHPdg4c4779zn8Wg0ys0338zNN9/8jmmmTp3K/fffP95FE0IIUUaOH7An67GrP0cy6+D6AdGQQX/GZtPG3kKgAJghE8M0UErRUhVienWchSc0v0vu4mCShaSEEEIcdJ6v8ILCqAfL8bFtj919ObJZh+1b9pAeSBOKRqiqqSJRE6emJkracunPezTGD5NaBaQZQgghhHhHp05LENmlo1BsbrR41fbYvTvFns4+7JxNRXUF9U01hMMmmlZ4IVZGQygFZx418YdMDpNgQQghhNiH2ZMrmT25kp6cTddgjpc6+7CzeaKVcRpbajFNAwDD0IlETGorwkxKTNBpnQ8zskS1EEKIkjqmppJZkwtz4WiGQW3jmwMFjUjEIBo2qI6HqI+FeGHr4TN9f6HWZOxbqUmwIIQQoqTOm1HP8g/OACAajxKLFSq5NQ2iUZNIxKQiYlITNakMhQibh8+rariJZWxb6cstzRBCCCHKIhQOYRgGul4IBkIhg1gsRDxikoiHSUQNYqbBCVMqy1xScfiEa0IIISaUPb/4JDC0+qShEYuZVERNEvEQdRUhauMm8aHmicPGeDRBSM2CEEKII4lSqhgsRKMmVbEQ1fEwDRUhqkLmYdUEATIaQgghhBi1IAjQdQ3T1AkZOhXREImoWWyCOPyChbF3UJQOjkIIIY4oKlBoGpimjmnoGJpG2NSIhXQqQiZz2qrKXUSB1CwIIYQoI8/10DSNUMggYuoYukbU1ImZhZqFw42ua+j62KoG1BjPPxBSsyCEEKJs7GSSdNrGMDTCIYNISCca0gnrhZqGw81EnWdBahaEEEKU3Lcf2cj/PLUDnDyD/WmamipwvYCc7ZOxfCzfx/ODchdTDJFgQQghREk9tqEPQ9dom1TF1kmTSe7cze5EBb4fkHc8fKWorzBprfDLXdRxJ6MhhBBCCKAr6dBSHX7H475SVIR1WmpiHH/iFFb9OcOuNevYVVlLZU0lU49qIh42mFodK2GpS0NGQwghhDjibe21SFsez2wa3Ovx9buz6GhUhA1q4yYz2mo47ZyZmHWNkOwhs3UTmzbsZnd/jqTtlrbw4h1JzYIQQohxsbEnT9byyDk+rw+m+Y+7O/nXvzh+RBqlFLqmETF0qqMmEUMnEWukpirC889XkOzaQzQeZfX6HnoG8zyzI8NHZzYy9/iGMt3V+JJmCCGEEEesTT15BrMOuzN5dqYt1nbmeK0zyey/f4h135oHwPNbkviBQqEAiJoahq5jGhqhydVo2lQ2bqli62s7Gdz4Grs21qNps/nA0bXlvLVxJcGCEEKII1Zv2mZ7OsfrfTle7cqyrSdDT0+GXVu7mfz/7mbh+cdiOT6Ta6Oc1lqFFygMXcNToGuFPgx1lRFyWQccp5Bpqpc1L2zl6RkNfGROS3lv8AgnwYIQQogxaf/i72lorMSyPFLJHKn+FG7eAt8HK43RUMOz67rZ8OLr1E5q4oUTWzn9qDqaKkMoVQgaDF2jayAHQLyuhpxpQrofa/d2/uexN5a0nugmagdHCRaEEEIcsNgF3wYVsGcfaRzbwTCqIJ9h4LV+nti6jVUtk5gxu5UzjmtkSk2EnrSL6wdU1xRGQIQiIdKmSdDfxY5XtpTmZkpAYxyaIcqw7KQEC0IIUSab9+TJWF6hHV+9sT8eKSyglHd8Zk+u3K+8ulMumgZNVaGDVNqRqj75S7yeHfuVNrljJ2efOQ3/PafQtXuA9ECabFcnL3R1su6lRo6eMZkpLZXEwiaJRATPCzBDBrquM5DPgZU+yHdTOlKzIIQQYr/1Zz1CRmEtBD94I1IwDY2KiEnnoDVi/75s77NQwNT66EEq7Rsu/NFKnvrTehjofGOnpkM4BvEEqACySfCcws8Aro3nB5x9QgvrqiIkkzUkkw0M9Axg9/Wy/qletk+aRPv0JkIhnWAoeAr8AAwDfO+g35fYNwkWhBCiDCy38CI1DR3HC4iEdGLhwsJJ23pzvJ5MMyke48VtKSqjJsc2x9+WR3fKxQsUthfs9fh4m3HtA/R1D0J2cOSBmmbeP/cETmirxgsU23tzrFqzm55N28HKgFF41fRnbHI5F03TqKyMEA43koxHSff0kdm2mfVd3YSqa9ANncAPcB0XrGx5vkofJDIaQgghjjAbunJowHEto39RW65PoMDzAwIFecdnMOeyJ2/RlbXJOAEN0QDXVzhewOvdOWJhA13T0DQIFPiBKm5j0ZspfHP3A0Vz4o1mjCV3v0J/xsb1ArbuTtG9sxff8yF40zTMkQrmLZjD6dNq6c97OJ6itS7O9AuPZc+Z7exJWeiaxoxJCTb1ZAiHC3MBBoFC0wJiFTFUYx2ZPUB2ADefKtRUDL8QAx/Md54NcqKRZgghhDjCzHhTkLBuVwbPV5zUXvWu573WlcP2CjULnh/g+QE51yftumRcvxggOEGA4wWEjDfeDsbQ8sR+oIrBRs4e2xoKlusXg45XOx0cL6AnY1MTM9jd75PMOXTuHsT3fVShfaB4bmLKFE5qrybn+ugUmlEcL8ByFZqmUVcVwXEDNnansRwf0zTwfYVhaJimjmcahCNhKupryYbDkBmk2IHDd0HTaZ49a0z3J8ZOggUhhBgHwx0Rt/RahRe9F3DilJGdE/uzHvmh5gfHC4ov6IzrknN98r5P3vXJOoUahd68TVjX0bQwpqHj+QrPVwRDL1M/UGQsj/cce+CTFu0aLAQHgYKc7dGTsUk5LhFDpzUR5vnNHhtf7yXVnwLeUgWuGxx1bBPxkIFFAARoPuiajusXyhg4Q/9VoOsaoZDO8KtHKfD9AN8z0XSNWGUM36tF0zV0XSfZl8S1XU6a3XzA93eoKUczxPXXX88NN9wwYt+MGTN49dVX9zsPCRaEEGIcRUM6SimU0lizI43lBvTnHWqjIZqro7h+UAwUHC/AVwrHD8j7PhnHozvj4g29aLtSLnsyHiFD4+jaGNNrKjF0DaUKtQqDlsOFM8c2DbI/tAz0cJ6OH7BpIMe2AYeeZJ6+gTxWzirUKAwb/lnTSacdTEMjpumYvobnK9yhfhRKQWAqNK1Q4+D5ikjIwHJ8dP1NtSVGoVPj8L5CUGEQBMO1L2NrZjmUlKsZYvbs2Tz88MPFz6Y5ute/BAtCCDGOoiEDDYb6FhR+q9cEIbqyFoauDdUQFAKGtFvooJjzPHKux6Dl4/mFl2tFpNDZMe8E5J2AdT1ZnCBgeqISpRRJx2XB7KZRl6875eL5AcPvXy9QuL5CKYXnB5i6Rn/OY0dvhr6kRSZjoxs6hlF4efv+m5o8dIN83iViaGBouLrCNwv5GUPLFIZNDS8A1wtwh5pchkeBmKZONOoPjX4oFEgN1UBUxsMYhsbO7X1Yrs/n7lrLz/7yhAP+eznSmaZJS8uBz4IpwYIQQoyj2rhBV9LHNDQUOrpWeAFqeejMWDRXRNEofDvMez66VggsDE0jpGvFQKGpotDRMGl4DOZ9NA1e782Tsj3qY2Fy7v4PJ+xOucWagzd3igxUoXZDqULQkHV8Uo5Ld8ohmXWwLA/fL/Q90HQN5SuCbPqNIZGxSt572hQqI8Yb+SuF5SrCpk7YCPB8he0HuKaG4xeaUkKmTjik43rB22oNTEOjKhaivTbK5OoW7n6xgs3bBkbWbExg49kMkUqlRuyPRCJEIpG9nvP666/T2tpKNBqlo6OD5cuX097evt/XlGBBCCHGmaFr+AoMvdB+r2kaNVaYTckMIV0nETZRCuyhb+kRwyBk6ISMAF3TiId0TF0j5xaChLCpkXV8+rIefTmPo+oCrj73qP0qS1fSKQQHQ4GC5xf6Q3h+UOwkqWuQtj16LZudKYu+tIVledi2X2ymMAwD13YL8ycMqait4X1HVxM3DRSFpgw3UIT0AD8oLBTl+QrLK/Rh8AOFpxRKmYWfh8qlU2i+qYoYTKoKseiMN15inztr6oj7WXjrs9x35Zlj+wsqp3FohhiewLGtrW3E7q9//etcf/31b0t+1llncfvttzNjxgw6Ozu54YYbeN/73sfatWupqnr3DrlQ+DsalSeeeIIPf/jDtLa2omka99xzz4jjSimuu+46Jk2aRCwWY+7cubz++usj0vT393PJJZeQSCSoqanhiiuuIJPJjEizZs0a3ve+9xGNRmlra+Omm24abVGFEKIsGqtChAyNiKkTDRlURgxaElHipkFnLk9XzqLPshmwPLozDn15h56Mw2DeIxrSqAwb2H6A5QVkh5ohsnaApmkkogY7k84+r9+X8diTdulOuYW+Eb4iZ3tkLY+s7ZOzPfKOj+0GuF5A0nLpzObZnbbY2GeTtQs1CkqpwhBHXUM3Cn0xim86TaemoZq6aJi4aRI3DWKmQcTQqQiZVIQNEhGT6phJfdykvsKkqSpEc2WItpowM5pizGqOMWdSnJNbKzhzcoK/veDoEYHC3kzoQGGc7dixg2QyWdyWLVu213QLFizgE5/4BHPmzGH+/Pncf//9DA4Octddd+33tUZds5DNZjnppJO4/PLL+djHPva24zfddBM//OEP+eUvf8n06dP5h3/4B+bPn8/69euJRguzi11yySV0dnayYsUKXNfls5/9LF/4whe44447gELVyrx585g7dy633norL7/8Mpdffjk1NTV84QtfGG2RhRCi5JqqQuxJuwSqMBIgHjGY3VjN2j1JNg/msdyArFMYJjm1NkJlxKA+HkLTNAJVaBLIOgFpu/Bf2w2Ih3W6Ug6bOlPveN2etFucdyEIFJZb6B/hDtUouF4w9I2+sFS0rxSdWYvOtM22AYeugdzQHAiFL3+apmEYBr7+luGZZpiWlkoS4dDQvA+FmoKQXvgOOnwNKBxTb/pv3DSoCoUI6ToRU+eMo6oPxl/BIWk8myESiQSJRGLU59fU1HDcccexcePG/T5n1MHCggULWLBgwV6PKaX4/ve/z9e+9jU+8pGPAPDv//7vNDc3c8899/CpT32KV155hQceeIDnnnuO008/HYAf/ehHfPCDH+Sf//mfaW1t5Ve/+hWO4/CLX/yCcDjM7NmzWb16Nd/97nclWBBCTBiNVSG6kk7xG3o8YnDqpFpm1HnYbsDmVIZ13TnStk8iYhAoheX55J2AnFuoVcg6hc+moZGyPLb2pLHtd+6voGsaPqo4V8Nwx0I/KJQhUAo7KAQpCkXO89mVsulMOaRyhSYLXdcwjMLwRcPQCAIdTdcIPO+NORYiFRw3pYbKkImi0MThasFQkAEBhUDB2MuLMREJceq00b/kDgeHwqRMmUyGTZs2cemll+73OaNuhtiXLVu20NXVxdy5c4v7qqurOeuss1i5ciUAK1eupKamphgoAMydOxdd13nmmWeKac4991zC4Tdm7Zo/fz4bNmxgYGBgr9e2bZtUKjViE0KIchv+FqiKn6EyalJbGWZSPMbs5jg5N+DVPXl6si4DOZ+k5ZO2C1veKbyAPV/ROZAnl3OpTbzzGhAaxSZtdG345aQVXuBD3+yVAjcIcIOAlOOSdwK8gOJoDUPTigGDaeqEw2bhPpQqrNOg6VQ21nHBsbVEQjphUydkaMSGmiLiIYPKkEl1JERNLExtLExdPEx9RYTzZtQfsYECvFGzMNZtNP7mb/6Gxx9/nK1bt/LUU0/xF3/xFxiGwac//en9zmNcOzh2dXUB0Nw8cgKN5ubm4rGuri6amkYO9zFNk7q6uhFppk+f/rY8ho/V1r59ApLly5e/bdIJIYQot+ZEiF0D9tv26xrEQwaNsQizmmBNZ5at/TaJqFGoFfAVtluYh0EFit6URTJj43kBU+or9nqt3YPOm4YgjlzJsviuV29848/7hZqLAIWpF+Y7KJZP1wmFDDwvQKmgMM1zLlUYCRGtpH16E8fWVBI2dfxAYeoGbx6voGsQNnVmTtp7WUXp7Ny5k09/+tP09fXR2NjIe9/7Xp5++mkaGxv3O4/DZjTEsmXLWLp0afFzKpV6W09RIYQoB9PQ8VUAb3qdKgUhQydmmMRNj2l1EdZ25elOOURDBo5faEIIAkVPMk9vf54gULQ0VVBX8fZf3fes6Sz2F6gMhaiNhwibw7M+Do2ACAoTQLlBgEKR93z8AHQ0TL2wGbpGyNQJhXR8X8dxdBzHJz2YLoyEMMM0HD2d6ZMTJGKFawyPhBjuK6Fp2oipsMUbytEMceedd47tgoxzsDA84UN3dzeTJk0q7u/u7ubkk08upunp6Rlxnud59Pf3F89vaWmhu7t7RJrhz+80qcS+xpcKIUQ5mbqGp2v4gVbsOAiFyYeG51mImDotVSG2OB6DOafYvyCVc+npzaGUoqmxgpqKMMm8z9/84dVC/4RA0ZII0TA0L0PU0OnN22xLa0xLVBDWdWw/IFCq2BFRQ8P2ffwgwNALQzN1t9CxUh8KGArNEIU+C/17BlED3aACjNomjpvRxH9fflo5H+mENVFXnRzXPgvTp0+npaWFRx55pLgvlUrxzDPP0NHRAUBHRweDg4OsWrWqmObRRx8lCALOOuusYponnngC13WLaVasWMGMGTP22gQhhBCHsvpKk8k1YQztjf4EgVK8acZjdCBkaNTECqMLLNdnT9JiT18O3w9oaqzA0DXSeZfetEVfxqEv6zCYd9nQk6c77ZKxfTrTDntyHtsGbNb2pujOWfTkC1u/5ZB2PZzAL9Zx6Jo2tIGGVpxdcnjoZF9vluzO7YWOjUaIKUdNYnrz/o3NF4ePUdcsZDKZEcMttmzZwurVq6mrq6O9vZ2rr76af/zHf+TYY48tDp1sbW3lox/9KADHH388F110EZ///Oe59dZbcV2XJUuW8KlPfYrW1lYA/uqv/oobbriBK664gmuvvZa1a9fygx/8gO9973vjc9dCCFEG7fUjOyau3ZnB0DXCemFSpoihETY1KiIme5IW/f15PM8nFgsRMnRszydvF17mOdvDNHQ0Cs0c2w2dyohRGEVhudheQDxiMljvYXkBOhrRkE5DhUlFqLDUdcAbQx4DBYrCiInhkROZjEPP5u3FiZj02iaOP6aeYxpipX94h4mJWrMw6mDh+eef5/zzzy9+Hu4nsGjRIm6//Xa++tWvks1m+cIXvsDg4CDvfe97eeCBB4pzLAD86le/YsmSJVx44YXous7FF1/MD3/4w+Lx6upqHnroIRYvXsxpp51GQ0MD1113nQybFEIcVsKmjhcY1AyNTshFfCxPkXcDmqtj9A/kyWYdIpHCjIf60KiGvOWRf1M+mgaO5xcWgnJ9unqyDA7mCIdNNk5OoBRkMg6eF1BTE6XjuAZqYiamoWFqDE3cFAytaFmo/SjUKmTAyoCmQyTO0ce3cc6xdfzN+/dv9kjxdofC0MkDuqY6XCbcfotUKkV1dTXJZPKAJq0QQoiDbXufRc7xydo+g5bDgOXQlbVJDQ2dfGpDL+vW7KC+qYaWlioiYQPb8fE8n3zew/MCXNfH8wKqqiLk8y59PUkCP6AiUUFtXZw93SlymRyGUViYyvM8orEodY0Jjjuqjsl1cTxfkXc8UnmXVM4hl3MZGMjTtWMPTs9uiMRpmN7OJQtmcuPCGWV+agfHwX5nDOf/nm8/iBkd2wgRz8ry1N/NL+n77bAZDSGEEBNNe32UjT15TD2gKhzC8nzqYkMdFU2dU4+u57VXu8ik8gxETBKJyFCAEOA4hdUag0Bh5R2y6TyuU+jnNfukNk6cVseq13owQyaT2hqpqYli2z6plEXPrl627O6kp7ORusYaKivDaJqG6/pksw65TJ5MMoM32A+hCDPOmMX5p04+bAOFUjpimiGEEEKMn2OaYmzekyfIucRNE9sPqAoHZLWAabUR3v+eo3jsyU0kk3nCYQNN04qLO0FhRIXv+ST7koW1I+oSzJhSzXumVvHqrkFmHd9UWJwqYuL5Afn6ODU1MTa/ZpLd00e2uweiFZghkyAICPI5cC3QDcJ1DTRNbmD19ReW8QkdXiZqM4QEC0IIUWZHNcZYs8MjbOjETANfKQI8AuVz5rRqepKtvLRqG6ZpEI+HMQxtaFbGAMvyyCQzBEMBRCaZ4fXdKT57yhQ+f047q3Zl2JO2MYYWgvJ8RX0iQlN9nJ2dTXR3DpAeSOOlkxAKY1ZUUlHdTEtrLVMmVXHv/5WFm4QEC0IIcUgwdI2QoRM1DLxA4QUBjhGQdwNOnV7Hli0D9HX3k6+MU1EVwzR18nmXwd7BwtLRQ1zHZf3Lu/jjzAaipo6uQXMiMpSnwgsKC0xFTIOKqElbaxWprENfX466ujimqaNpkIiH33GmSHHgpBlCCCHEATOGZlAM6TohXcfUC2s0+EFhLoSOUyez4k8Zkn1J8tk84UgYK2fhWG9ZrlpBNpXl9e4sJ01JUBs3iRgatl9YXMoPFG6gyDs6IUOnMlpY6bIuESUWNsg7hYWi7vnc6XsppRgrjXFohhiXkoyOBAtCCHEIKM6aqGsYeiFAgMI8CI5fmDNh5uzJrFm1BStrYeWsN61OVfi2qeuF1SEjsQimrtOaCBMaCkDcoLA0tTfUFOEGiv6cR8b2Gcw6NFVHCZQiEQvzk0/MLt+DOMwNT4I11jxKTYIFIYQ4BBhvWptB17QR3x4DBa4X0FwbY/K0ZrZv3F1Y2EmDaDxKTUMN1dVRwmGDUEjnz185d0TeL+/M4HoBlutjD/Vt8JUiW+nRbzsM5DwaKkNURQyuPf/oEt61mCgkWBBCiEOAoRfWjdC1wsJOwwI1tA31OQiFDJRSaLpGVU0VM2e38t6ZjdTHTaIhnZD+9m+dJ06pBGBDV2GNiULnyEINQ0XaYkvCImzotFXL+joHm4yGEEIIccCGp8cLFHiqsDKk46viqpFeUFiF0jR1dF3HDJt0/+wTo7rG3laCPIFKdmfz9GRdUrY3Hrci9mGidnAc14WkhBBCHBh3aAEn1w+wvICcV5jF0fIKzQZKFdIM1yrEK8dvCejLTm9jTmMVkytlzQexdxIsCCHEISDv+OQdn6TtknZdso5P1vHJuQFKFaqePb8wc6NSil23/MW4Xn/erEYmVUbfPaEYE10bn63UpBlCCCHK7NXOLJYbkHI8Uq7LoOUxmPdJ2wE5x8f1Ck0Qvq/I5903RkGMs9OnVx+cjMUbtHFoRpBgQQghjiyv7M6StT2StkPScRi0XPqyHoN5j6ztkXc8bMcna3sEgSKftUj/16JyF1scYSRYEEKIMupJ27hBQL/l0JcvBAr9eY+09UagYA/1ZchmHfLZ/LtnKg5ZMhpCCCHEu/raA6+hFGQdH8sNqK8IcVxDFMdXpCyfnOvjeAG+H+C4hbkRcrbH9u1JBvYMMvAfl5T7FsQYaEN/xppHqUmwIIQQB9HPntnGrqTD9gELU9fpz9js7EkzOGihaRptkxNs7YsyrT5O2vbpSVr0JPN0dWUY7M/guR5KKfb84pPlvhVxBJNgQQghDoLvPLaJTb0WK1ZuAyCRiGJZLvF4mEQiQk0NbN3cS09nP7UN1eyeUk06bbOnJ0M2nSUUDlFVXUE8HmJyS1V5b0aMm/EYzSCjIYQQ4jBxdG0cQ9N4qamCM2Y00VgR4pWuDLv7suzalSI1kCGfzeN7Pl15m0yqMLtiZaKCk0+bytTGSkxdxzQ0bv7YrHLfjhgnE3VSJgkWhBDiIPiP53bRl7LYurmXmkSUaFsNq1/poa8nCUA4GiYSi6CUws7bNDRVM62tmhmTqoprRMRCOo2V8mv6cCIdHIUQQgBw/9oemmtiDGRsrJzF65v6OfvoOmpqokyZnKAyGsL1C3MneEFAKmVzTFsNU2pjVEUMAPxAURUx+L9nTyvvzQiBBAtCCDGuNvXkiZkGLVVhHtqexMpa9Hb2kXWOomNmE/bQWg95x8ceGvmQiIVJxEK014aL+eiaRk1UfkUfbmSJaiGEOMLt6LdJWx4Z12Nzb46enT0AhCIhoiGNeMgkaXmkbTD0gEjIIB4xCRk6TVUh6mIhoPAyMDSNT5zcWs7bEQeBNEMIIcQRrq0uwkDWIR4y6Evb+J5PvCrOhz5wPNNqIwzmfaKmjuMpVNjA0DWipk7Y1GiqDFEXiWDohXH0IV2W7hGHDgkWhBBiHEVDBjHDIDe03HNVbRUXHFuLoWvEwwrHV4TNAEM3iId0KiI6YUOnIR6mIR7GGBoXd8rURDlvQxwkMhpCCCEECggUhM1CzYDnegxaHpMqI4QNDdPQCBka8ZBOImqQiBpEDZ36aJjKaKFJ4ugmWSr6cCXNEEIIIbBdn7zvUV0RBg0Mw8DyAkxdw9R1QnpAPGQQC+nURA2qIyHipkltNMzMSRXlLr4QeyXBghBCjKNU3qPPclCqUF1shgwaKkLomoapF2oVDF2nJhqiNhKiOhwmYuqyPPQRQkZDCCHEEe6l7Wm68xY7UzaW6xeCBVOnOhwipOuEdJ2oqRE1TRqiEWqiYeJho9hkIQ5/2tA21jxKTYIFIYQYB6935+jJWmwbzLN9wCaZsdE0jVzWxgkCEnqIkK5RETKpDoepjYapipnS9CAmBAkWhBBiDJ7ZNIjrK7rzFq/sybK136I3ZbFjRxLfH6pd0DSihoEbBEQNk5pIiFjYkEDhCCSjIYQQ4gjy8Cu99Fo23RmHvpxLb8ajP2OTzrvs6c+Rz+YxTbMQLOiFrSJkEjF0oiGDSEiaHo5EE3XVyVH/a33iiSf48Ic/TGtrK5qmcc8994w4/pnPfKYYOQ1vF1100Yg0/f39XHLJJSQSCWpqarjiiivIZDIj0qxZs4b3ve99RKNR2trauOmmm0Z/d0IIcRD89qVOdmVydKVt+nIug3kfy/XJOx6eHxCJmBw7o4V4VZxcJkfSdgmZOpVhk1jYIBo2iISMct+GKIO3vh8PdCu1UQcL2WyWk046iZtvvvkd01x00UV0dnYWt1//+tcjjl9yySWsW7eOFStWcO+99/LEE0/whS98oXg8lUoxb948pk6dyqpVq/jOd77D9ddfz09/+tPRFlcIIcbVH17uJuN6DFo+lqcwtMKcCZVRs7DGQzxMS10cw9CwLRsra7G6M0fY1ImGjUKtgqnTXhcp960Isd9G3QyxYMECFixYsM80kUiElpaWvR575ZVXeOCBB3juuec4/fTTAfjRj37EBz/4Qf75n/+Z1tZWfvWrX+E4Dr/4xS8Ih8PMnj2b1atX893vfndEUPFmtm1j23bxcyqVGu2tCSHEPj31+gCW7+P4AY4foGkQMjR8pREoneqKMCHboyeZ5/XXenAsh9rGWhwvIGRoREIG0xui5b4NUWblmFRp2I033siyZcv40pe+xPe///39Pu+gNJo99thjNDU1MWPGDK666ir6+vqKx1auXElNTU0xUACYO3cuuq7zzDPPFNOce+65hMNvrMA2f/58NmzYwMDAwF6vuXz5cqqrq4tbW1vbwbg1IcQRLO/7BKowZTOAoWuEzcJ0zQB5x2NzV4rnn99Oqj9F67RJTD+6gU1daV7sHJBAQZS1GeK5557jJz/5CXPmzBn1ueMeLFx00UX8+7//O4888gj/9E//xOOPP86CBQvwfR+Arq4umpqaRpxjmiZ1dXV0dXUV0zQ3N49IM/x5OM1bLVu2jGQyWdx27Ngx3rcmhDiCrdmRRikIlCJQCk3TUEqRsjzW7U7z4HM7+cNDr7Bq5UYM06DjfTO44Kw2zjqukfbGCl7qzJb7FsQRLJPJcMkll/Bv//Zv1NbWjvr8cR8N8alPfar484knnsicOXM4+uijeeyxx7jwwgvH+3JFkUiESETaAIUQB4flBrhBgILC6AZNMWgF/O+rvax/eReZZAbd0Jlz+nTOnd3MtKE+CY6nsLwQRjnrnsUhYzxHQ7y1uX1f78HFixezcOFC5s6dyz/+4z+O+poHfejkUUcdRUNDAxs3buTCCy+kpaWFnp6eEWk8z6O/v7/Yz6GlpYXu7u4RaYY/v1NfCCGEOJjyro/t+/iBQtNg64DNvf+7lZ5de1CBoiJRwQfOP44Pz26kKmQSKFAolIKPzJHfW6JgPOdZeGtz+9e//nWuv/76t6W/8847eeGFF3juuecO+JoHPVjYuXMnfX19TJo0CYCOjg4GBwdZtWoVp512GgCPPvooQRBw1llnFdP8/d//Pa7rEgqFAFixYgUzZsw4oOoTIYQYi1VbU7hBgBcobD9gx6DDbx58lWwqy4mnTuOkoxqYXh/hlOZqKkOFX6umocl6D+Kg2rFjB4nEG0uZ761WYceOHXzpS19ixYoVRKMH3mdm1MFCJpNh48aNxc9btmxh9erV1NXVUVdXxw033MDFF19MS0sLmzZt4qtf/SrHHHMM8+fPB+D444/noosu4vOf/zy33norruuyZMkSPvWpT9Ha2grAX/3VX3HDDTdwxRVXcO2117J27Vp+8IMf8L3vfe+Ab1QIIQ6U5wcYQ98IezIuf3q5C8/xOP3so/nYqZNojIdpikVpqAwTCRn4gWJGS7zcxRaHoPFcGyKRSIwIFvZm1apV9PT0cOqppxb3+b7PE088wb/+679i2zaG8e5zfow6WHj++ec5//zzi5+XLl0KwKJFi7jllltYs2YNv/zlLxkcHKS1tZV58+bxzW9+c0TE86tf/YolS5Zw4YUXous6F198MT/84Q+Lx6urq3nooYdYvHgxp512Gg0NDVx33XXvOGxSCCEOJj9QbEpm2NhrsbE7w2uvdDLt6GYuOL6RKVXRwqJQFWFmtcr0zWLfSr3q5IUXXsjLL788Yt9nP/tZZs6cybXXXrtfgQIcQLBw3nnnoZR6x+MPPvjgu+ZRV1fHHXfcsc80c+bM4X//939HWzwhhBh3XTmLP29O0jmQZ/0r3WR6ekmc0k5LVYhEOERl1JRAQRySqqqqOOGEE0bsq6iooL6+/m3790UmJxdCiHfxQmcagEhIx8pZMNiJ6/q83mvh+AFz2qrKXEIxUWja+GylJgtJCSHEPvzi2W3oGkRCBmHTIFYRI63p6LrGnoxLZzZf7iKKCeRQWHXyscceG/U5EiwIIcRerNmRpi/rYOo6UVMnGtKJR0wS1TF6gCAorAvRl/PKXVQxgYxHzUA5ahakGUIIId5ie7+NoWtETYOIoVMRNoiaOoauEQQBxBKEQkYhTUjnofV7yl1kIQ4qqVkQQoi30Cis+2DoGlHDIB4q1C4AeF5AuKGZIFB4QUBl2KAqHCpvgcWEUerREONFggUhhHiLQClcX+H5AbqmETF1KiI6tfEQjuPjpDNYlouuaVx2uixaJ/afNEMIIcRhImTo6FqhdsEc2qKmTiJqEA4bYBjEYqGyfMMTohykZkEIId5ieOnpkKETNQzCuk7I0AgZGoaho4dC1FVGcPyg3EUVE8yhMBriQEiwIIQQe6FrGqahETF0QrqOMdTW7PsBhmkQj5j7nKBOiL3RGXuVfjmaBCRYEEKIt/AChT+0OUGApxS+UvTnPAZ6U4QjYeIR+fUpjhzyr10IId7Cdn1cP8APCktMG0Od0gKlSPcnaZjcREXYQBohxGhN1GYI6eAohBBvcVRjDEPXCBk68ZBBxDAIGzqVYQPsPNU1cSoiOtURg398eOO7ZyjEEE0DfYybTPcshBCHiFi4sBpfoBRRw6AyZGL7eXAtWidVURUxCBRUhOU7lzj8SbAghCiprb0WfqA4uilW7qLskzbUoVHXCp0co4bBzn4LdINJtXEMTSNQiiXnTC93UcUEMlw7MNY8Sk2CBSFESWzqyWN7AUoVOg4eynYPOviBIlAKRSFwiBg66zb3oVXV0lAZxlcKoxy/tcWENlH7LEiwIIQoiWTOxfUDNE3b72Dhzhd3sSNp8ZXzjj7IpRtJ08APFHnHJ+/4JB2XrpxFPu8yfcYUJlWHiYd0/t97ppW0XGLik5oFIYR4B+t2Zci7PinHJVCKd4oVtvVZTK2PAvDdxzcTNjUsV/GXt7/Ao4+/RrZ/kPzvrjzo5X21M02/7bAnZ7M75dCb8Vi/Y4Ctz75AYvox5J2A+rj8+hRHDvnXLoQ46PxA4fgBKccl5/l7HYa1rc9i854s923ooj/nYXkBpqaRcXxe3dyPnbc5+4I5TPq//0PnTy4ec5l2DzrYXkAQKCzXx3YDbC8g53lkXQ/b90nbPv05n67BPJ2daXDyBEGAocNnz2gfcxnEkWeirg0hwYIQ4qDzfIUbBDh+QDLv4b6lamHznjzb+3Os60vRl/XIuwG2X+jb0Jex2b65iynTWzjtqDqaa2JUfOI2Wqe1cO3HZ/G5s6aOujzdqUKTiFIK1w/w/DcmYfIDhRcoLM9nMO+TtQq1IQ0NcbbHEmiaxt9deMx4PRpxhJFVJ4UQYi9e7cwWXsiBwlMKy1MM5j3+72/WsX77AF+ZdwwN0QhbUlksT9FeG2Eg57G53ybveGztTGH39XLUe4+jNREmZGic/p7jePbxdfzg3hCb+izmHdXA+TPr97tM23pz1MRDaBo4XoDrFwIZy/eLW3/eJ2kV+iwopYhGQxCK4LneQXxaQhyaJFgQQozatj4Lz3/34Y/rdmUKnQQ9Hyfw8QOF7QWkbR/L9Umnba768Uo+dMFxtNVG6Mm4VIZ1amIG6bzL5s4U61ZvJ1LfwJlH1dJSFUbX4JSj6kinj+GVlWv4g1J0pxzW9qY4c1ItZx1ds9eybO21yFgeezI2Xbk8R6lKoiGjGCzkPZ+s65H1PAYtj5TlYbl+cZlqpRS4NuFI+CA8UXGkkLUhhBCHtV2DDkFQqLYfbt9/ZtPgO76cH9/QT2cujzlU7ZrzfPJugBsoMpbHpt1JAAZ7B/n3H90FlfWQS1I36wROP2UKIUNnzaotaLrGlxedzYXT6sl6HhrgKThzVjOZzEw2PbcGgL50DXuyLuv6krRVxUmEQ5hG4dfq8HBNP1D02w6aVpid0XJ9LC/ADQKyrkfa9cg4HoN5j6wd4Lg+uq4Rj5hs252C7ABd//Y3pXjc4jAlfRaEEIeFbX0W0ZCB5xcCAs8vtOGroXkFHC8gZ/tkPQ/bC/jPVTv569OmjMjjmU2DrO5Jct+absKmzvtn1BM1dbJOwEDOozdl0dOTJTWQIRQJYWcHId0HQP/Kbh7qOoXzPnACyTsuLeb5ameWiG2g8cZvSuPsdh7WYNPTLzDQfxyW4/NSuLAi5IzmStprw4UVI/XCWZqmkXE8jq9L4PoBGbdwD07gY/kBedcn4wTkhvpMaJpGRcQk7/hs29RN/s/fKsVfgRCHHAkWhBAjDGZdYuGhdnwvGKqmL3RQNHQNxw/IuC4pxyNpefTnPK7+3St8/yPHA/DwK70ESrFj0KarO8PUKdU8+kovhq6Rzrns2ZMllcxh5Syyu3eBa7/xdcsIgW5Qkajgj1edNaJcMydVAPDittSIb1Znn9RKsj9D/2uv8eSeQapqq7ByFvcHikRdgmnT65k9tZbJ1RHCpsYxdXFChk7W8ci5Prbv4wQBtl+o9RiugVBKEQnp+IHi1S395LZvKtnfgTh86YxDB0ekg6MQosyGAwQvUGRdj7zn46vCi9QdeqlmHZ+MHdCbdRnMe2TyLgtueYa+gTy6rjH35Em8uHWAfN5lxqQq/vuRjdh5GwDd0DFDJrGKGNnAh1gV+Uf/br/Ld8rUBKu3p4u/ML2WCowLZ9A50Eb3nix7etJ4rkc4EsbKWTz/5w08/2RA61GTmXlsA9ZRAVUhE3uoQ6PtB1heoTki6wTknUJwZHsBrhfw2o4BNjz1Ivk/fe2gPG9xZJFmCCHEYUHToCdr46lCpz/L88l7AbancAOF5RZGDqTtgGTOJWO5pPMugymLVMomOZDh3zb2EAQBuq6TcwJOOL6JVNZB1zUMo9As8NDisw+4jCe3V7FmR7r42dDh+JY47nH1pCyfsKmhozFoefRnHLZ0pXl9QxeP3vscT1RUctknz+CCo2vxggDH93F8heMVtqTts7k7zZr1PXRt6wIry4z3nDIej1aICUuCBSFE0ZZei7BZWJZ5e7owe2F/ziMe0rH9AMdT2L4q9GdwfTKWRzLnMJi0SCYtkgOZEUMLfd/n5a39LDxlEmnbJ2xoREydv71g7NM3z2mr4qXthYChKR7F9RW9VqH2otBJ0SeBQSwUpbEqwnFTqlm/tZHX1u/mP37zPOrjp3P21CqgMH1uyvJ5cPVu1jy/mcCyqJ3czOnnzOB/v/zeMZdViGEy3bMQYkJ5tTOL4wXMaSu8MLf0WtiuP9ReDxFDpyKsszMZ0Jsp1Ar4foA/NCLC9QJSeZeePVl696Sx83ZheOEQXdcxTINk0hqX4GBvTmqvKt5Lzvapj4VJOS67VZ6cE+AFOq7vEwAVEZPj2moxDJ1Vf36V39z3Ms5Fs5lSHcHyAh5atYtXXtjIGefO4sRpddz8sVkHpcziyKZpY59USZohhBAlM3NSBc9vSRY/D/dVSFouOzI5XtqdJWl5+H5A50CeQCniEROlVGFEhOXR1ZUm2Z/B896oTTAMg0gsQk1tnMbGCh75YkdJ7mXYi9tSWJ6PGwToGpi6hpt1ybkBIVPn2MnVhM+fzbNPvsavbnuYqtZWdF0nubuT0y84havOm8anT52yj6sJceCkz4IQoqRe785xbHN8THkECp56fYDGRIRgaJXF1wcyPLM9zZbuNLmcg237pFI2Vt6mojJKJGLiuj65rEM+W1grYZhpmtQ1JpjeXsOU+gp+8onZY73NUTtlagJ/S6GGww3yWJ6PUmAaGo3xEL0Zl507UzRNacLKJdANnYGeAaafJE0OQryTUQULy5cv57e//S2vvvoqsViM97znPfzTP/0TM2bMKKaxLIsvf/nL3Hnnndi2zfz58/nxj39Mc3NzMc327du56qqr+NOf/kRlZSWLFi1i+fLlmOYbxXnsscdYunQp69ato62tja997Wt85jOfGfsdCzHO1u3K4PmFb9tJ28XUNWKmQSxsYOgahq6N+OY7Hl7emcF2ff70at+opjl+qzOPqmbFK3uockNowNZUlpc6c/Sn7UKTg6/IZByy6RyhcIhkf4YgKCwzHQRBsdmh97ZPjdOdjY/Tp1fz/BZwgwDXt8i5OrGwTkPcZENnhlnHNTCtsQJT1ziqPkrY0A5ojQkhRuuI6LPw+OOPs3jxYs444ww8z+Pv/u7vmDdvHuvXr6eiovDL8JprruG+++7jN7/5DdXV1SxZsoSPfexj/PnPfwYKHZ4WLlxIS0sLTz31FJ2dnVx22WWEQiG+/e1vA7BlyxYWLlzIlVdeya9+9SseeeQRPve5zzFp0iTmz58/zo9AiAPz5GsD7MzmMIbqBJO2S2/WKy7B3FIVoiYSojIUGrdgYWuvRSrvsidr05u3yXk+338iydXnHnXAeVpeYVRDRcSgM22Tzrv4QWE1xlzOxbZcTpwzmUQsRG/KYteuFOnB7CEbKAw7fXo13kaF7QcoBYmIga5pVEZNNE3jmIYoS86ZXu5iiiOMNvRnrHmU2qiChQceeGDE59tvv52mpiZWrVrFueeeSzKZ5Oc//zl33HEHF1xwAQC33XYbxx9/PE8//TRnn302Dz30EOvXr+fhhx+mubmZk08+mW9+85tce+21XH/99YTDYW699VamT5/Ov/zLvwBw/PHH8+STT/K9731PggVxSHhha4rNqQxJy8PQNfpzHruTDtt7M6SyDpbl0d5SRUttnHhI56LZjWO+5qud2cLaBjmbPXmb7oxD1g5I2v5+55F1FD0pm+kN0Tf2eR470nlm1FVSFw+RtVx2dmXo788RBAHbfvjhMZe9XKpiJk1elOpwGF8F5DyfqliIZM6VQEGIURjTehTJZKFzVF1dHQCrVq3CdV3mzp1bTDNz5kza29tZuXIlACtXruTEE08c0Swxf/58UqkU69atK6Z5cx7DaYbz2BvbtkmlUiM2IcbTi9tSPL8lybObk3Rm8qTsQqe+lOWzbneaLT1ptu1MsXNniv7+PNs607y8tZ8XtvaP6bqrt6d56vUBulIW21I5tqdzdGcculIuO5M2PSmLT9z2wrvmk3UKQx5/+uw2Gi//r+L+T50ymae3JPnt+h6e3ZFh7Wu9pFIW8XiIbT+YuIECwOzJlZw/s55pdXHqoxHCuk4iavDLv5pT7qKJI9RwM8RYt1I74A6OQRBw9dVXc84553DCCScA0NXVRTgcpqamZkTa5uZmurq6imneHCgMHx8+tq80qVSKfD5PLPb2le6WL1/ODTfccKC3I8Q+Da+eOGA7hQWRPB9T18g4AVv6LLoG8nR2prGHAgjfV/T15ejvh1DIOKBrrt+dLVwz77Anb9GbcwEYzPvsyboMZBzSlkvO9vD84F1yK3h84x7+/Q/rRwxxBLBcnyee24Gu61RVRYjFTJ7+2/cfULkPRWFTxzQ0nCDgHy86rtzFEUewI6LPwpstXryYtWvX8uSTT45neQ7YsmXLWLp0afFzKpWira2tjCUSh4Md/TZ5x8dyA7JeYVXC3pxDxg6w3IA9WZc9QzMXDgcKw5QqzFdg2x7Tr7mPqqoIV3zgaNbszvDzT564z+u+sjtLzn6jyWF3yqE745K1PQIFWasQLGRyDvm8h+Psuyki6ygGsw73b+jDHpq4qOGzdxb7GzQmohiGTlNTBfF4+G3BxETnB4V+JJ84ubXcRRFiQjqgYGHJkiXce++9PPHEE0yZ8sZ45JaWFhzHYXBwcETtQnd3Ny0tLcU0zz777Ij8uru7i8eG/zu8781pEonEXmsVACKRCJFI5EBuR4i3eXlnBg1QgDe8oJJfmP446wQM5gvLGA9mHXqTeZJJ613zTKdtvvS+vbeT7xqwydo+7lBnPMcLGLRcBmyHbQM2nSmHgaxNKueSzjn4fkAm4xaGNlouju3Q8Nk7mXNKO7+5/Eyi4TdqMzKWx46+HF+8azUbN3Tt9fo3f2wWs57fSU0iSix8+I2odryA/rxT7mIIgaZpaGOelOkQ7+ColOKLX/wid999N4899hjTp4/8xXfaaacRCoV45JFHuPjiiwHYsGED27dvp6OjMDFLR0cH3/rWt+jp6aGpqQmAFStWkEgkmDVrVjHN/fffPyLvFStWFPMQ4mB6YN0eoDCDIVBcIyFpu/TlPHrSLgNDayLsSVp0d2fw36UZYMv3Fu51/59e7aOxMkKgFFnbRw2NpMj7HinHoyfj0Jcr1F70Z2zS6cKWSuYwDAPf83Fsp1gTsG7NLv7zxR1cfsbUoclfNB7Z2M3f3vYCuUxun2WsqYlSUxEmEQuXZX6EgymZc8elk6kQY3VENEMsXryYO+64g9/97ndUVVUV+xhUV1cTi8Worq7miiuuYOnSpdTV1ZFIJPjiF79IR0cHZ59dWDRm3rx5zJo1i0svvZSbbrqJrq4uvva1r7F48eJizcCVV17Jv/7rv/LVr36Vyy+/nEcffZS77rqL++67b5xvX4iRvvPYJlZtS5HOu4RMnfaGCo5rjKJrGmnbpyvt0pOy6E/bDCQt+vvzuO6+mwDeKVD4+C9WkYiHOb29isqwgeMHVIZNTE3DV4oBy6Ur7dKfKdQqJJMWmYxDJp3HczxClSFi8TDJfr84g6Lv+/zLXS/z+Gv9tDfEufLMdl7bk3/HQOHNTREt9RVMro0xpTo8hid46HlxW6q4ZoQQ4sBoahSNk+9U9XHbbbcVJ0wanpTp17/+9YhJmYabGAC2bdvGVVddxWOPPUZFRQWLFi3ixhtvfNukTNdccw3r169nypQp/MM//MOoJmVKpVJUV1eTTCZJJBL7fZ44cn3urrXs7M3i+gFhU8fxAnp6shw9tYa6ygiaBn1pm57+HIODFpbl7bVtX9c1YrEQa//xA3u9zl/e/gK7e7P4foBl+dTURIlHTOqrIhzdGKcmZmJ5haaO7pRD92Cenr4c6bRNLmsX12DQdZ2KRBxd10gPZvF9/23laWypJZux91mroGka5597LHd95tSxPcBD1H1ru1l4QvO7JxRHtIP9zhjO/1v3ryZaUTWmvKxsmr//4Mklfb+NKliYSCRYODJ0Jh0ylofjBcyeXLnf5z2/JYmmaXh+gOUFZFyX53al2D5gsSdlMZCycJzCNMeNjRUEQYDjBFiWRz7v7rXZQdc14vEwtbVRnlj6ztMG37e2mxe70mzak2NHX5b+/jyO42MYOvX1MWZOrsE0NLK2R1/apncwz8BAnkzGxspa+H6hJkPTNMyQSWNzNUGgSCXz5LP5UXVO1DSNcCRM86RqXrjugv0+b6J4cVuKaMjg+NbxnUFTHH5KFSws/+NL4xIsLFtwUknfb4dfTyZxRPEDhecX1jR46vUBAgV9ls1H5rTs87ywqTOYd/EDheX7PLx5gO6kRU8yT8jQ0XUNy/JwXZ/e3iy+r/CHOh8Ov4zf3Lzw6X9/kXjEfNdRDgALT2hm4QnN/PalTrYnK3m912J3f47O3izd3RnSaYdj22vIWi6DGYdUyiaTsbFzdjFQ0HWdSCxCfUMl9fVxKqMmfckou3YZZJKZ/Q4YwpEwTS3VtLcengH1KVMPz/sSE1c5+izccsst3HLLLWzduhWA2bNnc91117FgwYL9zkOCBTFhbezJk3d8MpZH1vUKIxU8D9cP+NGTW/jie995hr7KqIntBqzuGeT3a3roHcgRChlcdFILkxJherMug3mfpzf2sXt3itduumifZfn1ZaeMuvwfO2kSAL99qZPXaiKsiZjs7suyZ0+W17YNUFERZmAgTyplYefsYr8EwzCYMrWBU2Y0EjF1ptVF0DSNnYM21ZURXt9sMNiXGrHA03ANQigSIpcuzMxoGAYVVTHaW6s4rmVs33SEEIeuKVOmcOONN3LssceilOKXv/wlH/nIR3jxxReZPXv/OjNLsCAmpM178tiuT872GLAcei2bvOdjuYqBXOGl+tV7N5CxfX588ay3nf/TZ7ezqSfLa1sHqKgI0dZcVbY2+4+dNInfrekiamqsCRl4XkBvbw7fV3hegGu7+L6PpmnEK+PMmNHIOcfWc2xDDA3ecTnlqV/6AypQxOJhWlqqOKqlinVb+tmWyROJRmifVkeiMkJbQyUnSzW9EKUxDktUj3ZpiA9/eORMrN/61re45ZZbePrppyVYEIevVzuzBAosNyDtePTbDt0Zhx2DDo5XaCrQNNC1Qrv/x3+xivqqKJURg96Mw2DWJmN5DAzkMQyNU49tZEZj9N0vfBANN5v8x/M7qKsI8Upliq07BvG8gHC0MDohEovw1/OP4Rvz928Gwr1N1Tz77x9CN3SOm9nMtKZK6ivD1MRMJsX3Pn+JEGJ86WjoY1wIavj8ty5rsD/zDfm+z29+8xuy2eyopiOQYEFMKK915cjaPlnHw/Z9evM2u1I2m3stdvYVRjLUVIQJmTpBoEjnXQbTNgPZwoQ8yaRFPu/iugG+H1BfH+fESTH+79nTyntjQy49vY1Lgd+s3s266bVs2pPj9Z2DpNM2Z57Qst+BwjtRCppaavjACU2ETZ26mEFFSH4NCDERvXWW4q9//etcf/31e0378ssv09HRgWVZVFZWcvfddxfnNtof8ltCTBib9xT6KAxaDt05i/68S8YOWN+ZYUdvlnTaLo5wMA2ddMYmmbTxvIBIxCQSMQgCRX19vPCNPWxw2lH1HFdz6LXXf+LkVj7xps/nff/PXHBs7ZjzbZ9Sje36zGqsoDIUImYahAydM4+qHnPeQoh3p41DM8Tw+Tt27BgxGmJftQozZsxg9erVJJNJ/vu//5tFixbx+OOP73fAIMGCmDBSeY++nM3uTJ5X9+TZ0pujayBHMmljWYXaAl3XsO3CWgmaVhjOWFUVIZGI0JCIEjJ1ErEQt358Ys1QWFsZIfmWtScOxHkzG3hhe5KoYdJQESFs6syS/gpClMx4joZIJBL7PXQyHA5zzDHHAIXZlp977jl+8IMf8JOf/GS/zpdgQUwIq7en6Uzn6cpZ7Eo6bO3LsbsvSyplEwQK0zQwDB3D0FFKEY2aRKMmsViI6oowk+sKkx19a8HEXHHw7s+dPi75VEZ0GhNRAqWIhnRmTpJAQYgjURAE2Pb+z2wqwYI4ZL2yO8tA1sENFFnXY9NgtrD6YsohlXMJAkUiEcEwCv0TDKMQbhuahhcU5hmojJq01MQ4rjH2jos4HUkmVRY6cvpKSaAgRBnomoY+xnaI0Z6/bNkyFixYQHt7O+l0mjvuuIPHHnuMBx98cL/zkGBBHJIKHRk9ei2bDX1Z+rIeKctnIGszmHUYTFmEQgY1lRFCho5paMTCJkopNE3D9nyCoPBzU1VIAoUhF580iRWv7CFmyP/6QpTDePZZ2F89PT1cdtlldHZ2Ul1dzZw5c3jwwQf5wAf2PiX93shvDHHIeb27ECj05x06sxbbBhx29GZIZh0syyOTcfC8gGOPqiv06K+MUBs3qQgb6BoEqjCz40Dew3ID2mtk6fI3a03ERjU1thBiYvv5z38+5jwkWBCHlB39hTkQdqfzdGYtNvXa9CTz2G5h/gTT1AmHjULHxViIqmiI9toIbdUR4iGzOM2xEwS83punosbguNpDb7RDOUmgIET56IxDM8QY52k4EBIsiEPGtj4LpQrrNuzM5Hm5M08y6+B6AYFSuG5hYSfPC6isDHNUY5xptREaYxEaYhHChl6snuvNObTV+Fx+5tTy3pQQQrxJOZohxoMEC+KQsK3PYqhPIvGISWtFjHVaHi8ISOVdUikbyyoMHZxxdB2zJif44NGNREPGUH8Fg2Ob48X8nt+SpFImGxJCHGL0oW2seZSa/DYVZbf9TYHCsKk1ceKhQfKOj6lrmKZGdXWE049t4IPHNjBvVuM+8zx9ukwyJIQQ40WCBVE2w80OexOPmExKhMm5FVSEdaoiBn934TGlLaAQQowzTdPQxtiOMNbzD4QEC6IstvZavEOcABRmKDupKUFzZZiGaIS5xzeUrGxCCHGwaIx60ci95lFqEiyIktreZ+G/JUoY/of/5t26pnHejPpSFUsIIcQ+SLAgSmJP2kXTNAxdw39TtKBrEA0ZBEoxqTpcxhIKIcTBV44ZHMeDBAuiJBqrQvRmvEJ73VAdgq5Be320zCUTQojSKkczwlhJsCBKpqGy8M9t54DNlFqZVVEIISYKCRZEyUmgIIQ4UsmkTEIIIYTYp4k6dLIcE0EJIYQQYgKRmgUhhBCiRGS6ZyGEEELs00RthpBgQQghhCiRiTqDo/RZEEIIIcQ+Sc2CEEIIUSLSDCGEEEKIfZqoHRylGUIIIYQQ+zSqYGH58uWcccYZVFVV0dTUxEc/+lE2bNgwIs15551XrGYZ3q688soRabZv387ChQuJx+M0NTXxla98Bc/zRqR57LHHOPXUU4lEIhxzzDHcfvvtB3aHQgghxCHire/HA91KbVTBwuOPP87ixYt5+umnWbFiBa7rMm/ePLLZ7Ih0n//85+ns7CxuN910U/GY7/ssXLgQx3F46qmn+OUvf8ntt9/OddddV0yzZcsWFi5cyPnnn8/q1au5+uqr+dznPseDDz44xtsVQgghykcbp63URtVn4YEHHhjx+fbbb6epqYlVq1Zx7rnnFvfH43FaWlr2msdDDz3E+vXrefjhh2lububkk0/mm9/8Jtdeey3XX3894XCYW2+9lenTp/Mv//IvABx//PE8+eSTfO9732P+/PmjvUchhBBCjMGY+iwkk0kA6urqRuz/1a9+RUNDAyeccALLli0jl8sVj61cuZITTzyR5ubm4r758+eTSqVYt25dMc3cuXNH5Dl//nxWrlz5jmWxbZtUKjViE0IIIQ4lwwtJjXUrtQMeDREEAVdffTXnnHMOJ5xwQnH/X/3VXzF16lRaW1tZs2YN1157LRs2bOC3v/0tAF1dXSMCBaD4uaura59pUqkU+XyeWCz2tvIsX76cG2644UBvRwghhDjodDT0MTYkjPX8A3HAwcLixYtZu3YtTz755Ij9X/jCF4o/n3jiiUyaNIkLL7yQTZs2cfTRRx94Sd/FsmXLWLp0afFzKpWira3toF1PCCGEOFIcUDPEkiVLuPfee/nTn/7ElClT9pn2rLPOAmDjxo0AtLS00N3dPSLN8Ofhfg7vlCaRSOy1VgEgEomQSCRGbEIIIcShZKI2Q4wqWFBKsWTJEu6++24effRRpk+f/q7nrF69GoBJkyYB0NHRwcsvv0xPT08xzYoVK0gkEsyaNauY5pFHHhmRz4oVK+jo6BhNcYUQQohDijZOf0ptVMHC4sWL+c///E/uuOMOqqqq6Orqoquri3w+D8CmTZv45je/yapVq9i6dSu///3vueyyyzj33HOZM2cOAPPmzWPWrFlceumlvPTSSzz44IN87WtfY/HixUQiEQCuvPJKNm/ezFe/+lVeffVVfvzjH3PXXXdxzTXXjPPtCyGEEKVzRNQs3HLLLSSTSc477zwmTZpU3P7rv/4LgHA4zMMPP8y8efOYOXMmX/7yl7n44ov5wx/+UMzDMAzuvfdeDMOgo6ODv/7rv+ayyy7jG9/4RjHN9OnTue+++1ixYgUnnXQS//Iv/8LPfvYzGTYphBBClMGoOjgqpfZ5vK2tjccff/xd85k6dSr333//PtOcd955vPjii6MpnhBCCHFI08ZhNEQ5miFkISkhhBCiRMajGeGQb4YQQgghxJFHahaEEEKIEpmoNQsSLAghhBAlMh5DHw/5oZNCCCGEOPJIzYIQQghRIrpW2MaaR6lJsCCEEEKUiDRDCCGEEGKfyjGD4/LlyznjjDOoqqqiqamJj370o2zYsGFUeUiwIIQQQhzGHn/8cRYvXszTTz/NihUrcF2XefPmkc1m9zsPaYYQQgghSkRj7M0Ioz37gQceGPH59ttvp6mpiVWrVnHuuefuVx4SLAghhBAlMp4dHFOp1Ij9kUikuCDjviSTSQDq6ur2/5r7XzwhhBBCHCra2tqorq4ubsuXL3/Xc4Ig4Oqrr+acc87hhBNO2O9rSc2CEEIIUSLjORpix44dJBKJ4v79qVVYvHgxa9eu5cknnxzVNSVYEEIIIUpkPKd7TiQSI4KFd7NkyRLuvfdennjiCaZMmTKqa0qwIIQQQhzGlFJ88Ytf5O677+axxx5j+vTpo85DggUhhBCiRDRGP5phb3mMxuLFi7njjjv43e9+R1VVFV1dXQBUV1cTi8X2Kw8JFoQQQogS0dHQx9gOoY8yXLjlllsAOO+880bsv+222/jMZz6zX3lIsCCEEEIcxpRSY85DggUhhBCiRMrRDDEeJFgQQgghSmWCRgsSLAghhBAlIqtOCiGEEOKwJDULQgghRKmMw6RM0gwhhBBCHMYmaJcFaYYQQgghxL5JzYIQQghRKhO0akGCBSGEEKJEZDSEEEIIIQ5LUrMghBBClMh4LlFdShIsCCGEECUyQbssSDOEEEIIIfZtVMHCLbfcwpw5c0gkEiQSCTo6OvjjH/9YPG5ZFosXL6a+vp7Kykouvvhiuru7R+Sxfft2Fi5cSDwep6mpia985St4njcizWOPPcapp55KJBLhmGOO4fbbbz/wOxRCCCEOFdo4bSU2qmBhypQp3HjjjaxatYrnn3+eCy64gI985COsW7cOgGuuuYY//OEP/OY3v+Hxxx9n9+7dfOxjHyue7/s+CxcuxHEcnnrqKX75y19y++23c9111xXTbNmyhYULF3L++eezevVqrr76aj73uc/x4IMPjtMtCyGEEOWhjdOfkpdbjXGh67q6Or7zne/w8Y9/nMbGRu644w4+/vGPA/Dqq69y/PHHs3LlSs4++2z++Mc/8qEPfYjdu3fT3NwMwK233sq1117Lnj17CIfDXHvttdx3332sXbu2eI1PfepTDA4O8sADD+x3uVKpFNXV1SSTSRKJxFhuUQghxGHuYL8zhvP/37U7qawaW/6ZdIr3nTClpO+3A+6z4Ps+d955J9lslo6ODlatWoXrusydO7eYZubMmbS3t7Ny5UoAVq5cyYknnlgMFADmz59PKpUq1k6sXLlyRB7DaYbzeCe2bZNKpUZsQgghhBi7UQcLL7/8MpWVlUQiEa688kruvvtuZs2aRVdXF+FwmJqamhHpm5ub6erqAqCrq2tEoDB8fPjYvtKkUiny+fw7lmv58uVUV1cXt7a2ttHemhBCCHFQTdAuC6MPFmbMmMHq1at55plnuOqqq1i0aBHr168/GGUblWXLlpFMJovbjh07yl0kIYQQYqQJGi2Mep6FcDjMMcccA8Bpp53Gc889xw9+8AM++clP4jgOg4ODI2oXuru7aWlpAaClpYVnn312RH7DoyXenOatIyi6u7tJJBLEYrF3LFckEiESiYz2doQQQgjxLsY8z0IQBNi2zWmnnUYoFOKRRx4pHtuwYQPbt2+no6MDgI6ODl5++WV6enqKaVasWEEikWDWrFnFNG/OYzjNcB5CCCHERDVRR0OMqmZh2bJlLFiwgPb2dtLpNHfccQePPfYYDz74INXV1VxxxRUsXbqUuro6EokEX/ziF+no6ODss88GYN68ecyaNYtLL72Um266ia6uLr72ta+xePHiYq3AlVdeyb/+67/y1a9+lcsvv5xHH32Uu+66i/vuu2/8714IIYQooSNiuueenh4uu+wyOjs7qa6uZs6cOTz44IN84AMfAOB73/seuq5z8cUXY9s28+fP58c//nHxfMMwuPfee7nqqqvo6OigoqKCRYsW8Y1vfKOYZvr06dx3331cc801/OAHP2DKlCn87Gc/Y/78+eN0y0IIIYQYjTHPs3CoknkWhBBC7K9SzbOwcv2ucZlnoWPW5JK+32QhKSGEEKJUJuhKUrKQlBBCCCH2SWoWhBBCiBIZj9EMh/xoCCGEEEIcuCNiNIQQQgghDtwE7bIgfRaEEEIIsW9SsyCEEEKUygStWpBgQQghhCiRidrBUZohhBBCCLFPUrMghBBClIiMhhBCCCHEPk3QLgvSDCGEEEKIfZOaBSGEEKJUJmjVggQLQgghRInIaAghhBBCHJYkWBBCCCFKRXtjRMSBbqOtWHjiiSf48Ic/TGtrK5qmcc8994y62BIsCCGEECWijdM2GtlslpNOOombb775gMstfRaEEEKIUilDB8cFCxawYMGCMV1SggUhhBBiAkqlUiM+RyIRIpHIQbmWNEMIIYQQJaKN0x+AtrY2qquri9vy5csPWrmlZkEIIYQokfGc7nnHjh0kEoni/oNVqwASLAghhBATUiKRGBEsHEwSLAghhBAlMkEncDx8gwWlFPD2DiBCCCHEWw2/K4bfHQdNGaKFTCbDxo0bi5+3bNnC6tWrqauro729fb/yOGyDhb6+PqDQAUQIIYTYH+l0murq6nIXY1w9//zznH/++cXPS5cuBWDRokXcfvvt+5XHYRss1NXVAbB9+/bD7i++1FKpFG1tbW/rTCMOjDzP8SPPcnwdyc9TKUU6naa1tfWgXqcca0Ocd955Y64xOWyDBV0vjAqtrq4+4v7RHyyl7ExzJJDnOX7kWY6vI/V5luKLpcY4jIYYl5KMjsyzIIQQQoh9OmxrFoQQQohDjYyGOMREIhG+/vWvH9RJKo4U8izHlzzP8SPPcnzJ8zz4xnNSplLS1EEfJyKEEEIc2VKpFNXV1azfuoeqMfYHSadSzJrWSDKZLFnfEumzIIQQQoh9OmybIYQQQohDzURthpBgQQghhCiRidrBUZohhBBCCLFPUrMghBBClMhEbYY4LGsWbr75ZqZNm0Y0GuWss87i2WefLXeRyu6JJ57gwx/+MK2trWiaxj333DPiuFKK6667jkmTJhGLxZg7dy6vv/76iDT9/f1ccsklJBIJampquOKKK8hkMiPSrFmzhve9731Eo1Ha2tq46aabDvatldzy5cs544wzqKqqoqmpiY9+9KNs2LBhRBrLsli8eDH19fVUVlZy8cUX093dPSLN9u3bWbhwIfF4nKamJr7yla/ged6INI899hinnnoqkUiEY445Zr/ncZ9IbrnlFubMmVOcNbCjo4M//vGPxePyLA/cjTfeiKZpXH311cV98jzLSxunPyWnDjN33nmnCofD6he/+IVat26d+vznP69qampUd3d3uYtWVvfff7/6+7//e/Xb3/5WAeruu+8ecfzGG29U1dXV6p577lEvvfSS+j//5/+o6dOnq3w+X0xz0UUXqZNOOkk9/fTT6n//93/VMcccoz796U8XjyeTSdXc3KwuueQStXbtWvXrX/9axWIx9ZOf/KRUt1kS8+fPV7fddptau3atWr16tfrgBz+o2tvbVSaTKaa58sorVVtbm3rkkUfU888/r84++2z1nve8p3jc8zx1wgknqLlz56oXX3xR3X///aqhoUEtW7asmGbz5s0qHo+rpUuXqvXr16sf/ehHyjAM9cADD5T0fg+23//+9+q+++5Tr732mtqwYYP6u7/7OxUKhdTatWuVUvIsD9Szzz6rpk2bpubMmaO+9KUvFffL8yyPZDKpAPXa9l7VOeiMaXtte68CVDKZLFn5D7tg4cwzz1SLFy8ufvZ9X7W2tqrly5eXsVSHlrcGC0EQqJaWFvWd73ynuG9wcFBFIhH161//Wiml1Pr16xWgnnvuuWKaP/7xj0rTNLVr1y6llFI//vGPVW1trbJtu5jm2muvVTNmzDjId1RePT09ClCPP/64Uqrw7EKhkPrNb35TTPPKK68oQK1cuVIpVQjedF1XXV1dxTS33HKLSiQSxef31a9+Vc2ePXvEtT75yU+q+fPnH+xbKrva2lr1s5/9TJ7lAUqn0+rYY49VK1asUO9///uLwYI8z/IpBgs7elVn0hnT9tqO0gcLh1UzhOM4rFq1irlz5xb36brO3LlzWblyZRlLdmjbsmULXV1dI55bdXU1Z511VvG5rVy5kpqaGk4//fRimrlz56LrOs8880wxzbnnnks4HC6mmT9/Phs2bGBgYKBEd1N6yWQSeGOl01WrVuG67ojnOXPmTNrb20c8zxNPPJHm5uZimvnz55NKpVi3bl0xzZvzGE5zOP9b9n2fO++8k2w2S0dHhzzLA7R48WIWLlz4tnuW51l+2jhtpXZYdXDs7e3F9/0R/8gBmpubefXVV8tUqkNfV1cXwF6f2/Cxrq4umpqaRhw3TZO6uroRaaZPn/62PIaP1dbWHpTyl1MQBFx99dWcc845nHDCCUDhXsPhMDU1NSPSvvV57u15Dx/bV5pUKkU+nycWix2MWyqLl19+mY6ODizLorKykrvvvptZs2axevVqeZajdOedd/LCCy/w3HPPve2Y/NsUB+qwChaEKLXFixezdu1annzyyXIXZUKbMWMGq1evJplM8t///d8sWrSIxx9/vNzFmnB27NjBl770JVasWEE0Gi13ccReyGiIQ0BDQwOGYbytZ293dzctLS1lKtWhb/jZ7Ou5tbS00NPTM+K453n09/ePSLO3PN58jcPJkiVLuPfee/nTn/7ElClTivtbWlpwHIfBwcER6d/6PN/tWb1TmkQicdh9cwuHwxxzzDGcdtppLF++nJNOOokf/OAH8ixHadWqVfT09HDqqadimiamafL444/zwx/+ENM0aW5uludZZhN1NMRhFSyEw2FOO+00HnnkkeK+IAh45JFH6OjoKGPJDm3Tp0+npaVlxHNLpVI888wzxefW0dHB4OAgq1atKqZ59NFHCYKAs846q5jmiSeewHXdYpoVK1YwY8aMw6oJQinFkiVLuPvuu3n00Uff1vRy2mmnEQqFRjzPDRs2sH379hHP8+WXXx4RgK1YsYJEIsGsWbOKad6cx3CaI+HfchAE2LYtz3KULrzwQl5++WVWr15d3E4//XQuueSS4s/yPMtsonZaKFlXyhK58847VSQSUbfffrtav369+sIXvqBqampG9Ow9EqXTafXiiy+qF198UQHqu9/9rnrxxRfVtm3blFKFoZM1NTXqd7/7nVqzZo36yEc+stehk6eccop65pln1JNPPqmOPfbYEUMnBwcHVXNzs7r00kvV2rVr1Z133qni8fhhN3TyqquuUtXV1eqxxx5TnZ2dxS2XyxXTXHnllaq9vV09+uij6vnnn1cdHR2qo6OjeHx4eNq8efPU6tWr1QMPPKAaGxv3OjztK1/5inrllVfUzTfffFgOT/vbv/1b9fjjj6stW7aoNWvWqL/9279Vmqaphx56SCklz3Ks3jwaQil5nuUyPBpi064+1ZN2x7Rt2tUnQyfHw49+9CPV3t6uwuGwOvPMM9XTTz9d7iKV3Z/+9CcFvG1btGiRUqowfPIf/uEfVHNzs4pEIurCCy9UGzZsGJFHX1+f+vSnP60qKytVIpFQn/3sZ1U6nR6R5qWXXlLvfe97VSQSUZMnT1Y33nhjqW6xZPb2HAF12223FdPk83n1//7f/1O1tbUqHo+rv/iLv1CdnZ0j8tm6datasGCBisViqqGhQX35y19WruuOSPOnP/1JnXzyySocDqujjjpqxDUOF5dffrmaOnWqCofDqrGxUV144YXFQEEpeZZj9dZgQZ5neQwHC5t39ak9aXdM2+YyBAuaUkqVvj5DCCGEOHKkUimqq6vZsruPqkRiTHmlUymmt9aTTCZJjDGv/XVY9VkQQgghxPiToZNCCCFEyYzHaIbS93CUYEEIIYQoEZlnQQghhBCHJQkWhBBCCLFP0gwhhBBClIg0QwghhBDisCQ1C0IIIUSJjMfaDuVYG0KCBSGEEKJEJmozhAQLQgghRImMxzpQ5VhHSvosCCGEEGKfpGZBCCGEKJUJWrUgwYIQQghRIhO1g6M0QwghhBBin6RmQQghhCgRGQ0hhBBCiH2aoF0WpBlCCCGEEPsmNQtCCCFEqUzQqgUJFoQQQogSkdEQQgghhDgsSc2CEEIIUSLpdGrMoxnS6dT4FGYUJFgQQgghDrJwOExLSwvHTm8bl/xaWloIh8Pjktf+0JRSqmRXE0IIIY5QlmXhOM645BUOh4lGo+OS1/6QYEEIIYQQ+yQdHIUQQgixTxIsCCGEEGKfJFgQQgghxD5JsCCEEEKIfZJgQQghhBD7JMGCEEIIIfZJggUhhBBC7NP/D+dkQs5i4jMSAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import rasterio as rio\n", + "\n", + "with rio.open(pgf.fim_path) as ds:\n", + " fim = ds.read(1)\n", + " fim[fim == ds.nodata] = np.nan\n", + "\n", + "plt.imshow(fim, cmap=\"Blues\")\n", + "plt.colorbar()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Paths written to data/paths.txt\n" + ] + } + ], + "source": [ + "# save output data file paths we can load our PyGeoFlood instance later with\n", + "# pgf = PyGeoFlood.from_paths(\"data/paths.txt\")\n", + "pgf.to_paths(\"data/paths.txt\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Temporary workaround to obtain Dinf HAND (optional)\n", + "- Dinf HAND creates more realistic FIM than D8 HAND\n", + "- The previous workflow uses D8 HAND as input to the FIM step\n", + "- Dinf HAND is not yet supported in pygeoflood (coming soon)\n", + "- This is a workaround to use TauDEM to obtain Dinf HAND\n", + "\n", + "**Note**: TauDEM must be installed on your system for the following steps to work." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "vscode": { + "languageId": "shellscript" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PitRemove version 5.3.9\n", + "Input file data/OC1mTest.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -340282346638528859811704183484516925440.000000\n", + "Nodata value recast to float used in partition raster: -340282346638528859811704183484516925440.000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This run may take on the order of 1 minutes to complete.\n", + "This estimate is very approximate. \n", + "Run time is highly uncertain as it depends on the complexity of the input data \n", + "and speed and memory of the computer. This estimate is based on our testing on \n", + "a dual quad core Dell Xeon E5405 2.0GHz PC with 16GB RAM.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Processes: 8\n", + "Header read time: 0.144063\n", + "Data read time: 0.022310\n", + "Compute time: 1.109974\n", + "Write time: 0.450810\n", + "Total time: 1.727157\n", + "DinfFlowDir version 5.3.9\n", + "Input file data/OC1mTest_fel.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -300000000549775575777803994281145270272.000000\n", + "Nodata value recast to float used in partition raster: -300000000549775575777803994281145270272.000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This run may take on the order of 3 minutes to complete.\n", + "This estimate is very approximate. \n", + "Run time is highly uncertain as it depends on the complexity of the input data \n", + "and speed and memory of the computer. This estimate is based on our testing on \n", + "a dual quad core Dell Xeon E5405 2.0GHz PC with 16GB RAM.\n", + "All slopes evaluated. 539517 flats to resolve.\n", + "Draining flats towards lower adjacent terrain\n", + "..................................................................................................................................................................................................................................................................................................................................................................................................................\n", + "Draining flats away from higher adjacent terrain\n", + ".....................................................\n", + "Setting directions\n", + "Iteration complete. Number of flats remaining: 13592\n", + "Draining flats towards lower adjacent terrain\n", + "...................................\n", + "Draining flats away from higher adjacent terrain\n", + ".........\n", + "Setting directions\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Processors: 8\n", + "Header read time: 0.019067\n", + "Data read time: 0.047244\n", + "Compute Slope time: 1.134700\n", + "Write Slope time: 0.411829\n", + "Resolve Flat time: 9.764547\n", + "Write Flat time: 0.463723\n", + "Total time: 11.841111\n", + "DinfDistDown -v version 5.3.9\n", + "Input file data/OC1mTest_ang.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -340282346638528859811704183484516925440.000000\n", + "Nodata value recast to float used in partition raster: -340282346638528859811704183484516925440.000000\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This run may take on the order of 1 minutes to complete.\n", + "This estimate is very approximate. \n", + "Run time is highly uncertain as it depends on the complexity of the input data \n", + "and speed and memory of the computer. This estimate is based on our testing on \n", + "a dual quad core Dell Xeon E5405 2.0GHz PC with 16GB RAM.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Input file data/OC1mTest_fel.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -300000000549775575777803994281145270272.000000\n", + "Nodata value recast to float used in partition raster: -300000000549775575777803994281145270272.000000\n", + "Input file data/OC1mTest_channel_network.tif has projected coordinate system.\n", + "Nodata value input to create partition from file: -32768.000000\n", + "Nodata value recast to int16_t used in partition raster: -32768\n", + "Processors: 8\n", + "Read time: 0.106575\n", + "Compute time: 4.125068\n", + "Write time: 0.363995\n", + "Total time: 4.595638\n" + ] + } + ], + "source": [ + "%%bash\n", + "\n", + "# bash script to generate Dinf HAND with TauDEM\n", + "\n", + "# Notes before running this cell:\n", + "# - Open taudem_hand.sh and update the first two blocks as necessary\n", + "# - Ensure the TauDEM executables pitremove, dinfflowdir, and dinfdistdown are on your path\n", + "\n", + "bash taudem_hand.sh" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running inundate with parameters:\n", + " custom_hand = data/OC1mTest_HAND_taudem.tif\n", + " custom_flood_stage = None\n", + " custom_segment_catchments_raster = None\n", + " custom_path = data/OC1mTest_HAND_taudem_fim\n", + "Flood inundation raster written to data/OC1mTest_HAND_taudem_fim.tif\n", + "inundate completed in 1.3339 seconds\n", + "\n" + ] + } + ], + "source": [ + "# create FIM with Dinf HAND written in previous step\n", + "pgf.inundate(\n", + " custom_hand=\"data/OC1mTest_HAND_taudem.tif\",\n", + " custom_path=\"data/OC1mTest_HAND_taudem_fim\", # output FIM path\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot flood inundation map (Dinf HAND based)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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oSnHGBgYYMOGDaRSKbq6uvjkJz9JEART9rn//vt505vehOM4LF26lFtvvfXw36EQQghxrNCmaZthhxQszJ8/ny9+8Yts3ryZxx57jLe//e387u/+Lk899RQAn/jEJ/iP//gPvve97/HAAw+we/du3vve9zafH4YhGzZswPM8fvnLX/LNb36TW2+9lc985jPNfbZv386GDRu48MILefzxx7nmmmv44z/+Y+6+++5pestCCCGEOBSaOsK1K9va2vjrv/5rfv/3f5/Ozk5uu+02fv/3fx+AZ599lpUrV7Jp0ybOPfdcfvzjH/Pbv/3b7N69m+7ubgBuvvlmrrvuOvbu3Ytt21x33XXceeedbNmypfka73//+5mYmOCuu+466PMqFovk83mGRgvkcrkjeYtCCCGOc8Vike72PIXC0blmTF6THnxyJ5nskR2/XCpy/mnzj9q57s9hJziGYch3vvMdKpUKa9euZfPmzfi+z7p165r7rFixggULFrBp0yYANm3axGmnndYMFADWr19PsVhsjk5s2rRpyjEm95k8xutxXZdisThlE0IIIY4lk9UQR7rNtEMOFp588kkymQyO43DllVfygx/8gFWrVjE4OIht27S0tEzZv7u7m8HBQQAGBwenBAqTj08+dqB9isUitVrtdc/rxhtvJJ/PN7f+/v5DfWtCCCHEUTVHUxYOPVhYvnw5jz/+OA8//DBXXXUVl19+OU8//fTROLdDcv3111MoFJrbjh07ZvuUhBBCiOPCIZdO2rbN0qVLATjrrLN49NFH+cpXvsL73vc+PM9jYmJiyujC0NAQPT09APT09PDII49MOd5ktcQr93l1BcXQ0BC5XI5kMvm65+U4Do7jHOrbEUIIIWbOHK2dPOKmTFEU4bouZ511FpZlcd999zUf27p1KwMDA6xduxaAtWvX8uSTTzI8PNzc55577iGXy7Fq1armPq88xuQ+k8cQQggh5iptmn7NtEMaWbj++uu5+OKLWbBgAaVSidtuu43777+fu+++m3w+zxVXXMG1115LW1sbuVyOP/mTP2Ht2rWce+65AFx00UWsWrWKD37wg3zpS19icHCQT3/602zcuLE5KnDllVfyv/7X/+JTn/oUH/3oR/npT3/Kd7/7Xe68887pf/dCCCGEeEOHFCwMDw/zoQ99iD179pDP51m9ejV3330373znOwH48pe/jK7rXHrppbiuy/r16/na177WfL5hGNxxxx1cddVVrF27lnQ6zeWXX87nP//55j6LFy/mzjvv5BOf+ARf+cpXmD9/Pv/yL//C+vXrp+ktCyGEELNjrq4NccR9Fo5V0mdBCCHEwZqpPgubnt41LX0W1q6aNzf6LAghhBDixCALSQkhhBAzZY5WQ0iwIIQQQsyQ6ahmmI1qCJmGEEIIIcQByciCEEIIMUPmajWEBAtCCCHEDJmjKQsSLAghhBAzZo5GC5KzIIQQQogDkpEFIYQQYobM1WoICRaEEEKIGTJXExxlGkIIIYQQByQjC0IIIcQMmaP5jRIsCCGEEDNmjkYLMg0hhBBCiAOSkQUhhBBihszVaggZWRBCCCFmiravIuJwt0ONFR588EHe85730NfXh6Zp3H777Yd82hIsCCGEEMexSqXC6aefzle/+tXDPoZMQwghhBAzZDbyGy+++GIuvvjiI3pNCRaEEEKImTKN0UKxWJxyt+M4OI5zhAffP5mGEEIIIWaINk2/APr7+8nn883txhtvPGrnLSMLQgghxBy0Y8cOcrlc8/bRGlUACRaEEEKIGTOda0PkcrkpwcLRJMGCEEIIMUPmaANHCRaEEEKI41m5XOb5559v3t6+fTuPP/44bW1tLFiw4KCOcdwGC0opAEqvyhYVQgghXm3yWjF57ThqZmFo4bHHHuPCCy9s3r722msBuPzyy7n11lsP6hjHbbAwOjoKwNLF/bN8JkIIIeaKUqlEPp8/asefjXbPF1xwwREHQcdtsNDW1gbAwMDAUf2LPxEUi0X6+/tfk3krDo98ntNHPsvpdSJ/nkopSqUSfX19s30qx6TjNljQ9biFRD6fP+H+0R8tM5l5eyKQz3P6yGc5vU7Uz3MmvlhqTEM1xLScyaE5boMFIYQQ4lgzV6shpIOjEEIIIQ7ouB1ZcByHz372s0e1o9WJQj7L6SWf5/SRz3J6yed59E1nU6aZpKmjXicihBBCnNiKxSL5fJ6nX9pL9gjzQUrFIqsWdVIoFKSDoxBCCHG8masjC5KzIIQQQogDkpEFIYQQYobM1WoICRaEEEKIGSLTEMeQr371qyxatIhEIsGaNWt45JFHZvuUZt2DDz7Ie97zHvr6+tA0jdtvv33K40opPvOZz9Db20symWTdunVs27Ztyj5jY2Ncdtll5HI5WlpauOKKKyiXy1P2eeKJJzjvvPNIJBL09/fzpS996Wi/tRl34403cs4555DNZunq6uKSSy5h69atU/ap1+ts3LiR9vZ2MpkMl156KUNDQ1P2GRgYYMOGDaRSKbq6uvjkJz9JEART9rn//vt505vehOM4LF269KD7uM8lN910E6tXr242Alq7di0//vGPm4/LZ3n4vvjFL6JpGtdcc03zPvk8xWFRx5nvfOc7yrZt9Y1vfEM99dRT6mMf+5hqaWlRQ0NDs31qs+pHP/qR+ou/+Av1/e9/XwHqBz/4wZTHv/jFL6p8Pq9uv/129Zvf/Eb9zu/8jlq8eLGq1WrNfd71rnep008/XT300EPqZz/7mVq6dKn6wAc+0Hy8UCio7u5uddlll6ktW7aob3/72yqZTKp/+qd/mqm3OSPWr1+vbrnlFrVlyxb1+OOPq3e/+91qwYIFqlwuN/e58sorVX9/v7rvvvvUY489ps4991z1W7/1W83HgyBQp556qlq3bp369a9/rX70ox+pjo4Odf311zf3efHFF1UqlVLXXnutevrpp9U//uM/KsMw1F133TWj7/do++EPf6juvPNO9dxzz6mtW7eqP//zP1eWZaktW7YopeSzPFyPPPKIWrRokVq9erX60z/90+b98nnOjkKhoAD13MCI2jPhHdH23MCIAlShUJix8z/ugoU3v/nNauPGjc3bYRiqvr4+deONN87iWR1bXh0sRFGkenp61F//9V8375uYmFCO46hvf/vbSimlnn76aQWoRx99tLnPj3/8Y6Vpmtq1a5dSSqmvfe1rqrW1Vbmu29znuuuuU8uXLz/K72h2DQ8PK0A98MADSqn4s7MsS33ve99r7vPMM88oQG3atEkpFQdvuq6rwcHB5j433XSTyuVyzc/vU5/6lDrllFOmvNb73vc+tX79+qP9lmZda2ur+pd/+Rf5LA9TqVRSy5YtU/fcc49629ve1gwW5POcPc1gYceI2lPwjmh7bsfMBwvH1TSE53ls3ryZdevWNe/TdZ1169axadOmWTyzY9v27dsZHByc8rnl83nWrFnT/Nw2bdpES0sLZ599dnOfdevWoes6Dz/8cHOf888/H9u2m/usX7+erVu3Mj4+PkPvZuYVCgVg3+Jlmzdvxvf9KZ/nihUrWLBgwZTP87TTTqO7u7u5z/r16ykWizz11FPNfV55jMl9jud/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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import rasterio as rio\n", + "\n", + "with rio.open(\"data/OC1mTest_HAND_taudem_fim.tif\") as ds:\n", + " fim = ds.read(1)\n", + " fim[fim == ds.nodata] = np.nan\n", + "\n", + "plt.imshow(fim, cmap=\"Blues\")\n", + "plt.colorbar()\n", + "plt.show()" + ] + } + ], + "metadata": { + "colab": { + "authorship_tag": "ABX9TyMNCi84+7QiD4ra1kbkEbpz", + "include_colab_link": true, + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 0000000..1101222 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,77 @@ +.. pygeoflood documentation master file, created by + sphinx-quickstart on Fri May 24 10:07:38 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +**pygeoflood** docs +======================== + +**pygeoflood** is a suite of terrain-analysis tools for mapping flood inundation in near-real time. + +This package is under active development as we incorporate efficient methods for mapping fluvial, pluvial, and coastal flooding. + +View the source code on GitHub: https://github.com/passah2o/pygeoflood + +.. implementation of geonet and geoflood, which are topographic based channel extraction packages that delineate slope, curvature, flow direction, and flow accumulation in order to implement the height above nearest drainage (HAND) inundation mapping method. + +.. This package is under active development as we build out additional methods to map compound flooding in near-real time. + +Installation +############# + +**pygeoflood** currently supports Python 3.10, 3.11, and 3.12. We recommend installing with our provided conda environment file. This will install all dependencies and a compatible version of python. + +.. code-block:: bash + + conda env create -f pygeoflood-env.yml + +Alternatively, you can install the package with pip: + +.. code-block:: bash + + pip install git+https://github.com/passah2o/pygeoflood + +Examples +################# + +.. toctree:: + :maxdepth: 2 + +.. nbgallery:: + examples/fim_workflow_combined + examples/fim_workflow_indiv_steps + +.. Getting Started +.. ############### + +.. Background +.. ########## + +.. User Guide +.. ########## + +Contributing +############# + +.. toctree:: + :maxdepth: 1 + + Contributing bug reports and development + +API Reference +############# + +.. toctree:: + :maxdepth: 1 + + pygeoflood API reference + + +.. Acknowledgements +.. ################ + + + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 0000000..7ebbd6d --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/debug.css b/_static/debug.css new file mode 100644 index 0000000..74d4aec --- /dev/null +++ b/_static/debug.css @@ -0,0 +1,69 @@ +/* + This CSS file should be overridden by the theme authors. It's + meant for debugging and developing the skeleton that this theme provides. +*/ +body { + font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji"; + background: lavender; +} +.sb-announcement { + background: rgb(131, 131, 131); +} +.sb-announcement__inner { + background: black; + color: white; +} +.sb-header { + background: lightskyblue; +} +.sb-header__inner { + background: royalblue; + color: white; +} +.sb-header-secondary { + background: lightcyan; +} +.sb-header-secondary__inner { + background: cornflowerblue; + color: white; +} +.sb-sidebar-primary { + background: lightgreen; +} +.sb-main { + background: blanchedalmond; +} +.sb-main__inner { + background: antiquewhite; +} +.sb-header-article { + background: lightsteelblue; +} +.sb-article-container { + background: snow; +} +.sb-article-main { + background: white; +} +.sb-footer-article { + background: lightpink; +} +.sb-sidebar-secondary { + background: lightgoldenrodyellow; +} +.sb-footer-content { + background: plum; +} +.sb-footer-content__inner { + background: palevioletred; +} +.sb-footer { + background: pink; +} +.sb-footer__inner { + background: salmon; +} +.sb-article { + background: white; +} diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 0000000..0398ebb --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 0000000..7e4c114 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 0000000..c7fe6c6 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/nbsphinx-broken-thumbnail.svg b/_static/nbsphinx-broken-thumbnail.svg new file mode 100644 index 0000000..4919ca8 --- /dev/null +++ b/_static/nbsphinx-broken-thumbnail.svg @@ -0,0 +1,9 @@ + + + + diff --git a/_static/nbsphinx-code-cells.css b/_static/nbsphinx-code-cells.css new file mode 100644 index 0000000..a3fb27c --- /dev/null +++ b/_static/nbsphinx-code-cells.css @@ -0,0 +1,259 @@ +/* remove conflicting styling from Sphinx themes */ +div.nbinput.container div.prompt *, +div.nboutput.container div.prompt *, +div.nbinput.container div.input_area pre, +div.nboutput.container div.output_area pre, +div.nbinput.container div.input_area .highlight, +div.nboutput.container div.output_area .highlight { + border: none; + padding: 0; + margin: 0; + box-shadow: none; +} + +div.nbinput.container > div[class*=highlight], +div.nboutput.container > div[class*=highlight] { + margin: 0; +} + +div.nbinput.container div.prompt *, +div.nboutput.container div.prompt * { + background: none; +} + +div.nboutput.container div.output_area .highlight, +div.nboutput.container div.output_area pre { + background: unset; +} + +div.nboutput.container div.output_area div.highlight { + color: unset; /* override Pygments text color */ +} + +/* avoid gaps between output lines */ +div.nboutput.container div[class*=highlight] pre { + line-height: normal; +} + +/* input/output containers */ +div.nbinput.container, +div.nboutput.container { + display: -webkit-flex; + display: flex; + align-items: flex-start; + margin: 0; + width: 100%; +} +@media (max-width: 540px) { + div.nbinput.container, + div.nboutput.container { + flex-direction: column; + } +} + +/* input container */ +div.nbinput.container { + padding-top: 5px; +} + +/* last container */ +div.nblast.container { + padding-bottom: 5px; +} + +/* input prompt */ +div.nbinput.container div.prompt pre, +/* for sphinx_immaterial theme: */ +div.nbinput.container div.prompt pre > code { + color: #307FC1; +} + +/* output prompt */ +div.nboutput.container div.prompt pre, +/* for sphinx_immaterial theme: */ +div.nboutput.container div.prompt pre > code { + color: #BF5B3D; +} + +/* all prompts */ +div.nbinput.container div.prompt, +div.nboutput.container div.prompt { + width: 4.5ex; + padding-top: 5px; + position: relative; + user-select: none; +} + +div.nbinput.container div.prompt > div, +div.nboutput.container div.prompt > div { + position: absolute; + right: 0; + margin-right: 0.3ex; +} + +@media (max-width: 540px) { + div.nbinput.container div.prompt, + div.nboutput.container div.prompt { + width: unset; + text-align: left; + padding: 0.4em; + } + div.nboutput.container div.prompt.empty { + padding: 0; + } + + div.nbinput.container div.prompt > div, + div.nboutput.container div.prompt > div { + position: unset; + } +} + +/* disable scrollbars and line breaks on prompts */ +div.nbinput.container div.prompt pre, +div.nboutput.container div.prompt pre { + overflow: hidden; + white-space: pre; +} + +/* input/output area */ +div.nbinput.container div.input_area, +div.nboutput.container div.output_area { + -webkit-flex: 1; + flex: 1; + overflow: auto; +} +@media (max-width: 540px) { + div.nbinput.container div.input_area, + div.nboutput.container div.output_area { + width: 100%; + } +} + +/* input area */ +div.nbinput.container div.input_area { + border: 1px solid #e0e0e0; + border-radius: 2px; + /*background: #f5f5f5;*/ +} + +/* override MathJax center alignment in output cells */ +div.nboutput.container div[class*=MathJax] { + text-align: left !important; +} + +/* override sphinx.ext.imgmath center alignment in output cells */ +div.nboutput.container div.math p { + text-align: left; +} + +/* standard error */ +div.nboutput.container div.output_area.stderr { + background: #fdd; +} + +/* ANSI colors */ +.ansi-black-fg { color: #3E424D; } +.ansi-black-bg { background-color: #3E424D; } +.ansi-black-intense-fg { color: #282C36; } +.ansi-black-intense-bg { background-color: #282C36; } +.ansi-red-fg { color: #E75C58; } +.ansi-red-bg { background-color: #E75C58; } +.ansi-red-intense-fg { color: #B22B31; } +.ansi-red-intense-bg { background-color: #B22B31; } +.ansi-green-fg { color: #00A250; } +.ansi-green-bg { background-color: #00A250; } +.ansi-green-intense-fg { color: #007427; } +.ansi-green-intense-bg { background-color: #007427; } +.ansi-yellow-fg { color: #DDB62B; } +.ansi-yellow-bg { background-color: #DDB62B; } +.ansi-yellow-intense-fg { color: #B27D12; } +.ansi-yellow-intense-bg { background-color: #B27D12; } +.ansi-blue-fg { color: #208FFB; } +.ansi-blue-bg { background-color: #208FFB; } +.ansi-blue-intense-fg { color: #0065CA; } +.ansi-blue-intense-bg { background-color: #0065CA; } +.ansi-magenta-fg { color: #D160C4; } +.ansi-magenta-bg { background-color: #D160C4; } +.ansi-magenta-intense-fg { color: #A03196; } +.ansi-magenta-intense-bg { background-color: #A03196; } +.ansi-cyan-fg { color: #60C6C8; } +.ansi-cyan-bg { background-color: #60C6C8; } +.ansi-cyan-intense-fg { color: #258F8F; } +.ansi-cyan-intense-bg { background-color: #258F8F; } +.ansi-white-fg { color: #C5C1B4; } +.ansi-white-bg { background-color: #C5C1B4; } +.ansi-white-intense-fg { color: #A1A6B2; } +.ansi-white-intense-bg { background-color: #A1A6B2; } + +.ansi-default-inverse-fg { color: #FFFFFF; } +.ansi-default-inverse-bg { background-color: #000000; } + +.ansi-bold { font-weight: bold; } +.ansi-underline { text-decoration: underline; } + + +div.nbinput.container div.input_area div[class*=highlight] > pre, +div.nboutput.container div.output_area div[class*=highlight] > pre, +div.nboutput.container div.output_area div[class*=highlight].math, +div.nboutput.container div.output_area.rendered_html, +div.nboutput.container div.output_area > div.output_javascript, +div.nboutput.container div.output_area:not(.rendered_html) > img{ + padding: 5px; + margin: 0; +} + +/* fix copybtn overflow problem in chromium (needed for 'sphinx_copybutton') */ +div.nbinput.container div.input_area > div[class^='highlight'], +div.nboutput.container div.output_area > div[class^='highlight']{ + overflow-y: hidden; +} + +/* hide copy button on prompts for 'sphinx_copybutton' extension ... */ +.prompt .copybtn, +/* ... and 'sphinx_immaterial' theme */ +.prompt .md-clipboard.md-icon { + display: none; +} + +/* Some additional styling taken form the Jupyter notebook CSS */ +.jp-RenderedHTMLCommon table, +div.rendered_html table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 12px; + table-layout: fixed; +} +.jp-RenderedHTMLCommon thead, +div.rendered_html thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} +.jp-RenderedHTMLCommon tr, +.jp-RenderedHTMLCommon th, +.jp-RenderedHTMLCommon td, +div.rendered_html tr, +div.rendered_html th, +div.rendered_html td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} +.jp-RenderedHTMLCommon th, +div.rendered_html th { + font-weight: bold; +} +.jp-RenderedHTMLCommon tbody tr:nth-child(odd), +div.rendered_html tbody tr:nth-child(odd) { + background: #f5f5f5; +} +.jp-RenderedHTMLCommon tbody tr:hover, +div.rendered_html tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + diff --git a/_static/nbsphinx-gallery.css b/_static/nbsphinx-gallery.css new file mode 100644 index 0000000..365c27a --- /dev/null +++ b/_static/nbsphinx-gallery.css @@ -0,0 +1,31 @@ +.nbsphinx-gallery { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: 5px; + margin-top: 1em; + margin-bottom: 1em; +} + +.nbsphinx-gallery > a { + padding: 5px; + border: 1px dotted currentColor; + border-radius: 2px; + text-align: center; +} + +.nbsphinx-gallery > a:hover { + border-style: solid; +} + +.nbsphinx-gallery img { + max-width: 100%; + max-height: 100%; +} + +.nbsphinx-gallery > a > div:first-child { + display: flex; + align-items: start; + justify-content: center; + height: 120px; + margin-bottom: 5px; +} diff --git a/_static/nbsphinx-no-thumbnail.svg b/_static/nbsphinx-no-thumbnail.svg new file mode 100644 index 0000000..9dca758 --- /dev/null +++ b/_static/nbsphinx-no-thumbnail.svg @@ -0,0 +1,9 @@ + + + + diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 0000000..02b4b12 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,258 @@ +.highlight pre { line-height: 125%; } +.highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ +.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .ges { color: #000000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8f5902 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #204a87 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ +.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ +.highlight .w { color: #f8f8f8 } /* Text.Whitespace */ +.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ +.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ +@media not print { +body[data-theme="dark"] .highlight pre { line-height: 125%; } +body[data-theme="dark"] .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight .hll { background-color: #404040 } +body[data-theme="dark"] .highlight { background: #202020; color: #d0d0d0 } +body[data-theme="dark"] .highlight .c { color: #ababab; font-style: italic } /* Comment */ +body[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +body[data-theme="dark"] .highlight .esc { color: #d0d0d0 } /* Escape */ +body[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */ +body[data-theme="dark"] .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */ +body[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */ +body[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */ +body[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */ +body[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */ +body[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */ +body[data-theme="dark"] .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */ +body[data-theme="dark"] .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */ +body[data-theme="dark"] .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */ +body[data-theme="dark"] .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ +body[data-theme="dark"] .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ +body[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body[data-theme="dark"] .highlight .gd { color: #ff3a3a } /* Generic.Deleted */ +body[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body[data-theme="dark"] .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body[data-theme="dark"] .highlight .gr { color: #ff3a3a } /* Generic.Error */ +body[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */ +body[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */ +body[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +body[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +body[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +body[data-theme="dark"] .highlight .gt { color: #ff3a3a } /* Generic.Traceback */ +body[data-theme="dark"] .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ +body[data-theme="dark"] .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ +body[data-theme="dark"] .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ +body[data-theme="dark"] .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */ +body[data-theme="dark"] .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */ +body[data-theme="dark"] .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */ +body[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */ +body[data-theme="dark"] .highlight .m { color: #51b2fd } /* Literal.Number */ +body[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */ +body[data-theme="dark"] .highlight .na { color: #bbbbbb } /* Name.Attribute */ +body[data-theme="dark"] .highlight .nb { color: #2fbccd } /* Name.Builtin */ +body[data-theme="dark"] .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */ +body[data-theme="dark"] .highlight .no { color: #40ffff } /* Name.Constant */ +body[data-theme="dark"] .highlight .nd { color: #ffa500 } /* Name.Decorator */ +body[data-theme="dark"] .highlight .ni { color: #d0d0d0 } /* Name.Entity */ +body[data-theme="dark"] .highlight .ne { color: #bbbbbb } /* Name.Exception */ +body[data-theme="dark"] .highlight .nf { color: #71adff } /* Name.Function */ +body[data-theme="dark"] .highlight .nl { color: #d0d0d0 } /* Name.Label */ +body[data-theme="dark"] .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */ +body[data-theme="dark"] .highlight .nx { color: #d0d0d0 } /* Name.Other */ +body[data-theme="dark"] .highlight .py { color: #d0d0d0 } /* Name.Property */ +body[data-theme="dark"] .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */ +body[data-theme="dark"] .highlight .nv { color: #40ffff } /* Name.Variable */ +body[data-theme="dark"] .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */ +body[data-theme="dark"] .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */ +body[data-theme="dark"] .highlight .w { color: #666666 } /* Text.Whitespace */ +body[data-theme="dark"] .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */ +body[data-theme="dark"] .highlight .mf { color: #51b2fd } /* Literal.Number.Float */ +body[data-theme="dark"] .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */ +body[data-theme="dark"] .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */ +body[data-theme="dark"] .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */ +body[data-theme="dark"] .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */ +body[data-theme="dark"] .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +body[data-theme="dark"] .highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +body[data-theme="dark"] .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */ +body[data-theme="dark"] .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +body[data-theme="dark"] .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +body[data-theme="dark"] .highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +body[data-theme="dark"] .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +body[data-theme="dark"] .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +body[data-theme="dark"] .highlight .sx { color: #ffa500 } /* Literal.String.Other */ +body[data-theme="dark"] .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +body[data-theme="dark"] .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +body[data-theme="dark"] .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +body[data-theme="dark"] .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */ +body[data-theme="dark"] .highlight .fm { color: #71adff } /* Name.Function.Magic */ +body[data-theme="dark"] .highlight .vc { color: #40ffff } /* Name.Variable.Class */ +body[data-theme="dark"] .highlight .vg { color: #40ffff } /* Name.Variable.Global */ +body[data-theme="dark"] .highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +body[data-theme="dark"] .highlight .vm { color: #40ffff } /* Name.Variable.Magic */ +body[data-theme="dark"] .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */ +@media (prefers-color-scheme: dark) { +body:not([data-theme="light"]) .highlight pre { line-height: 125%; } +body:not([data-theme="light"]) .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight .hll { background-color: #404040 } +body:not([data-theme="light"]) .highlight { background: #202020; color: #d0d0d0 } +body:not([data-theme="light"]) .highlight .c { color: #ababab; font-style: italic } /* Comment */ +body:not([data-theme="light"]) .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +body:not([data-theme="light"]) .highlight .esc { color: #d0d0d0 } /* Escape */ +body:not([data-theme="light"]) .highlight .g { color: #d0d0d0 } /* Generic */ +body:not([data-theme="light"]) .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */ +body:not([data-theme="light"]) .highlight .l { color: #d0d0d0 } /* Literal */ +body:not([data-theme="light"]) .highlight .n { color: #d0d0d0 } /* Name */ +body:not([data-theme="light"]) .highlight .o { color: #d0d0d0 } /* Operator */ +body:not([data-theme="light"]) .highlight .x { color: #d0d0d0 } /* Other */ +body:not([data-theme="light"]) .highlight .p { color: #d0d0d0 } /* Punctuation */ +body:not([data-theme="light"]) .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */ +body:not([data-theme="light"]) .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */ +body:not([data-theme="light"]) .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */ +body:not([data-theme="light"]) .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ +body:not([data-theme="light"]) .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ +body:not([data-theme="light"]) .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body:not([data-theme="light"]) .highlight .gd { color: #ff3a3a } /* Generic.Deleted */ +body:not([data-theme="light"]) .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body:not([data-theme="light"]) .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body:not([data-theme="light"]) .highlight .gr { color: #ff3a3a } /* Generic.Error */ +body:not([data-theme="light"]) .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */ +body:not([data-theme="light"]) .highlight .go { color: #cccccc } /* Generic.Output */ +body:not([data-theme="light"]) .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +body:not([data-theme="light"]) .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +body:not([data-theme="light"]) .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +body:not([data-theme="light"]) .highlight .gt { color: #ff3a3a } /* Generic.Traceback */ +body:not([data-theme="light"]) .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ +body:not([data-theme="light"]) .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ +body:not([data-theme="light"]) .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ +body:not([data-theme="light"]) .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */ +body:not([data-theme="light"]) .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */ +body:not([data-theme="light"]) .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */ +body:not([data-theme="light"]) .highlight .ld { color: #d0d0d0 } /* Literal.Date */ +body:not([data-theme="light"]) .highlight .m { color: #51b2fd } /* Literal.Number */ +body:not([data-theme="light"]) .highlight .s { color: #ed9d13 } /* Literal.String */ +body:not([data-theme="light"]) .highlight .na { color: #bbbbbb } /* Name.Attribute */ +body:not([data-theme="light"]) .highlight .nb { color: #2fbccd } /* Name.Builtin */ +body:not([data-theme="light"]) .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */ +body:not([data-theme="light"]) .highlight .no { color: #40ffff } /* Name.Constant */ +body:not([data-theme="light"]) .highlight .nd { color: #ffa500 } /* Name.Decorator */ +body:not([data-theme="light"]) .highlight .ni { color: #d0d0d0 } /* Name.Entity */ +body:not([data-theme="light"]) .highlight .ne { color: #bbbbbb } /* Name.Exception */ +body:not([data-theme="light"]) .highlight .nf { color: #71adff } /* Name.Function */ +body:not([data-theme="light"]) .highlight .nl { color: #d0d0d0 } /* Name.Label */ +body:not([data-theme="light"]) .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */ +body:not([data-theme="light"]) .highlight .nx { color: #d0d0d0 } /* Name.Other */ +body:not([data-theme="light"]) .highlight .py { color: #d0d0d0 } /* Name.Property */ +body:not([data-theme="light"]) .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */ +body:not([data-theme="light"]) .highlight .nv { color: #40ffff } /* Name.Variable */ +body:not([data-theme="light"]) .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */ +body:not([data-theme="light"]) .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */ +body:not([data-theme="light"]) .highlight .w { color: #666666 } /* Text.Whitespace */ +body:not([data-theme="light"]) .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */ +body:not([data-theme="light"]) .highlight .mf { color: #51b2fd } /* Literal.Number.Float */ +body:not([data-theme="light"]) .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */ +body:not([data-theme="light"]) .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */ +body:not([data-theme="light"]) .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */ +body:not([data-theme="light"]) .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */ +body:not([data-theme="light"]) .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +body:not([data-theme="light"]) .highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +body:not([data-theme="light"]) .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */ +body:not([data-theme="light"]) .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +body:not([data-theme="light"]) .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +body:not([data-theme="light"]) .highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +body:not([data-theme="light"]) .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +body:not([data-theme="light"]) .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +body:not([data-theme="light"]) .highlight .sx { color: #ffa500 } /* Literal.String.Other */ +body:not([data-theme="light"]) .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +body:not([data-theme="light"]) .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +body:not([data-theme="light"]) .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +body:not([data-theme="light"]) .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */ +body:not([data-theme="light"]) .highlight .fm { color: #71adff } /* Name.Function.Magic */ +body:not([data-theme="light"]) .highlight .vc { color: #40ffff } /* Name.Variable.Class */ +body:not([data-theme="light"]) .highlight .vg { color: #40ffff } /* Name.Variable.Global */ +body:not([data-theme="light"]) .highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +body:not([data-theme="light"]) .highlight .vm { color: #40ffff } /* Name.Variable.Magic */ +body:not([data-theme="light"]) .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */ +} +} \ No newline at end of file diff --git a/_static/scripts/furo-extensions.js b/_static/scripts/furo-extensions.js new file mode 100644 index 0000000..e69de29 diff --git a/_static/scripts/furo.js b/_static/scripts/furo.js new file mode 100644 index 0000000..0abb2af --- /dev/null +++ b/_static/scripts/furo.js @@ -0,0 +1,3 @@ +/*! For license information please see furo.js.LICENSE.txt */ +(()=>{var t={856:function(t,e,n){var o,r;r=void 0!==n.g?n.g:"undefined"!=typeof window?window:this,o=function(){return function(t){"use strict";var e={navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:0,reflow:!1,events:!0},n=function(t,e,n){if(n.settings.events){var o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n});e.dispatchEvent(o)}},o=function(t){var e=0;if(t.offsetParent)for(;t;)e+=t.offsetTop,t=t.offsetParent;return e>=0?e:0},r=function(t){t&&t.sort((function(t,e){return o(t.content)=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},l=function(t,e){var n=t[t.length-1];if(function(t,e){return!(!s()||!c(t.content,e,!0))}(n,e))return n;for(var o=t.length-1;o>=0;o--)if(c(t[o].content,e))return t[o]},a=function(t,e){if(e.nested&&t.parentNode){var n=t.parentNode.closest("li");n&&(n.classList.remove(e.nestedClass),a(n,e))}},i=function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.remove(e.navClass),t.content.classList.remove(e.contentClass),a(o,e),n("gumshoeDeactivate",o,{link:t.nav,content:t.content,settings:e}))}},u=function(t,e){if(e.nested){var n=t.parentNode.closest("li");n&&(n.classList.add(e.nestedClass),u(n,e))}};return function(o,c){var s,a,d,f,m,v={setup:function(){s=document.querySelectorAll(o),a=[],Array.prototype.forEach.call(s,(function(t){var e=document.getElementById(decodeURIComponent(t.hash.substr(1)));e&&a.push({nav:t,content:e})})),r(a)},detect:function(){var t=l(a,m);t?d&&t.content===d.content||(i(d,m),function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.add(e.navClass),t.content.classList.add(e.contentClass),u(o,e),n("gumshoeActivate",o,{link:t.nav,content:t.content,settings:e}))}}(t,m),d=t):d&&(i(d,m),d=null)}},h=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame(v.detect)},g=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame((function(){r(a),v.detect()}))};return v.destroy=function(){d&&i(d,m),t.removeEventListener("scroll",h,!1),m.reflow&&t.removeEventListener("resize",g,!1),a=null,s=null,d=null,f=null,m=null},m=function(){var t={};return Array.prototype.forEach.call(arguments,(function(e){for(var n in e){if(!e.hasOwnProperty(n))return;t[n]=e[n]}})),t}(e,c||{}),v.setup(),v.detect(),t.addEventListener("scroll",h,!1),m.reflow&&t.addEventListener("resize",g,!1),v}}(r)}.apply(e,[]),void 0===o||(t.exports=o)}},e={};function n(o){var r=e[o];if(void 0!==r)return r.exports;var c=e[o]={exports:{}};return t[o].call(c.exports,c,c.exports,n),c.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";var t=n(856),e=n.n(t),o=null,r=null,c=document.documentElement.scrollTop;const s=64;function l(){const t=localStorage.getItem("theme")||"auto";var e;"light"!==(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"auto"===t?"light":"light"==t?"dark":"auto":"auto"===t?"dark":"dark"==t?"light":"auto")&&"dark"!==e&&"auto"!==e&&(console.error(`Got invalid theme mode: ${e}. Resetting to auto.`),e="auto"),document.body.dataset.theme=e,localStorage.setItem("theme",e),console.log(`Changed to ${e} mode.`)}function a(){!function(){const t=document.getElementsByClassName("theme-toggle");Array.from(t).forEach((t=>{t.addEventListener("click",l)}))}(),function(){let t=0,e=!1;window.addEventListener("scroll",(function(n){t=window.scrollY,e||(window.requestAnimationFrame((function(){var n;(function(t){const e=Math.floor(r.getBoundingClientRect().top);console.log(`headerTop: ${e}`),0==e&&t!=e?r.classList.add("scrolled"):r.classList.remove("scrolled")})(n=t),function(t){tc&&document.documentElement.classList.remove("show-back-to-top"),c=t}(n),function(t){null!==o&&(0==t?o.scrollTo(0,0):Math.ceil(t)>=Math.floor(document.documentElement.scrollHeight-window.innerHeight)?o.scrollTo(0,o.scrollHeight):document.querySelector(".scroll-current"))}(n),e=!1})),e=!0)})),window.scroll()}(),null!==o&&new(e())(".toc-tree a",{reflow:!0,recursive:!0,navClass:"scroll-current",offset:()=>{let t=parseFloat(getComputedStyle(document.documentElement).fontSize);return r.getBoundingClientRect().height+2.5*t+1}})}document.addEventListener("DOMContentLoaded",(function(){document.body.parentNode.classList.remove("no-js"),r=document.querySelector("header"),o=document.querySelector(".toc-scroll"),a()}))})()})(); +//# sourceMappingURL=furo.js.map \ No newline at end of file diff --git a/_static/scripts/furo.js.LICENSE.txt b/_static/scripts/furo.js.LICENSE.txt new file mode 100644 index 0000000..1632189 --- /dev/null +++ b/_static/scripts/furo.js.LICENSE.txt @@ -0,0 +1,7 @@ +/*! + * gumshoejs v5.1.2 (patched by @pradyunsg) + * A simple, framework-agnostic scrollspy script. + * (c) 2019 Chris Ferdinandi + * MIT License + * http://github.com/cferdinandi/gumshoe + */ diff --git a/_static/scripts/furo.js.map b/_static/scripts/furo.js.map new file mode 100644 index 0000000..80ea12b --- /dev/null +++ b/_static/scripts/furo.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/furo.js","mappings":"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","sources":["webpack:///./src/furo/assets/scripts/gumshoe-patched.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/global","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///./src/furo/assets/scripts/furo.js"],"sourcesContent":["/*!\n * gumshoejs v5.1.2 (patched by @pradyunsg)\n * A simple, framework-agnostic scrollspy script.\n * (c) 2019 Chris Ferdinandi\n * MIT License\n * http://github.com/cferdinandi/gumshoe\n */\n\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], function () {\n return factory(root);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(root);\n } else {\n root.Gumshoe = factory(root);\n }\n})(\n typeof global !== \"undefined\"\n ? global\n : typeof window !== \"undefined\"\n ? window\n : this,\n function (window) {\n \"use strict\";\n\n //\n // Defaults\n //\n\n var defaults = {\n // Active classes\n navClass: \"active\",\n contentClass: \"active\",\n\n // Nested navigation\n nested: false,\n nestedClass: \"active\",\n\n // Offset & reflow\n offset: 0,\n reflow: false,\n\n // Event support\n events: true,\n };\n\n //\n // Methods\n //\n\n /**\n * Merge two or more objects together.\n * @param {Object} objects The objects to merge together\n * @returns {Object} Merged values of defaults and options\n */\n var extend = function () {\n var merged = {};\n Array.prototype.forEach.call(arguments, function (obj) {\n for (var key in obj) {\n if (!obj.hasOwnProperty(key)) return;\n merged[key] = obj[key];\n }\n });\n return merged;\n };\n\n /**\n * Emit a custom event\n * @param {String} type The event type\n * @param {Node} elem The element to attach the event to\n * @param {Object} detail Any details to pass along with the event\n */\n var emitEvent = function (type, elem, detail) {\n // Make sure events are enabled\n if (!detail.settings.events) return;\n\n // Create a new event\n var event = new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n detail: detail,\n });\n\n // Dispatch the event\n elem.dispatchEvent(event);\n };\n\n /**\n * Get an element's distance from the top of the Document.\n * @param {Node} elem The element\n * @return {Number} Distance from the top in pixels\n */\n var getOffsetTop = function (elem) {\n var location = 0;\n if (elem.offsetParent) {\n while (elem) {\n location += elem.offsetTop;\n elem = elem.offsetParent;\n }\n }\n return location >= 0 ? location : 0;\n };\n\n /**\n * Sort content from first to last in the DOM\n * @param {Array} contents The content areas\n */\n var sortContents = function (contents) {\n if (contents) {\n contents.sort(function (item1, item2) {\n var offset1 = getOffsetTop(item1.content);\n var offset2 = getOffsetTop(item2.content);\n if (offset1 < offset2) return -1;\n return 1;\n });\n }\n };\n\n /**\n * Get the offset to use for calculating position\n * @param {Object} settings The settings for this instantiation\n * @return {Float} The number of pixels to offset the calculations\n */\n var getOffset = function (settings) {\n // if the offset is a function run it\n if (typeof settings.offset === \"function\") {\n return parseFloat(settings.offset());\n }\n\n // Otherwise, return it as-is\n return parseFloat(settings.offset);\n };\n\n /**\n * Get the document element's height\n * @private\n * @returns {Number}\n */\n var getDocumentHeight = function () {\n return Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.offsetHeight,\n document.body.clientHeight,\n document.documentElement.clientHeight,\n );\n };\n\n /**\n * Determine if an element is in view\n * @param {Node} elem The element\n * @param {Object} settings The settings for this instantiation\n * @param {Boolean} bottom If true, check if element is above bottom of viewport instead\n * @return {Boolean} Returns true if element is in the viewport\n */\n var isInView = function (elem, settings, bottom) {\n var bounds = elem.getBoundingClientRect();\n var offset = getOffset(settings);\n if (bottom) {\n return (\n parseInt(bounds.bottom, 10) <\n (window.innerHeight || document.documentElement.clientHeight)\n );\n }\n return parseInt(bounds.top, 10) <= offset;\n };\n\n /**\n * Check if at the bottom of the viewport\n * @return {Boolean} If true, page is at the bottom of the viewport\n */\n var isAtBottom = function () {\n if (\n Math.ceil(window.innerHeight + window.pageYOffset) >=\n getDocumentHeight()\n )\n return true;\n return false;\n };\n\n /**\n * Check if the last item should be used (even if not at the top of the page)\n * @param {Object} item The last item\n * @param {Object} settings The settings for this instantiation\n * @return {Boolean} If true, use the last item\n */\n var useLastItem = function (item, settings) {\n if (isAtBottom() && isInView(item.content, settings, true)) return true;\n return false;\n };\n\n /**\n * Get the active content\n * @param {Array} contents The content areas\n * @param {Object} settings The settings for this instantiation\n * @return {Object} The content area and matching navigation link\n */\n var getActive = function (contents, settings) {\n var last = contents[contents.length - 1];\n if (useLastItem(last, settings)) return last;\n for (var i = contents.length - 1; i >= 0; i--) {\n if (isInView(contents[i].content, settings)) return contents[i];\n }\n };\n\n /**\n * Deactivate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var deactivateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested || !nav.parentNode) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Remove the active class\n li.classList.remove(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n deactivateNested(li, settings);\n };\n\n /**\n * Deactivate a nav and content area\n * @param {Object} items The nav item and content to deactivate\n * @param {Object} settings The settings for this instantiation\n */\n var deactivate = function (items, settings) {\n // Make sure there are items to deactivate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Remove the active class from the nav and content\n li.classList.remove(settings.navClass);\n items.content.classList.remove(settings.contentClass);\n\n // Deactivate any parent navs in a nested navigation\n deactivateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeDeactivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Activate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var activateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Add the active class\n li.classList.add(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n activateNested(li, settings);\n };\n\n /**\n * Activate a nav and content area\n * @param {Object} items The nav item and content to activate\n * @param {Object} settings The settings for this instantiation\n */\n var activate = function (items, settings) {\n // Make sure there are items to activate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Add the active class to the nav and content\n li.classList.add(settings.navClass);\n items.content.classList.add(settings.contentClass);\n\n // Activate any parent navs in a nested navigation\n activateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeActivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Create the Constructor object\n * @param {String} selector The selector to use for navigation items\n * @param {Object} options User options and settings\n */\n var Constructor = function (selector, options) {\n //\n // Variables\n //\n\n var publicAPIs = {};\n var navItems, contents, current, timeout, settings;\n\n //\n // Methods\n //\n\n /**\n * Set variables from DOM elements\n */\n publicAPIs.setup = function () {\n // Get all nav items\n navItems = document.querySelectorAll(selector);\n\n // Create contents array\n contents = [];\n\n // Loop through each item, get it's matching content, and push to the array\n Array.prototype.forEach.call(navItems, function (item) {\n // Get the content for the nav item\n var content = document.getElementById(\n decodeURIComponent(item.hash.substr(1)),\n );\n if (!content) return;\n\n // Push to the contents array\n contents.push({\n nav: item,\n content: content,\n });\n });\n\n // Sort contents by the order they appear in the DOM\n sortContents(contents);\n };\n\n /**\n * Detect which content is currently active\n */\n publicAPIs.detect = function () {\n // Get the active content\n var active = getActive(contents, settings);\n\n // if there's no active content, deactivate and bail\n if (!active) {\n if (current) {\n deactivate(current, settings);\n current = null;\n }\n return;\n }\n\n // If the active content is the one currently active, do nothing\n if (current && active.content === current.content) return;\n\n // Deactivate the current content and activate the new content\n deactivate(current, settings);\n activate(active, settings);\n\n // Update the currently active content\n current = active;\n };\n\n /**\n * Detect the active content on scroll\n * Debounced for performance\n */\n var scrollHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(publicAPIs.detect);\n };\n\n /**\n * Update content sorting on resize\n * Debounced for performance\n */\n var resizeHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(function () {\n sortContents(contents);\n publicAPIs.detect();\n });\n };\n\n /**\n * Destroy the current instantiation\n */\n publicAPIs.destroy = function () {\n // Undo DOM changes\n if (current) {\n deactivate(current, settings);\n }\n\n // Remove event listeners\n window.removeEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.removeEventListener(\"resize\", resizeHandler, false);\n }\n\n // Reset variables\n contents = null;\n navItems = null;\n current = null;\n timeout = null;\n settings = null;\n };\n\n /**\n * Initialize the current instantiation\n */\n var init = function () {\n // Merge user options into defaults\n settings = extend(defaults, options || {});\n\n // Setup variables based on the current DOM\n publicAPIs.setup();\n\n // Find the currently active content\n publicAPIs.detect();\n\n // Setup event listeners\n window.addEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.addEventListener(\"resize\", resizeHandler, false);\n }\n };\n\n //\n // Initialize and return the public APIs\n //\n\n init();\n return publicAPIs;\n };\n\n //\n // Return the Constructor\n //\n\n return Constructor;\n },\n);\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import Gumshoe from \"./gumshoe-patched.js\";\n\n////////////////////////////////////////////////////////////////////////////////\n// Scroll Handling\n////////////////////////////////////////////////////////////////////////////////\nvar tocScroll = null;\nvar header = null;\nvar lastScrollTop = document.documentElement.scrollTop;\nconst GO_TO_TOP_OFFSET = 64;\n\nfunction scrollHandlerForHeader(positionY) {\n const headerTop = Math.floor(header.getBoundingClientRect().top);\n\n console.log(`headerTop: ${headerTop}`);\n if (headerTop == 0 && positionY != headerTop) {\n header.classList.add(\"scrolled\");\n } else {\n header.classList.remove(\"scrolled\");\n }\n}\n\nfunction scrollHandlerForBackToTop(positionY) {\n if (positionY < GO_TO_TOP_OFFSET) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n } else {\n if (positionY < lastScrollTop) {\n document.documentElement.classList.add(\"show-back-to-top\");\n } else if (positionY > lastScrollTop) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n }\n }\n lastScrollTop = positionY;\n}\n\nfunction scrollHandlerForTOC(positionY) {\n if (tocScroll === null) {\n return;\n }\n\n // top of page.\n if (positionY == 0) {\n tocScroll.scrollTo(0, 0);\n } else if (\n // bottom of page.\n Math.ceil(positionY) >=\n Math.floor(document.documentElement.scrollHeight - window.innerHeight)\n ) {\n tocScroll.scrollTo(0, tocScroll.scrollHeight);\n } else {\n // somewhere in the middle.\n const current = document.querySelector(\".scroll-current\");\n if (current == null) {\n return;\n }\n\n // https://github.com/pypa/pip/issues/9159 This breaks scroll behaviours.\n // // scroll the currently \"active\" heading in toc, into view.\n // const rect = current.getBoundingClientRect();\n // if (0 > rect.top) {\n // current.scrollIntoView(true); // the argument is \"alignTop\"\n // } else if (rect.bottom > window.innerHeight) {\n // current.scrollIntoView(false);\n // }\n }\n}\n\nfunction scrollHandler(positionY) {\n scrollHandlerForHeader(positionY);\n scrollHandlerForBackToTop(positionY);\n scrollHandlerForTOC(positionY);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Theme Toggle\n////////////////////////////////////////////////////////////////////////////////\nfunction setTheme(mode) {\n if (mode !== \"light\" && mode !== \"dark\" && mode !== \"auto\") {\n console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`);\n mode = \"auto\";\n }\n\n document.body.dataset.theme = mode;\n localStorage.setItem(\"theme\", mode);\n console.log(`Changed to ${mode} mode.`);\n}\n\nfunction cycleThemeOnce() {\n const currentTheme = localStorage.getItem(\"theme\") || \"auto\";\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n\n if (prefersDark) {\n // Auto (dark) -> Light -> Dark\n if (currentTheme === \"auto\") {\n setTheme(\"light\");\n } else if (currentTheme == \"light\") {\n setTheme(\"dark\");\n } else {\n setTheme(\"auto\");\n }\n } else {\n // Auto (light) -> Dark -> Light\n if (currentTheme === \"auto\") {\n setTheme(\"dark\");\n } else if (currentTheme == \"dark\") {\n setTheme(\"light\");\n } else {\n setTheme(\"auto\");\n }\n }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Setup\n////////////////////////////////////////////////////////////////////////////////\nfunction setupScrollHandler() {\n // Taken from https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event\n let last_known_scroll_position = 0;\n let ticking = false;\n\n window.addEventListener(\"scroll\", function (e) {\n last_known_scroll_position = window.scrollY;\n\n if (!ticking) {\n window.requestAnimationFrame(function () {\n scrollHandler(last_known_scroll_position);\n ticking = false;\n });\n\n ticking = true;\n }\n });\n window.scroll();\n}\n\nfunction setupScrollSpy() {\n if (tocScroll === null) {\n return;\n }\n\n // Scrollspy -- highlight table on contents, based on scroll\n new Gumshoe(\".toc-tree a\", {\n reflow: true,\n recursive: true,\n navClass: \"scroll-current\",\n offset: () => {\n let rem = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return header.getBoundingClientRect().height + 2.5 * rem + 1;\n },\n });\n}\n\nfunction setupTheme() {\n // Attach event handlers for toggling themes\n const buttons = document.getElementsByClassName(\"theme-toggle\");\n Array.from(buttons).forEach((btn) => {\n btn.addEventListener(\"click\", cycleThemeOnce);\n });\n}\n\nfunction setup() {\n setupTheme();\n setupScrollHandler();\n setupScrollSpy();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Main entrypoint\n////////////////////////////////////////////////////////////////////////////////\nfunction main() {\n document.body.parentNode.classList.remove(\"no-js\");\n\n header = document.querySelector(\"header\");\n tocScroll = document.querySelector(\".toc-scroll\");\n\n setup();\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", main);\n"],"names":["root","g","window","this","defaults","navClass","contentClass","nested","nestedClass","offset","reflow","events","emitEvent","type","elem","detail","settings","event","CustomEvent","bubbles","cancelable","dispatchEvent","getOffsetTop","location","offsetParent","offsetTop","sortContents","contents","sort","item1","item2","content","isInView","bottom","bounds","getBoundingClientRect","parseFloat","getOffset","parseInt","innerHeight","document","documentElement","clientHeight","top","isAtBottom","Math","ceil","pageYOffset","max","body","scrollHeight","offsetHeight","getActive","last","length","item","useLastItem","i","deactivateNested","nav","parentNode","li","closest","classList","remove","deactivate","items","link","activateNested","add","selector","options","navItems","current","timeout","publicAPIs","querySelectorAll","Array","prototype","forEach","call","getElementById","decodeURIComponent","hash","substr","push","active","activate","scrollHandler","cancelAnimationFrame","requestAnimationFrame","detect","resizeHandler","destroy","removeEventListener","merged","arguments","obj","key","hasOwnProperty","extend","setup","addEventListener","factory","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","n","getter","__esModule","d","a","definition","o","Object","defineProperty","enumerable","get","globalThis","Function","e","prop","tocScroll","header","lastScrollTop","scrollTop","GO_TO_TOP_OFFSET","cycleThemeOnce","currentTheme","localStorage","getItem","mode","matchMedia","matches","console","error","dataset","theme","setItem","log","buttons","getElementsByClassName","from","btn","setupTheme","last_known_scroll_position","ticking","scrollY","positionY","headerTop","floor","scrollHandlerForHeader","scrollHandlerForBackToTop","scrollTo","querySelector","scrollHandlerForTOC","scroll","setupScrollHandler","recursive","rem","getComputedStyle","fontSize","height"],"sourceRoot":""} \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 0000000..2c774d1 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/skeleton.css b/_static/skeleton.css new file mode 100644 index 0000000..467c878 --- /dev/null +++ b/_static/skeleton.css @@ -0,0 +1,296 @@ +/* Some sane resets. */ +html { + height: 100%; +} + +body { + margin: 0; + min-height: 100%; +} + +/* All the flexbox magic! */ +body, +.sb-announcement, +.sb-content, +.sb-main, +.sb-container, +.sb-container__inner, +.sb-article-container, +.sb-footer-content, +.sb-header, +.sb-header-secondary, +.sb-footer { + display: flex; +} + +/* These order things vertically */ +body, +.sb-main, +.sb-article-container { + flex-direction: column; +} + +/* Put elements in the center */ +.sb-header, +.sb-header-secondary, +.sb-container, +.sb-content, +.sb-footer, +.sb-footer-content { + justify-content: center; +} +/* Put elements at the ends */ +.sb-article-container { + justify-content: space-between; +} + +/* These elements grow. */ +.sb-main, +.sb-content, +.sb-container, +article { + flex-grow: 1; +} + +/* Because padding making this wider is not fun */ +article { + box-sizing: border-box; +} + +/* The announcements element should never be wider than the page. */ +.sb-announcement { + max-width: 100%; +} + +.sb-sidebar-primary, +.sb-sidebar-secondary { + flex-shrink: 0; + width: 17rem; +} + +.sb-announcement__inner { + justify-content: center; + + box-sizing: border-box; + height: 3rem; + + overflow-x: auto; + white-space: nowrap; +} + +/* Sidebars, with checkbox-based toggle */ +.sb-sidebar-primary, +.sb-sidebar-secondary { + position: fixed; + height: 100%; + top: 0; +} + +.sb-sidebar-primary { + left: -17rem; + transition: left 250ms ease-in-out; +} +.sb-sidebar-secondary { + right: -17rem; + transition: right 250ms ease-in-out; +} + +.sb-sidebar-toggle { + display: none; +} +.sb-sidebar-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + + transition: width 0ms ease 250ms, height 0ms ease 250ms, opacity 250ms ease; + + opacity: 0; + background-color: rgba(0, 0, 0, 0.54); +} + +#sb-sidebar-toggle--primary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--primary"], +#sb-sidebar-toggle--secondary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--secondary"] { + width: 100%; + height: 100%; + opacity: 1; + transition: width 0ms ease, height 0ms ease, opacity 250ms ease; +} + +#sb-sidebar-toggle--primary:checked ~ .sb-container .sb-sidebar-primary { + left: 0; +} +#sb-sidebar-toggle--secondary:checked ~ .sb-container .sb-sidebar-secondary { + right: 0; +} + +/* Full-width mode */ +.drop-secondary-sidebar-for-full-width-content + .hide-when-secondary-sidebar-shown { + display: none !important; +} +.drop-secondary-sidebar-for-full-width-content .sb-sidebar-secondary { + display: none !important; +} + +/* Mobile views */ +.sb-page-width { + width: 100%; +} + +.sb-article-container, +.sb-footer-content__inner, +.drop-secondary-sidebar-for-full-width-content .sb-article, +.drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 100vw; +} + +.sb-article, +.match-content-width { + padding: 0 1rem; + box-sizing: border-box; +} + +@media (min-width: 32rem) { + .sb-article, + .match-content-width { + padding: 0 2rem; + } +} + +/* Tablet views */ +@media (min-width: 42rem) { + .sb-article-container { + width: auto; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 42rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 46rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 46rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 50rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 50rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Tablet views */ +@media (min-width: 59rem) { + .sb-sidebar-secondary { + position: static; + } + .hide-when-secondary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 63rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 67rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Desktop views */ +@media (min-width: 76rem) { + .sb-sidebar-primary { + position: static; + } + .hide-when-primary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} + +/* Full desktop views */ +@media (min-width: 80rem) { + .sb-article, + .match-content-width { + width: 46rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } +} + +@media (min-width: 84rem) { + .sb-article, + .match-content-width { + width: 50rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } +} + +@media (min-width: 88rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-page-width { + width: 88rem; + } +} diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/styles/furo-extensions.css b/_static/styles/furo-extensions.css new file mode 100644 index 0000000..8229587 --- /dev/null +++ b/_static/styles/furo-extensions.css @@ -0,0 +1,2 @@ +#furo-sidebar-ad-placement{padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)}#furo-sidebar-ad-placement .ethical-sidebar{background:var(--color-background-secondary);border:none;box-shadow:none}#furo-sidebar-ad-placement .ethical-sidebar:hover{background:var(--color-background-hover)}#furo-sidebar-ad-placement .ethical-sidebar a{color:var(--color-foreground-primary)}#furo-sidebar-ad-placement .ethical-callout a{color:var(--color-foreground-secondary)!important}#furo-readthedocs-versions{background:transparent;display:block;position:static;width:100%}#furo-readthedocs-versions .rst-versions{background:#1a1c1e}#furo-readthedocs-versions .rst-current-version{background:var(--color-sidebar-item-background);cursor:unset}#furo-readthedocs-versions .rst-current-version:hover{background:var(--color-sidebar-item-background)}#furo-readthedocs-versions .rst-current-version .fa-book{color:var(--color-foreground-primary)}#furo-readthedocs-versions>.rst-other-versions{padding:0}#furo-readthedocs-versions>.rst-other-versions small{opacity:1}#furo-readthedocs-versions .injected .rst-versions{position:unset}#furo-readthedocs-versions:focus-within,#furo-readthedocs-versions:hover{box-shadow:0 0 0 1px var(--color-sidebar-background-border)}#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:hover .rst-current-version{background:#1a1c1e;font-size:inherit;height:auto;line-height:inherit;padding:12px;text-align:right}#furo-readthedocs-versions:focus-within .rst-current-version .fa-book,#furo-readthedocs-versions:hover .rst-current-version .fa-book{color:#fff;float:left}#furo-readthedocs-versions:focus-within .fa-caret-down,#furo-readthedocs-versions:hover .fa-caret-down{display:none}#furo-readthedocs-versions:focus-within .injected,#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:focus-within .rst-other-versions,#furo-readthedocs-versions:hover .injected,#furo-readthedocs-versions:hover .rst-current-version,#furo-readthedocs-versions:hover .rst-other-versions{display:block}#furo-readthedocs-versions:focus-within>.rst-current-version,#furo-readthedocs-versions:hover>.rst-current-version{display:none}.highlight:hover button.copybtn{color:var(--color-code-foreground)}.highlight button.copybtn{align-items:center;background-color:var(--color-code-background);border:none;color:var(--color-background-item);cursor:pointer;height:1.25em;right:.5rem;top:.625rem;transition:color .3s,opacity .3s;width:1.25em}.highlight button.copybtn:hover{background-color:var(--color-code-background);color:var(--color-brand-content)}.highlight button.copybtn:after{background-color:transparent;color:var(--color-code-foreground);display:none}.highlight button.copybtn.success{color:#22863a;transition:color 0ms}.highlight button.copybtn.success:after{display:block}.highlight button.copybtn svg{padding:0}body{--sd-color-primary:var(--color-brand-primary);--sd-color-primary-highlight:var(--color-brand-content);--sd-color-primary-text:var(--color-background-primary);--sd-color-shadow:rgba(0,0,0,.05);--sd-color-card-border:var(--color-card-border);--sd-color-card-border-hover:var(--color-brand-content);--sd-color-card-background:var(--color-card-background);--sd-color-card-text:var(--color-foreground-primary);--sd-color-card-header:var(--color-card-marginals-background);--sd-color-card-footer:var(--color-card-marginals-background);--sd-color-tabs-label-active:var(--color-brand-content);--sd-color-tabs-label-hover:var(--color-foreground-muted);--sd-color-tabs-label-inactive:var(--color-foreground-muted);--sd-color-tabs-underline-active:var(--color-brand-content);--sd-color-tabs-underline-hover:var(--color-foreground-border);--sd-color-tabs-underline-inactive:var(--color-background-border);--sd-color-tabs-overline:var(--color-background-border);--sd-color-tabs-underline:var(--color-background-border)}.sd-tab-content{box-shadow:0 -2px var(--sd-color-tabs-overline),0 1px var(--sd-color-tabs-underline)}.sd-card{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)}.sd-shadow-sm{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-md{box-shadow:0 .3rem .75rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-lg{box-shadow:0 .6rem 1.5rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-card-hover:hover{transform:none}.sd-cards-carousel{gap:.25rem;padding:.25rem}body{--tabs--label-text:var(--color-foreground-muted);--tabs--label-text--hover:var(--color-foreground-muted);--tabs--label-text--active:var(--color-brand-content);--tabs--label-text--active--hover:var(--color-brand-content);--tabs--label-background:transparent;--tabs--label-background--hover:transparent;--tabs--label-background--active:transparent;--tabs--label-background--active--hover:transparent;--tabs--padding-x:0.25em;--tabs--margin-x:1em;--tabs--border:var(--color-background-border);--tabs--label-border:transparent;--tabs--label-border--hover:var(--color-foreground-muted);--tabs--label-border--active:var(--color-brand-content);--tabs--label-border--active--hover:var(--color-brand-content)}[role=main] .container{max-width:none;padding-left:0;padding-right:0}.shadow.docutils{border:none;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)!important}.sphinx-bs .card{background-color:var(--color-background-secondary);color:var(--color-foreground)} +/*# sourceMappingURL=furo-extensions.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo-extensions.css.map b/_static/styles/furo-extensions.css.map new file mode 100644 index 0000000..c26eac7 --- /dev/null +++ b/_static/styles/furo-extensions.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo-extensions.css","mappings":"AAGA,2BACE,oFACA,4CAKE,6CAHA,YACA,eAEA,CACA,kDACE,yCAEF,8CACE,sCAEJ,8CACE,kDAEJ,2BAGE,uBACA,cAHA,gBACA,UAEA,CAGA,yCACE,mBAEF,gDAEE,gDADA,YACA,CACA,sDACE,gDACF,yDACE,sCAEJ,+CACE,UACA,qDACE,UAGF,mDACE,eAEJ,yEAEE,4DAEA,mHASE,mBAPA,kBAEA,YADA,oBAGA,aADA,gBAIA,CAEA,qIAEE,WADA,UACA,CAEJ,uGACE,aAEF,iUAGE,cAEF,mHACE,aC1EJ,gCACE,mCAEF,0BAEE,mBAUA,8CACA,YAFA,mCAKA,eAZA,cAIA,YADA,YAYA,iCAdA,YAcA,CAEA,gCAEE,8CADA,gCACA,CAEF,gCAGE,6BADA,mCADA,YAEA,CAEF,kCAEE,cADA,oBACA,CACA,wCACE,cAEJ,8BACE,UCzCN,KAEE,6CAA8C,CAC9C,uDAAwD,CACxD,uDAAwD,CAGxD,iCAAsC,CAGtC,+CAAgD,CAChD,uDAAwD,CACxD,uDAAwD,CACxD,oDAAqD,CACrD,6DAA8D,CAC9D,6DAA8D,CAG9D,uDAAwD,CACxD,yDAA0D,CAC1D,4DAA6D,CAC7D,2DAA4D,CAC5D,8DAA+D,CAC/D,iEAAkE,CAClE,uDAAwD,CACxD,wDAAyD,CAG3D,gBACE,qFAGF,SACE,6EAEF,cACE,uFAEF,cACE,uFAEF,cACE,uFAGF,qBACE,eAEF,mBACE,WACA,eChDF,KACE,gDAAiD,CACjD,uDAAwD,CACxD,qDAAsD,CACtD,4DAA6D,CAC7D,oCAAqC,CACrC,2CAA4C,CAC5C,4CAA6C,CAC7C,mDAAoD,CACpD,wBAAyB,CACzB,oBAAqB,CACrB,6CAA8C,CAC9C,gCAAiC,CACjC,yDAA0D,CAC1D,uDAAwD,CACxD,8DAA+D,CCbjE,uBACE,eACA,eACA,gBAGF,iBACE,YACA,+EAGF,iBACE,mDACA","sources":["webpack:///./src/furo/assets/styles/extensions/_readthedocs.sass","webpack:///./src/furo/assets/styles/extensions/_copybutton.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-design.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-inline-tabs.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-panels.sass"],"sourcesContent":["// This file contains the styles used for tweaking how ReadTheDoc's embedded\n// contents would show up inside the theme.\n\n#furo-sidebar-ad-placement\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n .ethical-sidebar\n // Remove the border and box-shadow.\n border: none\n box-shadow: none\n // Manage the background colors.\n background: var(--color-background-secondary)\n &:hover\n background: var(--color-background-hover)\n // Ensure the text is legible.\n a\n color: var(--color-foreground-primary)\n\n .ethical-callout a\n color: var(--color-foreground-secondary) !important\n\n#furo-readthedocs-versions\n position: static\n width: 100%\n background: transparent\n display: block\n\n // Make the background color fit with the theme's aesthetic.\n .rst-versions\n background: rgb(26, 28, 30)\n\n .rst-current-version\n cursor: unset\n background: var(--color-sidebar-item-background)\n &:hover\n background: var(--color-sidebar-item-background)\n .fa-book\n color: var(--color-foreground-primary)\n\n > .rst-other-versions\n padding: 0\n small\n opacity: 1\n\n .injected\n .rst-versions\n position: unset\n\n &:hover,\n &:focus-within\n box-shadow: 0 0 0 1px var(--color-sidebar-background-border)\n\n .rst-current-version\n // Undo the tweaks done in RTD's CSS\n font-size: inherit\n line-height: inherit\n height: auto\n text-align: right\n padding: 12px\n\n // Match the rest of the body\n background: #1a1c1e\n\n .fa-book\n float: left\n color: white\n\n .fa-caret-down\n display: none\n\n .rst-current-version,\n .rst-other-versions,\n .injected\n display: block\n\n > .rst-current-version\n display: none\n",".highlight\n &:hover button.copybtn\n color: var(--color-code-foreground)\n\n button.copybtn\n // Align things correctly\n align-items: center\n\n height: 1.25em\n width: 1.25em\n\n top: 0.625rem // $code-spacing-vertical\n right: 0.5rem\n\n // Make it look better\n color: var(--color-background-item)\n background-color: var(--color-code-background)\n border: none\n\n // Change to cursor to make it obvious that you can click on it\n cursor: pointer\n\n // Transition smoothly, for aesthetics\n transition: color 300ms, opacity 300ms\n\n &:hover\n color: var(--color-brand-content)\n background-color: var(--color-code-background)\n\n &::after\n display: none\n color: var(--color-code-foreground)\n background-color: transparent\n\n &.success\n transition: color 0ms\n color: #22863a\n &::after\n display: block\n\n svg\n padding: 0\n","body\n // Colors\n --sd-color-primary: var(--color-brand-primary)\n --sd-color-primary-highlight: var(--color-brand-content)\n --sd-color-primary-text: var(--color-background-primary)\n\n // Shadows\n --sd-color-shadow: rgba(0, 0, 0, 0.05)\n\n // Cards\n --sd-color-card-border: var(--color-card-border)\n --sd-color-card-border-hover: var(--color-brand-content)\n --sd-color-card-background: var(--color-card-background)\n --sd-color-card-text: var(--color-foreground-primary)\n --sd-color-card-header: var(--color-card-marginals-background)\n --sd-color-card-footer: var(--color-card-marginals-background)\n\n // Tabs\n --sd-color-tabs-label-active: var(--color-brand-content)\n --sd-color-tabs-label-hover: var(--color-foreground-muted)\n --sd-color-tabs-label-inactive: var(--color-foreground-muted)\n --sd-color-tabs-underline-active: var(--color-brand-content)\n --sd-color-tabs-underline-hover: var(--color-foreground-border)\n --sd-color-tabs-underline-inactive: var(--color-background-border)\n --sd-color-tabs-overline: var(--color-background-border)\n --sd-color-tabs-underline: var(--color-background-border)\n\n// Tabs\n.sd-tab-content\n box-shadow: 0 -2px var(--sd-color-tabs-overline), 0 1px var(--sd-color-tabs-underline)\n\n// Shadows\n.sd-card // Have a shadow by default\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n.sd-shadow-sm\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-md\n box-shadow: 0 0.3rem 0.75rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-lg\n box-shadow: 0 0.6rem 1.5rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Cards\n.sd-card-hover:hover // Don't change scale on hover\n transform: none\n\n.sd-cards-carousel // Have a bit of gap in the carousel by default\n gap: 0.25rem\n padding: 0.25rem\n","// This file contains styles to tweak sphinx-inline-tabs to work well with Furo.\n\nbody\n --tabs--label-text: var(--color-foreground-muted)\n --tabs--label-text--hover: var(--color-foreground-muted)\n --tabs--label-text--active: var(--color-brand-content)\n --tabs--label-text--active--hover: var(--color-brand-content)\n --tabs--label-background: transparent\n --tabs--label-background--hover: transparent\n --tabs--label-background--active: transparent\n --tabs--label-background--active--hover: transparent\n --tabs--padding-x: 0.25em\n --tabs--margin-x: 1em\n --tabs--border: var(--color-background-border)\n --tabs--label-border: transparent\n --tabs--label-border--hover: var(--color-foreground-muted)\n --tabs--label-border--active: var(--color-brand-content)\n --tabs--label-border--active--hover: var(--color-brand-content)\n","// This file contains styles to tweak sphinx-panels to work well with Furo.\n\n// sphinx-panels includes Bootstrap 4, which uses .container which can conflict\n// with docutils' `.. container::` directive.\n[role=\"main\"] .container\n max-width: initial\n padding-left: initial\n padding-right: initial\n\n// Make the panels look nicer!\n.shadow.docutils\n border: none\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Make panel colors respond to dark mode\n.sphinx-bs .card\n background-color: var(--color-background-secondary)\n color: var(--color-foreground)\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/_static/styles/furo.css b/_static/styles/furo.css new file mode 100644 index 0000000..05a56b1 --- /dev/null +++ b/_static/styles/furo.css @@ -0,0 +1,2 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}@media print{.content-icon-container,.headerlink,.mobile-header,.related-pages{display:none!important}.highlight{border:.1pt solid var(--color-foreground-border)}a,blockquote,dl,ol,p,pre,table,ul{page-break-inside:avoid}caption,figure,h1,h2,h3,h4,h5,h6,img{page-break-after:avoid;page-break-inside:avoid}dl,ol,ul{page-break-before:avoid}}.visually-hidden{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;background:var(--color-background-primary);border:0!important;color:var(--color-foreground-primary);white-space:nowrap!important}:-moz-focusring{outline:auto}body{--font-stack:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;--font-stack--monospace:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-stack--headings:var(--font-stack);--font-size--normal:100%;--font-size--small:87.5%;--font-size--small--2:81.25%;--font-size--small--3:75%;--font-size--small--4:62.5%;--sidebar-caption-font-size:var(--font-size--small--2);--sidebar-item-font-size:var(--font-size--small);--sidebar-search-input-font-size:var(--font-size--small);--toc-font-size:var(--font-size--small--3);--toc-font-size--mobile:var(--font-size--normal);--toc-title-font-size:var(--font-size--small--4);--admonition-font-size:0.8125rem;--admonition-title-font-size:0.8125rem;--code-font-size:var(--font-size--small--2);--api-font-size:var(--font-size--small);--header-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*4);--header-padding:0.5rem;--sidebar-tree-space-above:1.5rem;--sidebar-caption-space-above:1rem;--sidebar-item-line-height:1rem;--sidebar-item-spacing-vertical:0.5rem;--sidebar-item-spacing-horizontal:1rem;--sidebar-item-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*2);--sidebar-expander-width:var(--sidebar-item-height);--sidebar-search-space-above:0.5rem;--sidebar-search-input-spacing-vertical:0.5rem;--sidebar-search-input-spacing-horizontal:0.5rem;--sidebar-search-input-height:1rem;--sidebar-search-icon-size:var(--sidebar-search-input-height);--toc-title-padding:0.25rem 0;--toc-spacing-vertical:1.5rem;--toc-spacing-horizontal:1.5rem;--toc-item-spacing-vertical:0.4rem;--toc-item-spacing-horizontal:1rem;--icon-search:url('data:image/svg+xml;charset=utf-8,');--icon-pencil:url('data:image/svg+xml;charset=utf-8,');--icon-abstract:url('data:image/svg+xml;charset=utf-8,');--icon-info:url('data:image/svg+xml;charset=utf-8,');--icon-flame:url('data:image/svg+xml;charset=utf-8,');--icon-question:url('data:image/svg+xml;charset=utf-8,');--icon-warning:url('data:image/svg+xml;charset=utf-8,');--icon-failure:url('data:image/svg+xml;charset=utf-8,');--icon-spark:url('data:image/svg+xml;charset=utf-8,');--color-admonition-title--caution:#ff9100;--color-admonition-title-background--caution:rgba(255,145,0,.2);--color-admonition-title--warning:#ff9100;--color-admonition-title-background--warning:rgba(255,145,0,.2);--color-admonition-title--danger:#ff5252;--color-admonition-title-background--danger:rgba(255,82,82,.2);--color-admonition-title--attention:#ff5252;--color-admonition-title-background--attention:rgba(255,82,82,.2);--color-admonition-title--error:#ff5252;--color-admonition-title-background--error:rgba(255,82,82,.2);--color-admonition-title--hint:#00c852;--color-admonition-title-background--hint:rgba(0,200,82,.2);--color-admonition-title--tip:#00c852;--color-admonition-title-background--tip:rgba(0,200,82,.2);--color-admonition-title--important:#00bfa5;--color-admonition-title-background--important:rgba(0,191,165,.2);--color-admonition-title--note:#00b0ff;--color-admonition-title-background--note:rgba(0,176,255,.2);--color-admonition-title--seealso:#448aff;--color-admonition-title-background--seealso:rgba(68,138,255,.2);--color-admonition-title--admonition-todo:grey;--color-admonition-title-background--admonition-todo:hsla(0,0%,50%,.2);--color-admonition-title:#651fff;--color-admonition-title-background:rgba(101,31,255,.2);--icon-admonition-default:var(--icon-abstract);--color-topic-title:#14b8a6;--color-topic-title-background:rgba(20,184,166,.2);--icon-topic-default:var(--icon-pencil);--color-problematic:#b30000;--color-foreground-primary:#000;--color-foreground-secondary:#5a5c63;--color-foreground-muted:#6b6f76;--color-foreground-border:#878787;--color-background-primary:#fff;--color-background-secondary:#f8f9fb;--color-background-hover:#efeff4;--color-background-hover--transparent:#efeff400;--color-background-border:#eeebee;--color-background-item:#ccc;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#0a4bff;--color-brand-content:#2757dd;--color-brand-visited:#872ee0;--color-api-background:var(--color-background-hover--transparent);--color-api-background-hover:var(--color-background-hover);--color-api-overall:var(--color-foreground-secondary);--color-api-name:var(--color-problematic);--color-api-pre-name:var(--color-problematic);--color-api-paren:var(--color-foreground-secondary);--color-api-keyword:var(--color-foreground-primary);--color-api-added:#21632c;--color-api-added-border:#38a84d;--color-api-changed:#046172;--color-api-changed-border:#06a1bc;--color-api-deprecated:#605706;--color-api-deprecated-border:#f0d90f;--color-api-removed:#b30000;--color-api-removed-border:#ff5c5c;--color-highlight-on-target:#ffc;--color-inline-code-background:var(--color-background-secondary);--color-highlighted-background:#def;--color-highlighted-text:var(--color-foreground-primary);--color-guilabel-background:#ddeeff80;--color-guilabel-border:#bedaf580;--color-guilabel-text:var(--color-foreground-primary);--color-admonition-background:transparent;--color-table-header-background:var(--color-background-secondary);--color-table-border:var(--color-background-border);--color-card-border:var(--color-background-secondary);--color-card-background:transparent;--color-card-marginals-background:var(--color-background-secondary);--color-header-background:var(--color-background-primary);--color-header-border:var(--color-background-border);--color-header-text:var(--color-foreground-primary);--color-sidebar-background:var(--color-background-secondary);--color-sidebar-background-border:var(--color-background-border);--color-sidebar-brand-text:var(--color-foreground-primary);--color-sidebar-caption-text:var(--color-foreground-muted);--color-sidebar-link-text:var(--color-foreground-secondary);--color-sidebar-link-text--top-level:var(--color-brand-primary);--color-sidebar-item-background:var(--color-sidebar-background);--color-sidebar-item-background--current:var( --color-sidebar-item-background );--color-sidebar-item-background--hover:linear-gradient(90deg,var(--color-background-hover--transparent) 0%,var(--color-background-hover) var(--sidebar-item-spacing-horizontal),var(--color-background-hover) 100%);--color-sidebar-item-expander-background:transparent;--color-sidebar-item-expander-background--hover:var( --color-background-hover );--color-sidebar-search-text:var(--color-foreground-primary);--color-sidebar-search-background:var(--color-background-secondary);--color-sidebar-search-background--focus:var(--color-background-primary);--color-sidebar-search-border:var(--color-background-border);--color-sidebar-search-icon:var(--color-foreground-muted);--color-toc-background:var(--color-background-primary);--color-toc-title-text:var(--color-foreground-muted);--color-toc-item-text:var(--color-foreground-secondary);--color-toc-item-text--hover:var(--color-foreground-primary);--color-toc-item-text--active:var(--color-brand-primary);--color-content-foreground:var(--color-foreground-primary);--color-content-background:transparent;--color-link:var(--color-brand-content);--color-link-underline:var(--color-background-border);--color-link--hover:var(--color-brand-content);--color-link-underline--hover:var(--color-foreground-border);--color-link--visited:var(--color-brand-visited);--color-link-underline--visited:var(--color-background-border);--color-link--visited--hover:var(--color-brand-visited);--color-link-underline--visited--hover:var(--color-foreground-border)}.only-light{display:block!important}html body .only-dark{display:none!important}@media not print{body[data-theme=dark]{--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body[data-theme=dark] .only-light{display:none!important}body[data-theme=dark] .only-dark{display:block!important}@media(prefers-color-scheme:dark){body:not([data-theme=light]){--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body:not([data-theme=light]) .only-light{display:none!important}body:not([data-theme=light]) .only-dark{display:block!important}}}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:block}@media(prefers-color-scheme:dark){body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-dark{display:block}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:none}}body[data-theme=dark] .theme-toggle svg.theme-icon-when-dark,body[data-theme=light] .theme-toggle svg.theme-icon-when-light{display:block}body{font-family:var(--font-stack)}code,kbd,pre,samp{font-family:var(--font-stack--monospace)}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article{line-height:1.5}h1,h2,h3,h4,h5,h6{border-radius:.5rem;font-family:var(--font-stack--headings);font-weight:700;line-height:1.25;margin:.5rem -.5rem;padding-left:.5rem;padding-right:.5rem}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p{margin-top:0}h1{font-size:2.5em;margin-bottom:1rem}h1,h2{margin-top:1.75rem}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.25em}h5{font-size:1.125em}h6{font-size:1em}small{font-size:80%;opacity:75%}p{margin-bottom:.75rem;margin-top:.5rem}hr.docutils{background-color:var(--color-background-border);border:0;height:1px;margin:2rem 0;padding:0}.centered{text-align:center}a{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}a:visited{color:var(--color-link--visited);text-decoration-color:var(--color-link-underline--visited)}a:visited:hover{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}a:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link{color:inherit}a.muted-link:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link:hover:visited{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}html{overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth}.sidebar-scroll,.toc-scroll,article[role=main] *{scrollbar-color:var(--color-foreground-border) transparent;scrollbar-width:thin}.sidebar-scroll::-webkit-scrollbar,.toc-scroll::-webkit-scrollbar,article[role=main] ::-webkit-scrollbar{height:.25rem;width:.25rem}.sidebar-scroll::-webkit-scrollbar-thumb,.toc-scroll::-webkit-scrollbar-thumb,article[role=main] ::-webkit-scrollbar-thumb{background-color:var(--color-foreground-border);border-radius:.125rem}body,html{height:100%}.skip-to-content,body,html{background:var(--color-background-primary);color:var(--color-foreground-primary)}.skip-to-content{border-radius:1rem;left:.25rem;padding:1rem;position:fixed;top:.25rem;transform:translateY(-200%);transition:transform .3s ease-in-out;z-index:40}.skip-to-content:focus-within{transform:translateY(0)}article{background:var(--color-content-background);color:var(--color-content-foreground);overflow-wrap:break-word}.page{display:flex;min-height:100%}.mobile-header{background-color:var(--color-header-background);border-bottom:1px solid var(--color-header-border);color:var(--color-header-text);display:none;height:var(--header-height);width:100%;z-index:10}.mobile-header.scrolled{border-bottom:none;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.mobile-header .header-center a{color:var(--color-header-text);text-decoration:none}.main{display:flex;flex:1}.sidebar-drawer{background:var(--color-sidebar-background);border-right:1px solid var(--color-sidebar-background-border);box-sizing:border-box;display:flex;justify-content:flex-end;min-width:15em;width:calc(50% - 26em)}.sidebar-container,.toc-drawer{box-sizing:border-box;width:15em}.toc-drawer{background:var(--color-toc-background);padding-right:1rem}.sidebar-sticky,.toc-sticky{display:flex;flex-direction:column;height:min(100%,100vh);height:100vh;position:sticky;top:0}.sidebar-scroll,.toc-scroll{flex-grow:1;flex-shrink:1;overflow:auto;scroll-behavior:smooth}.content{display:flex;flex-direction:column;justify-content:space-between;padding:0 3em;width:46em}.icon{display:inline-block;height:1rem;width:1rem}.icon svg{height:100%;width:100%}.announcement{align-items:center;background-color:var(--color-announcement-background);color:var(--color-announcement-text);display:flex;height:var(--header-height);overflow-x:auto}.announcement+.page{min-height:calc(100% - var(--header-height))}.announcement-content{box-sizing:border-box;min-width:100%;padding:.5rem;text-align:center;white-space:nowrap}.announcement-content a{color:var(--color-announcement-text);text-decoration-color:var(--color-announcement-text)}.announcement-content a:hover{color:var(--color-announcement-text);text-decoration-color:var(--color-link--hover)}.no-js .theme-toggle-container{display:none}.theme-toggle-container{display:flex}.theme-toggle{background:transparent;border:none;cursor:pointer;display:flex;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1.25rem;width:1.25rem}.theme-toggle-header{align-items:center;display:flex;justify-content:center}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1.5rem;width:1.5rem}.nav-overlay-icon,.toc-header-icon{align-items:center;justify-content:center}.toc-content-icon{height:1.5rem;width:1.5rem}.content-icon-container{display:flex;float:right;gap:.5rem;margin-bottom:1rem;margin-left:1rem;margin-top:1.5rem}.content-icon-container .edit-this-page svg,.content-icon-container .view-this-page svg{color:inherit;height:1.25rem;width:1.25rem}.sidebar-toggle{display:none;position:absolute}.sidebar-toggle[name=__toc]{left:20px}.sidebar-toggle:checked{left:40px}.overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms,height 0ms,opacity .25s ease-out;width:0}.sidebar-overlay{z-index:20}.toc-overlay{z-index:40}.sidebar-drawer{transition:left .25s ease-in-out;z-index:30}.toc-drawer{transition:right .25s ease-in-out;z-index:50}#__navigation:checked~.sidebar-overlay{height:100%;opacity:1;width:100%}#__navigation:checked~.page .sidebar-drawer{left:0;top:0}#__toc:checked~.toc-overlay{height:100%;opacity:1;width:100%}#__toc:checked~.page .toc-drawer{right:0;top:0}.back-to-top{background:var(--color-background-primary);border-radius:1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 1px 0 hsla(220,9%,46%,.502);display:none;font-size:.8125rem;left:0;margin-left:50%;padding:.5rem .75rem .5rem .5rem;position:fixed;text-decoration:none;top:1rem;transform:translateX(-50%);z-index:10}.back-to-top svg{height:1rem;width:1rem;fill:currentColor;display:inline-block}.back-to-top span{margin-left:.25rem}.show-back-to-top .back-to-top{align-items:center;display:flex}@media(min-width:97em){html{font-size:110%}}@media(max-width:82em){.toc-content-icon{display:flex}.toc-drawer{border-left:1px solid var(--color-background-muted);height:100vh;position:fixed;right:-15em;top:0}.toc-tree{border-left:none;font-size:var(--toc-font-size--mobile)}.sidebar-drawer{width:calc(50% - 18.5em)}}@media(max-width:67em){.content{margin-left:auto;margin-right:auto;padding:0 1em}}@media(max-width:63em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.theme-toggle-header,.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.mobile-header{align-items:center;display:flex;justify-content:space-between;position:sticky;top:0}.mobile-header .header-left,.mobile-header .header-right{display:flex;height:var(--header-height);padding:0 var(--header-padding)}.mobile-header .header-left label,.mobile-header .header-right label{height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.nav-overlay-icon .icon,.theme-toggle svg{height:1.5rem;width:1.5rem}:target{scroll-margin-top:calc(var(--header-height) + 2.5rem)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}}@media(max-width:48em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){article[role=main] aside.sidebar{float:none;margin:1rem 0;width:100%}}.admonition,.topic{background:var(--color-admonition-background);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);font-size:var(--admonition-font-size);margin:1rem auto;overflow:hidden;padding:0 .5rem .5rem;page-break-inside:avoid}.admonition>:nth-child(2),.topic>:nth-child(2){margin-top:0}.admonition>:last-child,.topic>:last-child{margin-bottom:0}.admonition p.admonition-title,p.topic-title{font-size:var(--admonition-title-font-size);font-weight:500;line-height:1.3;margin:0 -.5rem .5rem;padding:.4rem .5rem .4rem 2rem;position:relative}.admonition p.admonition-title:before,p.topic-title:before{content:"";height:1rem;left:.5rem;position:absolute;width:1rem}p.admonition-title{background-color:var(--color-admonition-title-background)}p.admonition-title:before{background-color:var(--color-admonition-title);-webkit-mask-image:var(--icon-admonition-default);mask-image:var(--icon-admonition-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}p.topic-title{background-color:var(--color-topic-title-background)}p.topic-title:before{background-color:var(--color-topic-title);-webkit-mask-image:var(--icon-topic-default);mask-image:var(--icon-topic-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.admonition{border-left:.2rem solid var(--color-admonition-title)}.admonition.caution{border-left-color:var(--color-admonition-title--caution)}.admonition.caution>.admonition-title{background-color:var(--color-admonition-title-background--caution)}.admonition.caution>.admonition-title:before{background-color:var(--color-admonition-title--caution);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.warning{border-left-color:var(--color-admonition-title--warning)}.admonition.warning>.admonition-title{background-color:var(--color-admonition-title-background--warning)}.admonition.warning>.admonition-title:before{background-color:var(--color-admonition-title--warning);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.danger{border-left-color:var(--color-admonition-title--danger)}.admonition.danger>.admonition-title{background-color:var(--color-admonition-title-background--danger)}.admonition.danger>.admonition-title:before{background-color:var(--color-admonition-title--danger);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.attention{border-left-color:var(--color-admonition-title--attention)}.admonition.attention>.admonition-title{background-color:var(--color-admonition-title-background--attention)}.admonition.attention>.admonition-title:before{background-color:var(--color-admonition-title--attention);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.error{border-left-color:var(--color-admonition-title--error)}.admonition.error>.admonition-title{background-color:var(--color-admonition-title-background--error)}.admonition.error>.admonition-title:before{background-color:var(--color-admonition-title--error);-webkit-mask-image:var(--icon-failure);mask-image:var(--icon-failure)}.admonition.hint{border-left-color:var(--color-admonition-title--hint)}.admonition.hint>.admonition-title{background-color:var(--color-admonition-title-background--hint)}.admonition.hint>.admonition-title:before{background-color:var(--color-admonition-title--hint);-webkit-mask-image:var(--icon-question);mask-image:var(--icon-question)}.admonition.tip{border-left-color:var(--color-admonition-title--tip)}.admonition.tip>.admonition-title{background-color:var(--color-admonition-title-background--tip)}.admonition.tip>.admonition-title:before{background-color:var(--color-admonition-title--tip);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.important{border-left-color:var(--color-admonition-title--important)}.admonition.important>.admonition-title{background-color:var(--color-admonition-title-background--important)}.admonition.important>.admonition-title:before{background-color:var(--color-admonition-title--important);-webkit-mask-image:var(--icon-flame);mask-image:var(--icon-flame)}.admonition.note{border-left-color:var(--color-admonition-title--note)}.admonition.note>.admonition-title{background-color:var(--color-admonition-title-background--note)}.admonition.note>.admonition-title:before{background-color:var(--color-admonition-title--note);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition.seealso{border-left-color:var(--color-admonition-title--seealso)}.admonition.seealso>.admonition-title{background-color:var(--color-admonition-title-background--seealso)}.admonition.seealso>.admonition-title:before{background-color:var(--color-admonition-title--seealso);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.admonition-todo{border-left-color:var(--color-admonition-title--admonition-todo)}.admonition.admonition-todo>.admonition-title{background-color:var(--color-admonition-title-background--admonition-todo)}.admonition.admonition-todo>.admonition-title:before{background-color:var(--color-admonition-title--admonition-todo);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition-todo>.admonition-title{text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:first-child{margin-top:.125rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:last-child{margin-bottom:.75rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list>dt{font-size:var(--font-size--small);text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd:empty{margin-bottom:.5rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul{margin-left:-1.2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p:nth-child(2){margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p+p:last-child:empty{margin-bottom:0;margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{color:var(--color-api-overall)}.sig:not(.sig-inline){background:var(--color-api-background);border-radius:.25rem;font-family:var(--font-stack--monospace);font-size:var(--api-font-size);font-weight:700;margin-left:-.25rem;margin-right:-.25rem;padding:.25rem .5rem .25rem 3em;text-indent:-2.5em;transition:background .1s ease-out}.sig:not(.sig-inline):hover{background:var(--color-api-background-hover)}.sig:not(.sig-inline) a.reference .viewcode-link{font-weight:400;width:4.25rem}em.property{font-style:normal}em.property:first-child{color:var(--color-api-keyword)}.sig-name{color:var(--color-api-name)}.sig-prename{color:var(--color-api-pre-name);font-weight:400}.sig-paren{color:var(--color-api-paren)}.sig-param{font-style:normal}div.deprecated,div.versionadded,div.versionchanged,div.versionremoved{border-left:.1875rem solid;border-radius:.125rem;padding-left:.75rem}div.deprecated p,div.versionadded p,div.versionchanged p,div.versionremoved p{margin-bottom:.125rem;margin-top:.125rem}div.versionadded{border-color:var(--color-api-added-border)}div.versionadded .versionmodified{color:var(--color-api-added)}div.versionchanged{border-color:var(--color-api-changed-border)}div.versionchanged .versionmodified{color:var(--color-api-changed)}div.deprecated{border-color:var(--color-api-deprecated-border)}div.deprecated .versionmodified{color:var(--color-api-deprecated)}div.versionremoved{border-color:var(--color-api-removed-border)}div.versionremoved .versionmodified{color:var(--color-api-removed)}.viewcode-back,.viewcode-link{float:right;text-align:right}.line-block{margin-bottom:.75rem;margin-top:.5rem}.line-block .line-block{margin-bottom:0;margin-top:0;padding-left:1rem}.code-block-caption,article p.caption,table>caption{font-size:var(--font-size--small);text-align:center}.toctree-wrapper.compound .caption,.toctree-wrapper.compound :not(.caption)>.caption-text{font-size:var(--font-size--small);margin-bottom:0;text-align:initial;text-transform:uppercase}.toctree-wrapper.compound>ul{margin-bottom:0;margin-top:0}.sig-inline,code.literal{background:var(--color-inline-code-background);border-radius:.2em;font-size:var(--font-size--small--2);padding:.1em .2em}pre.literal-block .sig-inline,pre.literal-block code.literal{font-size:inherit;padding:0}p .sig-inline,p code.literal{border:1px solid var(--color-background-border)}.sig-inline{font-family:var(--font-stack--monospace)}div[class*=" highlight-"],div[class^=highlight-]{display:flex;margin:1em 0}div[class*=" highlight-"] .table-wrapper,div[class^=highlight-] .table-wrapper,pre{margin:0;padding:0}pre{overflow:auto}article[role=main] .highlight pre{line-height:1.5}.highlight pre,pre.literal-block{font-size:var(--code-font-size);padding:.625rem .875rem}pre.literal-block{background-color:var(--color-code-background);border-radius:.2rem;color:var(--color-code-foreground);margin-bottom:1rem;margin-top:1rem}.highlight{border-radius:.2rem;width:100%}.highlight .gp,.highlight span.linenos{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .hll{display:block;margin-left:-.875rem;margin-right:-.875rem;padding-left:.875rem;padding-right:.875rem}.code-block-caption{background-color:var(--color-code-background);border-bottom:1px solid;border-radius:.25rem;border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:var(--color-background-border);color:var(--color-code-foreground);display:flex;font-weight:300;padding:.625rem .875rem}.code-block-caption+div[class]{margin-top:0}.code-block-caption+div[class] pre{border-top-left-radius:0;border-top-right-radius:0}.highlighttable{display:block;width:100%}.highlighttable tbody{display:block}.highlighttable tr{display:flex}.highlighttable td.linenos{background-color:var(--color-code-background);border-bottom-left-radius:.2rem;border-top-left-radius:.2rem;color:var(--color-code-foreground);padding:.625rem 0 .625rem .875rem}.highlighttable .linenodiv{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;font-size:var(--code-font-size);padding-right:.875rem}.highlighttable td.code{display:block;flex:1;overflow:hidden;padding:0}.highlighttable td.code .highlight{border-bottom-left-radius:0;border-top-left-radius:0}.highlight span.linenos{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;display:inline-block;margin-right:.875rem;padding-left:0;padding-right:.875rem}.footnote-reference{font-size:var(--font-size--small--4);vertical-align:super}dl.footnote.brackets{color:var(--color-foreground-secondary);display:grid;font-size:var(--font-size--small);grid-template-columns:max-content auto}dl.footnote.brackets dt{margin:0}dl.footnote.brackets dt>.fn-backref{margin-left:.25rem}dl.footnote.brackets dt:after{content:":"}dl.footnote.brackets dt .brackets:before{content:"["}dl.footnote.brackets dt .brackets:after{content:"]"}dl.footnote.brackets dd{margin:0;padding:0 1rem}aside.footnote{color:var(--color-foreground-secondary);font-size:var(--font-size--small)}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>:not(span),div.citation>p{margin-left:2rem}img{box-sizing:border-box;height:auto;max-width:100%}article .figure,article figure{border-radius:.2rem;margin:0}article .figure :last-child,article figure :last-child{margin-bottom:0}article .align-left{clear:left;float:left;margin:0 1rem 1rem}article .align-right{clear:right;float:right;margin:0 1rem 1rem}article .align-center,article .align-default{display:block;margin-left:auto;margin-right:auto;text-align:center}article table.align-default{display:table;text-align:initial}.domainindex-jumpbox,.genindex-jumpbox{border-bottom:1px solid var(--color-background-border);border-top:1px solid var(--color-background-border);padding:.25rem}.domainindex-section h2,.genindex-section h2{margin-bottom:.5rem;margin-top:.75rem}.domainindex-section ul,.genindex-section ul{margin-bottom:0;margin-top:0}ol,ul{margin-bottom:1rem;margin-top:1rem;padding-left:1.2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}ol li>p:last-child,ul li>p:last-child{margin-top:.25rem}ol li>ol,ol li>ul,ul li>ol,ul li>ul{margin-bottom:.5rem;margin-top:.5rem}ol.arabic{list-style:decimal}ol.loweralpha{list-style:lower-alpha}ol.upperalpha{list-style:upper-alpha}ol.lowerroman{list-style:lower-roman}ol.upperroman{list-style:upper-roman}.simple li>ol,.simple li>ul,.toctree-wrapper li>ol,.toctree-wrapper li>ul{margin-bottom:0;margin-top:0}.field-list dt,.option-list dt,dl.footnote dt,dl.glossary dt,dl.simple dt,dl:not([class]) dt{font-weight:500;margin-top:.25rem}.field-list dt+dt,.option-list dt+dt,dl.footnote dt+dt,dl.glossary dt+dt,dl.simple dt+dt,dl:not([class]) dt+dt{margin-top:0}.field-list dt .classifier:before,.option-list dt .classifier:before,dl.footnote dt .classifier:before,dl.glossary dt .classifier:before,dl.simple dt .classifier:before,dl:not([class]) dt .classifier:before{content:":";margin-left:.2rem;margin-right:.2rem}.field-list dd ul,.field-list dd>p:first-child,.option-list dd ul,.option-list dd>p:first-child,dl.footnote dd ul,dl.footnote dd>p:first-child,dl.glossary dd ul,dl.glossary dd>p:first-child,dl.simple dd ul,dl.simple dd>p:first-child,dl:not([class]) dd ul,dl:not([class]) dd>p:first-child{margin-top:.125rem}.field-list dd ul,.option-list dd ul,dl.footnote dd ul,dl.glossary dd ul,dl.simple dd ul,dl:not([class]) dd ul{margin-bottom:.125rem}.math-wrapper{overflow-x:auto;width:100%}div.math{position:relative;text-align:center}div.math .headerlink,div.math:focus .headerlink{display:none}div.math:hover .headerlink{display:inline-block}div.math span.eqno{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);z-index:1}abbr[title]{cursor:help}.problematic{color:var(--color-problematic)}kbd:not(.compound){background-color:var(--color-background-secondary);border:1px solid var(--color-foreground-border);border-radius:.2rem;box-shadow:0 .0625rem 0 rgba(0,0,0,.2),inset 0 0 0 .125rem var(--color-background-primary);color:var(--color-foreground-primary);display:inline-block;font-size:var(--font-size--small--3);margin:0 .2rem;padding:0 .2rem;vertical-align:text-bottom}blockquote{background:var(--color-background-secondary);border-left:4px solid var(--color-background-border);margin-left:0;margin-right:0;padding:.5rem 1rem}blockquote .attribution{font-weight:600;text-align:right}blockquote.highlights,blockquote.pull-quote{font-size:1.25em}blockquote.epigraph,blockquote.pull-quote{border-left-width:0;border-radius:.5rem}blockquote.highlights{background:transparent;border-left-width:0}p .reference img{vertical-align:middle}p.rubric{font-size:1.125em;font-weight:700;line-height:1.25}dd p.rubric{font-size:var(--font-size--small);font-weight:inherit;line-height:inherit;text-transform:uppercase}article .sidebar{background-color:var(--color-background-secondary);border:1px solid var(--color-background-border);border-radius:.2rem;clear:right;float:right;margin-left:1rem;margin-right:0;width:30%}article .sidebar>*{padding-left:1rem;padding-right:1rem}article .sidebar>ol,article .sidebar>ul{padding-left:2.2rem}article .sidebar .sidebar-title{border-bottom:1px solid var(--color-background-border);font-weight:500;margin:0;padding:.5rem 1rem}[role=main] .table-wrapper.container{margin-bottom:.5rem;margin-top:1rem;overflow-x:auto;padding:.2rem .2rem .75rem;width:100%}table.docutils{border-collapse:collapse;border-radius:.2rem;border-spacing:0;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)}table.docutils th{background:var(--color-table-header-background)}table.docutils td,table.docutils th{border-bottom:1px solid var(--color-table-border);border-left:1px solid var(--color-table-border);border-right:1px solid var(--color-table-border);padding:0 .25rem}table.docutils td p,table.docutils th p{margin:.25rem}table.docutils td:first-child,table.docutils th:first-child{border-left:none}table.docutils td:last-child,table.docutils th:last-child{border-right:none}table.docutils td.text-left,table.docutils th.text-left{text-align:left}table.docutils td.text-right,table.docutils th.text-right{text-align:right}table.docutils td.text-center,table.docutils th.text-center{text-align:center}:target{scroll-margin-top:2.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(2.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(2.8rem + var(--header-height))}}.headerlink{font-weight:100;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-block-caption>.headerlink,dl dt>.headerlink,figcaption p>.headerlink,h1>.headerlink,h2>.headerlink,h3>.headerlink,h4>.headerlink,h5>.headerlink,h6>.headerlink,p.caption>.headerlink,table>caption>.headerlink{margin-left:.5rem;visibility:hidden}.code-block-caption:hover>.headerlink,dl dt:hover>.headerlink,figcaption p:hover>.headerlink,h1:hover>.headerlink,h2:hover>.headerlink,h3:hover>.headerlink,h4:hover>.headerlink,h5:hover>.headerlink,h6:hover>.headerlink,p.caption:hover>.headerlink,table>caption:hover>.headerlink{visibility:visible}.code-block-caption>.toc-backref,dl dt>.toc-backref,figcaption p>.toc-backref,h1>.toc-backref,h2>.toc-backref,h3>.toc-backref,h4>.toc-backref,h5>.toc-backref,h6>.toc-backref,p.caption>.toc-backref,table>caption>.toc-backref{color:inherit;text-decoration-line:none}figure:hover>figcaption>p>.headerlink,table:hover>caption>.headerlink{visibility:visible}:target>h1:first-of-type,:target>h2:first-of-type,:target>h3:first-of-type,:target>h4:first-of-type,:target>h5:first-of-type,:target>h6:first-of-type,span:target~h1:first-of-type,span:target~h2:first-of-type,span:target~h3:first-of-type,span:target~h4:first-of-type,span:target~h5:first-of-type,span:target~h6:first-of-type{background-color:var(--color-highlight-on-target)}:target>h1:first-of-type code.literal,:target>h2:first-of-type code.literal,:target>h3:first-of-type code.literal,:target>h4:first-of-type code.literal,:target>h5:first-of-type code.literal,:target>h6:first-of-type code.literal,span:target~h1:first-of-type code.literal,span:target~h2:first-of-type code.literal,span:target~h3:first-of-type code.literal,span:target~h4:first-of-type code.literal,span:target~h5:first-of-type code.literal,span:target~h6:first-of-type code.literal{background-color:transparent}.literal-block-wrapper:target .code-block-caption,.this-will-duplicate-information-and-it-is-still-useful-here li :target,figure:target,table:target>caption{background-color:var(--color-highlight-on-target)}dt:target{background-color:var(--color-highlight-on-target)!important}.footnote-reference:target,.footnote>dt:target+dd{background-color:var(--color-highlight-on-target)}.guilabel{background-color:var(--color-guilabel-background);border:1px solid var(--color-guilabel-border);border-radius:.5em;color:var(--color-guilabel-text);font-size:.9em;padding:0 .3em}footer{display:flex;flex-direction:column;font-size:var(--font-size--small);margin-top:2rem}.bottom-of-page{align-items:center;border-top:1px solid var(--color-background-border);color:var(--color-foreground-secondary);display:flex;justify-content:space-between;line-height:1.5;margin-top:1rem;padding-bottom:1rem;padding-top:1rem}@media(max-width:46em){.bottom-of-page{flex-direction:column-reverse;gap:.25rem;text-align:center}}.bottom-of-page .left-details{font-size:var(--font-size--small)}.bottom-of-page .right-details{display:flex;flex-direction:column;gap:.25rem;text-align:right}.bottom-of-page .icons{display:flex;font-size:1rem;gap:.25rem;justify-content:flex-end}.bottom-of-page .icons a{text-decoration:none}.bottom-of-page .icons img,.bottom-of-page .icons svg{font-size:1.125rem;height:1em;width:1em}.related-pages a{align-items:center;display:flex;text-decoration:none}.related-pages a:hover .page-info .title{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}.related-pages a svg.furo-related-icon,.related-pages a svg.furo-related-icon>use{color:var(--color-foreground-border);flex-shrink:0;height:.75rem;margin:0 .5rem;width:.75rem}.related-pages a.next-page{clear:right;float:right;max-width:50%;text-align:right}.related-pages a.prev-page{clear:left;float:left;max-width:50%}.related-pages a.prev-page svg{transform:rotate(180deg)}.page-info{display:flex;flex-direction:column;overflow-wrap:anywhere}.next-page .page-info{align-items:flex-end}.page-info .context{align-items:center;color:var(--color-foreground-muted);display:flex;font-size:var(--font-size--small);padding-bottom:.1rem;text-decoration:none}ul.search{list-style:none;padding-left:0}ul.search li{border-bottom:1px solid var(--color-background-border);padding:1rem 0}[role=main] .highlighted{background-color:var(--color-highlighted-background);color:var(--color-highlighted-text)}.sidebar-brand{display:flex;flex-direction:column;flex-shrink:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none}.sidebar-brand-text{color:var(--color-sidebar-brand-text);font-size:1.5rem;overflow-wrap:break-word}.sidebar-brand-text,.sidebar-logo-container{margin:var(--sidebar-item-spacing-vertical) 0}.sidebar-logo{display:block;margin:0 auto;max-width:100%}.sidebar-search-container{align-items:center;background:var(--color-sidebar-search-background);display:flex;margin-top:var(--sidebar-search-space-above);position:relative}.sidebar-search-container:focus-within,.sidebar-search-container:hover{background:var(--color-sidebar-search-background--focus)}.sidebar-search-container:before{background-color:var(--color-sidebar-search-icon);content:"";height:var(--sidebar-search-icon-size);left:var(--sidebar-item-spacing-horizontal);-webkit-mask-image:var(--icon-search);mask-image:var(--icon-search);position:absolute;width:var(--sidebar-search-icon-size)}.sidebar-search{background:transparent;border:none;border-bottom:1px solid var(--color-sidebar-search-border);border-top:1px solid var(--color-sidebar-search-border);box-sizing:border-box;color:var(--color-sidebar-search-foreground);padding:var(--sidebar-search-input-spacing-vertical) var(--sidebar-search-input-spacing-horizontal) var(--sidebar-search-input-spacing-vertical) calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size));width:100%;z-index:10}.sidebar-search:focus{outline:none}.sidebar-search::-moz-placeholder{font-size:var(--sidebar-search-input-font-size)}.sidebar-search::placeholder{font-size:var(--sidebar-search-input-font-size)}#searchbox .highlight-link{margin:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0;text-align:center}#searchbox .highlight-link a{color:var(--color-sidebar-search-icon);font-size:var(--font-size--small--2)}.sidebar-tree{font-size:var(--sidebar-item-font-size);margin-bottom:var(--sidebar-item-spacing-vertical);margin-top:var(--sidebar-tree-space-above)}.sidebar-tree ul{display:flex;flex-direction:column;list-style:none;margin-bottom:0;margin-top:0;padding:0}.sidebar-tree li{margin:0;position:relative}.sidebar-tree li>ul{margin-left:var(--sidebar-item-spacing-horizontal)}.sidebar-tree .icon,.sidebar-tree .reference{color:var(--color-sidebar-link-text)}.sidebar-tree .reference{box-sizing:border-box;display:inline-block;height:100%;line-height:var(--sidebar-item-line-height);overflow-wrap:anywhere;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none;width:100%}.sidebar-tree .reference:hover{background:var(--color-sidebar-item-background--hover);color:var(--color-sidebar-link-text)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23607D8B' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' viewBox='0 0 24 24'%3E%3Cpath stroke='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M11 7H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-5M10 14 20 4M15 4h5v5'/%3E%3C/svg%3E");margin:0 .25rem;vertical-align:middle}.sidebar-tree .current-page>.reference{font-weight:700}.sidebar-tree label{align-items:center;cursor:pointer;display:flex;height:var(--sidebar-item-height);justify-content:center;position:absolute;right:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--sidebar-expander-width)}.sidebar-tree .caption,.sidebar-tree :not(.caption)>.caption-text{color:var(--color-sidebar-caption-text);font-size:var(--sidebar-caption-font-size);font-weight:700;margin:var(--sidebar-caption-space-above) 0 0 0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-transform:uppercase}.sidebar-tree li.has-children>.reference{padding-right:var(--sidebar-expander-width)}.sidebar-tree .toctree-l1>.reference,.sidebar-tree .toctree-l1>label .icon{color:var(--color-sidebar-link-text--top-level)}.sidebar-tree label{background:var(--color-sidebar-item-expander-background)}.sidebar-tree label:hover{background:var(--color-sidebar-item-expander-background--hover)}.sidebar-tree .current>.reference{background:var(--color-sidebar-item-background--current)}.sidebar-tree .current>.reference:hover{background:var(--color-sidebar-item-background--hover)}.toctree-checkbox{display:none;position:absolute}.toctree-checkbox~ul{display:none}.toctree-checkbox~label .icon svg{transform:rotate(90deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label .icon svg{transform:rotate(-90deg)}.toc-title-container{padding:var(--toc-title-padding);padding-top:var(--toc-spacing-vertical)}.toc-title{color:var(--color-toc-title-text);font-size:var(--toc-title-font-size);padding-left:var(--toc-spacing-horizontal);text-transform:uppercase}.no-toc{display:none}.toc-tree-container{padding-bottom:var(--toc-spacing-vertical)}.toc-tree{border-left:1px solid var(--color-background-border);font-size:var(--toc-font-size);line-height:1.3;padding-left:calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))}.toc-tree>ul>li:first-child{padding-top:0}.toc-tree>ul>li:first-child>ul{padding-left:0}.toc-tree>ul>li:first-child>a{display:none}.toc-tree ul{list-style-type:none;margin-bottom:0;margin-top:0;padding-left:var(--toc-item-spacing-horizontal)}.toc-tree li{padding-top:var(--toc-item-spacing-vertical)}.toc-tree li.scroll-current>.reference{color:var(--color-toc-item-text--active);font-weight:700}.toc-tree a.reference{color:var(--color-toc-item-text);overflow-wrap:anywhere;text-decoration:none}.toc-scroll{max-height:100vh;overflow-y:scroll}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here){background:rgba(255,0,0,.25);color:var(--color-problematic)}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here):before{content:"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling. Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch."}.text-align\:left>p{text-align:left}.text-align\:center>p{text-align:center}.text-align\:right>p{text-align:right} +/*# sourceMappingURL=furo.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo.css.map b/_static/styles/furo.css.map new file mode 100644 index 0000000..3ecc371 --- /dev/null +++ b/_static/styles/furo.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo.css","mappings":"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sCAIA,aADF,WACE,CAKF,SACE,CAHJ,kBAEE,CAJE,gBAEJ,CAHI,iBAMA,yFAKA,aACA,eACA,cElbJ,iBAEE,aADA,iBACA,6BAEA,kCAEA,SACA,UAIA,gCACA,CALA,SAEA,SAEA,CAJA,0EAEA,CAFA,OAKA,CAGA,mDACE,iBAGF,gCACE,CADF,UACE,aAEJ,iCAEE,CAFF,UAEE,wCAEA,WACA,WADA,UACA,CACA,4CAGA,MACA,CADA,KACA,wCACA,UAGA,CAJA,UAIA,6DAUA,0CACE,CAFF,mBAEE,wEACA,CAVA,YACA,CAMF,mBAJE,OAOA,gBAJJ,gCACE,CANE,cACA,CAHA,oBACA,CAGA,QAGJ,CAII,0BACA,CADA,UACA,wCAEJ,kBACE,0DACA,gCACE,kBACA,CADA,YACA,oEACA,2CAMF,mDAII,CALN,YACE,CANE,cAKJ,CACE,iBAII,kEACA,yCACE,kDACA,yDACE,+CACA,uBANN,CAMM,+BANN,uCACE,qDACA,4BAEE,mBADA,0CACA,CADA,qBACA,0DACE,wCACA,sGALJ,oCACA,sBACE,kBAFF,UAEE,2CACA,wFACE,cACA,kEANN,uBACE,iDACA,CADA,UACA,0DACE,wDAEE,iEACA,qEANN,sCACE,CAGE,iBAHF,gBAGE,qBACE,CAJJ,uBACA,gDACE,wDACA,6DAHF,2CACA,CADA,gBACA,eACE,CAGE,sBANN,8BACE,CAII,iBAFF,4DACA,WACE,YADF,uCACE,6EACA,2BANN,8CACE,kDACA,0CACE,8BACA,yFACE,sBACA,sFALJ,mEACA,sBACE,kEACA,6EACE,uCACA,kEALJ,qGAEE,kEACA,6EACE,uCACA,kEALJ,8CACA,uDACE,sEACA,2EACE,sCACA,iEALJ,mGACA,qCACE,oDACA,0DACE,6GACA,gDAGR,yDCrEA,sEACE,CACA,6GACE,gEACF,iGAIF,wFACE,qDAGA,mGAEE,2CAEF,4FACE,gCACF,wGACE,8DAEE,6FAIA,iJAKN,6GACE,gDAKF,yDACA,qCAGA,6BACA,kBACA,qDAKA,oCAEA,+DAGA,2CAGE,oDAIA,oEAEE,qBAGJ,wDAEE,uCAEF,kE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","sources":["webpack:///./node_modules/normalize.css/normalize.css","webpack:///./src/furo/assets/styles/base/_print.sass","webpack:///./src/furo/assets/styles/base/_screen-readers.sass","webpack:///./src/furo/assets/styles/base/_theme.sass","webpack:///./src/furo/assets/styles/variables/_fonts.scss","webpack:///./src/furo/assets/styles/variables/_spacing.scss","webpack:///./src/furo/assets/styles/variables/_icons.scss","webpack:///./src/furo/assets/styles/variables/_admonitions.scss","webpack:///./src/furo/assets/styles/variables/_colors.scss","webpack:///./src/furo/assets/styles/base/_typography.sass","webpack:///./src/furo/assets/styles/_scaffold.sass","webpack:///./src/furo/assets/styles/variables/_layout.scss","webpack:///./src/furo/assets/styles/content/_admonitions.sass","webpack:///./src/furo/assets/styles/content/_api.sass","webpack:///./src/furo/assets/styles/content/_blocks.sass","webpack:///./src/furo/assets/styles/content/_captions.sass","webpack:///./src/furo/assets/styles/content/_code.sass","webpack:///./src/furo/assets/styles/content/_footnotes.sass","webpack:///./src/furo/assets/styles/content/_images.sass","webpack:///./src/furo/assets/styles/content/_indexes.sass","webpack:///./src/furo/assets/styles/content/_lists.sass","webpack:///./src/furo/assets/styles/content/_math.sass","webpack:///./src/furo/assets/styles/content/_misc.sass","webpack:///./src/furo/assets/styles/content/_rubrics.sass","webpack:///./src/furo/assets/styles/content/_sidebar.sass","webpack:///./src/furo/assets/styles/content/_tables.sass","webpack:///./src/furo/assets/styles/content/_target.sass","webpack:///./src/furo/assets/styles/content/_gui-labels.sass","webpack:///./src/furo/assets/styles/components/_footer.sass","webpack:///./src/furo/assets/styles/components/_sidebar.sass","webpack:///./src/furo/assets/styles/components/_table_of_contents.sass","webpack:///./src/furo/assets/styles/_shame.sass"],"sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","// This file contains styles for managing print media.\n\n////////////////////////////////////////////////////////////////////////////////\n// Hide elements not relevant to print media.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Hide icon container.\n .content-icon-container\n display: none !important\n\n // Hide showing header links if hovering over when printing.\n .headerlink\n display: none !important\n\n // Hide mobile header.\n .mobile-header\n display: none !important\n\n // Hide navigation links.\n .related-pages\n display: none !important\n\n////////////////////////////////////////////////////////////////////////////////\n// Tweaks related to decolorization.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Apply a border around code which no longer have a color background.\n .highlight\n border: 0.1pt solid var(--color-foreground-border)\n\n////////////////////////////////////////////////////////////////////////////////\n// Avoid page break in some relevant cases.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n ul, ol, dl, a, table, pre, blockquote, p\n page-break-inside: avoid\n\n h1, h2, h3, h4, h5, h6, img, figure, caption\n page-break-inside: avoid\n page-break-after: avoid\n\n ul, ol, dl\n page-break-before: avoid\n",".visually-hidden\n position: absolute !important\n width: 1px !important\n height: 1px !important\n padding: 0 !important\n margin: -1px !important\n overflow: hidden !important\n clip: rect(0,0,0,0) !important\n white-space: nowrap !important\n border: 0 !important\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n:-moz-focusring\n outline: auto\n","// This file serves as the \"skeleton\" of the theming logic.\n//\n// This contains the bulk of the logic for handling dark mode, color scheme\n// toggling and the handling of color-scheme-specific hiding of elements.\n\nbody\n @include fonts\n @include spacing\n @include icons\n @include admonitions\n @include default-admonition(#651fff, \"abstract\")\n @include default-topic(#14B8A6, \"pencil\")\n\n @include colors\n\n.only-light\n display: block !important\nhtml body .only-dark\n display: none !important\n\n// Ignore dark-mode hints if print media.\n@media not print\n // Enable dark-mode, if requested.\n body[data-theme=\"dark\"]\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n // Enable dark mode, unless explicitly told to avoid.\n @media (prefers-color-scheme: dark)\n body:not([data-theme=\"light\"])\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n//\n// Theme toggle presentation\n//\nbody[data-theme=\"auto\"]\n .theme-toggle svg.theme-icon-when-auto-light\n display: block\n\n @media (prefers-color-scheme: dark)\n .theme-toggle svg.theme-icon-when-auto-dark\n display: block\n .theme-toggle svg.theme-icon-when-auto-light\n display: none\n\nbody[data-theme=\"dark\"]\n .theme-toggle svg.theme-icon-when-dark\n display: block\n\nbody[data-theme=\"light\"]\n .theme-toggle svg.theme-icon-when-light\n display: block\n","// Fonts used by this theme.\n//\n// There are basically two things here -- using the system font stack and\n// defining sizes for various elements in %ages. We could have also used `em`\n// but %age is easier to reason about for me.\n\n@mixin fonts {\n // These are adapted from https://systemfontstack.com/\n --font-stack: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,\n sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --font-stack--monospace: \"SFMono-Regular\", Menlo, Consolas, Monaco,\n Liberation Mono, Lucida Console, monospace;\n --font-stack--headings: var(--font-stack);\n\n --font-size--normal: 100%;\n --font-size--small: 87.5%;\n --font-size--small--2: 81.25%;\n --font-size--small--3: 75%;\n --font-size--small--4: 62.5%;\n\n // Sidebar\n --sidebar-caption-font-size: var(--font-size--small--2);\n --sidebar-item-font-size: var(--font-size--small);\n --sidebar-search-input-font-size: var(--font-size--small);\n\n // Table of Contents\n --toc-font-size: var(--font-size--small--3);\n --toc-font-size--mobile: var(--font-size--normal);\n --toc-title-font-size: var(--font-size--small--4);\n\n // Admonitions\n //\n // These aren't defined in terms of %ages, since nesting these is permitted.\n --admonition-font-size: 0.8125rem;\n --admonition-title-font-size: 0.8125rem;\n\n // Code\n --code-font-size: var(--font-size--small--2);\n\n // API\n --api-font-size: var(--font-size--small);\n}\n","// Spacing for various elements on the page\n//\n// If the user wants to tweak things in a certain way, they are permitted to.\n// They also have to deal with the consequences though!\n\n@mixin spacing {\n // Header!\n --header-height: calc(\n var(--sidebar-item-line-height) + 4 * #{var(--sidebar-item-spacing-vertical)}\n );\n --header-padding: 0.5rem;\n\n // Sidebar\n --sidebar-tree-space-above: 1.5rem;\n --sidebar-caption-space-above: 1rem;\n\n --sidebar-item-line-height: 1rem;\n --sidebar-item-spacing-vertical: 0.5rem;\n --sidebar-item-spacing-horizontal: 1rem;\n --sidebar-item-height: calc(\n var(--sidebar-item-line-height) + 2 *#{var(--sidebar-item-spacing-vertical)}\n );\n\n --sidebar-expander-width: var(--sidebar-item-height); // be square\n\n --sidebar-search-space-above: 0.5rem;\n --sidebar-search-input-spacing-vertical: 0.5rem;\n --sidebar-search-input-spacing-horizontal: 0.5rem;\n --sidebar-search-input-height: 1rem;\n --sidebar-search-icon-size: var(--sidebar-search-input-height);\n\n // Table of Contents\n --toc-title-padding: 0.25rem 0;\n --toc-spacing-vertical: 1.5rem;\n --toc-spacing-horizontal: 1.5rem;\n --toc-item-spacing-vertical: 0.4rem;\n --toc-item-spacing-horizontal: 1rem;\n}\n","// Expose theme icons as CSS variables.\n\n$icons: (\n // Adapted from tabler-icons\n // url: https://tablericons.com/\n \"search\":\n url('data:image/svg+xml;charset=utf-8,'),\n // Factored out from mkdocs-material on 24-Aug-2020.\n // url: https://squidfunk.github.io/mkdocs-material/reference/admonitions/\n \"pencil\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"abstract\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"info\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"flame\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"question\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"warning\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"failure\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"spark\":\n url('data:image/svg+xml;charset=utf-8,')\n);\n\n@mixin icons {\n @each $name, $glyph in $icons {\n --icon-#{$name}: #{$glyph};\n }\n}\n","// Admonitions\n\n// Structure of these is:\n// admonition-class: color \"icon-name\";\n//\n// The colors are translated into CSS variables below. The icons are\n// used directly in the main declarations to set the `mask-image` in\n// the title.\n\n// prettier-ignore\n$admonitions: (\n // Each of these has an reST directives for it.\n \"caution\": #ff9100 \"spark\",\n \"warning\": #ff9100 \"warning\",\n \"danger\": #ff5252 \"spark\",\n \"attention\": #ff5252 \"warning\",\n \"error\": #ff5252 \"failure\",\n \"hint\": #00c852 \"question\",\n \"tip\": #00c852 \"info\",\n \"important\": #00bfa5 \"flame\",\n \"note\": #00b0ff \"pencil\",\n \"seealso\": #448aff \"info\",\n \"admonition-todo\": #808080 \"pencil\"\n);\n\n@mixin default-admonition($color, $icon-name) {\n --color-admonition-title: #{$color};\n --color-admonition-title-background: #{rgba($color, 0.2)};\n\n --icon-admonition-default: var(--icon-#{$icon-name});\n}\n\n@mixin default-topic($color, $icon-name) {\n --color-topic-title: #{$color};\n --color-topic-title-background: #{rgba($color, 0.2)};\n\n --icon-topic-default: var(--icon-#{$icon-name});\n}\n\n@mixin admonitions {\n @each $name, $values in $admonitions {\n --color-admonition-title--#{$name}: #{nth($values, 1)};\n --color-admonition-title-background--#{$name}: #{rgba(\n nth($values, 1),\n 0.2\n )};\n }\n}\n","// Colors used throughout this theme.\n//\n// The aim is to give the user more control. Thus, instead of hard-coding colors\n// in various parts of the stylesheet, the approach taken is to define all\n// colors as CSS variables and reusing them in all the places.\n//\n// `colors-dark` depends on `colors` being included at a lower specificity.\n\n@mixin colors {\n --color-problematic: #b30000;\n\n // Base Colors\n --color-foreground-primary: black; // for main text and headings\n --color-foreground-secondary: #5a5c63; // for secondary text\n --color-foreground-muted: #6b6f76; // for muted text\n --color-foreground-border: #878787; // for content borders\n\n --color-background-primary: white; // for content\n --color-background-secondary: #f8f9fb; // for navigation + ToC\n --color-background-hover: #efeff4ff; // for navigation-item hover\n --color-background-hover--transparent: #efeff400;\n --color-background-border: #eeebee; // for UI borders\n --color-background-item: #ccc; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #0a4bff;\n --color-brand-content: #2757dd;\n --color-brand-visited: #872ee0;\n\n // API documentation\n --color-api-background: var(--color-background-hover--transparent);\n --color-api-background-hover: var(--color-background-hover);\n --color-api-overall: var(--color-foreground-secondary);\n --color-api-name: var(--color-problematic);\n --color-api-pre-name: var(--color-problematic);\n --color-api-paren: var(--color-foreground-secondary);\n --color-api-keyword: var(--color-foreground-primary);\n\n --color-api-added: #21632c;\n --color-api-added-border: #38a84d;\n --color-api-changed: #046172;\n --color-api-changed-border: #06a1bc;\n --color-api-deprecated: #605706;\n --color-api-deprecated-border: #f0d90f;\n --color-api-removed: #b30000;\n --color-api-removed-border: #ff5c5c;\n\n --color-highlight-on-target: #ffffcc;\n\n // Inline code background\n --color-inline-code-background: var(--color-background-secondary);\n\n // Highlighted text (search)\n --color-highlighted-background: #ddeeff;\n --color-highlighted-text: var(--color-foreground-primary);\n\n // GUI Labels\n --color-guilabel-background: #ddeeff80;\n --color-guilabel-border: #bedaf580;\n --color-guilabel-text: var(--color-foreground-primary);\n\n // Admonitions!\n --color-admonition-background: transparent;\n\n //////////////////////////////////////////////////////////////////////////////\n // Everything below this should be one of:\n // - var(...)\n // - *-gradient(...)\n // - special literal values (eg: transparent, none)\n //////////////////////////////////////////////////////////////////////////////\n\n // Tables\n --color-table-header-background: var(--color-background-secondary);\n --color-table-border: var(--color-background-border);\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: transparent;\n --color-card-marginals-background: var(--color-background-secondary);\n\n // Header\n --color-header-background: var(--color-background-primary);\n --color-header-border: var(--color-background-border);\n --color-header-text: var(--color-foreground-primary);\n\n // Sidebar (left)\n --color-sidebar-background: var(--color-background-secondary);\n --color-sidebar-background-border: var(--color-background-border);\n\n --color-sidebar-brand-text: var(--color-foreground-primary);\n --color-sidebar-caption-text: var(--color-foreground-muted);\n --color-sidebar-link-text: var(--color-foreground-secondary);\n --color-sidebar-link-text--top-level: var(--color-brand-primary);\n\n --color-sidebar-item-background: var(--color-sidebar-background);\n --color-sidebar-item-background--current: var(\n --color-sidebar-item-background\n );\n --color-sidebar-item-background--hover: linear-gradient(\n 90deg,\n var(--color-background-hover--transparent) 0%,\n var(--color-background-hover) var(--sidebar-item-spacing-horizontal),\n var(--color-background-hover) 100%\n );\n\n --color-sidebar-item-expander-background: transparent;\n --color-sidebar-item-expander-background--hover: var(\n --color-background-hover\n );\n\n --color-sidebar-search-text: var(--color-foreground-primary);\n --color-sidebar-search-background: var(--color-background-secondary);\n --color-sidebar-search-background--focus: var(--color-background-primary);\n --color-sidebar-search-border: var(--color-background-border);\n --color-sidebar-search-icon: var(--color-foreground-muted);\n\n // Table of Contents (right)\n --color-toc-background: var(--color-background-primary);\n --color-toc-title-text: var(--color-foreground-muted);\n --color-toc-item-text: var(--color-foreground-secondary);\n --color-toc-item-text--hover: var(--color-foreground-primary);\n --color-toc-item-text--active: var(--color-brand-primary);\n\n // Actual page contents\n --color-content-foreground: var(--color-foreground-primary);\n --color-content-background: transparent;\n\n // Links\n --color-link: var(--color-brand-content);\n --color-link-underline: var(--color-background-border);\n --color-link--hover: var(--color-brand-content);\n --color-link-underline--hover: var(--color-foreground-border);\n\n --color-link--visited: var(--color-brand-visited);\n --color-link-underline--visited: var(--color-background-border);\n --color-link--visited--hover: var(--color-brand-visited);\n --color-link-underline--visited--hover: var(--color-foreground-border);\n}\n\n@mixin colors-dark {\n --color-problematic: #ee5151;\n\n // Base Colors\n --color-foreground-primary: #cfd0d0; // for main text and headings\n --color-foreground-secondary: #9ca0a5; // for secondary text\n --color-foreground-muted: #81868d; // for muted text\n --color-foreground-border: #666666; // for content borders\n\n --color-background-primary: #131416; // for content\n --color-background-secondary: #1a1c1e; // for navigation + ToC\n --color-background-hover: #1e2124ff; // for navigation-item hover\n --color-background-hover--transparent: #1e212400;\n --color-background-border: #303335; // for UI borders\n --color-background-item: #444; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #3d94ff;\n --color-brand-content: #5ca5ff;\n --color-brand-visited: #b27aeb;\n\n // Highlighted text (search)\n --color-highlighted-background: #083563;\n\n // GUI Labels\n --color-guilabel-background: #08356380;\n --color-guilabel-border: #13395f80;\n\n // API documentation\n --color-api-keyword: var(--color-foreground-secondary);\n --color-highlight-on-target: #333300;\n\n --color-api-added: #3db854;\n --color-api-added-border: #267334;\n --color-api-changed: #09b0ce;\n --color-api-changed-border: #056d80;\n --color-api-deprecated: #b1a10b;\n --color-api-deprecated-border: #6e6407;\n --color-api-removed: #ff7575;\n --color-api-removed-border: #b03b3b;\n\n // Admonitions\n --color-admonition-background: #18181a;\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: #18181a;\n --color-card-marginals-background: var(--color-background-hover);\n}\n","// This file contains the styling for making the content throughout the page,\n// including fonts, paragraphs, headings and spacing among these elements.\n\nbody\n font-family: var(--font-stack)\npre,\ncode,\nkbd,\nsamp\n font-family: var(--font-stack--monospace)\n\n// Make fonts look slightly nicer.\nbody\n -webkit-font-smoothing: antialiased\n -moz-osx-font-smoothing: grayscale\n\n// Line height from Bootstrap 4.1\narticle\n line-height: 1.5\n\n//\n// Headings\n//\nh1,\nh2,\nh3,\nh4,\nh5,\nh6\n line-height: 1.25\n font-family: var(--font-stack--headings)\n font-weight: bold\n\n border-radius: 0.5rem\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n margin-left: -0.5rem\n margin-right: -0.5rem\n padding-left: 0.5rem\n padding-right: 0.5rem\n\n + p\n margin-top: 0\n\nh1\n font-size: 2.5em\n margin-top: 1.75rem\n margin-bottom: 1rem\nh2\n font-size: 2em\n margin-top: 1.75rem\nh3\n font-size: 1.5em\nh4\n font-size: 1.25em\nh5\n font-size: 1.125em\nh6\n font-size: 1em\n\nsmall\n opacity: 75%\n font-size: 80%\n\n// Paragraph\np\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n\n// Horizontal rules\nhr.docutils\n height: 1px\n padding: 0\n margin: 2rem 0\n background-color: var(--color-background-border)\n border: 0\n\n.centered\n text-align: center\n\n// Links\na\n text-decoration: underline\n\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n &:visited\n color: var(--color-link--visited)\n text-decoration-color: var(--color-link-underline--visited)\n &:hover\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &.muted-link\n color: inherit\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &:visited\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n","// This file contains the styles for the overall layouting of the documentation\n// skeleton, including the responsive changes as well as sidebar toggles.\n//\n// This is implemented as a mobile-last design, which isn't ideal, but it is\n// reasonably good-enough and I got pretty tired by the time I'd finished this\n// to move the rules around to fix this. Shouldn't take more than 3-4 hours,\n// if you know what you're doing tho.\n\n// HACK: Not all browsers account for the scrollbar width in media queries.\n// This results in horizontal scrollbars in the breakpoint where we go\n// from displaying everything to hiding the ToC. We accomodate for this by\n// adding a bit of padding to the TOC drawer, disabling the horizontal\n// scrollbar and allowing the scrollbars to cover the padding.\n// https://www.456bereastreet.com/archive/201301/media_query_width_and_vertical_scrollbars/\n\n// HACK: Always having the scrollbar visible, prevents certain browsers from\n// causing the content to stutter horizontally between taller-than-viewport and\n// not-taller-than-viewport pages.\n\nhtml\n overflow-x: hidden\n overflow-y: scroll\n scroll-behavior: smooth\n\n.sidebar-scroll, .toc-scroll, article[role=main] *\n // Override Firefox scrollbar style\n scrollbar-width: thin\n scrollbar-color: var(--color-foreground-border) transparent\n\n // Override Chrome scrollbar styles\n &::-webkit-scrollbar\n width: 0.25rem\n height: 0.25rem\n &::-webkit-scrollbar-thumb\n background-color: var(--color-foreground-border)\n border-radius: 0.125rem\n\n//\n// Overalls\n//\nhtml,\nbody\n height: 100%\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n.skip-to-content\n position: fixed\n padding: 1rem\n border-radius: 1rem\n left: 0.25rem\n top: 0.25rem\n z-index: 40\n background: var(--color-background-primary)\n color: var(--color-foreground-primary)\n\n transform: translateY(-200%)\n transition: transform 300ms ease-in-out\n\n &:focus-within\n transform: translateY(0%)\n\narticle\n color: var(--color-content-foreground)\n background: var(--color-content-background)\n overflow-wrap: break-word\n\n.page\n display: flex\n // fill the viewport for pages with little content.\n min-height: 100%\n\n.mobile-header\n width: 100%\n height: var(--header-height)\n background-color: var(--color-header-background)\n color: var(--color-header-text)\n border-bottom: 1px solid var(--color-header-border)\n\n // Looks like sub-script/super-script have this, and we need this to\n // be \"on top\" of those.\n z-index: 10\n\n // We don't show the header on large screens.\n display: none\n\n // Add shadow when scrolled\n &.scrolled\n border-bottom: none\n box-shadow: 0 0 0.2rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.4rem rgba(0, 0, 0, 0.2)\n\n .header-center\n a\n color: var(--color-header-text)\n text-decoration: none\n\n.main\n display: flex\n flex: 1\n\n// Sidebar (left) also covers the entire left portion of screen.\n.sidebar-drawer\n box-sizing: border-box\n\n border-right: 1px solid var(--color-sidebar-background-border)\n background: var(--color-sidebar-background)\n\n display: flex\n justify-content: flex-end\n // These next two lines took me two days to figure out.\n width: calc((100% - #{$full-width}) / 2 + #{$sidebar-width})\n min-width: $sidebar-width\n\n// Scroll-along sidebars\n.sidebar-container,\n.toc-drawer\n box-sizing: border-box\n width: $sidebar-width\n\n.toc-drawer\n background: var(--color-toc-background)\n // See HACK described on top of this document\n padding-right: 1rem\n\n.sidebar-sticky,\n.toc-sticky\n position: sticky\n top: 0\n height: min(100%, 100vh)\n height: 100vh\n\n display: flex\n flex-direction: column\n\n.sidebar-scroll,\n.toc-scroll\n flex-grow: 1\n flex-shrink: 1\n\n overflow: auto\n scroll-behavior: smooth\n\n// Central items.\n.content\n padding: 0 $content-padding\n width: $content-width\n\n display: flex\n flex-direction: column\n justify-content: space-between\n\n.icon\n display: inline-block\n height: 1rem\n width: 1rem\n svg\n width: 100%\n height: 100%\n\n//\n// Accommodate announcement banner\n//\n.announcement\n background-color: var(--color-announcement-background)\n color: var(--color-announcement-text)\n\n height: var(--header-height)\n display: flex\n align-items: center\n overflow-x: auto\n & + .page\n min-height: calc(100% - var(--header-height))\n\n.announcement-content\n box-sizing: border-box\n padding: 0.5rem\n min-width: 100%\n white-space: nowrap\n text-align: center\n\n a\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-announcement-text)\n\n &:hover\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-link--hover)\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for theme\n////////////////////////////////////////////////////////////////////////////////\n.no-js .theme-toggle-container // don't show theme toggle if there's no JS\n display: none\n\n.theme-toggle-container\n display: flex\n\n.theme-toggle\n display: flex\n cursor: pointer\n border: none\n padding: 0\n background: transparent\n\n.theme-toggle svg\n height: 1.25rem\n width: 1.25rem\n color: var(--color-foreground-primary)\n display: none\n\n.theme-toggle-header\n display: flex\n align-items: center\n justify-content: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for elements\n////////////////////////////////////////////////////////////////////////////////\n.toc-overlay-icon, .nav-overlay-icon\n display: none\n cursor: pointer\n\n .icon\n color: var(--color-foreground-secondary)\n height: 1.5rem\n width: 1.5rem\n\n.toc-header-icon, .nav-overlay-icon\n // for when we set display: flex\n justify-content: center\n align-items: center\n\n.toc-content-icon\n height: 1.5rem\n width: 1.5rem\n\n.content-icon-container\n float: right\n display: flex\n margin-top: 1.5rem\n margin-left: 1rem\n margin-bottom: 1rem\n gap: 0.5rem\n\n .edit-this-page, .view-this-page\n svg\n color: inherit\n height: 1.25rem\n width: 1.25rem\n\n.sidebar-toggle\n position: absolute\n display: none\n// \n.sidebar-toggle[name=\"__toc\"]\n left: 20px\n.sidebar-toggle:checked\n left: 40px\n// \n\n.overlay\n position: fixed\n top: 0\n width: 0\n height: 0\n\n transition: width 0ms, height 0ms, opacity 250ms ease-out\n\n opacity: 0\n background-color: rgba(0, 0, 0, 0.54)\n.sidebar-overlay\n z-index: 20\n.toc-overlay\n z-index: 40\n\n// Keep things on top and smooth.\n.sidebar-drawer\n z-index: 30\n transition: left 250ms ease-in-out\n.toc-drawer\n z-index: 50\n transition: right 250ms ease-in-out\n\n// Show the Sidebar\n#__navigation:checked\n & ~ .sidebar-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .sidebar-drawer\n top: 0\n left: 0\n // Show the toc sidebar\n#__toc:checked\n & ~ .toc-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .toc-drawer\n top: 0\n right: 0\n\n////////////////////////////////////////////////////////////////////////////////\n// Back to top\n////////////////////////////////////////////////////////////////////////////////\n.back-to-top\n text-decoration: none\n\n display: none\n position: fixed\n left: 0\n top: 1rem\n padding: 0.5rem\n padding-right: 0.75rem\n border-radius: 1rem\n font-size: 0.8125rem\n\n background: var(--color-background-primary)\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), #6b728080 0px 0px 1px 0px\n\n z-index: 10\n\n margin-left: 50%\n transform: translateX(-50%)\n svg\n height: 1rem\n width: 1rem\n fill: currentColor\n display: inline-block\n\n span\n margin-left: 0.25rem\n\n .show-back-to-top &\n display: flex\n align-items: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Responsive layouting\n////////////////////////////////////////////////////////////////////////////////\n// Make things a bit bigger on bigger screens.\n@media (min-width: $full-width + $sidebar-width)\n html\n font-size: 110%\n\n@media (max-width: $full-width)\n // Collapse \"toc\" into the icon.\n .toc-content-icon\n display: flex\n .toc-drawer\n position: fixed\n height: 100vh\n top: 0\n right: -$sidebar-width\n border-left: 1px solid var(--color-background-muted)\n .toc-tree\n border-left: none\n font-size: var(--toc-font-size--mobile)\n\n // Accomodate for a changed content width.\n .sidebar-drawer\n width: calc((100% - #{$full-width - $sidebar-width}) / 2 + #{$sidebar-width})\n\n@media (max-width: $content-padded-width + $sidebar-width)\n // Center the page\n .content\n margin-left: auto\n margin-right: auto\n padding: 0 $content-padding--small\n\n@media (max-width: $content-padded-width--small + $sidebar-width)\n // Collapse \"navigation\".\n .nav-overlay-icon\n display: flex\n .sidebar-drawer\n position: fixed\n height: 100vh\n width: $sidebar-width\n\n top: 0\n left: -$sidebar-width\n\n // Swap which icon is visible.\n .toc-header-icon, .theme-toggle-header\n display: flex\n .toc-content-icon, .theme-toggle-content\n display: none\n\n // Show the header.\n .mobile-header\n position: sticky\n top: 0\n display: flex\n justify-content: space-between\n align-items: center\n\n .header-left,\n .header-right\n display: flex\n height: var(--header-height)\n padding: 0 var(--header-padding)\n label\n height: 100%\n width: 100%\n user-select: none\n\n .nav-overlay-icon .icon,\n .theme-toggle svg\n height: 1.5rem\n width: 1.5rem\n\n // Add a scroll margin for the content\n :target\n scroll-margin-top: calc(var(--header-height) + 2.5rem)\n\n // Show back-to-top below the header\n .back-to-top\n top: calc(var(--header-height) + 0.5rem)\n\n // Accommodate for the header.\n .page\n flex-direction: column\n justify-content: center\n\n@media (max-width: $content-width + 2* $content-padding--small)\n // Content should respect window limits.\n .content\n width: 100%\n overflow-x: auto\n\n@media (max-width: $content-width)\n article[role=main] aside.sidebar\n float: none\n width: 100%\n margin: 1rem 0\n","// Overall Layout Variables\n//\n// Because CSS variables can't be used in media queries. The fact that this\n// makes the layout non-user-configurable is a good thing.\n$content-padding: 3em;\n$content-padding--small: 1em;\n$content-width: 46em;\n$sidebar-width: 15em;\n$content-padded-width: $content-width + 2 * $content-padding;\n$content-padded-width--small: $content-width + 2 * $content-padding--small;\n$full-width: $content-padded-width + 2 * $sidebar-width;\n","//\n// The design here is strongly inspired by mkdocs-material.\n.admonition, .topic\n margin: 1rem auto\n padding: 0 0.5rem 0.5rem 0.5rem\n\n background: var(--color-admonition-background)\n\n border-radius: 0.2rem\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n font-size: var(--admonition-font-size)\n\n overflow: hidden\n page-break-inside: avoid\n\n // First element should have no margin, since the title has it.\n > :nth-child(2)\n margin-top: 0\n\n // Last item should have no margin, since we'll control that w/ padding\n > :last-child\n margin-bottom: 0\n\n.admonition p.admonition-title,\np.topic-title\n position: relative\n margin: 0 -0.5rem 0.5rem\n padding-left: 2rem\n padding-right: .5rem\n padding-top: .4rem\n padding-bottom: .4rem\n\n font-weight: 500\n font-size: var(--admonition-title-font-size)\n line-height: 1.3\n\n // Our fancy icon\n &::before\n content: \"\"\n position: absolute\n left: 0.5rem\n width: 1rem\n height: 1rem\n\n// Default styles\np.admonition-title\n background-color: var(--color-admonition-title-background)\n &::before\n background-color: var(--color-admonition-title)\n mask-image: var(--icon-admonition-default)\n mask-repeat: no-repeat\n\np.topic-title\n background-color: var(--color-topic-title-background)\n &::before\n background-color: var(--color-topic-title)\n mask-image: var(--icon-topic-default)\n mask-repeat: no-repeat\n\n//\n// Variants\n//\n.admonition\n border-left: 0.2rem solid var(--color-admonition-title)\n\n @each $type, $value in $admonitions\n &.#{$type}\n border-left-color: var(--color-admonition-title--#{$type})\n > .admonition-title\n background-color: var(--color-admonition-title-background--#{$type})\n &::before\n background-color: var(--color-admonition-title--#{$type})\n mask-image: var(--icon-#{nth($value, 2)})\n\n.admonition-todo > .admonition-title\n text-transform: uppercase\n","// This file stylizes the API documentation (stuff generated by autodoc). It's\n// deeply nested due to how autodoc structures the HTML without enough classes\n// to select the relevant items.\n\n// API docs!\ndl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)\n // Tweak the spacing of all the things!\n dd\n margin-left: 2rem\n > :first-child\n margin-top: 0.125rem\n > :last-child\n margin-bottom: 0.75rem\n\n // This is used for the arguments\n .field-list\n margin-bottom: 0.75rem\n\n // \"Headings\" (like \"Parameters\" and \"Return\")\n > dt\n text-transform: uppercase\n font-size: var(--font-size--small)\n\n dd:empty\n margin-bottom: 0.5rem\n dd > ul\n margin-left: -1.2rem\n > li\n > p:nth-child(2)\n margin-top: 0\n // When the last-empty-paragraph follows a paragraph, it doesn't need\n // to augument the existing spacing.\n > p + p:last-child:empty\n margin-top: 0\n margin-bottom: 0\n\n // Colorize the elements\n > dt\n color: var(--color-api-overall)\n\n.sig:not(.sig-inline)\n font-weight: bold\n\n font-size: var(--api-font-size)\n font-family: var(--font-stack--monospace)\n\n margin-left: -0.25rem\n margin-right: -0.25rem\n padding-top: 0.25rem\n padding-bottom: 0.25rem\n padding-right: 0.5rem\n\n // These are intentionally em, to properly match the font size.\n padding-left: 3em\n text-indent: -2.5em\n\n border-radius: 0.25rem\n\n background: var(--color-api-background)\n transition: background 100ms ease-out\n\n &:hover\n background: var(--color-api-background-hover)\n\n // adjust the size of the [source] link on the right.\n a.reference\n .viewcode-link\n font-weight: normal\n width: 4.25rem\n\nem.property\n font-style: normal\n &:first-child\n color: var(--color-api-keyword)\n.sig-name\n color: var(--color-api-name)\n.sig-prename\n font-weight: normal\n color: var(--color-api-pre-name)\n.sig-paren\n color: var(--color-api-paren)\n.sig-param\n font-style: normal\n\ndiv.versionadded,\ndiv.versionchanged,\ndiv.deprecated,\ndiv.versionremoved\n border-left: 0.1875rem solid\n border-radius: 0.125rem\n\n padding-left: 0.75rem\n\n p\n margin-top: 0.125rem\n margin-bottom: 0.125rem\n\ndiv.versionadded\n border-color: var(--color-api-added-border)\n .versionmodified\n color: var(--color-api-added)\n\ndiv.versionchanged\n border-color: var(--color-api-changed-border)\n .versionmodified\n color: var(--color-api-changed)\n\ndiv.deprecated\n border-color: var(--color-api-deprecated-border)\n .versionmodified\n color: var(--color-api-deprecated)\n\ndiv.versionremoved\n border-color: var(--color-api-removed-border)\n .versionmodified\n color: var(--color-api-removed)\n\n// Align the [docs] and [source] to the right.\n.viewcode-link, .viewcode-back\n float: right\n text-align: right\n",".line-block\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n .line-block\n margin-top: 0rem\n margin-bottom: 0rem\n padding-left: 1rem\n","// Captions\narticle p.caption,\ntable > caption,\n.code-block-caption\n font-size: var(--font-size--small)\n text-align: center\n\n// Caption above a TOCTree\n.toctree-wrapper.compound\n .caption, :not(.caption) > .caption-text\n font-size: var(--font-size--small)\n text-transform: uppercase\n\n text-align: initial\n margin-bottom: 0\n\n > ul\n margin-top: 0\n margin-bottom: 0\n","// Inline code\ncode.literal, .sig-inline\n background: var(--color-inline-code-background)\n border-radius: 0.2em\n // Make the font smaller, and use padding to recover.\n font-size: var(--font-size--small--2)\n padding: 0.1em 0.2em\n\n pre.literal-block &\n font-size: inherit\n padding: 0\n\n p &\n border: 1px solid var(--color-background-border)\n\n.sig-inline\n font-family: var(--font-stack--monospace)\n\n// Code and Literal Blocks\n$code-spacing-vertical: 0.625rem\n$code-spacing-horizontal: 0.875rem\n\n// Wraps every literal block + line numbers.\ndiv[class*=\" highlight-\"],\ndiv[class^=\"highlight-\"]\n margin: 1em 0\n display: flex\n\n .table-wrapper\n margin: 0\n padding: 0\n\npre\n margin: 0\n padding: 0\n overflow: auto\n\n // Needed to have more specificity than pygments' \"pre\" selector. :(\n article[role=\"main\"] .highlight &\n line-height: 1.5\n\n &.literal-block,\n .highlight &\n font-size: var(--code-font-size)\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n // Make it look like all the other blocks.\n &.literal-block\n margin-top: 1rem\n margin-bottom: 1rem\n\n border-radius: 0.2rem\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n\n// All code is always contained in this.\n.highlight\n width: 100%\n border-radius: 0.2rem\n\n // Make line numbers and prompts un-selectable.\n .gp, span.linenos\n user-select: none\n pointer-events: none\n\n // Expand the line-highlighting.\n .hll\n display: block\n margin-left: -$code-spacing-horizontal\n margin-right: -$code-spacing-horizontal\n padding-left: $code-spacing-horizontal\n padding-right: $code-spacing-horizontal\n\n/* Make code block captions be nicely integrated */\n.code-block-caption\n display: flex\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n border-radius: 0.25rem\n border-bottom-left-radius: 0\n border-bottom-right-radius: 0\n font-weight: 300\n border-bottom: 1px solid\n\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n border-color: var(--color-background-border)\n\n + div[class]\n margin-top: 0\n pre\n border-top-left-radius: 0\n border-top-right-radius: 0\n\n// When `html_codeblock_linenos_style` is table.\n.highlighttable\n width: 100%\n display: block\n tbody\n display: block\n\n tr\n display: flex\n\n // Line numbers\n td.linenos\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n padding: $code-spacing-vertical $code-spacing-horizontal\n padding-right: 0\n border-top-left-radius: 0.2rem\n border-bottom-left-radius: 0.2rem\n\n .linenodiv\n padding-right: $code-spacing-horizontal\n font-size: var(--code-font-size)\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n\n // Actual code\n td.code\n padding: 0\n display: block\n flex: 1\n overflow: hidden\n\n .highlight\n border-top-left-radius: 0\n border-bottom-left-radius: 0\n\n// When `html_codeblock_linenos_style` is inline.\n.highlight\n span.linenos\n display: inline-block\n padding-left: 0\n padding-right: $code-spacing-horizontal\n margin-right: $code-spacing-horizontal\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n","// Inline Footnote Reference\n.footnote-reference\n font-size: var(--font-size--small--4)\n vertical-align: super\n\n// Definition list, listing the content of each note.\n// docutils <= 0.17\ndl.footnote.brackets\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\n display: grid\n grid-template-columns: max-content auto\n dt\n margin: 0\n > .fn-backref\n margin-left: 0.25rem\n\n &:after\n content: \":\"\n\n .brackets\n &:before\n content: \"[\"\n &:after\n content: \"]\"\n\n dd\n margin: 0\n padding: 0 1rem\n\n// docutils >= 0.18\naside.footnote\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\naside.footnote > span,\ndiv.citation > span\n float: left\n font-weight: 500\n padding-right: 0.25rem\n\naside.footnote > *:not(span),\ndiv.citation > p\n margin-left: 2rem\n","//\n// Figures\n//\nimg\n box-sizing: border-box\n max-width: 100%\n height: auto\n\narticle\n figure, .figure\n border-radius: 0.2rem\n\n margin: 0\n :last-child\n margin-bottom: 0\n\n .align-left\n float: left\n clear: left\n margin: 0 1rem 1rem\n\n .align-right\n float: right\n clear: right\n margin: 0 1rem 1rem\n\n .align-default,\n .align-center\n display: block\n text-align: center\n margin-left: auto\n margin-right: auto\n\n // WELL, table needs to be stylised like a table.\n table.align-default\n display: table\n text-align: initial\n",".genindex-jumpbox, .domainindex-jumpbox\n border-top: 1px solid var(--color-background-border)\n border-bottom: 1px solid var(--color-background-border)\n padding: 0.25rem\n\n.genindex-section, .domainindex-section\n h2\n margin-top: 0.75rem\n margin-bottom: 0.5rem\n ul\n margin-top: 0\n margin-bottom: 0\n","ul,\nol\n padding-left: 1.2rem\n\n // Space lists out like paragraphs\n margin-top: 1rem\n margin-bottom: 1rem\n // reduce margins within li.\n li\n > p:first-child\n margin-top: 0.25rem\n margin-bottom: 0.25rem\n\n > p:last-child\n margin-top: 0.25rem\n\n > ul,\n > ol\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n\nol\n &.arabic\n list-style: decimal\n &.loweralpha\n list-style: lower-alpha\n &.upperalpha\n list-style: upper-alpha\n &.lowerroman\n list-style: lower-roman\n &.upperroman\n list-style: upper-roman\n\n// Don't space lists out when they're \"simple\" or in a `.. toctree::`\n.simple,\n.toctree-wrapper\n li\n > ul,\n > ol\n margin-top: 0\n margin-bottom: 0\n\n// Definition Lists\n.field-list,\n.option-list,\ndl:not([class]),\ndl.simple,\ndl.footnote,\ndl.glossary\n dt\n font-weight: 500\n margin-top: 0.25rem\n + dt\n margin-top: 0\n\n .classifier::before\n content: \":\"\n margin-left: 0.2rem\n margin-right: 0.2rem\n\n dd\n > p:first-child,\n ul\n margin-top: 0.125rem\n\n ul\n margin-bottom: 0.125rem\n",".math-wrapper\n width: 100%\n overflow-x: auto\n\ndiv.math\n position: relative\n text-align: center\n\n .headerlink,\n &:focus .headerlink\n display: none\n\n &:hover .headerlink\n display: inline-block\n\n span.eqno\n position: absolute\n right: 0.5rem\n top: 50%\n transform: translate(0, -50%)\n z-index: 1\n","// Abbreviations\nabbr[title]\n cursor: help\n\n// \"Problematic\" content, as identified by Sphinx\n.problematic\n color: var(--color-problematic)\n\n// Keyboard / Mouse \"instructions\"\nkbd:not(.compound)\n margin: 0 0.2rem\n padding: 0 0.2rem\n border-radius: 0.2rem\n border: 1px solid var(--color-foreground-border)\n color: var(--color-foreground-primary)\n vertical-align: text-bottom\n\n font-size: var(--font-size--small--3)\n display: inline-block\n\n box-shadow: 0 0.0625rem 0 rgba(0, 0, 0, 0.2), inset 0 0 0 0.125rem var(--color-background-primary)\n\n background-color: var(--color-background-secondary)\n\n// Blockquote\nblockquote\n border-left: 4px solid var(--color-background-border)\n background: var(--color-background-secondary)\n\n margin-left: 0\n margin-right: 0\n padding: 0.5rem 1rem\n\n .attribution\n font-weight: 600\n text-align: right\n\n &.pull-quote,\n &.highlights\n font-size: 1.25em\n\n &.epigraph,\n &.pull-quote\n border-left-width: 0\n border-radius: 0.5rem\n\n &.highlights\n border-left-width: 0\n background: transparent\n\n// Center align embedded-in-text images\np .reference img\n vertical-align: middle\n","p.rubric\n line-height: 1.25\n font-weight: bold\n font-size: 1.125em\n\n // For Numpy-style documentation that's got rubrics within it.\n // https://github.com/pradyunsg/furo/discussions/505\n dd &\n line-height: inherit\n font-weight: inherit\n\n font-size: var(--font-size--small)\n text-transform: uppercase\n","article .sidebar\n float: right\n clear: right\n width: 30%\n\n margin-left: 1rem\n margin-right: 0\n\n border-radius: 0.2rem\n background-color: var(--color-background-secondary)\n border: var(--color-background-border) 1px solid\n\n > *\n padding-left: 1rem\n padding-right: 1rem\n\n > ul, > ol // lists need additional padding, because bullets.\n padding-left: 2.2rem\n\n .sidebar-title\n margin: 0\n padding: 0.5rem 1rem\n border-bottom: var(--color-background-border) 1px solid\n\n font-weight: 500\n\n// TODO: subtitle\n// TODO: dedicated variables?\n","[role=main] .table-wrapper.container\n width: 100%\n overflow-x: auto\n margin-top: 1rem\n margin-bottom: 0.5rem\n padding: 0.2rem 0.2rem 0.75rem\n\ntable.docutils\n border-radius: 0.2rem\n border-spacing: 0\n border-collapse: collapse\n\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n th\n background: var(--color-table-header-background)\n\n td,\n th\n // Space things out properly\n padding: 0 0.25rem\n\n // Get the borders looking just-right.\n border-left: 1px solid var(--color-table-border)\n border-right: 1px solid var(--color-table-border)\n border-bottom: 1px solid var(--color-table-border)\n\n p\n margin: 0.25rem\n\n &:first-child\n border-left: none\n &:last-child\n border-right: none\n\n // MyST-parser tables set these classes for control of column alignment\n &.text-left\n text-align: left\n &.text-right\n text-align: right\n &.text-center\n text-align: center\n",":target\n scroll-margin-top: 2.5rem\n\n@media (max-width: $full-width - $sidebar-width)\n :target\n scroll-margin-top: calc(2.5rem + var(--header-height))\n\n // When a heading is selected\n section > span:target\n scroll-margin-top: calc(2.8rem + var(--header-height))\n\n// Permalinks\n.headerlink\n font-weight: 100\n user-select: none\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\ndl dt,\np.caption,\nfigcaption p,\ntable > caption,\n.code-block-caption\n > .headerlink\n margin-left: 0.5rem\n visibility: hidden\n &:hover > .headerlink\n visibility: visible\n\n // Don't change to link-like, if someone adds the contents directive.\n > .toc-backref\n color: inherit\n text-decoration-line: none\n\n// Figure and table captions are special.\nfigure:hover > figcaption > p > .headerlink,\ntable:hover > caption > .headerlink\n visibility: visible\n\n:target >, // Regular section[id] style anchors\nspan:target ~ // Non-regular span[id] style \"extra\" anchors\n h1,\n h2,\n h3,\n h4,\n h5,\n h6\n &:nth-of-type(1)\n background-color: var(--color-highlight-on-target)\n // .headerlink\n // visibility: visible\n code.literal\n background-color: transparent\n\ntable:target > caption,\nfigure:target\n background-color: var(--color-highlight-on-target)\n\n// Inline page contents\n.this-will-duplicate-information-and-it-is-still-useful-here li :target\n background-color: var(--color-highlight-on-target)\n\n// Code block permalinks\n.literal-block-wrapper:target .code-block-caption\n background-color: var(--color-highlight-on-target)\n\n// When a definition list item is selected\n//\n// There isn't really an alternative to !important here, due to the\n// high-specificity of API documentation's selector.\ndt:target\n background-color: var(--color-highlight-on-target) !important\n\n// When a footnote reference is selected\n.footnote > dt:target + dd,\n.footnote-reference:target\n background-color: var(--color-highlight-on-target)\n",".guilabel\n background-color: var(--color-guilabel-background)\n border: 1px solid var(--color-guilabel-border)\n color: var(--color-guilabel-text)\n\n padding: 0 0.3em\n border-radius: 0.5em\n font-size: 0.9em\n","// This file contains the styles used for stylizing the footer that's shown\n// below the content.\n\nfooter\n font-size: var(--font-size--small)\n display: flex\n flex-direction: column\n\n margin-top: 2rem\n\n// Bottom of page information\n.bottom-of-page\n display: flex\n align-items: center\n justify-content: space-between\n\n margin-top: 1rem\n padding-top: 1rem\n padding-bottom: 1rem\n\n color: var(--color-foreground-secondary)\n border-top: 1px solid var(--color-background-border)\n\n line-height: 1.5\n\n @media (max-width: $content-width)\n text-align: center\n flex-direction: column-reverse\n gap: 0.25rem\n\n .left-details\n font-size: var(--font-size--small)\n\n .right-details\n display: flex\n flex-direction: column\n gap: 0.25rem\n text-align: right\n\n .icons\n display: flex\n justify-content: flex-end\n gap: 0.25rem\n font-size: 1rem\n\n a\n text-decoration: none\n\n svg,\n img\n font-size: 1.125rem\n height: 1em\n width: 1em\n\n// Next/Prev page information\n.related-pages\n a\n display: flex\n align-items: center\n\n text-decoration: none\n &:hover .page-info .title\n text-decoration: underline\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n svg.furo-related-icon,\n svg.furo-related-icon > use\n flex-shrink: 0\n\n color: var(--color-foreground-border)\n\n width: 0.75rem\n height: 0.75rem\n margin: 0 0.5rem\n\n &.next-page\n max-width: 50%\n\n float: right\n clear: right\n text-align: right\n\n &.prev-page\n max-width: 50%\n\n float: left\n clear: left\n\n svg\n transform: rotate(180deg)\n\n.page-info\n display: flex\n flex-direction: column\n overflow-wrap: anywhere\n\n .next-page &\n align-items: flex-end\n\n .context\n display: flex\n align-items: center\n\n padding-bottom: 0.1rem\n\n color: var(--color-foreground-muted)\n font-size: var(--font-size--small)\n text-decoration: none\n","// This file contains the styles for the contents of the left sidebar, which\n// contains the navigation tree, logo, search etc.\n\n////////////////////////////////////////////////////////////////////////////////\n// Brand on top of the scrollable tree.\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-brand\n display: flex\n flex-direction: column\n flex-shrink: 0\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n text-decoration: none\n\n.sidebar-brand-text\n color: var(--color-sidebar-brand-text)\n overflow-wrap: break-word\n margin: var(--sidebar-item-spacing-vertical) 0\n font-size: 1.5rem\n\n.sidebar-logo-container\n margin: var(--sidebar-item-spacing-vertical) 0\n\n.sidebar-logo\n margin: 0 auto\n display: block\n max-width: 100%\n\n////////////////////////////////////////////////////////////////////////////////\n// Search\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-search-container\n display: flex\n align-items: center\n margin-top: var(--sidebar-search-space-above)\n\n position: relative\n\n background: var(--color-sidebar-search-background)\n &:hover,\n &:focus-within\n background: var(--color-sidebar-search-background--focus)\n\n &::before\n content: \"\"\n position: absolute\n left: var(--sidebar-item-spacing-horizontal)\n width: var(--sidebar-search-icon-size)\n height: var(--sidebar-search-icon-size)\n\n background-color: var(--color-sidebar-search-icon)\n mask-image: var(--icon-search)\n\n.sidebar-search\n box-sizing: border-box\n\n border: none\n border-top: 1px solid var(--color-sidebar-search-border)\n border-bottom: 1px solid var(--color-sidebar-search-border)\n\n padding-top: var(--sidebar-search-input-spacing-vertical)\n padding-bottom: var(--sidebar-search-input-spacing-vertical)\n padding-right: var(--sidebar-search-input-spacing-horizontal)\n padding-left: calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size))\n\n width: 100%\n\n color: var(--color-sidebar-search-foreground)\n background: transparent\n z-index: 10\n\n &:focus\n outline: none\n\n &::placeholder\n font-size: var(--sidebar-search-input-font-size)\n\n//\n// Hide Search Matches link\n//\n#searchbox .highlight-link\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0\n margin: 0\n text-align: center\n\n a\n color: var(--color-sidebar-search-icon)\n font-size: var(--font-size--small--2)\n\n////////////////////////////////////////////////////////////////////////////////\n// Structure/Skeleton of the navigation tree (left)\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-tree\n font-size: var(--sidebar-item-font-size)\n margin-top: var(--sidebar-tree-space-above)\n margin-bottom: var(--sidebar-item-spacing-vertical)\n\n ul\n padding: 0\n margin-top: 0\n margin-bottom: 0\n\n display: flex\n flex-direction: column\n\n list-style: none\n\n li\n position: relative\n margin: 0\n\n > ul\n margin-left: var(--sidebar-item-spacing-horizontal)\n\n .icon\n color: var(--color-sidebar-link-text)\n\n .reference\n box-sizing: border-box\n color: var(--color-sidebar-link-text)\n\n // Fill the parent.\n display: inline-block\n line-height: var(--sidebar-item-line-height)\n text-decoration: none\n\n // Don't allow long words to cause wrapping.\n overflow-wrap: anywhere\n\n height: 100%\n width: 100%\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n &:hover\n color: var(--color-sidebar-link-text)\n background: var(--color-sidebar-item-background--hover)\n\n // Add a nice little \"external-link\" arrow here.\n &.external::after\n content: url('data:image/svg+xml,')\n margin: 0 0.25rem\n vertical-align: middle\n color: var(--color-sidebar-link-text)\n\n // Make the current page reference bold.\n .current-page > .reference\n font-weight: bold\n\n label\n position: absolute\n top: 0\n right: 0\n height: var(--sidebar-item-height)\n width: var(--sidebar-expander-width)\n\n cursor: pointer\n user-select: none\n\n display: flex\n justify-content: center\n align-items: center\n\n .caption, :not(.caption) > .caption-text\n font-size: var(--sidebar-caption-font-size)\n color: var(--color-sidebar-caption-text)\n\n font-weight: bold\n text-transform: uppercase\n\n margin: var(--sidebar-caption-space-above) 0 0 0\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n // If it has children, add a bit more padding to wrap the content to avoid\n // overlapping with the