diff --git a/Makefile b/Makefile
index adf4eb0c4079749a2f86a0a862292f3ed0931265..a7c69643704677ab7650f8b350c74cad0b5c7a4e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 format:
-	poetry run black --target-version py39 .
+	poetry run black --target-version py39 -l 88 .
 	poetry run ruff --select I --fix .
 
 PYTHON_FILES=.
@@ -7,9 +7,9 @@ lint: PYTHON_FILES=.
 lint_diff: PYTHON_FILES=$(shell git diff --name-only --diff-filter=d main | grep -E '\.py$$')
 
 lint lint_diff:
-	poetry run black --target-version py39 $(PYTHON_FILES) --check
+	poetry run black --target-version py39 -l 88 $(PYTHON_FILES) --check
 	poetry run ruff .
 	poetry run mypy $(PYTHON_FILES)
 
 test:
-	poetry run pytest -vv -n 20 --cov=semantic_router --cov-report=term-missing --cov-report=xml --cov-fail-under=80
+	poetry run pytest -vv -n 20 --cov=semantic_router --cov-report=term-missing --cov-report=xml
diff --git a/docs/07-ollama-local-execution.ipynb b/docs/07-ollama-local-execution.ipynb
index 91a011cb51efa4ca98cb47d227f4b43fbbd9bda3..cf26b77ec5355d41efb6a69a896c52a3dd8f53f8 100644
--- a/docs/07-ollama-local-execution.ipynb
+++ b/docs/07-ollama-local-execution.ipynb
@@ -211,8 +211,10 @@
     "from semantic_router.llms.ollama import OllamaLLM\n",
     "\n",
     "\n",
-    "llm = OllamaLLM(llm_name=\"openhermes\") # Change llm_name if you want to use a different LLM with dynamic routes.\n",
-    "rl = RouteLayer(encoder = encoder, routes=routes, llm=llm)"
+    "llm = OllamaLLM(\n",
+    "    llm_name=\"openhermes\"\n",
+    ")  # Change llm_name if you want to use a different LLM with dynamic routes.\n",
+    "rl = RouteLayer(encoder=encoder, routes=routes, llm=llm)"
    ]
   },
   {
@@ -303,15 +305,15 @@
     "\n",
     "def get_time(timezone: str) -> str:\n",
     "    \"\"\"\n",
-    "Finds the current time in a specific timezone.\n",
+    "    Finds the current time in a specific timezone.\n",
     "\n",
-    ":param timezone: The timezone to find the current time in, should\n",
-    "    be a valid timezone from the IANA Time Zone Database like\n",
-    "    \"America/New_York\" or \"Europe/London\". Do NOT put the place\n",
-    "    name itself like \"rome\", or \"new york\", you must provide\n",
-    "    the IANA format.\n",
-    ":type timezone: str\n",
-    ":return: The current time in the specified timezone.\n",
+    "    :param timezone: The timezone to find the current time in, should\n",
+    "        be a valid timezone from the IANA Time Zone Database like\n",
+    "        \"America/New_York\" or \"Europe/London\". Do NOT put the place\n",
+    "        name itself like \"rome\", or \"new york\", you must provide\n",
+    "        the IANA format.\n",
+    "    :type timezone: str\n",
+    "    :return: The current time in the specified timezone.\n",
     "    \"\"\"\n",
     "    now = datetime.now(ZoneInfo(timezone))\n",
     "    return now.strftime(\"%H:%M\")"
@@ -449,7 +451,6 @@
     }
    ],
    "source": [
-    "\n",
     "get_time(**out.function_call)"
    ]
   },
diff --git a/docs/examples/rolling-window-splitter.ipynb b/docs/examples/rolling-window-splitter.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..b94d3a5615ec9b2edda91da90a481be235829bef
--- /dev/null
+++ b/docs/examples/rolling-window-splitter.ipynb
@@ -0,0 +1,193 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "text = \"\"\"\n",
+    "In a recent surge of social media discussions on Weibo, Chinese netizens have been engaging in conversations about the struggles and challenges of earning money. The online debate sparked a wave of opinions and perspectives on the relationship between hard work, high pay, and finding contentment. Among the tweets, several users pontificated that one should avoid earning \"too much hard-earned money.\"\n",
+    "The tweets and discussions revolve around the idea that working too hard for one's income can have a detrimental effect on one's life, both physically and mentally. Some users advocate for finding opportunities that align with one's strengths and passions, rather than simply focusing on high-paying jobs that may require excessive hours and intense labor.\n",
+    "One Weibo user pontificates, \"Don't earn that much hard-earned money,\" a sentiment echoed by others with tweets such as, \"Why is it that when earning money, that process always has to be so tough?\" This question is followed by a comparison between two types of people - those who are used to earning money the hard way and those who seem to effortlessly obtain wealth. While the former group is depicted as having been taught to suffer from a young age, the latter is shown as being able to focus solely on their natural talents and thriving in their niche advantageously.\n",
+    "Discussions on the platform draw attention to a variety of issues that those who earn money the hard way might face. For example, they are described as likely having to work overtime, forgo time off for illness or rest, and maintain an unyielding dedication to their occupation, which often results in a never-ending cycle of work without any perceived progression in their lives.\n",
+    "Another tweet that captures this sentiment reads, \"Drowning in more work and poverty despite trying harder and harder,\" pointing to a sense of despair and dissatisfaction that comes with work that is both disproportionately demanding and inadequately rewarding. Critics also note how the pursuit of hard-earned money could potentially create physical and mental health risks due to the unrelenting pressure and stress that these jobs might impose.\n",
+    "Conversely, those in favor of earning money with less difficulty contend that it's crucial to harness one's strengths and passions to create opportunities that yield financial success without the need for excessive labor. The debate revolves around the concept that people should seek out ways to work smarter, not harder, especially if it means a healthier and more fulfilling lifestyle.\n",
+    "In fact, the notion of a \"vicious cycle,\" often attributed to those chasing hard-earned money, is juxtaposed with an idealized image of someone operating in their zone of excellence. Confidently focused on their strengths, such individuals are depicted as enjoying a more relaxed and less stressful work environment, one in which they can thrive without the need for never-ending overtime or self-sacrifice.\n",
+    "Some tweets even extend this sentiment to the broader socio-economic context, observing how wealth is not merely derived from manual labor or high-paying positions requiring extraordinary work hours. The tweets emphasize the importance of cultivating an entrepreneurial spirit and a penchant for innovative thinking, especially in the modern digital age.\n",
+    "One user writes, \"Too hard-earned money isn't worth it. Learn how to make money using your brain, not your body,\" while another suggests, \"Love will flow towards those who are not lacking in love, and money will flow towards those who are not lacking in money!\"\n",
+    "While some of the discussions take a somewhat passive-aggressive view, others acknowledge that financial security and comfort might not always be possible for everyone. In a more realistic tone, a user remarks, \"If life were so easy that diligence led to wealth, then the world's richest person would be the best worker bee. But that's not the case.\" This acknowledgment underscores the complexities of the economy and the role that factors like luck, connections, and a rapidly evolving job market can play in financial success.\n",
+    "Some users are quick to criticize the notion that earning money the hard way should be avoided, with one tweet expressing, \"The person who advises you to avoid hard-earned money is likely a scammer who profits off providing emotional value in exchange for exploitation.\" Others argue that while it's essential to find enjoyment and fulfillment in one's work, it's crucial not to shun or belittle those who choose to work in physically demanding or high-paying industries.\n",
+    "Overall, the Weibo discussions offer a fascinating insight into the complexities of the modern Chinese labor market and the work-life balance that people strive to achieve. As in many countries, striking the right balance between work and play is an ongoing challenge for many Chinese citizens. However, the conversations on Weibo signal an increasing awareness of the importance of finding meaningful, fulfilling, and financially rewarding work that doesn't necessitate excessive sacrifice or sufferance.\n",
+    "In the end, as one user succinctly puts it, \"Make sure you're earning your money in a way that brings you joy and satisfaction. That's the only way to ensure that your life doesn't become a never-ending cycle of hard work without any tangible progress.\"\n",
+    "In this context, social media discussions focusing on the trials and tribulations of earning money serve not only as an outlet for venting frustrations but also as a means of promoting dialogue and shared understanding about the challenges faced by workers across all industries. These virtual conversations sparked by tweets and in-depth discussions likely resonate with a wide swath of Chinese citizens struggling to navigate the complexities of balancing a career that pays well with one that brings them joy, fulfillment, and a sense of purpose.\n",
+    "As the discussions on Weibo continue to evolve and unfold, it is evident that the discourse around work, money, and life satisfaction holds the potential to inspire meaningful change and shift societal attitudes towards a more holistic, balanced, and humane understanding of success and prosperity.\n",
+    "---\n",
+    "Note: The translated tweets and user quotes from Chinese to English were used as the foundation for the long-form news article. The author tried to maintain the integrity of the original content in the translation while adapting it to fit a journalistic format. No inaccuracies were introduced during translation, and the opinion-based nature of the original content was preserved while maintaining objectivity.\n",
+    "Heart count: 0/2\n",
+    "Note: The author did not include any Chinese characters in the final response.\n",
+    "Collapse\n",
+    "\"\"\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/Users/jamesbriggs/opt/anaconda3/envs/decision-layer/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
+      "  from .autonotebook import tqdm as notebook_tqdm\n"
+     ]
+    }
+   ],
+   "source": [
+    "import os\n",
+    "from getpass import getpass\n",
+    "from semantic_router.splitters import RollingWindowSplitter\n",
+    "from semantic_router.encoders import OpenAIEncoder\n",
+    "\n",
+    "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n",
+    "    \"Enter your OpenAI API key: \"\n",
+    ")\n",
+    "\n",
+    "splitter = RollingWindowSplitter(\n",
+    "    encoder=OpenAIEncoder(),\n",
+    "    min_split_tokens=50,\n",
+    "    max_split_tokens=300,\n",
+    "    window_size=5,  # sentences\n",
+    "    plot_splits=True,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "\u001b[33m2024-02-23 08:44:26 WARNING semantic_router.utils.logger Single document exceeds the maximum token limit of 300. Splitting to sentences before semantically splitting.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 0: Trying threshold: 0.8881277932028191\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 0: Median tokens per split: 24.0\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 0: Adjusting high to 0.8781277932028191\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 1: Trying threshold: 0.8687934834140205\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 1: Median tokens per split: 34.5\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Iteration 1: Adjusting high to 0.8587934834140205\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:26 INFO semantic_router.utils.logger Final optimal threshold: 0.8687934834140205\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 218 tokens due to threshold 0.8687934834140205.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 262 tokens due to exceeding token limit of 300.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 137 tokens due to threshold 0.8687934834140205.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 249 tokens due to threshold 0.8687934834140205.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 117 tokens due to threshold 0.8687934834140205.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 171 tokens due to threshold 0.8687934834140205.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Split finalized with 72 tokens due to threshold 0.8687934834140205.\u001b[0m\n",
+      "\u001b[32m2024-02-23 08:44:27 INFO semantic_router.utils.logger Final split added with 23 tokens due to remaining documents.\u001b[0m\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "<Figure size 1200x600 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "splits = splitter([text])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Split 1, tokens 218, triggered by: 0.85\n",
+      "\u001b[31mIn a recent surge of social media discussions on Weibo, Chinese netizens have been engaging in conversations about the struggles and challenges of earning money. The online debate sparked a wave of opinions and perspectives on the relationship between hard work, high pay, and finding contentment. Among the tweets, several users pontificated that one should avoid earning \"too much hard-earned money.\" The tweets and discussions revolve around the idea that working too hard for one's income can have a detrimental effect on one's life, both physically and mentally. Some users advocate for finding opportunities that align with one's strengths and passions, rather than simply focusing on high-paying jobs that may require excessive hours and intense labor. One Weibo user pontificates, \"Don't earn that much hard-earned money,\" a sentiment echoed by others with tweets such as, \"Why is it that when earning money, that process always has to be so tough?\" This question is followed by a comparison between two types of people - those who are used to earning money the hard way and those who seem to effortlessly obtain wealth.\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n",
+      "Split 2, tokens 262, triggered by: token limit\n",
+      "\u001b[32mWhile the former group is depicted as having been taught to suffer from a young age, the latter is shown as being able to focus solely on their natural talents and thriving in their niche advantageously. Discussions on the platform draw attention to a variety of issues that those who earn money the hard way might face. For example, they are described as likely having to work overtime, forgo time off for illness or rest, and maintain an unyielding dedication to their occupation, which often results in a never-ending cycle of work without any perceived progression in their lives. Another tweet that captures this sentiment reads, \"Drowning in more work and poverty despite trying harder and harder,\" pointing to a sense of despair and dissatisfaction that comes with work that is both disproportionately demanding and inadequately rewarding. Critics also note how the pursuit of hard-earned money could potentially create physical and mental health risks due to the unrelenting pressure and stress that these jobs might impose. Conversely, those in favor of earning money with less difficulty contend that it's crucial to harness one's strengths and passions to create opportunities that yield financial success without the need for excessive labor. The debate revolves around the concept that people should seek out ways to work smarter, not harder, especially if it means a healthier and more fulfilling lifestyle.\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n",
+      "Split 3, tokens 137, triggered by: 0.85\n",
+      "\u001b[34mIn fact, the notion of a \"vicious cycle,\" often attributed to those chasing hard-earned money, is juxtaposed with an idealized image of someone operating in their zone of excellence. Confidently focused on their strengths, such individuals are depicted as enjoying a more relaxed and less stressful work environment, one in which they can thrive without the need for never-ending overtime or self-sacrifice. Some tweets even extend this sentiment to the broader socio-economic context, observing how wealth is not merely derived from manual labor or high-paying positions requiring extraordinary work hours. The tweets emphasize the importance of cultivating an entrepreneurial spirit and a penchant for innovative thinking, especially in the modern digital age.\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n",
+      "Split 4, tokens 249, triggered by: 0.86\n",
+      "\u001b[35mOne user writes, \"Too hard-earned money isn't worth it. Learn how to make money using your brain, not your body,\" while another suggests, \"Love will flow towards those who are not lacking in love, and money will flow towards those who are not lacking in money!\" While some of the discussions take a somewhat passive-aggressive view, others acknowledge that financial security and comfort might not always be possible for everyone. In a more realistic tone, a user remarks, \"If life were so easy that diligence led to wealth, then the world's richest person would be the best worker bee. But that's not the case.\" This acknowledgment underscores the complexities of the economy and the role that factors like luck, connections, and a rapidly evolving job market can play in financial success. Some users are quick to criticize the notion that earning money the hard way should be avoided, with one tweet expressing, \"The person who advises you to avoid hard-earned money is likely a scammer who profits off providing emotional value in exchange for exploitation.\" Others argue that while it's essential to find enjoyment and fulfillment in one's work, it's crucial not to shun or belittle those who choose to work in physically demanding or high-paying industries.\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n",
+      "Split 5, tokens 117, triggered by: 0.87\n",
+      "\u001b[31mOverall, the Weibo discussions offer a fascinating insight into the complexities of the modern Chinese labor market and the work-life balance that people strive to achieve. As in many countries, striking the right balance between work and play is an ongoing challenge for many Chinese citizens. However, the conversations on Weibo signal an increasing awareness of the importance of finding meaningful, fulfilling, and financially rewarding work that doesn't necessitate excessive sacrifice or sufferance. In the end, as one user succinctly puts it, \"Make sure you're earning your money in a way that brings you joy and satisfaction.\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n",
+      "Split 6, tokens 171, triggered by: 0.82\n",
+      "\u001b[32mThat's the only way to ensure that your life doesn't become a never-ending cycle of hard work without any tangible progress.\" In this context, social media discussions focusing on the trials and tribulations of earning money serve not only as an outlet for venting frustrations but also as a means of promoting dialogue and shared understanding about the challenges faced by workers across all industries. These virtual conversations sparked by tweets and in-depth discussions likely resonate with a wide swath of Chinese citizens struggling to navigate the complexities of balancing a career that pays well with one that brings them joy, fulfillment, and a sense of purpose. As the discussions on Weibo continue to evolve and unfold, it is evident that the discourse around work, money, and life satisfaction holds the potential to inspire meaningful change and shift societal attitudes towards a more holistic, balanced, and humane understanding of success and prosperity.\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n",
+      "Split 7, tokens 72, triggered by: 0.80\n",
+      "\u001b[34m--- Note: The translated tweets and user quotes from Chinese to English were used as the foundation for the long-form news article. The author tried to maintain the integrity of the original content in the translation while adapting it to fit a journalistic format. No inaccuracies were introduced during translation, and the opinion-based nature of the original content was preserved while maintaining objectivity.\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n",
+      "Split 8, tokens 23, triggered by: final split\n",
+      "\u001b[35mHeart count: 0/2 Note: The author did not include any Chinese characters in the final response. Collapse\u001b[0m\n",
+      "----------------------------------------------------------------------------------------\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "splitter.print(splits)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/examples/unstructured-element-splitter.ipynb b/docs/examples/unstructured-element-splitter.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..c13a6a59b1b90c4a9d1cd36016cf007ad5ab10af
--- /dev/null
+++ b/docs/examples/unstructured-element-splitter.ipynb
@@ -0,0 +1,340 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Partition elements using Unstructured library "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# It may take longer to install the package\n",
+    "!pip install -qU \\\n",
+    "    \"unstructured[pdf]==0.12.4\" \\\n",
+    "    \"semantic-router==0.0.24\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Start by downloading and processing an ArXiv paper."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "Some weights of the model checkpoint at microsoft/table-transformer-structure-recognition were not used when initializing TableTransformerForObjectDetection: ['model.backbone.conv_encoder.model.layer2.0.downsample.1.num_batches_tracked', 'model.backbone.conv_encoder.model.layer3.0.downsample.1.num_batches_tracked', 'model.backbone.conv_encoder.model.layer4.0.downsample.1.num_batches_tracked']\n",
+      "- This IS expected if you are initializing TableTransformerForObjectDetection from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).\n",
+      "- This IS NOT expected if you are initializing TableTransformerForObjectDetection from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).\n"
+     ]
+    }
+   ],
+   "source": [
+    "from unstructured.partition.auto import partition\n",
+    "\n",
+    "article_url = \"https://arxiv.org/pdf/2402.05131.pdf\"\n",
+    "elements = partition(url=article_url, strategy=\"hi_res\", pdf_infer_table_structure=True)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Define helper functions"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Validate if parsed title element is a real title"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import re\n",
+    "\n",
+    "\n",
+    "def is_valid_title(title: str) -> bool:\n",
+    "    # Rule 1: Title starts with a lowercase letter\n",
+    "    if re.match(r\"^[a-z]\", title):\n",
+    "        return False\n",
+    "    # Rule 2: Title has a special character (excluding :, -, and .)\n",
+    "    if re.search(r\"[^\\w\\s:\\-\\.]\", title):\n",
+    "        return False\n",
+    "    # Rule 3: Title ends with a dot\n",
+    "    if title.endswith(\".\"):\n",
+    "        return False\n",
+    "    return True"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Group elements by valid titles"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from unstructured.documents.elements import Element\n",
+    "from colorama import Fore, Style\n",
+    "\n",
+    "\n",
+    "def group_elements_by_title(elements: list[Element]) -> dict:\n",
+    "    grouped_elements = {}\n",
+    "    current_title = \"Untitled\"  # Default title for initial text without a title\n",
+    "\n",
+    "    for element in elements:\n",
+    "        element_dict = element.to_dict()\n",
+    "\n",
+    "        if element_dict.get(\"type\") == \"Title\":\n",
+    "            potential_title = element_dict.get(\"text\", \"Untitled\")\n",
+    "            if is_valid_title(potential_title):\n",
+    "                print(f\"{Fore.GREEN}{potential_title}: True{Style.RESET_ALL}\")\n",
+    "                current_title = potential_title\n",
+    "            else:\n",
+    "                print(f\"{Fore.RED}{potential_title}: False{Style.RESET_ALL}\")\n",
+    "                continue\n",
+    "        else:\n",
+    "            if current_title not in grouped_elements:\n",
+    "                grouped_elements[current_title] = []\n",
+    "            else:\n",
+    "                grouped_elements[current_title].append(element)\n",
+    "    return grouped_elements"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Generates chunks grouped elements using semantic RollingWindow splitter"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from semantic_router.splitters import RollingWindowSplitter\n",
+    "\n",
+    "\n",
+    "def create_title_chunks(\n",
+    "    grouped_elements: dict, splitter: RollingWindowSplitter\n",
+    ") -> list:\n",
+    "    title_with_chunks = []\n",
+    "    for title, elements in grouped_elements.items():\n",
+    "        if not elements:\n",
+    "            continue\n",
+    "        combined_element_texts = []\n",
+    "        chunks = []\n",
+    "\n",
+    "        for element in elements:\n",
+    "            if not element.text:\n",
+    "                continue\n",
+    "            element_dict = element.to_dict()\n",
+    "            if element_dict.get(\"type\") == \"Table\":\n",
+    "                # Process accumulated text before the table\n",
+    "                if combined_element_texts:\n",
+    "                    splits = splitter(combined_element_texts)\n",
+    "                    chunks.extend([split.content for split in splits])\n",
+    "                    combined_element_texts = []  # Reset combined texts after processing\n",
+    "\n",
+    "                # Add table as a separate chunk\n",
+    "                table_text_html = element.metadata.text_as_html\n",
+    "                chunks.append(table_text_html)\n",
+    "            else:\n",
+    "                combined_element_texts.append(element.text)\n",
+    "\n",
+    "        # Process any remaining accumulated text after the last table\n",
+    "        # or if no table was encountered\n",
+    "\n",
+    "        if combined_element_texts:\n",
+    "            splits = splitter(combined_element_texts)\n",
+    "            chunks.extend([split.content for split in splits])\n",
+    "\n",
+    "        if chunks:\n",
+    "            title_with_chunks.append({\"title\": title, \"chunks\": chunks})\n",
+    "\n",
+    "    return title_with_chunks"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Display chunked text in colors"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from IPython.display import display, HTML\n",
+    "import itertools\n",
+    "\n",
+    "\n",
+    "def print_chunks_by_title(chunks_by_title):\n",
+    "    color_cycle = itertools.cycle([\"red\", \"green\", \"blue\", \"magenta\"])\n",
+    "    html_output = \"\"\n",
+    "    for section in chunks_by_title:\n",
+    "        title = section[\"title\"]\n",
+    "        chunks = section[\"chunks\"]\n",
+    "        html_output += f\"<h3 style='color: black;'>{title}</h3>\"\n",
+    "        for chunk in chunks:\n",
+    "            color = next(color_cycle)\n",
+    "            html_output += f\"<p style='color: {color};'>{chunk}</p>\"\n",
+    "    display(HTML(html_output))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Process the elements"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os\n",
+    "from semantic_router.encoders import OpenAIEncoder\n",
+    "\n",
+    "encoder = OpenAIEncoder(openai_api_key=os.environ[\"OPENAI_API_KEY\"])\n",
+    "\n",
+    "splitter = RollingWindowSplitter(\n",
+    "    encoder=encoder,\n",
+    "    window_size=1,  # Compares each element with the previous one\n",
+    "    min_split_tokens=50,\n",
+    "    max_split_tokens=300,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\u001b[31met! ee: False\u001b[0m\n",
+      "\u001b[31mb e F 0 1: False\u001b[0m\n",
+      "\u001b[31m] L C . s c [: False\u001b[0m\n",
+      "\u001b[32mFinancial Report Chunking for Effective Retrieval Augmented Generation: True\u001b[0m\n",
+      "\u001b[32mIntroduction: True\u001b[0m\n",
+      "\u001b[31m2 Jimeno Yepes et al.: False\u001b[0m\n",
+      "\u001b[31m1 https://www.sec.gov 2 https://www.sec.gov/files/cf-frm.pdf: False\u001b[0m\n",
+      "\u001b[32m2 Related work: True\u001b[0m\n",
+      "\u001b[31m4 Jimeno Yepes et al.: False\u001b[0m\n",
+      "\u001b[32m3 Methods: True\u001b[0m\n",
+      "\u001b[32m3.1 RAG setting for the experiments: True\u001b[0m\n",
+      "\u001b[32m3.2 Indexing and retrieval: True\u001b[0m\n",
+      "\u001b[31m7 https://weaviate.io/developers/weaviate 8 https://huggingface.co/sentence-transformers/multi-qa-mpnet-base-dot-: False\u001b[0m\n",
+      "\u001b[31mv1: False\u001b[0m\n",
+      "\u001b[32m3.3 Generation: True\u001b[0m\n",
+      "\u001b[31mQuestion: {query}: False\u001b[0m\n",
+      "\u001b[32m3.4 Chunking: True\u001b[0m\n",
+      "\u001b[32m3.5 Dataset: True\u001b[0m\n",
+      "\u001b[32m4 Results: True\u001b[0m\n",
+      "\u001b[31m11 https://platform.openai.com/docs/guides/embeddings/limitations-risks: False\u001b[0m\n",
+      "\u001b[31m10 Jimeno Yepes et al.: False\u001b[0m\n",
+      "\u001b[32m5 Discussion: True\u001b[0m\n",
+      "\u001b[31m12 Jimeno Yepes et al.: False\u001b[0m\n",
+      "\u001b[32m6 Conclusions and Future Work: True\u001b[0m\n",
+      "\u001b[32mReferences: True\u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "grouped_elements = group_elements_by_title(elements)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "chunks_by_title = create_title_chunks(grouped_elements, splitter)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<h3 style='color: black;'>Untitled</h3><p style='color: red;'>2 v 1 3 1 5 0 . 2 0 4 2 : v i X r a</p><h3 style='color: black;'>Financial Report Chunking for Effective Retrieval Augmented Generation</h3><p style='color: green;'>Unstructured Technologies Sacramento, CA, USA leah@unstructured.io https://unstructured.io Abstract. Chunking information is a key step in Retrieval Augmented Generation (RAG). Current research primarily centers on paragraph- level chunking. This approach treats all texts as equal and neglects the information contained in the structure of documents. We propose an expanded approach to chunk documents by moving beyond mere paragraph-level chunking to chunk primary by structural element com- ponents of documents. Dissecting documents into these constituent ele- ments creates a new way to chunk documents that yields the best chunk size without tuning. We introduce a novel framework that evaluates how chunking based on element types annotated by document understanding models contributes to the overall context and accuracy of the informa- tion retrieved. We also demonstrate how this approach impacts RAG assisted Question & Answer task performance. Our research includes a comprehensive analysis of various element types, their role in effective information retrieval, and the impact they have on the quality of RAG outputs. Findings support that element type based chunking largely im- prove RAG results on financial reporting. Through this research, we are also able to answer how to uncover highly accurate RAG. Keywords: Retrieval Augmented Generation · Document Chunking · Document Pre-Processing · Financial Domain · Large Language Models</p><h3 style='color: black;'>Introduction</h3><p style='color: blue;'>contents of extensive documents [25,22,18]. By dissecting large volumes of text into smaller, more focused segments, LLMs can process each part with greater precision, ensuring a thorough understanding of each section. This segmented approach allows for meticulous analysis of unstructured data, enabling LLMs to construct a more comprehensive and coherent understanding of the entire docu- ment [41]. There remains a challenge in ensuring factual accuracy and relevance in the generated responses, especially when dealing with complex or extensive information. Recently, Retrieval Augmented Generation (RAG) [21,12] has been devel- oped to address the hallucination problem with LLMs [15,43] when recovering factual information directly from an LLM. In RAG, instead of answering a user query directly using an LLM, the user query is used to retrieve documents or segments from a corpus and the top retrieved documents or segments are used to generate the answer in conjunction with an LLM. In this way, RAG con- straints the answer to the set of retrieved documents. RAGs have been used as well to answer questions from single documents [14]. The documents are split into smaller parts or chunks, indexed by a retrieval system and recovered and processed depending on the user information need. In a sense, this process allows answering questions about information in a single document, thus contributing to the set of techniques available for document understanding.</p><p style='color: magenta;'>Since documents need to be chunked for RAG processing, this raises the question about what is the best practice to chunk documents for effective RAG document understanding. There are several dimensions to consider when decid- ing how to chunk a document, which includes the size of the chunks. The retrieval system in RAG can use traditional retrieval systems using bag- of-words methods or a vector database. If a vector database is used, then an embedding needs to be obtained from each chunk, thus the number of tokens in the chunk is relevant since the neural networks processing the chunks might have constraints on the number of tokens. As well, different chunk sizes might have undesirable retrieval results. Since the most relevant retrieved chunks need to be processed by an LLM, the number of tokens in retrieved chunks might have an effect in the generation of the answer [25]. As we see, chunking is re- quired for RAG systems and there are several advantages and disadvantages when considering how to chunk a document.</p><p style='color: red;'>In this work, we study specifically the chunking of U.S. Securities and Ex- change Commission (SEC)1 Financial Reports2, including 10-Ks, 10-Qs, and 8-Ks. This study plays a critical role in offering insights into the financial health and operational dynamics of public companies. These documents present unique challenges in terms of document processing and information extraction as they consist of varying sizes and layouts, and contain a variety of tabular informa- tion. Previous work has evaluated the processing of these reports with simple chunking strategies (e.g., tokens), but we believe that a more effective use of these reports might be achieved by a better pre-processing of the documents</p><p style='color: green;'>Financial Report Chunking for Effective Retrieval Augmented Generation and chunking configuration3 [14]. To the best of our knowledge, this is the first systematic study on chunking for document understanding and more specifically for processing financial reports.</p><h3 style='color: black;'>2 Related work</h3><p style='color: blue;'>Exploring the structure of financial reports is an exceptional area for es- tablishing optimal principles for chunking. The intricate nature of document structures and contents has resulted in most of the work processing financial reports focusing on the identification of structural elements. Among previous work, we find El-Haj et al. [10] and the FinTOC challenges [17,4,11] that have worked at the document structure level for UK and French financial reports. Ad- 3 https://www.cnbc.com/2023/12/19/gpt-and-other-ai-models-cant-analyze- an-sec-filing-researchers-find.html</p><p style='color: magenta;'>ditionally, there is recent work that considers U.S. SEC reports, which includes DocLayNet [33] and more specifically with the report tables in FinTabNet [45]. On the side of financial models, there is work in sentiment analysis in fi- nance [37], which includes the pre-training of specialised models such as Fin- BERT by Liu et al. [26], which is a BERT based model pre-trained on large corpora including large collections of financial news collected from different sites and FinBERT by DeSola et al, [9] trained on Wikipedia, BookCorpus and U.S. SEC data. Additional models include BloombergGPT [40], FinGPT [42] and Instruct-FinGPT[44]. More advance datasets in the financial domain include FinQA [6], LLMWare [27], ConFIRM [8] and TAT-QA [46] among others [7,38,19] that have been prepared for retrieval and or Questions and Answering (Q&A) tasks over snippets of fi- nancial data that includes tabular data, which has allowed methods on large language models to be tested on them [39]. Most of the previous work has focused on understanding the layout of fi- nancial documents or understanding specific snippets of existing reports with different levels of complexity, but there has not been much research in under- standing financial report documents, except some more recent work that includes FinanceBench [14], in which a set of questions about the content of financial re- ports are proposed that includes the evidence snippet.</p><p style='color: red;'>More specifically on document chunking methods for RAG, there are stan- dard approaches being considered such as chunking text into spans of a given token length (e.g. 128 and 256) or chunking based on sentences. Open source projects already allow simple processing of documents (e.g. Unstructured4, Lla- maindex5 or Langchain 6), without explicitly considering the table structure on which these chunking strategies are applied. Even though different approaches are available, an exhaustive evaluation of chunking applied to RAG and specifically to financial reporting, except for some limited chunking analysis [14,36], is non-existent. In our work, we compare a broad range of chunking approaches in addition to more simple ones and provide an analysis of the outcomes of different methods when asking questions about different aspects of the reports.</p><h3 style='color: black;'>3.1 RAG setting for the experiments</h3><p style='color: green;'>Financial Report Chunking for Effective Retrieval Augmented Generation document, the document is split into chunks and the chunks are indexed into a vector database (vectordb). When a question is sent to the RAG system, the top-k chunks most similar to the question are retrieved from the vector database and used to generate the answer using a large language model as generator. In order to retrieve chunks from the vector database, the question is encoded into a vector that is compared to the vector previously generated from the chunks. To prompt the generator, the question is converted into a set of instructions that instruct the LLM to find the answer within the top-k retrieved chunks. question vectordb top k question vector chunks encoder v | generator —+ answer * question to prompt + rome</p><p style='color: blue;'>Fig. 1. RAG steps to answer a question about a document In our experiments, we modify the way documents are chunked prior to being indexed in the vector database. All other settings remain constant. In the following sections, we describe in more detail each one of the components and processes used.</p><h3 style='color: black;'>3.2 Indexing and retrieval</h3><p style='color: magenta;'>As shown in figure 2, to index a document, first the document is split into chunks, then each chunk is processed by an encoder model and then indexed into the vector database. Based on the chunking strategy a document will be split into a larger or smaller set of chunks. chunks vectors Fig. 2. Indexing of document chunks into the vector database ttps://huggingface. co/sentence-transformers/multi-qa-mpnet-base-dot-</p><p style='color: red;'>6 Jimeno Yepes et al. As shown in figure 1, to retrieve chunks relevant to a question, the question is converted into a vector representation and the vector database returns a ranked list of chunks based on the similarity between question vector and the chunks in the database. Weaviate implements an approximate nearest neighbours algo- rithm [28] as their retrieval approach, which supports fast retrieval with high accuracy. In our experiments, we retrieve the top-10 chunks for each question.</p><h3 style='color: black;'>3.3 Generation</h3><p style='color: green;'>We have used GPT-4 [31] as the generator, which has shown best performance compared to earlier versions. As well, its performance was better compared to existing open source alternatives [22] such as Mixtral [16]. We used the prompt presented in figure 3 that we designed on another similar RAG implementation with different document types. The prompt conditions the answer to the query and the chunks, referred to as source, and if the generator cannot answer it should return No answer. please answer the question below by referencing the list of sources provided after the question; if the question can not be answered just respond ’No answer’. The sources are listed after \"Sources:\".  Question: {query}  Sources: {key} - {source} ...  Sources: {key} - {source} ...</p><p style='color: blue;'>Fig. 3. Example prompt template used by the generator</p><h3 style='color: black;'>3.4 Chunking</h3><p style='color: magenta;'>In addition to chunking based on the number of tokens, we have processed the documents using computer vision and natural language processing to extract elements identified in the reports. The list of elements considered are provided by the Unstructured9 open source library. From the set of processing strategies, 9 https://unstructured-io.github.io/unstructured/introduction.html# elements</p><p style='color: red;'>Financial Report Chunking for Effective Retrieval Augmented Generation we use Chipper, a vision encoder decoder10 model inspired by Donut [20] to showcase the performance difference. The Chipper model outputs results as a JSON representation of the document, listing elements per page characterized by their element type. Additionally, Chipper provides a bounding box enclosing each element on the page and the corresponding element text.</p><p style='color: green;'>These elements are sometimes short to be considered as chunks, so to gen- erate chunks from elements the following steps have been followed. Given the structure of finance reporting documents, our structural chunking efforts are con- centrated on processing titles, texts, and tables. The steps to generate element- based chunks are:</p><p style='color: blue;'>– if the element text length is smaller than 2,048 characters, a merge with the following element is attempted – iteratively, element texts are merged following the step above till either the desired length is achieved, without breaking the element – if a title element is found, a new chunk is started – if a table element is found, a new chunk is started, preserving the entire table After element-based chunks have been derived, three types of metadata are generated to enrich the content and support efficient indexing. The first two types, generated via predefined prompt templates with GPT-4, include: 1) up to 6 representative keywords of the composite chunk 2) a summarised paragraph of the composite chunk. The third type is 3) Naive representation using the first two sentences from a composite chunk (a kind of prefix) and in the case of tables, the description of the table, which is typically identified in the table caption.</p><h3 style='color: black;'>3.5 Dataset</h3><p style='color: magenta;'>This dataset is made of 150 instances with questions and answers from 84 unique reports. The dataset does not include the source documents, which we have downloaded. We were able to recover only 80 documents, which reduces the number of questions to 141 from the original 150. The distribution of Un- structured elements predictions are shown in table 1. Documents have a varying number of pages, spanning from 4 pages (FOOT- LOCKER 2022 8K dated-2022-05-20) to 549 pages (e.g. PEPSICO 2021 10K), with an average of 147.34 with std 97.78 with a total of 11,787 pages combined. Each instance contains a link to the report, the question, a question type , the answer and supporting evidence, with page number where the evidence is located 10 https://huggingface.co/docs/transformers/model_doc/vision-encoder- decoder 8 Jimeno Yepes et al. Table 1. Unstructured element types distribution for Chipper predictions against doc- uments in FinanceBench.</p><p style='color: red;'><table><thead><th>Element Type</th><th>[Chipper Entities</th></thead><tr><td>NarrativeText</td><td>61,780</td></tr><tr><td>Title</td><td>29,664</td></tr><tr><td>ListItem</td><td>33,054</td></tr><tr><td>UncategorizedText</td><td>9,400</td></tr><tr><td>Footer</td><td>1,026</td></tr><tr><td>Table</td><td>7,700</td></tr><tr><td>Header</td><td>3,959</td></tr><tr><td>Image</td><td>26</td></tr><tr><td>FigureCaption</td><td>54</td></tr><tr><td>Formula</td><td>29</td></tr><tr><td>Address</td><td>229</td></tr><tr><td>Total</td><td>146,921</td></tr></table></p><p style='color: green;'>in the document, that allows for a closer evaluation of the results. Based on the page number, evidence contexts are located in different areas in the documents, ranging from the first page in some cases up to page 304 in one instance. The mean page number to find the evidence is 54.58 with a standard deviation of 43.66, which shows that evidence contexts to answer the questions are spread within a document.</p><p style='color: blue;'>These characteristics make FinanceBench a perfect dataset for evaluating RAG. An example instance is available in table 2.</p><h3 style='color: black;'>4 Results</h3><p style='color: magenta;'>We are considering 80 documents and 141 questions from FinanceBench. Using the OpenAI tokenizer from the model text-embedding-ada-002 that uses the tokenizer cl100k base11, there are on average 102,444.35 tokens with std of 61,979.45, which shows the large variability of document lengths as seen by the different number of pages per document presented above. Chunking Efficiency The first thing we analyzed is the total number of chunks, as it impacts indexing time. We would like to observe the relationship between accuracy and total chunk size. Table 3 shows the number of chunks derived from each one of the processing methods. Unstructured element-based chunks are closer in size to Base 512, and as the chunk size decreases for the basic chunking strategies, the total number of chunks increases linearly. Financial Report Chunking for Effective Retrieval Augmented Generation Table 2. Example question from the FinanceBench dataset</p><p style='color: red;'><table><thead><th>Field</th><th>Value</th></thead><tr><td></td><td>financebench-id|financebench.id_00859</td></tr><tr><td>doc_name</td><td>VERIZON.2021_10K</td></tr><tr><td>doc_link</td><td>https: //www.verizon.com/about/sites/default /files/2021-Annual- Report-on-Form-10-K.pdf</td></tr><tr><td>question_type</td><td>*novel-generated’</td></tr><tr><td>question</td><td>Among all of the derivative instruments that Verizon used to manage] the exposure to fluctuations of foreign currencies exchange rates or interest rates, which one had the highest notional value in FY 2021?</td></tr><tr><td>answer</td><td>Cross currency swaps. Its notional value was $32,502 million.,</td></tr><tr><td>evidence_text</td><td>Derivative Instruments We enter into derivative transactions primarily to manage our exposure to fluctuations in foreign currency exchange rates and interest rates. We employ risk management strategies, which may include the use of a variety of derivatives including interest rate swaps, cross currency swaps, forward starting interest rate swaps, trea- sury rate locks, interest rate caps, swaptions and foreign exchange for- wards. We do not hold derivatives for trading purposes. The following table sets forth the notional amounts of our outstanding derivative in- struments: (dollars in millions) At December 31, 2021 2020 Interest rate swaps $ 19,779 $ 17,768 Cross currency swaps 32,502 26,288 Forward starting interest rate 1,000 2,000 Foreign exchange forwards 932</td></tr><tr><td>page-number</td><td></td></tr></table></p><p style='color: green;'>Table 3. Chunks statistics for basic chunking elements and Unstructured elements</p><p style='color: blue;'><table><thead><th>Processing|total</th><th>chunks|mean</th><th>chunks per document</th><th>(std)|tables mean (std)</th></thead><tr><td>Base 128</td><td>| 64,058</td><td>800.73 (484.11)</td><td></td></tr><tr><td>Base 256</td><td>| 32,051</td><td>400.64 (242.04) (</td><td></td></tr><tr><td>Base 512</td><td>| 16,046</td><td>200.58 (121. 01)</td><td></td></tr><tr><td>Chipper</td><td>20,843</td><td>260.57 (145.80)</td><td>96.20 (57.53)</td></tr></table></p><p style='color: magenta;'>Retrieval Accuracy Secondly, we evaluate the capabilities of each chunking strategy in terms of retrieval accuracy. We use the page numbers in the ground truth to calculate the page-level retrieval accuracy, and we use ROUGE [24] and BLEU [32] scores to evaluate the accuracy of paragraph-level retrieval compared to the ground truth evidence paragraphs. As shown in Table 4, when compared to Unstructured element-based chunk- ing strategies, basic chunking strategies seem to have higher page-level retrieval accuracy but lower paragraph-level accuracy on average. Additionally, basic chunking strategies also lack consistency between page-level and paragraph-level accuracy; higher page-level accuracy doesn’t ensure higher paragraph-level ac- curacy. For example, Base 128 has the second highest page-level accuracy but the lowest paragraph-level scores among all. On the other hand, element-based chunking strategies showed more consistent results. A fascinating discovery is that when various chunking strategies are com- bined, it results in enhanced retrieval scores, achieving superior performance at both the page level (84.4%) and paragraph level (with ROUGE at 0.568% and BLEU at 0.452%). This finding addresses an unresolved question: how to improve the accuracy of RAG.</p><p style='color: red;'>The element based method provides the highest scores and it also provides a mechanism to chunk documents without the need to fine tune hyper-parameters like the number of tokens in a chunk. This suggests the element based method is more generalizable and can be applied to new types of documents.</p><p style='color: green;'>Q&A Accuracy Third, we evaluate the Q&A accuracy for the chunking strate- gies. In addition to manual evaluation, we have investigated an automatic evalua- tion using GPT-4. GPT-4 compares how the answers provided by our method are similar to or different from the FinanceBench gold standard, similar approaches have been previously evaluated [13,23,29,30]. The automatic evaluation allows scaling the evaluation efforts for the different chunking strategies that we have considered. We used the prompt template in figure 4.</p><p style='color: blue;'>Begin with True or False. Are the two following answers (Answer 1 and Answer 2) the same with respect to the question between single quotes ’{question}’?  Answer 1: ’{ground_truth_answer}’ Answer 2: ’{generated_answer}’  Fig. 4. Evaluation prompt template. The {question}, {ground truth answer} and {generated answer} fields are substituted for each question accordingly.</p><p style='color: magenta;'>Results in table 5 show that element-based chunking strategies offer the best question-answering accuracy, which is consistent with page retrieval and para- graph retrieval accuracy. Lastly, our approach stands out for its efficiency. Not only is element-based chunking generalizable without the need to select the chunk size, but when com- pared to the aggregation results that yield the highest retrieval scores. Element- based chunking achieves the highest retrieval scores with only half the number of chunks required compared to methods that do not consider the structure of the documents (62,529 v.s. 112,155). This can reduce the indexing cost and im- prove query latency because there are only half as many vectors to index for the vectordb that stores the chunks. This underscores the effectiveness of our solu- tion in optimizing the balance between performance and computational resource requirements. Financial Report Chunking for Effective Retrieval Augmented Generation</p><p style='color: red;'>Table 4. Retrieval results. For each chunking strategy, we show the number of chunks for all the documents (Total Chunks), Page Accuracy, and ROUGE and BLEU scores. ROUGE and BLEU are calculated as the maximum score from the list of recovered contexts for a question when compared to the known evidence for that question.</p><p style='color: green;'><table><thead><th>Chunking strategy</th><th>Total Chunks}</th><th>Page Accuracy</th><th>ROUGE|BLEU.</th></thead><tr><td>Base 128</td><td>64,058</td><td>72.34</td><td>0.383</td></tr><tr><td>Base 256</td><td>32,051</td><td>73.05</td><td>0.433</td></tr><tr><td>Base 512</td><td>16,046</td><td>68.09</td><td>0.455</td></tr><tr><td>Base Aggregation</td><td>112,155</td><td>83.69</td><td>0.536</td></tr><tr><td>Keywords Chipper</td><td></td><td>46.10</td><td>0.444</td></tr><tr><td>Summary Chipper</td><td></td><td>62.41</td><td>0.473</td></tr><tr><td>Prefix &amp; Table Description Chipper</td><td></td><td>67.38</td><td>0.514</td></tr><tr><td>Chipper Aggregation</td><td>a</td><td>84.40</td><td>0.568</td></tr></table></p><p style='color: blue;'>Table 5. Q&A results. We show the percentage of questions with no answer and as well the accuracy either estimated automatically using GPT-4 or manually.</p><p style='color: magenta;'><table><thead><th>Chunking strategy</th><th>No</th><th></th><th>answer|GPT-4|Manual</th></thead><tr><td>Base 128</td><td>35.46</td><td>29.08</td><td>| 35.46</td></tr><tr><td>Base 256</td><td>5.5¢</td><td>32.62</td><td>| 36.88</td></tr><tr><td>Base 512</td><td>24.82</td><td>41.84</td><td>| 48.23</td></tr><tr><td>Keywords Chipper</td><td>22.70 |</td><td>43.97]</td><td>53.19</td></tr><tr><td>Summary Chipper</td><td>17.73</td><td>|43.97])</td><td>51.77</td></tr><tr><td>Prefix &amp; Table Description Chipper]</td><td>20.57</td><td>41.13</td><td>| 53.19</td></tr></table></p><h3 style='color: black;'>5 Discussion</h3><p style='color: red;'>We have observed that using basic 512 chunking strategies produces results most similar to the Unstructured element-based approach, which may be due to the fact that 512 tokens share a similar length with the token size within our element-based chunks and capture a long context, but fail keep a coherent context in some cases, leaving out relevant information required for Q&A. This is further observed when considering the ROUGE and BLEU scores in table 4, where the chunk contexts for the baseline have lower scores. These findings support existing research stating that the best basic chunk size varies from data to data [3]. These results show, as well, that our method adapts to different documents without tuning. Our method relies on the struc- tural information that is present in the document’s layout to adjust the chunk size automatically.</p><p style='color: green;'>We have evaluated aggregating the output of different chunking methods in the retrieval experiments as sown in table 4. Even though the aggregation seems to be effective for retrieval, the Q&A exceeded the GPT-4 token limit, which resulted in a non-effective Q&A solution using the selected model. As well, we evaluated variations of the prompt used to generate the answers (see figure 3). Re-ordering the retrieval context and the question, but results were not statistically different. We experimented as well with variations of the verbs using in the prompt, e.g. changing referencing with using, which seemed to lower the quality of the answers generated. This shows that prompt engineering is a relevant factor in RAG. We evaluated using GPT-4 for evaluation instead of relying on manual evalu- ation. In most cases, GPT-4 evaluated correctly but failed when a more elaborate answer is provided. As shown in figure 5, the answer is 39.7% while the estimated answer is 39.73% but with a detailed explanation of the calculation.</p><p style='color: blue;'>Question: ’What is Coca Cola’s FY2021 COGS % margin? Calculate what was asked by utilizing the line items clearly shown in the income statement.’?  Answer 1: ’39.7%’ Answer 2: ’From the income statement referenced on page 60 of COCACOLA_2021_10K_embedded.json, we can see that Coca Cola’s total revenue in FY2021 was $38,655 million and their cost of goods sold (COGS) was $15,357 million. To calculate the COGS % margin, we divide the COGS by the total revenue and multiply by 100: (15,357 / 38,655) * 100 = 39.73% So, Coca Cola’s FY2021 COGS % margin was approximately 39.73%.’ </p><p style='color: magenta;'>Fig. 5. Evaluation prompt template</p><h3 style='color: black;'>6 Conclusions and Future Work</h3><p style='color: red;'>Financial Report Chunking for Effective Retrieval Augmented Generation Furthermore, we would like to study the impact of RAG configuration and ele- ment type based chunking.</p><h3 style='color: black;'>References</h3><p style='color: green;'>2. Balaguer, A., Benara, V., de Freitas Cunha, R.L., de M. Estev˜ao Filho, R., Hendry, T., Holstein, D., Marsman, J., Mecklenburg, N., Malvar, S., Nunes, L.O., Padilha, R., Sharp, M., Silva, B., Sharma, S., Aski, V., Chandra, R.: Rag vs fine-tuning: Pipelines, tradeoffs, and a case study on agriculture (2024) 3. Barnett, S., Kurniawan, S., Thudumu, S., Brannelly, Z., Abdelrazek, M.: Seven Failure Points When Engineering a Retrieval Augmented Generation System (2024)</p><p style='color: blue;'>4. Bentabet, N.I., Juge, R., El Maarouf, I., Mouilleron, V., Valsamou-Stanislawski, D., El-Haj, M.: The financial document structure extraction shared task (fintoc 2020). In: Proceedings of the 1st Joint Workshop on Financial Narrative Processing and MultiLing Financial Summarisation. pp. 13–22 (2020)</p><p style='color: magenta;'>5. Chen, H., Jiao, F., Li, X., Qin, C., Ravaut, M., Zhao, R., Xiong, C., Joty, S.: Chat- GPT’s One-year Anniversary: Are Open-Source Large Language Models Catching up? arXiv preprint arXiv:2311.16989 (2023) 6. Chen, Z., Chen, W., Smiley, C., Shah, S., Borova, I., Langdon, D., Moussa, R., Beane, M., Huang, T.H., Routledge, B., et al.: Finqa: A dataset of numerical reasoning over financial data. arXiv preprint arXiv:2109.00122 (2021) 7. Chen, Z., Li, S., Smiley, C., Ma, Z., Shah, S., Wang, W.Y.: ConvFinQA: Exploring the Chain of Numerical Reasoning in Conversational Finance Question Answering (2022) 8. Choi, S., Gazeley, W., Wong, S.H., Li, T.: Conversational Financial Information Retrieval Model (ConFIRM). arXiv preprint arXiv:2310.13001 (2023)</p><p style='color: red;'>9. DeSola, V., Hanna, K., Nonis, P.: Finbert: pre-trained model on sec filings for financial natural language tasks. University of California (2019) 10. El-Haj, M., Rayson, P., Young, S., Walker, M.: Detecting document structure in a very large corpus of UK financial reports. European Language Resources Associa- tion (ELRA) (2014) 11. El Maarouf, I., Kang, J., Azzi, A.A., Bellato, S., Gan, M., El-Haj, M.: The financial document structure extraction shared task (FinTOC2021). In: Proceedings of the 3rd Financial Narrative Processing Workshop. pp. 111–119 (2021)</p><p style='color: green;'>12. Gao, Y., Xiong, Y., Gao, X., Jia, K., Pan, J., Bi, Y., Dai, Y., Sun, J., Wang, H.: Retrieval-augmented generation for large language models: A survey. arXiv preprint arXiv:2312.10997 (2023) 13. Hada, R., Gumma, V., de Wynter, A., Diddee, H., Ahmed, M., Choudhury, M., Bali, K., Sitaram, S.: Are large language model-based evaluators the solution to scaling up multilingual evaluation? arXiv preprint arXiv:2309.07462 (2023) 14. Islam, P., Kannappan, A., Kiela, D., Qian, R., Scherrer, N., Vidgen, B.: Fi- nanceBench: A New Benchmark for Financial Question Answering. arXiv preprint arXiv:2311.11944 (2023)</p><p style='color: blue;'>15. Ji, Z., Lee, N., Frieske, R., Yu, T., Su, D., Xu, Y., Ishii, E., Bang, Y.J., Madotto, A., Fung, P.: Survey of Hallucination in Natural Language Generation. ACM Comput- ing Surveys 55(12), 1–38 (Mar 2023). https://doi.org/10.1145/3571730, http:// dx.doi.org/10.1145/3571730</p><p style='color: magenta;'>14 Jimeno Yepes et al. 16. Jiang, A.Q., Sablayrolles, A., Roux, A., Mensch, A., Savary, B., Bamford, C., Chaplot, D.S., de las Casas, D., Hanna, E.B., Bressand, F., Lengyel, G., Bour, G., Lample, G., Lavaud, L.R., Saulnier, L., Lachaux, M.A., Stock, P., Subramanian, S., Yang, S., Antoniak, S., Scao, T.L., Gervet, T., Lavril, T., Wang, T., Lacroix, T., Sayed, W.E.: Mixtral of Experts (2024)</p><p style='color: red;'>17. Juge, R., Bentabet, I., Ferradans, S.: The fintoc-2019 shared task: Financial doc- ument structure extraction. In: Proceedings of the Second Financial Narrative Processing Workshop (FNP 2019). pp. 51–57 (2019)</p><p style='color: green;'>18. Kaddour, J., Harris, J., Mozes, M., Bradley, H., Raileanu, R., McHardy, R.: Chal- lenges and applications of large language models. arXiv preprint arXiv:2307.10169 (2023)</p><p style='color: blue;'>19. Kaur, S., Smiley, C., Gupta, A., Sain, J., Wang, D., Siddagangappa, S., Aguda, T., Shah, S.: REFinD: Relation Extraction Financial Dataset. In: the 46th International ACM SIGIR Conference on Re- Proceedings of search and Development in Information Retrieval. SIGIR ’23, ACM (Jul 2023). https://doi.org/10.1145/3539618.3591911, http://dx.doi.org/10.1145/ 3539618.3591911</p><p style='color: magenta;'>20. Kim, G., Hong, T., Yim, M., Park, J., Yim, J., Hwang, W., Yun, S., Han, D., Park, S.: Donut: Document understanding transformer without ocr. arXiv preprint arXiv:2111.15664 7, 15 (2021) 21. Lewis, P., Perez, E., Piktus, A., Petroni, F., Karpukhin, V., Goyal, N., K¨uttler, H., Lewis, M., Yih, W.t., Rockt¨aschel, T., et al.: Retrieval-augmented generation for knowledge-intensive NLP tasks. Advances in Neural Information Processing Systems 33, 9459–9474 (2020)</p><p style='color: red;'>22. Li, D., Shao, R., Xie, A., Sheng, Y., Zheng, L., Gonzalez, J.E., Stoica, I., Ma, X., Zhang, H.: How Long Can Open-Source LLMs Truly Promise on Context Length? (June 2023), https://lmsys.org/blog/2023-06-29-longchat</p><p style='color: green;'>23. Li, Y., Duan, Y.: The evaluation of experiments of artificial general intelligence with gpt-4 based on dikwp. arXiv preprint (2023) 24. Lin, C.Y.: Rouge: A package for automatic evaluation of summaries. In: Text sum- marization branches out. pp. 74–81 (2004) 25. Liu, N.F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F., Liang, P.: Lost in the middle: How language models use long contexts. arXiv preprint arXiv:2307.03172 (2023) 26. Liu, Z., Huang, D., Huang, K., Li, Z., Zhao, J.: Finbert: A pre-trained financial language representation model for financial text mining. In: Proceedings of the twenty-ninth international conference on international joint conferences on artificial intelligence. pp. 4513–4519 (2021) llmware: Rag Instruct Benchmark Tester. https://huggingface.co/datasets/ llmware/rag_instruct_benchmark_tester, Accessed: January 15, 2024</p><p style='color: blue;'>28. Malkov, Y.A., Yashunin, D.A.: Efficient and robust approximate nearest neigh- bor search using hierarchical navigable small world graphs. IEEE transactions on pattern analysis and machine intelligence 42(4), 824–836 (2018)</p><p style='color: magenta;'>29. Moore, S., Nguyen, H.A., Chen, T., Stamper, J.: Assessing the quality of multiple- choice questions using gpt-4 and rule-based methods. In: European Conference on Technology Enhanced Learning. pp. 229–245. Springer (2023) 30. Naismith, B., Mulcaire, P., Burstein, J.: Automated evaluation of written discourse coherence using gpt-4. In: Proceedings of the 18th Workshop on Innovative Use of NLP for Building Educational Applications (BEA 2023). pp. 394–403 (2023) 31. OpenAI, :, Achiam, J., Adler, S., Agarwal, S., et al.: GPT-4 Technical Report</p><p style='color: red;'>(2023) Financial Report Chunking for Effective Retrieval Augmented Generation 32. Papineni, K., Roukos, S., Ward, T., Zhu, W.J.: Bleu: a method for automatic evaluation of machine translation. In: Proceedings of the 40th annual meeting of the Association for Computational Linguistics. pp. 311–318 (2002) 33. Pfitzmann, B., Auer, C., Dolfi, M., Nassar, A.S., Staar, P.: Doclaynet: A large human-annotated dataset for document-layout segmentation. In: Proceedings of the 28th ACM SIGKDD Conference on Knowledge Discovery and Data Mining. pp. 3743–3751 (2022)</p><p style='color: green;'>34. Pinecone: Chunking strategies for llm applications, https://www.pinecone.io/ learn/chunking-strategies/ 35. Reimers, N., Gurevych, I.: Sentence-bert: Sentence embeddings using siamese bert- networks. In: Proceedings of the 2019 Conference on Empirical Methods in Nat- ural Language Processing. Association for Computational Linguistics (11 2019), https://arxiv.org/abs/1908.10084</p><p style='color: blue;'>36. Retteter, J.: Mastering Table Extraction: Revolutionize Your Earnings Re- ports Analysis with AI. https://medium.com/unstructured-io/mastering- table-extraction-revolutionize-your-earnings-reports-analysis-with- ai-1bc32c22720e, Accessed: January 15, 2024 37. Rizinski, M., Peshov, H., Mishev, K., Jovanovik, M., Trajanov, D.: Sentiment Anal- ysis in Finance: From Transformers Back to eXplainable Lexicons (XLex) (2023) 38. Shah, R.S., Chawla, K., Eidnani, D., Shah, A., Du, W., Chava, S., Raman, N., Smiley, C., Chen, J., Yang, D.: WHEN FLUE MEETS FLANG: Benchmarks and Large Pre-trained Language Model for Financial Domain (2022) 39. Singh Phogat, K., Harsha, C., Dasaratha, S., Ramakrishna, S., Akhil Puranam, S.: Zero-Shot Question Answering over Financial Documents using Large Language Models. arXiv e-prints pp. arXiv–2311 (2023)</p><p style='color: magenta;'>40. Wu, S., Irsoy, O., Lu, S., Dabravolski, V., Dredze, M., Gehrmann, S., Kambadur, P., Rosenberg, D., Mann, G.: BloombergGPT: A Large Language Model for Finance (2023) 41. Xu, P., Ping, W., Wu, X., McAfee, L., Zhu, C., Liu, Z., Subramanian, S., Bakhtu- rina, E., Shoeybi, M., Catanzaro, B.: Retrieval meets Long Context Large Language Models (2023) 42. Yang, H., Liu, X.Y., Wang, C.D.: FinGPT: Open-Source Financial Large Language Models (2023) 43. Ye, H., Liu, T., Zhang, A., Hua, W., Jia, W.: Cognitive Mirage: A Review of Hallucinations in Large Language Models (2023) 44. Zhang, B., Yang, H., Liu, X.Y.: Instruct-FinGPT: Financial Sentiment Analysis by Instruction Tuning of General-Purpose Large Language Models (2023)</p><p style='color: red;'>45. Zheng, X., Burdick, D., Popa, L., Zhong, X., Wang, N.X.R.: Global table extractor (gte): A framework for joint table identification and cell structure recognition using visual context. In: Proceedings of the IEEE/CVF winter conference on applications of computer vision. pp. 697–706 (2021) 46. Zhu, F., Lei, W., Huang, Y., Wang, C., Zhang, S., Lv, J., Feng, F., Chua, T.S.: TAT-QA: A question answering benchmark on a hybrid of tabular and textual content in finance. arXiv preprint arXiv:2105.07624 (2021)</p>"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "print_chunks_by_title(chunks_by_title)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "---"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.18"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/poetry.lock b/poetry.lock
index 1f68d5a7e70ac6c73db6fe986666a264df5417fe..fff4911a18d411f8d16f02740c7becdf57f58d02 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -123,13 +123,13 @@ files = [
 
 [[package]]
 name = "anyio"
-version = "4.2.0"
+version = "4.3.0"
 description = "High level compatibility layer for multiple asynchronous event loop implementations"
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"},
-    {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"},
+    {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"},
+    {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"},
 ]
 
 [package.dependencies]
@@ -449,13 +449,13 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
 
 [[package]]
 name = "cohere"
-version = "4.47"
+version = "4.49"
 description = "Python SDK for the Cohere API"
 optional = false
 python-versions = ">=3.8,<4.0"
 files = [
-    {file = "cohere-4.47-py3-none-any.whl", hash = "sha256:8b96a1ab57713eceffb4ffd58bf647055676fb741a4e5153c14296f9814c77fa"},
-    {file = "cohere-4.47.tar.gz", hash = "sha256:d689212079c1a545bd497b143cff7aa5632831fa6cf41bf7acc93b4a6effb839"},
+    {file = "cohere-4.49-py3-none-any.whl", hash = "sha256:145fdf55e44c50bc69d892d124cf47534686a30e3d83bd94c350513196d19def"},
+    {file = "cohere-4.49.tar.gz", hash = "sha256:509e81c44f8e1b4eb31b27d8ea388e79e04c5bee8308ac1a337a6053dd3f5a87"},
 ]
 
 [package.dependencies]
@@ -528,65 +528,128 @@ traitlets = ">=4"
 [package.extras]
 test = ["pytest"]
 
+[[package]]
+name = "contourpy"
+version = "1.2.0"
+description = "Python library for calculating contours of 2D quadrilateral grids"
+optional = true
+python-versions = ">=3.9"
+files = [
+    {file = "contourpy-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0274c1cb63625972c0c007ab14dd9ba9e199c36ae1a231ce45d725cbcbfd10a8"},
+    {file = "contourpy-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab459a1cbbf18e8698399c595a01f6dcc5c138220ca3ea9e7e6126232d102bb4"},
+    {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fdd887f17c2f4572ce548461e4f96396681212d858cae7bd52ba3310bc6f00f"},
+    {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d16edfc3fc09968e09ddffada434b3bf989bf4911535e04eada58469873e28e"},
+    {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c203f617abc0dde5792beb586f827021069fb6d403d7f4d5c2b543d87edceb9"},
+    {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b69303ceb2e4d4f146bf82fda78891ef7bcd80c41bf16bfca3d0d7eb545448aa"},
+    {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:884c3f9d42d7218304bc74a8a7693d172685c84bd7ab2bab1ee567b769696df9"},
+    {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1b1208102be6e851f20066bf0e7a96b7d48a07c9b0cfe6d0d4545c2f6cadab"},
+    {file = "contourpy-1.2.0-cp310-cp310-win32.whl", hash = "sha256:34b9071c040d6fe45d9826cbbe3727d20d83f1b6110d219b83eb0e2a01d79488"},
+    {file = "contourpy-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:bd2f1ae63998da104f16a8b788f685e55d65760cd1929518fd94cd682bf03e41"},
+    {file = "contourpy-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd10c26b4eadae44783c45ad6655220426f971c61d9b239e6f7b16d5cdaaa727"},
+    {file = "contourpy-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5c6b28956b7b232ae801406e529ad7b350d3f09a4fde958dfdf3c0520cdde0dd"},
+    {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebeac59e9e1eb4b84940d076d9f9a6cec0064e241818bcb6e32124cc5c3e377a"},
+    {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139d8d2e1c1dd52d78682f505e980f592ba53c9f73bd6be102233e358b401063"},
+    {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e9dc350fb4c58adc64df3e0703ab076f60aac06e67d48b3848c23647ae4310e"},
+    {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18fc2b4ed8e4a8fe849d18dce4bd3c7ea637758c6343a1f2bae1e9bd4c9f4686"},
+    {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:16a7380e943a6d52472096cb7ad5264ecee36ed60888e2a3d3814991a0107286"},
+    {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d8faf05be5ec8e02a4d86f616fc2a0322ff4a4ce26c0f09d9f7fb5330a35c95"},
+    {file = "contourpy-1.2.0-cp311-cp311-win32.whl", hash = "sha256:67b7f17679fa62ec82b7e3e611c43a016b887bd64fb933b3ae8638583006c6d6"},
+    {file = "contourpy-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:99ad97258985328b4f207a5e777c1b44a83bfe7cf1f87b99f9c11d4ee477c4de"},
+    {file = "contourpy-1.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:575bcaf957a25d1194903a10bc9f316c136c19f24e0985a2b9b5608bdf5dbfe0"},
+    {file = "contourpy-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9e6c93b5b2dbcedad20a2f18ec22cae47da0d705d454308063421a3b290d9ea4"},
+    {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:464b423bc2a009088f19bdf1f232299e8b6917963e2b7e1d277da5041f33a779"},
+    {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68ce4788b7d93e47f84edd3f1f95acdcd142ae60bc0e5493bfd120683d2d4316"},
+    {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7d1f8871998cdff5d2ff6a087e5e1780139abe2838e85b0b46b7ae6cc25399"},
+    {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e739530c662a8d6d42c37c2ed52a6f0932c2d4a3e8c1f90692ad0ce1274abe0"},
+    {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:247b9d16535acaa766d03037d8e8fb20866d054d3c7fbf6fd1f993f11fc60ca0"},
+    {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:461e3ae84cd90b30f8d533f07d87c00379644205b1d33a5ea03381edc4b69431"},
+    {file = "contourpy-1.2.0-cp312-cp312-win32.whl", hash = "sha256:1c2559d6cffc94890b0529ea7eeecc20d6fadc1539273aa27faf503eb4656d8f"},
+    {file = "contourpy-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:491b1917afdd8638a05b611a56d46587d5a632cabead889a5440f7c638bc6ed9"},
+    {file = "contourpy-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5fd1810973a375ca0e097dee059c407913ba35723b111df75671a1976efa04bc"},
+    {file = "contourpy-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:999c71939aad2780f003979b25ac5b8f2df651dac7b38fb8ce6c46ba5abe6ae9"},
+    {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7caf9b241464c404613512d5594a6e2ff0cc9cb5615c9475cc1d9b514218ae8"},
+    {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:266270c6f6608340f6c9836a0fb9b367be61dde0c9a9a18d5ece97774105ff3e"},
+    {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbd50d0a0539ae2e96e537553aff6d02c10ed165ef40c65b0e27e744a0f10af8"},
+    {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11f8d2554e52f459918f7b8e6aa20ec2a3bce35ce95c1f0ef4ba36fbda306df5"},
+    {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ce96dd400486e80ac7d195b2d800b03e3e6a787e2a522bfb83755938465a819e"},
+    {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d3364b999c62f539cd403f8123ae426da946e142312a514162adb2addd8d808"},
+    {file = "contourpy-1.2.0-cp39-cp39-win32.whl", hash = "sha256:1c88dfb9e0c77612febebb6ac69d44a8d81e3dc60f993215425b62c1161353f4"},
+    {file = "contourpy-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:78e6ad33cf2e2e80c5dfaaa0beec3d61face0fb650557100ee36db808bfa6843"},
+    {file = "contourpy-1.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be16975d94c320432657ad2402f6760990cb640c161ae6da1363051805fa8108"},
+    {file = "contourpy-1.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b95a225d4948b26a28c08307a60ac00fb8671b14f2047fc5476613252a129776"},
+    {file = "contourpy-1.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0d7e03c0f9a4f90dc18d4e77e9ef4ec7b7bbb437f7f675be8e530d65ae6ef956"},
+    {file = "contourpy-1.2.0.tar.gz", hash = "sha256:171f311cb758de7da13fc53af221ae47a5877be5a0843a9fe150818c51ed276a"},
+]
+
+[package.dependencies]
+numpy = ">=1.20,<2.0"
+
+[package.extras]
+bokeh = ["bokeh", "selenium"]
+docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"]
+mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.6.1)", "types-Pillow"]
+test = ["Pillow", "contourpy[test-no-images]", "matplotlib"]
+test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"]
+
 [[package]]
 name = "coverage"
-version = "7.4.1"
+version = "7.4.2"
 description = "Code coverage measurement for Python"
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"},
-    {file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"},
-    {file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"},
-    {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"},
-    {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"},
-    {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"},
-    {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"},
-    {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"},
-    {file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"},
-    {file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"},
-    {file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"},
-    {file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"},
-    {file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"},
-    {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"},
-    {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"},
-    {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"},
-    {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"},
-    {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"},
-    {file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"},
-    {file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"},
-    {file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"},
-    {file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"},
-    {file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"},
-    {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"},
-    {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"},
-    {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"},
-    {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"},
-    {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"},
-    {file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"},
-    {file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"},
-    {file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"},
-    {file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"},
-    {file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"},
-    {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"},
-    {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"},
-    {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"},
-    {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"},
-    {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"},
-    {file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"},
-    {file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"},
-    {file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"},
-    {file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"},
-    {file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"},
-    {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"},
-    {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"},
-    {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"},
-    {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"},
-    {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"},
-    {file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"},
-    {file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"},
-    {file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"},
-    {file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"},
+    {file = "coverage-7.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf54c3e089179d9d23900e3efc86d46e4431188d9a657f345410eecdd0151f50"},
+    {file = "coverage-7.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fe6e43c8b510719b48af7db9631b5fbac910ade4bd90e6378c85ac5ac706382c"},
+    {file = "coverage-7.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b98c89db1b150d851a7840142d60d01d07677a18f0f46836e691c38134ed18b"},
+    {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5f9683be6a5b19cd776ee4e2f2ffb411424819c69afab6b2db3a0a364ec6642"},
+    {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78cdcbf7b9cb83fe047ee09298e25b1cd1636824067166dc97ad0543b079d22f"},
+    {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2599972b21911111114100d362aea9e70a88b258400672626efa2b9e2179609c"},
+    {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ef00d31b7569ed3cb2036f26565f1984b9fc08541731ce01012b02a4c238bf03"},
+    {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:20a875bfd8c282985c4720c32aa05056f77a68e6d8bbc5fe8632c5860ee0b49b"},
+    {file = "coverage-7.4.2-cp310-cp310-win32.whl", hash = "sha256:b3f2b1eb229f23c82898eedfc3296137cf1f16bb145ceab3edfd17cbde273fb7"},
+    {file = "coverage-7.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7df95fdd1432a5d2675ce630fef5f239939e2b3610fe2f2b5bf21fa505256fa3"},
+    {file = "coverage-7.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8ddbd158e069dded57738ea69b9744525181e99974c899b39f75b2b29a624e2"},
+    {file = "coverage-7.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81a5fb41b0d24447a47543b749adc34d45a2cf77b48ca74e5bf3de60a7bd9edc"},
+    {file = "coverage-7.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2412e98e70f16243be41d20836abd5f3f32edef07cbf8f407f1b6e1ceae783ac"},
+    {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb79414c15c6f03f56cc68fa06994f047cf20207c31b5dad3f6bab54a0f66ef"},
+    {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf89ab85027427d351f1de918aff4b43f4eb5f33aff6835ed30322a86ac29c9e"},
+    {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a178b7b1ac0f1530bb28d2e51f88c0bab3e5949835851a60dda80bff6052510c"},
+    {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:06fe398145a2e91edaf1ab4eee66149c6776c6b25b136f4a86fcbbb09512fd10"},
+    {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:18cac867950943fe93d6cd56a67eb7dcd2d4a781a40f4c1e25d6f1ed98721a55"},
+    {file = "coverage-7.4.2-cp311-cp311-win32.whl", hash = "sha256:f72cdd2586f9a769570d4b5714a3837b3a59a53b096bb954f1811f6a0afad305"},
+    {file = "coverage-7.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:d779a48fac416387dd5673fc5b2d6bd903ed903faaa3247dc1865c65eaa5a93e"},
+    {file = "coverage-7.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:adbdfcda2469d188d79771d5696dc54fab98a16d2ef7e0875013b5f56a251047"},
+    {file = "coverage-7.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ac4bab32f396b03ebecfcf2971668da9275b3bb5f81b3b6ba96622f4ef3f6e17"},
+    {file = "coverage-7.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:006d220ba2e1a45f1de083d5022d4955abb0aedd78904cd5a779b955b019ec73"},
+    {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3733545eb294e5ad274abe131d1e7e7de4ba17a144505c12feca48803fea5f64"},
+    {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42a9e754aa250fe61f0f99986399cec086d7e7a01dd82fd863a20af34cbce962"},
+    {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2ed37e16cf35c8d6e0b430254574b8edd242a367a1b1531bd1adc99c6a5e00fe"},
+    {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b953275d4edfab6cc0ed7139fa773dfb89e81fee1569a932f6020ce7c6da0e8f"},
+    {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32b4ab7e6c924f945cbae5392832e93e4ceb81483fd6dc4aa8fb1a97b9d3e0e1"},
+    {file = "coverage-7.4.2-cp312-cp312-win32.whl", hash = "sha256:f5df76c58977bc35a49515b2fbba84a1d952ff0ec784a4070334dfbec28a2def"},
+    {file = "coverage-7.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:34423abbaad70fea9d0164add189eabaea679068ebdf693baa5c02d03e7db244"},
+    {file = "coverage-7.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b11f9c6587668e495cc7365f85c93bed34c3a81f9f08b0920b87a89acc13469"},
+    {file = "coverage-7.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:51593a1f05c39332f623d64d910445fdec3d2ac2d96b37ce7f331882d5678ddf"},
+    {file = "coverage-7.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69f1665165ba2fe7614e2f0c1aed71e14d83510bf67e2ee13df467d1c08bf1e8"},
+    {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3c8bbb95a699c80a167478478efe5e09ad31680931ec280bf2087905e3b95ec"},
+    {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:175f56572f25e1e1201d2b3e07b71ca4d201bf0b9cb8fad3f1dfae6a4188de86"},
+    {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8562ca91e8c40864942615b1d0b12289d3e745e6b2da901d133f52f2d510a1e3"},
+    {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d9a1ef0f173e1a19738f154fb3644f90d0ada56fe6c9b422f992b04266c55d5a"},
+    {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f40ac873045db4fd98a6f40387d242bde2708a3f8167bd967ccd43ad46394ba2"},
+    {file = "coverage-7.4.2-cp38-cp38-win32.whl", hash = "sha256:d1b750a8409bec61caa7824bfd64a8074b6d2d420433f64c161a8335796c7c6b"},
+    {file = "coverage-7.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b4ae777bebaed89e3a7e80c4a03fac434a98a8abb5251b2a957d38fe3fd30088"},
+    {file = "coverage-7.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ff7f92ae5a456101ca8f48387fd3c56eb96353588e686286f50633a611afc95"},
+    {file = "coverage-7.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:861d75402269ffda0b33af94694b8e0703563116b04c681b1832903fac8fd647"},
+    {file = "coverage-7.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3507427d83fa961cbd73f11140f4a5ce84208d31756f7238d6257b2d3d868405"},
+    {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf711d517e21fb5bc429f5c4308fbc430a8585ff2a43e88540264ae87871e36a"},
+    {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c00e54f0bd258ab25e7f731ca1d5144b0bf7bec0051abccd2bdcff65fa3262c9"},
+    {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f8e845d894e39fb53834da826078f6dc1a933b32b1478cf437007367efaf6f6a"},
+    {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:840456cb1067dc350af9080298c7c2cfdddcedc1cb1e0b30dceecdaf7be1a2d3"},
+    {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c11ca2df2206a4e3e4c4567f52594637392ed05d7c7fb73b4ea1c658ba560265"},
+    {file = "coverage-7.4.2-cp39-cp39-win32.whl", hash = "sha256:3ff5bdb08d8938d336ce4088ca1a1e4b6c8cd3bef8bb3a4c0eb2f37406e49643"},
+    {file = "coverage-7.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:ac9e95cefcf044c98d4e2c829cd0669918585755dd9a92e28a1a7012322d0a95"},
+    {file = "coverage-7.4.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:f593a4a90118d99014517c2679e04a4ef5aee2d81aa05c26c734d271065efcb6"},
+    {file = "coverage-7.4.2.tar.gz", hash = "sha256:1a5ee18e3a8d766075ce9314ed1cb695414bae67df6a4b0805f5137d93d6f1cb"},
 ]
 
 [package.dependencies]
@@ -595,6 +658,21 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1
 [package.extras]
 toml = ["tomli"]
 
+[[package]]
+name = "cycler"
+version = "0.12.1"
+description = "Composable style cycles"
+optional = true
+python-versions = ">=3.8"
+files = [
+    {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"},
+    {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"},
+]
+
+[package.extras]
+docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
+tests = ["pytest", "pytest-cov", "pytest-xdist"]
+
 [[package]]
 name = "debugpy"
 version = "1.8.1"
@@ -793,6 +871,71 @@ files = [
     {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"},
 ]
 
+[[package]]
+name = "fonttools"
+version = "4.49.0"
+description = "Tools to manipulate font files"
+optional = true
+python-versions = ">=3.8"
+files = [
+    {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d970ecca0aac90d399e458f0b7a8a597e08f95de021f17785fb68e2dc0b99717"},
+    {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac9a745b7609f489faa65e1dc842168c18530874a5f5b742ac3dd79e26bca8bc"},
+    {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ba0e00620ca28d4ca11fc700806fd69144b463aa3275e1b36e56c7c09915559"},
+    {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdee3ab220283057e7840d5fb768ad4c2ebe65bdba6f75d5d7bf47f4e0ed7d29"},
+    {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ce7033cb61f2bb65d8849658d3786188afd80f53dad8366a7232654804529532"},
+    {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:07bc5ea02bb7bc3aa40a1eb0481ce20e8d9b9642a9536cde0218290dd6085828"},
+    {file = "fonttools-4.49.0-cp310-cp310-win32.whl", hash = "sha256:86eef6aab7fd7c6c8545f3ebd00fd1d6729ca1f63b0cb4d621bccb7d1d1c852b"},
+    {file = "fonttools-4.49.0-cp310-cp310-win_amd64.whl", hash = "sha256:1fac1b7eebfce75ea663e860e7c5b4a8831b858c17acd68263bc156125201abf"},
+    {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:edc0cce355984bb3c1d1e89d6a661934d39586bb32191ebff98c600f8957c63e"},
+    {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:83a0d9336de2cba86d886507dd6e0153df333ac787377325a39a2797ec529814"},
+    {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36c8865bdb5cfeec88f5028e7e592370a0657b676c6f1d84a2108e0564f90e22"},
+    {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33037d9e56e2562c710c8954d0f20d25b8386b397250d65581e544edc9d6b942"},
+    {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8fb022d799b96df3eaa27263e9eea306bd3d437cc9aa981820850281a02b6c9a"},
+    {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33c584c0ef7dc54f5dd4f84082eabd8d09d1871a3d8ca2986b0c0c98165f8e86"},
+    {file = "fonttools-4.49.0-cp311-cp311-win32.whl", hash = "sha256:cbe61b158deb09cffdd8540dc4a948d6e8f4d5b4f3bf5cd7db09bd6a61fee64e"},
+    {file = "fonttools-4.49.0-cp311-cp311-win_amd64.whl", hash = "sha256:fc11e5114f3f978d0cea7e9853627935b30d451742eeb4239a81a677bdee6bf6"},
+    {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d647a0e697e5daa98c87993726da8281c7233d9d4ffe410812a4896c7c57c075"},
+    {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f3bbe672df03563d1f3a691ae531f2e31f84061724c319652039e5a70927167e"},
+    {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bebd91041dda0d511b0d303180ed36e31f4f54b106b1259b69fade68413aa7ff"},
+    {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4145f91531fd43c50f9eb893faa08399816bb0b13c425667c48475c9f3a2b9b5"},
+    {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ea329dafb9670ffbdf4dbc3b0e5c264104abcd8441d56de77f06967f032943cb"},
+    {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c076a9e548521ecc13d944b1d261ff3d7825048c338722a4bd126d22316087b7"},
+    {file = "fonttools-4.49.0-cp312-cp312-win32.whl", hash = "sha256:b607ea1e96768d13be26d2b400d10d3ebd1456343eb5eaddd2f47d1c4bd00880"},
+    {file = "fonttools-4.49.0-cp312-cp312-win_amd64.whl", hash = "sha256:a974c49a981e187381b9cc2c07c6b902d0079b88ff01aed34695ec5360767034"},
+    {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b85ec0bdd7bdaa5c1946398cbb541e90a6dfc51df76dfa88e0aaa41b335940cb"},
+    {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:af20acbe198a8a790618ee42db192eb128afcdcc4e96d99993aca0b60d1faeb4"},
+    {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d418b1fee41a1d14931f7ab4b92dc0bc323b490e41d7a333eec82c9f1780c75"},
+    {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b44a52b8e6244b6548851b03b2b377a9702b88ddc21dcaf56a15a0393d425cb9"},
+    {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7c7125068e04a70739dad11857a4d47626f2b0bd54de39e8622e89701836eabd"},
+    {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29e89d0e1a7f18bc30f197cfadcbef5a13d99806447c7e245f5667579a808036"},
+    {file = "fonttools-4.49.0-cp38-cp38-win32.whl", hash = "sha256:9d95fa0d22bf4f12d2fb7b07a46070cdfc19ef5a7b1c98bc172bfab5bf0d6844"},
+    {file = "fonttools-4.49.0-cp38-cp38-win_amd64.whl", hash = "sha256:768947008b4dc552d02772e5ebd49e71430a466e2373008ce905f953afea755a"},
+    {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:08877e355d3dde1c11973bb58d4acad1981e6d1140711230a4bfb40b2b937ccc"},
+    {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fdb54b076f25d6b0f0298dc706acee5052de20c83530fa165b60d1f2e9cbe3cb"},
+    {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0af65c720520710cc01c293f9c70bd69684365c6015cc3671db2b7d807fe51f2"},
+    {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f255ce8ed7556658f6d23f6afd22a6d9bbc3edb9b96c96682124dc487e1bf42"},
+    {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d00af0884c0e65f60dfaf9340e26658836b935052fdd0439952ae42e44fdd2be"},
+    {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:263832fae27481d48dfafcc43174644b6706639661e242902ceb30553557e16c"},
+    {file = "fonttools-4.49.0-cp39-cp39-win32.whl", hash = "sha256:0404faea044577a01bb82d47a8fa4bc7a54067fa7e324785dd65d200d6dd1133"},
+    {file = "fonttools-4.49.0-cp39-cp39-win_amd64.whl", hash = "sha256:b050d362df50fc6e38ae3954d8c29bf2da52be384649ee8245fdb5186b620836"},
+    {file = "fonttools-4.49.0-py3-none-any.whl", hash = "sha256:af281525e5dd7fa0b39fb1667b8d5ca0e2a9079967e14c4bfe90fd1cd13e0f18"},
+    {file = "fonttools-4.49.0.tar.gz", hash = "sha256:ebf46e7f01b7af7861310417d7c49591a85d99146fc23a5ba82fdb28af156321"},
+]
+
+[package.extras]
+all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"]
+graphite = ["lz4 (>=1.7.4.2)"]
+interpolatable = ["munkres", "pycairo", "scipy"]
+lxml = ["lxml (>=4.0)"]
+pathops = ["skia-pathops (>=0.5.0)"]
+plot = ["matplotlib"]
+repacker = ["uharfbuzz (>=0.23.0)"]
+symfont = ["sympy"]
+type1 = ["xattr"]
+ufo = ["fs (>=2.2.0,<3)"]
+unicode = ["unicodedata2 (>=15.1.0)"]
+woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
+
 [[package]]
 name = "frozenlist"
 version = "1.4.1"
@@ -927,13 +1070,13 @@ files = [
 
 [[package]]
 name = "httpcore"
-version = "1.0.3"
+version = "1.0.4"
 description = "A minimal low-level HTTP client."
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "httpcore-1.0.3-py3-none-any.whl", hash = "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2"},
-    {file = "httpcore-1.0.3.tar.gz", hash = "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544"},
+    {file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"},
+    {file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"},
 ]
 
 [package.dependencies]
@@ -944,7 +1087,7 @@ h11 = ">=0.13,<0.15"
 asyncio = ["anyio (>=4.0,<5.0)"]
 http2 = ["h2 (>=3,<5)"]
 socks = ["socksio (==1.*)"]
-trio = ["trio (>=0.22.0,<0.24.0)"]
+trio = ["trio (>=0.22.0,<0.25.0)"]
 
 [[package]]
 name = "httpx"
@@ -1047,6 +1190,24 @@ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.link
 perf = ["ipython"]
 testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"]
 
+[[package]]
+name = "importlib-resources"
+version = "6.1.1"
+description = "Read resources from Python packages"
+optional = true
+python-versions = ">=3.8"
+files = [
+    {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"},
+    {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"},
+]
+
+[package.dependencies]
+zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"]
+
 [[package]]
 name = "iniconfig"
 version = "2.0.0"
@@ -1218,14 +1379,127 @@ traitlets = ">=5.3"
 docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"]
 test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"]
 
+[[package]]
+name = "kiwisolver"
+version = "1.4.5"
+description = "A fast implementation of the Cassowary constraint solver"
+optional = true
+python-versions = ">=3.7"
+files = [
+    {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"},
+    {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"},
+    {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"},
+    {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"},
+    {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"},
+    {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"},
+    {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"},
+    {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"},
+    {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"},
+    {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"},
+    {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"},
+    {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"},
+    {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"},
+    {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"},
+    {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"},
+    {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"},
+    {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"},
+    {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"},
+    {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"},
+    {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"},
+    {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"},
+    {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"},
+    {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"},
+]
+
 [[package]]
 name = "llama-cpp-python"
-version = "0.2.44"
+version = "0.2.48"
 description = "Python bindings for the llama.cpp library"
 optional = true
 python-versions = ">=3.8"
 files = [
-    {file = "llama_cpp_python-0.2.44.tar.gz", hash = "sha256:afe0e93548d4ba75f20bc754039907594738a6381c9f4602922bcc8a418b2039"},
+    {file = "llama_cpp_python-0.2.48.tar.gz", hash = "sha256:37294f14c3b8157334beb8c9b6d92087f2c9d82730d733e6fc4fc15034271dd8"},
 ]
 
 [package.dependencies]
@@ -1309,6 +1583,55 @@ files = [
     {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
 ]
 
+[[package]]
+name = "matplotlib"
+version = "3.8.3"
+description = "Python plotting package"
+optional = true
+python-versions = ">=3.9"
+files = [
+    {file = "matplotlib-3.8.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cf60138ccc8004f117ab2a2bad513cc4d122e55864b4fe7adf4db20ca68a078f"},
+    {file = "matplotlib-3.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f557156f7116be3340cdeef7f128fa99b0d5d287d5f41a16e169819dcf22357"},
+    {file = "matplotlib-3.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f386cf162b059809ecfac3bcc491a9ea17da69fa35c8ded8ad154cd4b933d5ec"},
+    {file = "matplotlib-3.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3c5f96f57b0369c288bf6f9b5274ba45787f7e0589a34d24bdbaf6d3344632f"},
+    {file = "matplotlib-3.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:83e0f72e2c116ca7e571c57aa29b0fe697d4c6425c4e87c6e994159e0c008635"},
+    {file = "matplotlib-3.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:1c5c8290074ba31a41db1dc332dc2b62def469ff33766cbe325d32a3ee291aea"},
+    {file = "matplotlib-3.8.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5184e07c7e1d6d1481862ee361905b7059f7fe065fc837f7c3dc11eeb3f2f900"},
+    {file = "matplotlib-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d7e7e0993d0758933b1a241a432b42c2db22dfa37d4108342ab4afb9557cbe3e"},
+    {file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04b36ad07eac9740fc76c2aa16edf94e50b297d6eb4c081e3add863de4bb19a7"},
+    {file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c42dae72a62f14982f1474f7e5c9959fc4bc70c9de11cc5244c6e766200ba65"},
+    {file = "matplotlib-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf5932eee0d428192c40b7eac1399d608f5d995f975cdb9d1e6b48539a5ad8d0"},
+    {file = "matplotlib-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:40321634e3a05ed02abf7c7b47a50be50b53ef3eaa3a573847431a545585b407"},
+    {file = "matplotlib-3.8.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:09074f8057917d17ab52c242fdf4916f30e99959c1908958b1fc6032e2d0f6d4"},
+    {file = "matplotlib-3.8.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5745f6d0fb5acfabbb2790318db03809a253096e98c91b9a31969df28ee604aa"},
+    {file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97653d869a71721b639714b42d87cda4cfee0ee74b47c569e4874c7590c55c5"},
+    {file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:242489efdb75b690c9c2e70bb5c6550727058c8a614e4c7716f363c27e10bba1"},
+    {file = "matplotlib-3.8.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:83c0653c64b73926730bd9ea14aa0f50f202ba187c307a881673bad4985967b7"},
+    {file = "matplotlib-3.8.3-cp312-cp312-win_amd64.whl", hash = "sha256:ef6c1025a570354297d6c15f7d0f296d95f88bd3850066b7f1e7b4f2f4c13a39"},
+    {file = "matplotlib-3.8.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c4af3f7317f8a1009bbb2d0bf23dfaba859eb7dd4ccbd604eba146dccaaaf0a4"},
+    {file = "matplotlib-3.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c6e00a65d017d26009bac6808f637b75ceade3e1ff91a138576f6b3065eeeba"},
+    {file = "matplotlib-3.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7b49ab49a3bea17802df6872f8d44f664ba8f9be0632a60c99b20b6db2165b7"},
+    {file = "matplotlib-3.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6728dde0a3997396b053602dbd907a9bd64ec7d5cf99e728b404083698d3ca01"},
+    {file = "matplotlib-3.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:813925d08fb86aba139f2d31864928d67511f64e5945ca909ad5bc09a96189bb"},
+    {file = "matplotlib-3.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:cd3a0c2be76f4e7be03d34a14d49ded6acf22ef61f88da600a18a5cd8b3c5f3c"},
+    {file = "matplotlib-3.8.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fa93695d5c08544f4a0dfd0965f378e7afc410d8672816aff1e81be1f45dbf2e"},
+    {file = "matplotlib-3.8.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9764df0e8778f06414b9d281a75235c1e85071f64bb5d71564b97c1306a2afc"},
+    {file = "matplotlib-3.8.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5e431a09e6fab4012b01fc155db0ce6dccacdbabe8198197f523a4ef4805eb26"},
+    {file = "matplotlib-3.8.3.tar.gz", hash = "sha256:7b416239e9ae38be54b028abbf9048aff5054a9aba5416bef0bd17f9162ce161"},
+]
+
+[package.dependencies]
+contourpy = ">=1.0.1"
+cycler = ">=0.10"
+fonttools = ">=4.22.0"
+importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""}
+kiwisolver = ">=1.3.1"
+numpy = ">=1.21,<2"
+packaging = ">=20.0"
+pillow = ">=8"
+pyparsing = ">=2.3.1"
+python-dateutil = ">=2.7"
+
 [[package]]
 name = "matplotlib-inline"
 version = "0.1.6"
@@ -2399,6 +2722,20 @@ files = [
 plugins = ["importlib-metadata"]
 windows-terminal = ["colorama (>=0.4.6)"]
 
+[[package]]
+name = "pyparsing"
+version = "3.1.1"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = true
+python-versions = ">=3.6.8"
+files = [
+    {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"},
+    {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
 [[package]]
 name = "pyreadline3"
 version = "3.4.1"
@@ -2693,7 +3030,7 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""}
 name = "regex"
 version = "2023.12.25"
 description = "Alternative regular expression module, to replace re."
-optional = true
+optional = false
 python-versions = ">=3.7"
 files = [
     {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"},
@@ -3025,6 +3362,58 @@ files = [
 [package.dependencies]
 mpmath = ">=0.19"
 
+[[package]]
+name = "tiktoken"
+version = "0.6.0"
+description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tiktoken-0.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:277de84ccd8fa12730a6b4067456e5cf72fef6300bea61d506c09e45658d41ac"},
+    {file = "tiktoken-0.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c44433f658064463650d61387623735641dcc4b6c999ca30bc0f8ba3fccaf5c"},
+    {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afb9a2a866ae6eef1995ab656744287a5ac95acc7e0491c33fad54d053288ad3"},
+    {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62c05b3109fefca26fedb2820452a050074ad8e5ad9803f4652977778177d9f"},
+    {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ef917fad0bccda07bfbad835525bbed5f3ab97a8a3e66526e48cdc3e7beacf7"},
+    {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e095131ab6092d0769a2fda85aa260c7c383072daec599ba9d8b149d2a3f4d8b"},
+    {file = "tiktoken-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:05b344c61779f815038292a19a0c6eb7098b63c8f865ff205abb9ea1b656030e"},
+    {file = "tiktoken-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cefb9870fb55dca9e450e54dbf61f904aab9180ff6fe568b61f4db9564e78871"},
+    {file = "tiktoken-0.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:702950d33d8cabc039845674107d2e6dcabbbb0990ef350f640661368df481bb"},
+    {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8d49d076058f23254f2aff9af603863c5c5f9ab095bc896bceed04f8f0b013a"},
+    {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:430bc4e650a2d23a789dc2cdca3b9e5e7eb3cd3935168d97d43518cbb1f9a911"},
+    {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:293cb8669757301a3019a12d6770bd55bec38a4d3ee9978ddbe599d68976aca7"},
+    {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7bd1a288b7903aadc054b0e16ea78e3171f70b670e7372432298c686ebf9dd47"},
+    {file = "tiktoken-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac76e000183e3b749634968a45c7169b351e99936ef46f0d2353cd0d46c3118d"},
+    {file = "tiktoken-0.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17cc8a4a3245ab7d935c83a2db6bb71619099d7284b884f4b2aea4c74f2f83e3"},
+    {file = "tiktoken-0.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:284aebcccffe1bba0d6571651317df6a5b376ff6cfed5aeb800c55df44c78177"},
+    {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c1a3a5d33846f8cd9dd3b7897c1d45722f48625a587f8e6f3d3e85080559be8"},
+    {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6318b2bb2337f38ee954fd5efa82632c6e5ced1d52a671370fa4b2eff1355e91"},
+    {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f5f0f2ed67ba16373f9a6013b68da298096b27cd4e1cf276d2d3868b5c7efd1"},
+    {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:75af4c0b16609c2ad02581f3cdcd1fb698c7565091370bf6c0cf8624ffaba6dc"},
+    {file = "tiktoken-0.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:45577faf9a9d383b8fd683e313cf6df88b6076c034f0a16da243bb1c139340c3"},
+    {file = "tiktoken-0.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c1492ab90c21ca4d11cef3a236ee31a3e279bb21b3fc5b0e2210588c4209e68"},
+    {file = "tiktoken-0.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e2b380c5b7751272015400b26144a2bab4066ebb8daae9c3cd2a92c3b508fe5a"},
+    {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f497598b9f58c99cbc0eb764b4a92272c14d5203fc713dd650b896a03a50ad"},
+    {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e65e8bd6f3f279d80f1e1fbd5f588f036b9a5fa27690b7f0cc07021f1dfa0839"},
+    {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5f1495450a54e564d236769d25bfefbf77727e232d7a8a378f97acddee08c1ae"},
+    {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6c4e4857d99f6fb4670e928250835b21b68c59250520a1941618b5b4194e20c3"},
+    {file = "tiktoken-0.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:168d718f07a39b013032741867e789971346df8e89983fe3c0ef3fbd5a0b1cb9"},
+    {file = "tiktoken-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47fdcfe11bd55376785a6aea8ad1db967db7f66ea81aed5c43fad497521819a4"},
+    {file = "tiktoken-0.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb7d2ccbf1a7784810aff6b80b4012fb42c6fc37eaa68cb3b553801a5cc2d1fc"},
+    {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ccb7a111ee76af5d876a729a347f8747d5ad548e1487eeea90eaf58894b3138"},
+    {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2048e1086b48e3c8c6e2ceeac866561374cd57a84622fa49a6b245ffecb7744"},
+    {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07f229a5eb250b6403a61200199cecf0aac4aa23c3ecc1c11c1ca002cbb8f159"},
+    {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:432aa3be8436177b0db5a2b3e7cc28fd6c693f783b2f8722539ba16a867d0c6a"},
+    {file = "tiktoken-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:8bfe8a19c8b5c40d121ee7938cd9c6a278e5b97dc035fd61714b4f0399d2f7a1"},
+    {file = "tiktoken-0.6.0.tar.gz", hash = "sha256:ace62a4ede83c75b0374a2ddfa4b76903cf483e9cb06247f566be3bf14e6beed"},
+]
+
+[package.dependencies]
+regex = ">=2022.1.18"
+requests = ">=2.26.0"
+
+[package.extras]
+blobfile = ["blobfile (>=2)"]
+
 [[package]]
 name = "tokenizers"
 version = "0.15.2"
@@ -3311,13 +3700,13 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,
 
 [[package]]
 name = "transformers"
-version = "4.37.2"
+version = "4.38.1"
 description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow"
 optional = true
 python-versions = ">=3.8.0"
 files = [
-    {file = "transformers-4.37.2-py3-none-any.whl", hash = "sha256:595a8b12a1fcc4ad0ced49ce206c58e17be68c85d7aee3d7546d04a32c910d2e"},
-    {file = "transformers-4.37.2.tar.gz", hash = "sha256:f307082ae5d528b8480611a4879a4a11651012d0e9aaea3f6cf17219ffd95542"},
+    {file = "transformers-4.38.1-py3-none-any.whl", hash = "sha256:a7a9265fb060183e9d975cbbadc4d531b10281589c43f6d07563f86322728973"},
+    {file = "transformers-4.38.1.tar.gz", hash = "sha256:86dc84ccbe36123647e84cbd50fc31618c109a41e6be92514b064ab55bf1304c"},
 ]
 
 [package.dependencies]
@@ -3334,16 +3723,16 @@ tqdm = ">=4.27"
 
 [package.extras]
 accelerate = ["accelerate (>=0.21.0)"]
-agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.11,!=1.12.0)"]
-all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision"]
+agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch"]
+all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"]
 audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
 codecarbon = ["codecarbon (==1.2.0)"]
 deepspeed = ["accelerate (>=0.21.0)", "deepspeed (>=0.9.3)"]
-deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"]
-dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
-dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"]
-dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
-docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "torchaudio", "torchvision"]
+deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"]
+dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
+dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"]
+dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
+docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"]
 docs-specific = ["hf-doc-builder"]
 flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"]
 flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
@@ -3360,20 +3749,20 @@ ray = ["ray[tune] (>=2.7.0)"]
 retrieval = ["datasets (!=2.5.0)", "faiss-cpu"]
 sagemaker = ["sagemaker (>=2.31.0)"]
 sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"]
-serving = ["fastapi", "pydantic (<2)", "starlette", "uvicorn"]
+serving = ["fastapi", "pydantic", "starlette", "uvicorn"]
 sigopt = ["sigopt"]
 sklearn = ["scikit-learn"]
 speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"]
-testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"]
+testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"]
 tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"]
 tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"]
 tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
 timm = ["timm"]
 tokenizers = ["tokenizers (>=0.14,<0.19)"]
-torch = ["accelerate (>=0.21.0)", "torch (>=1.11,!=1.12.0)"]
+torch = ["accelerate (>=0.21.0)", "torch"]
 torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"]
 torch-vision = ["Pillow (>=10.0.1,<=15.0)", "torchvision"]
-torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch (>=1.11,!=1.12.0)", "tqdm (>=4.27)"]
+torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch", "tqdm (>=4.27)"]
 video = ["av (==9.2.0)", "decord (==0.6.0)"]
 vision = ["Pillow (>=10.0.1,<=15.0)"]
 
@@ -3599,9 +3988,10 @@ fastembed = ["fastembed"]
 hybrid = ["pinecone-text"]
 local = ["llama-cpp-python", "torch", "transformers"]
 pinecone = ["pinecone-client"]
+processing = ["matplotlib"]
 vision = ["pillow", "torch", "torchvision", "transformers"]
 
 [metadata]
 lock-version = "2.0"
 python-versions = ">=3.9,<3.13"
-content-hash = "26f85562a59d475cc411ed0aa003cc84cd8ebc328cfafed1c74e77d0aaa544d3"
+content-hash = "067185d9d8b058fbcf9bd00e3c9a0b5b3ada33cbfa7f77e81d164692d98ae22b"
diff --git a/pyproject.toml b/pyproject.toml
index 294ef44e7175b3563d58b7e4bc64b6170978057d..24c1fa09f7918f8ee0b3c6988086effa1093ca97 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "semantic-router"
-version = "0.0.23"
+version = "0.0.24"
 description = "Super fast semantic router for AI decision making"
 authors = [
     "James Briggs <james@aurelio.ai>",
@@ -31,8 +31,11 @@ llama-cpp-python = {version = "^0.2.28", optional = true}
 black = "^23.12.1"
 colorama = "^0.4.6"
 pinecone-client = {version="^3.0.0", optional = true}
+regex = "^2023.12.25"
 torchvision = { version = "^0.16.2", optional = true}
 pillow = { version= "^10.2.0", optional = true}
+tiktoken = "^0.6.0"
+matplotlib = { version="^3.8.3", optional = true}
 
 [tool.poetry.extras]
 hybrid = ["pinecone-text"]
@@ -40,6 +43,7 @@ fastembed = ["fastembed"]
 local = ["torch", "transformers", "llama-cpp-python"]
 pinecone = ["pinecone-client"]
 vision = ["torch", "torchvision", "transformers", "pillow"]
+processing = ["matplotlib"]
 
 [tool.poetry.group.dev.dependencies]
 ipykernel = "^6.25.0"
diff --git a/semantic_router/__init__.py b/semantic_router/__init__.py
index 7ac0c93ebe77c6c37c9cd8c960db48a399adac11..d810106abbd425f673391ada9a802561532318b3 100644
--- a/semantic_router/__init__.py
+++ b/semantic_router/__init__.py
@@ -4,4 +4,4 @@ from semantic_router.route import Route
 
 __all__ = ["RouteLayer", "HybridRouteLayer", "Route", "LayerConfig"]
 
-__version__ = "0.0.23"
+__version__ = "0.0.24"
diff --git a/semantic_router/index/base.py b/semantic_router/index/base.py
index 351692df71316a8d779de43de96014dff88e6a12..5271b897298af0d99efb5e6f23f87c94da4e7b12 100644
--- a/semantic_router/index/base.py
+++ b/semantic_router/index/base.py
@@ -37,7 +37,8 @@ class BaseIndex(BaseModel):
 
     def describe(self) -> dict:
         """
-        Returns a dictionary with index details such as type, dimensions, and total vector count.
+        Returns a dictionary with index details such as type, dimensions, and total
+        vector count.
         This method should be implemented by subclasses.
         """
         raise NotImplementedError("This method should be implemented by subclasses.")
diff --git a/semantic_router/index/local.py b/semantic_router/index/local.py
index e462463171bdd75d722588d9a99d2d5b338fb9f2..81da71d1d6114cb58849ec364a0fa175254020c6 100644
--- a/semantic_router/index/local.py
+++ b/semantic_router/index/local.py
@@ -16,7 +16,8 @@ class LocalIndex(BaseIndex):
         super().__init__(index=index, routes=routes, utterances=utterances)
         self.type = "local"
 
-    class Config:  # Stop pydantic from complaining about  Optional[np.ndarray] type hints.
+    class Config:
+        # Stop pydantic from complaining about Optional[np.ndarray]type hints.
         arbitrary_types_allowed = True
 
     def add(
@@ -83,7 +84,8 @@ class LocalIndex(BaseIndex):
             self.utterances = np.delete(self.utterances, delete_idx, axis=0)
         else:
             raise ValueError(
-                "Attempted to delete route records but either index, routes or utterances is None."
+                "Attempted to delete route records but either index, routes or "
+                "utterances is None."
             )
 
     def delete_index(self):
diff --git a/semantic_router/index/pinecone.py b/semantic_router/index/pinecone.py
index 84b3d9ed63b07a35dd8a365d46f11dc09a9eaa61..321dee3045d373354a313f84e52db22eefa06689 100644
--- a/semantic_router/index/pinecone.py
+++ b/semantic_router/index/pinecone.py
@@ -23,9 +23,9 @@ class PineconeRecord(BaseModel):
 
     def __init__(self, **data):
         super().__init__(**data)
-        # generate ID based on route name and utterances to prevent duplicates
         clean_route = clean_route_name(self.route)
-        utterance_id = hashlib.md5(self.utterance.encode()).hexdigest()
+        # Use SHA-256 for a more secure hash
+        utterance_id = hashlib.sha256(self.utterance.encode()).hexdigest()
         self.id = f"{clean_route}#{utterance_id}"
 
     def to_dict(self):
@@ -51,13 +51,8 @@ class PineconeIndex(BaseIndex):
     def __init__(self, **data):
         super().__init__(**data)
         self._initialize_client()
-
         self.type = "pinecone"
         self.client = self._initialize_client()
-        if not self.index_name.startswith(self.index_prefix):
-            self.index_name = f"{self.index_prefix}{self.index_name}"
-        # Create or connect to an existing Pinecone index
-        self.index = self._init_index()
 
     def _initialize_client(self, api_key: Optional[str] = None):
         try:
diff --git a/semantic_router/layer.py b/semantic_router/layer.py
index 0635c1ea9beef2afb4437b2406dc421ca831fbfd..3ef16206d638a96cf9274112c61388fec0e31a03 100644
--- a/semantic_router/layer.py
+++ b/semantic_router/layer.py
@@ -19,7 +19,8 @@ from semantic_router.utils.logger import logger
 
 
 def is_valid(layer_config: str) -> bool:
-    """Make sure the given string is json format and contains the 3 keys: ["encoder_name", "encoder_type", "routes"]"""
+    """Make sure the given string is json format and contains the 3 keys:
+    ["encoder_name", "encoder_type", "routes"]"""
     try:
         output_json = json.loads(layer_config)
         required_keys = ["encoder_name", "encoder_type", "routes"]
@@ -209,7 +210,8 @@ class RouteLayer:
         matching_routes = [route for route in self.routes if route.name == top_class]
         if not matching_routes:
             logger.error(
-                f"No route found with name {top_class}. Check to see if any Routes have been defined."
+                f"No route found with name {top_class}. Check to see if any Routes "
+                "have been defined."
             )
             return None
         return matching_routes[0]
diff --git a/semantic_router/llms/ollama.py b/semantic_router/llms/ollama.py
index 1c5dfed58857310ed5fff5e55c09988d2a38b4dd..df35ac06a97748ece6a2da86fad58bb7e4a0a52f 100644
--- a/semantic_router/llms/ollama.py
+++ b/semantic_router/llms/ollama.py
@@ -1,4 +1,5 @@
 from typing import List, Optional
+
 import requests
 
 from semantic_router.llms import BaseLLM
diff --git a/semantic_router/schema.py b/semantic_router/schema.py
index 8bb5a65f6f3c0d5e315ac433cc68b55cdc25989a..8841902161f6b72b1c5ee3245b3b08e1994609eb 100644
--- a/semantic_router/schema.py
+++ b/semantic_router/schema.py
@@ -1,5 +1,5 @@
 from enum import Enum
-from typing import Any, List, Optional
+from typing import List, Optional
 
 from pydantic.v1 import BaseModel
 from pydantic.v1.dataclasses import dataclass
@@ -77,6 +77,12 @@ class Message(BaseModel):
 
 
 class DocumentSplit(BaseModel):
-    docs: List[Any]
+    docs: List[str]
     is_triggered: bool = False
     triggered_score: Optional[float] = None
+    token_count: Optional[int] = None
+    metadata: Optional[dict] = None
+
+    @property
+    def content(self) -> str:
+        return " ".join(self.docs)
diff --git a/semantic_router/splitters/__init__.py b/semantic_router/splitters/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..44acb9e39ef60f0db98b2b07ddafee69cffeb756 100644
--- a/semantic_router/splitters/__init__.py
+++ b/semantic_router/splitters/__init__.py
@@ -0,0 +1,11 @@
+from semantic_router.splitters.base import BaseSplitter
+from semantic_router.splitters.consecutive_sim import ConsecutiveSimSplitter
+from semantic_router.splitters.cumulative_sim import CumulativeSimSplitter
+from semantic_router.splitters.rolling_window import RollingWindowSplitter
+
+__all__ = [
+    "BaseSplitter",
+    "ConsecutiveSimSplitter",
+    "CumulativeSimSplitter",
+    "RollingWindowSplitter",
+]
diff --git a/semantic_router/splitters/base.py b/semantic_router/splitters/base.py
index 7f66c8bceff2292f1193161c57d87178d07a60aa..0514e014e34e50b03a1285395591d71f67775b17 100644
--- a/semantic_router/splitters/base.py
+++ b/semantic_router/splitters/base.py
@@ -1,14 +1,38 @@
-from typing import Any, List
+from typing import List
 
-from pydantic.v1 import BaseModel
+from colorama import Fore, Style
+from pydantic.v1 import BaseModel, Extra
 
 from semantic_router.encoders import BaseEncoder
+from semantic_router.schema import DocumentSplit
 
 
 class BaseSplitter(BaseModel):
     name: str
     encoder: BaseEncoder
-    score_threshold: float
 
-    def __call__(self, docs: List[Any]) -> List[List[float]]:
+    class Config:
+        extra = Extra.allow
+
+    def __call__(self, docs: List[str]) -> List[DocumentSplit]:
         raise NotImplementedError("Subclasses must implement this method")
+
+    def print(self, document_splits: List[DocumentSplit]) -> None:
+        colors = [Fore.RED, Fore.GREEN, Fore.BLUE, Fore.MAGENTA]
+        for i, split in enumerate(document_splits):
+            color = colors[i % len(colors)]
+            colored_content = f"{color}{split.content}{Style.RESET_ALL}"
+            if split.is_triggered:
+                triggered = f"{split.triggered_score:.2f}"
+            elif i == len(document_splits) - 1:
+                triggered = "final split"
+            else:
+                triggered = "token limit"
+            print(
+                f"Split {i + 1}, "
+                f"tokens {split.token_count}, "
+                f"triggered by: {triggered}"
+            )
+            print(colored_content)
+            print("-" * 88)
+            print("\n")
diff --git a/semantic_router/splitters/consecutive_sim.py b/semantic_router/splitters/consecutive_sim.py
index f30bbc755061640300f861e04fc7febba57fe947..4a2e110645ae90932871c36c5eb30f537943ad6f 100644
--- a/semantic_router/splitters/consecutive_sim.py
+++ b/semantic_router/splitters/consecutive_sim.py
@@ -19,8 +19,9 @@ class ConsecutiveSimSplitter(BaseSplitter):
         name: str = "consecutive_similarity_splitter",
         score_threshold: float = 0.45,
     ):
-        super().__init__(name=name, score_threshold=score_threshold, encoder=encoder)
+        super().__init__(name=name, encoder=encoder)
         encoder.score_threshold = score_threshold
+        self.score_threshold = score_threshold
 
     def __call__(self, docs: List[Any]):
         # Check if there's only a single document
diff --git a/semantic_router/splitters/cumulative_sim.py b/semantic_router/splitters/cumulative_sim.py
index f7a6475ad809a8b1eb877f592cf9ca0799941ba2..e9dd8deb2b1f24f519fab47c8fb61cc7e8f0f221 100644
--- a/semantic_router/splitters/cumulative_sim.py
+++ b/semantic_router/splitters/cumulative_sim.py
@@ -8,9 +8,9 @@ from semantic_router.splitters.base import BaseSplitter
 
 
 class CumulativeSimSplitter(BaseSplitter):
-
     """
-    Called "cumulative sim" because we check the similarities of the embeddings of cumulative concatenated documents with the next document.
+    Called "cumulative sim" because we check the similarities of the
+    embeddings of cumulative concatenated documents with the next document.
     """
 
     def __init__(
@@ -19,15 +19,17 @@ class CumulativeSimSplitter(BaseSplitter):
         name: str = "cumulative_similarity_splitter",
         score_threshold: float = 0.45,
     ):
-        super().__init__(name=name, score_threshold=score_threshold, encoder=encoder)
+        super().__init__(name=name, encoder=encoder)
         encoder.score_threshold = score_threshold
+        self.score_threshold = score_threshold
 
     def __call__(self, docs: List[str]):
         total_docs = len(docs)
         # Check if there's only a single document
         if total_docs == 1:
             raise ValueError(
-                "There is only one document provided; at least two are required to determine topics based on similarity."
+                "There is only one document provided; at least two are required "
+                "to determine topics based on similarity."
             )
         splits = []
         curr_split_start_idx = 0
@@ -35,10 +37,12 @@ class CumulativeSimSplitter(BaseSplitter):
         for idx in range(0, total_docs):
             if idx + 1 < total_docs:  # Ensure there is a next document to compare with.
                 if idx == 0:
-                    # On the first iteration, compare the first document directly to the second.
+                    # On the first iteration, compare the
+                    # first document directly to the second.
                     curr_split_docs = docs[idx]
                 else:
-                    # For subsequent iterations, compare cumulative documents up to the current one with the next.
+                    # For subsequent iterations, compare cumulative
+                    # documents up to the current one with the next.
                     curr_split_docs = "\n".join(docs[curr_split_start_idx : idx + 1])
                 next_doc = docs[idx + 1]
 
diff --git a/semantic_router/splitters/rolling_window.py b/semantic_router/splitters/rolling_window.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e7c651de4fbe3e113e6ad0313f7b2d2ce1355d3
--- /dev/null
+++ b/semantic_router/splitters/rolling_window.py
@@ -0,0 +1,334 @@
+from typing import List
+
+import numpy as np
+
+from semantic_router.encoders.base import BaseEncoder
+from semantic_router.schema import DocumentSplit
+from semantic_router.splitters.base import BaseSplitter
+from semantic_router.splitters.utils import split_to_sentences, tiktoken_length
+from semantic_router.utils.logger import logger
+
+
+class RollingWindowSplitter(BaseSplitter):
+    def __init__(
+        self,
+        encoder: BaseEncoder,
+        threshold_adjustment=0.01,
+        dynamic_threshold: bool = True,
+        window_size=5,
+        min_split_tokens=100,
+        max_split_tokens=300,
+        split_tokens_tolerance=10,
+        plot_splits=False,
+        name="rolling_window_splitter",
+    ):
+        super().__init__(name=name, encoder=encoder)
+        self.calculated_threshold: float
+        self.encoder = encoder
+        self.threshold_adjustment = threshold_adjustment
+        self.dynamic_threshold = dynamic_threshold
+        self.window_size = window_size
+        self.plot_splits = plot_splits
+        self.min_split_tokens = min_split_tokens
+        self.max_split_tokens = max_split_tokens
+        self.split_tokens_tolerance = split_tokens_tolerance
+
+    def encode_documents(self, docs: List[str]) -> np.ndarray:
+        try:
+            embeddings = self.encoder(docs)
+            return np.array(embeddings)
+        except Exception as e:
+            logger.error(f"Error encoding documents {docs}: {e}")
+            raise
+
+    def calculate_similarity_scores(self, encoded_docs: np.ndarray) -> List[float]:
+        raw_similarities = []
+        for idx in range(1, len(encoded_docs)):
+            window_start = max(0, idx - self.window_size)
+            cumulative_context = np.mean(encoded_docs[window_start:idx], axis=0)
+            curr_sim_score = np.dot(cumulative_context, encoded_docs[idx]) / (
+                np.linalg.norm(cumulative_context) * np.linalg.norm(encoded_docs[idx])
+                + 1e-10
+            )
+            raw_similarities.append(curr_sim_score)
+        return raw_similarities
+
+    def find_split_indices(self, similarities: List[float]) -> List[int]:
+        split_indices = []
+        for idx in range(1, len(similarities)):
+            if similarities[idx] < self.calculated_threshold:
+                split_indices.append(idx + 1)
+        return split_indices
+
+    def find_optimal_threshold(self, docs: List[str], encoded_docs: np.ndarray):
+        token_counts = [tiktoken_length(doc) for doc in docs]
+        cumulative_token_counts = np.cumsum([0] + token_counts)
+        similarity_scores = self.calculate_similarity_scores(encoded_docs)
+
+        # Analyze the distribution of similarity scores to set initial bounds
+        median_score = np.median(similarity_scores)
+        std_dev = np.std(similarity_scores)
+
+        # Set initial bounds based on median and standard deviation
+        low = max(0.0, float(median_score - std_dev))
+        high = min(1.0, float(median_score + std_dev))
+
+        iteration = 0
+        while low <= high:
+            self.calculated_threshold = (low + high) / 2
+            logger.info(
+                f"Iteration {iteration}: Trying threshold: {self.calculated_threshold}"
+            )
+            split_indices = self.find_split_indices(similarity_scores)
+
+            # Calculate the token counts for each split using the cumulative sums
+            split_token_counts = [
+                cumulative_token_counts[end] - cumulative_token_counts[start]
+                for start, end in zip(
+                    [0] + split_indices, split_indices + [len(token_counts)]
+                )
+            ]
+
+            # Calculate the median token count for the splits
+            median_tokens = np.median(split_token_counts)
+            logger.info(
+                f"Iteration {iteration}: Median tokens per split: {median_tokens}"
+            )
+            if (
+                self.min_split_tokens - self.split_tokens_tolerance
+                <= median_tokens
+                <= self.max_split_tokens + self.split_tokens_tolerance
+            ):
+                logger.info(
+                    f"Iteration {iteration}: "
+                    f"Optimal threshold {self.calculated_threshold} found "
+                    f"with median tokens ({median_tokens}) in target range "
+                    f" {self.min_split_tokens}-{self.max_split_tokens}."
+                )
+                break
+            elif median_tokens < self.min_split_tokens:
+                high = self.calculated_threshold - self.threshold_adjustment
+                logger.info(f"Iteration {iteration}: Adjusting high to {high}")
+            else:
+                low = self.calculated_threshold + self.threshold_adjustment
+                logger.info(f"Iteration {iteration}: Adjusting low to {low}")
+            iteration += 1
+
+        logger.info(f"Final optimal threshold: {self.calculated_threshold}")
+        return self.calculated_threshold
+
+    def split_documents(
+        self, docs: List[str], split_indices: List[int], similarities: List[float]
+    ) -> List[DocumentSplit]:
+        """
+        This method iterates through each document, appending it to the current split
+        until it either reaches a split point (determined by split_indices) or exceeds
+        the maximum token limit for a split (self.max_split_tokens).
+        When a document causes the current token count to exceed this limit,
+        or when a split point is reached and the minimum token requirement is met,
+        the current split is finalized and added to the List of splits.
+        """
+        token_counts = [tiktoken_length(doc) for doc in docs]
+        splits, current_split = [], []
+        current_tokens_count = 0
+
+        for doc_idx, doc in enumerate(docs):
+            doc_token_count = token_counts[doc_idx]
+
+            # Check if current index is a split point based on similarity
+            if doc_idx + 1 in split_indices:
+                if current_tokens_count + doc_token_count >= self.min_split_tokens:
+                    # Include the current document before splitting
+                    # if it doesn't exceed the max limit
+                    current_split.append(doc)
+                    current_tokens_count += doc_token_count
+
+                    triggered_score = (
+                        similarities[doc_idx] if doc_idx < len(similarities) else None
+                    )
+                    splits.append(
+                        DocumentSplit(
+                            docs=current_split.copy(),
+                            is_triggered=True,
+                            triggered_score=triggered_score,
+                            token_count=current_tokens_count,
+                        )
+                    )
+                    logger.info(
+                        f"Split finalized with {current_tokens_count} tokens due to "
+                        f"threshold {self.calculated_threshold}."
+                    )
+                    current_split, current_tokens_count = [], 0
+                    continue  # Move to the next document after splitting
+
+            # Check if adding the current document exceeds the max token limit
+            if current_tokens_count + doc_token_count > self.max_split_tokens:
+                if current_tokens_count >= self.min_split_tokens:
+                    splits.append(
+                        DocumentSplit(
+                            docs=current_split.copy(),
+                            is_triggered=False,
+                            triggered_score=None,
+                            token_count=current_tokens_count,
+                        )
+                    )
+                    logger.info(
+                        f"Split finalized with {current_tokens_count} tokens due to "
+                        f"exceeding token limit of {self.max_split_tokens}."
+                    )
+                    current_split, current_tokens_count = [], 0
+
+            current_split.append(doc)
+            current_tokens_count += doc_token_count
+
+        # Handle the last split
+        if current_split:
+            splits.append(
+                DocumentSplit(
+                    docs=current_split.copy(),
+                    is_triggered=False,
+                    triggered_score=None,
+                    token_count=current_tokens_count,
+                )
+            )
+            logger.info(
+                f"Final split added with {current_tokens_count} "
+                "tokens due to remaining documents."
+            )
+
+        # Validation to ensure no tokens are lost during the split
+        original_token_count = sum(token_counts)
+        split_token_count = sum(
+            [tiktoken_length(doc) for split in splits for doc in split.docs]
+        )
+        if original_token_count != split_token_count:
+            logger.error(
+                f"Token count mismatch: {original_token_count} != {split_token_count}"
+            )
+            raise ValueError(
+                f"Token count mismatch: {original_token_count} != {split_token_count}"
+            )
+
+        return splits
+
+    def plot_similarity_scores(
+        self, similarities: List[float], split_indices: List[int]
+    ):
+        try:
+            from matplotlib import pyplot as plt
+        except ImportError:
+            logger.warning(
+                "Plotting is disabled. Please `pip install "
+                "semantic-router[processing]`."
+            )
+            return
+
+        if not self.plot_splits:
+            return
+        plt.figure(figsize=(12, 6))
+        plt.plot(similarities, label="Similarity Scores", marker="o")
+        for split_index in split_indices:
+            plt.axvline(
+                x=split_index - 1,
+                color="r",
+                linestyle="--",
+                label="Split" if split_index == split_indices[0] else "",
+            )
+        plt.axhline(
+            y=self.calculated_threshold,
+            color="g",
+            linestyle="-.",
+            label="Threshold Similarity Score",
+        )
+
+        # Annotating each similarity score
+        for i, score in enumerate(similarities):
+            plt.annotate(
+                f"{score:.2f}",  # Formatting to two decimal places
+                (i, score),
+                textcoords="offset points",
+                xytext=(0, 10),  # Positioning the text above the point
+                ha="center",
+            )  # Center-align the text
+
+        plt.xlabel("Document Segment Index")
+        plt.ylabel("Similarity Score")
+        plt.title(
+            f"Threshold: {self.calculated_threshold} |"
+            f" Window Size: {self.window_size}",
+            loc="right",
+            fontsize=10,
+        )
+        plt.suptitle("Document Similarity Scores", fontsize=14)
+        plt.legend()
+        plt.show()
+
+    def plot_sentence_similarity_scores(
+        self, docs: List[str], threshold: float, window_size: int
+    ):
+        try:
+            from matplotlib import pyplot as plt
+        except ImportError:
+            logger.warning("Plotting is disabled. Please `pip install matplotlib`.")
+            return
+        """
+        Computes similarity scores between the average of the last
+        'window_size' sentences and the next one,
+        plots a graph of these similarity scores, and prints the first
+        sentence after a similarity score below
+        a specified threshold.
+        """
+        sentences = [sentence for doc in docs for sentence in split_to_sentences(doc)]
+        encoded_sentences = self.encode_documents(sentences)
+        similarity_scores = []
+
+        for i in range(window_size, len(encoded_sentences)):
+            window_avg_encoding = np.mean(
+                encoded_sentences[i - window_size : i], axis=0
+            )
+            sim_score = np.dot(window_avg_encoding, encoded_sentences[i]) / (
+                np.linalg.norm(window_avg_encoding)
+                * np.linalg.norm(encoded_sentences[i])
+                + 1e-10
+            )
+            similarity_scores.append(sim_score)
+
+        plt.figure(figsize=(10, 8))
+        plt.plot(similarity_scores, marker="o", linestyle="-", color="b")
+        plt.title("Sliding Window Sentence Similarity Scores")
+        plt.xlabel("Sentence Index")
+        plt.ylabel("Similarity Score")
+        plt.grid(True)
+        plt.axhline(y=threshold, color="r", linestyle="--", label="Threshold")
+        plt.show()
+
+        for i, score in enumerate(similarity_scores):
+            if score < threshold:
+                print(
+                    f"First sentence after similarity score "
+                    f"below {threshold}: {sentences[i + window_size]}"
+                )
+
+    def __call__(self, docs: List[str]) -> List[DocumentSplit]:
+        if not docs:
+            raise ValueError("At least one document is required for splitting.")
+
+        if len(docs) == 1:
+            token_count = tiktoken_length(docs[0])
+            if token_count > self.max_split_tokens:
+                logger.warning(
+                    f"Single document exceeds the maximum token limit "
+                    f"of {self.max_split_tokens}. "
+                    "Splitting to sentences before semantically splitting."
+                )
+            docs = split_to_sentences(docs[0])
+        encoded_docs = self.encode_documents(docs)
+        if self.dynamic_threshold:
+            self.find_optimal_threshold(docs, encoded_docs)
+        else:
+            self.calculated_threshold = self.encoder.score_threshold
+        similarities = self.calculate_similarity_scores(encoded_docs)
+        split_indices = self.find_split_indices(similarities=similarities)
+        splits = self.split_documents(docs, split_indices, similarities)
+        self.plot_similarity_scores(similarities, split_indices)
+        return splits
diff --git a/semantic_router/splitters/utils.py b/semantic_router/splitters/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..349c3eaac76017c53dd5425abfe65e7e2952a679
--- /dev/null
+++ b/semantic_router/splitters/utils.py
@@ -0,0 +1,63 @@
+import regex
+import tiktoken
+
+
+def split_to_sentences(text: str) -> list[str]:
+    """
+    Enhanced regex pattern to split a given text into sentences more accurately.
+
+    The enhanced regex pattern includes handling for:
+    - Direct speech and quotations.
+    - Abbreviations, initials, and acronyms.
+    - Decimal numbers and dates.
+    - Ellipses and other punctuation marks used in informal text.
+    - Removing control characters and format characters.
+
+    Args:
+        text (str): The text to split into sentences.
+
+    Returns:
+        list: A list of sentences extracted from the text.
+    """
+    regex_pattern = r"""
+        # Negative lookbehind for word boundary, word char, dot, word char
+        (?<!\b\w\.\w.)
+        # Negative lookbehind for single uppercase initials like "A."
+        (?<!\b[A-Z][a-z]\.)
+        # Negative lookbehind for abbreviations like "U.S."
+        (?<!\b[A-Z]\.)
+        # Negative lookbehind for abbreviations with uppercase letters and dots
+        (?<!\b\p{Lu}\.\p{Lu}.)
+        # Negative lookbehind for numbers, to avoid splitting decimals
+        (?<!\b\p{N}\.)
+        # Positive lookbehind for punctuation followed by whitespace
+        (?<=\.|\?|!|:|\.\.\.)\s+
+        # Positive lookahead for uppercase letter or opening quote at word boundary
+        (?="?(?=[A-Z])|"\b)
+        # OR
+        |
+        # Splits after punctuation that follows closing punctuation, followed by
+        # whitespace
+        (?<=[\"\'\]\)\}][\.!?])\s+(?=[\"\'\(A-Z])
+        # OR
+        |
+        # Splits after punctuation if not preceded by a period
+        (?<=[^\.][\.!?])\s+(?=[A-Z])
+        # OR
+        |
+        # Handles splitting after ellipses
+        (?<=\.\.\.)\s+(?=[A-Z])
+        # OR
+        |
+        # Matches and removes control characters and format characters
+        [\p{Cc}\p{Cf}]+
+    """
+    sentences = regex.split(regex_pattern, text, flags=regex.VERBOSE)
+    sentences = [sentence.strip() for sentence in sentences if sentence.strip()]
+    return sentences
+
+
+def tiktoken_length(text: str) -> int:
+    tokenizer = tiktoken.get_encoding("cl100k_base")
+    tokens = tokenizer.encode(text, disallowed_special=())
+    return len(tokens)
diff --git a/tests/unit/llms/test_llm_ollama.py b/tests/unit/llms/test_llm_ollama.py
index 299989821d2dc2885f4e4cbe89dd0308d24fffda..369e5f4444789c3bb70988455bb49c7df4792445 100644
--- a/tests/unit/llms/test_llm_ollama.py
+++ b/tests/unit/llms/test_llm_ollama.py
@@ -1,4 +1,5 @@
 import pytest
+
 from semantic_router.llms.ollama import OllamaLLM
 from semantic_router.schema import Message
 
diff --git a/tests/unit/test_layer.py b/tests/unit/test_layer.py
index 3f2c413f45f279656bada2ffdc7ee47b96ef1a6c..415150a597ee396d593c88b651658bd28410fc80 100644
--- a/tests/unit/test_layer.py
+++ b/tests/unit/test_layer.py
@@ -399,10 +399,11 @@ class TestRouteLayer:
         # Load the LayerConfig from the temporary file
         layer_config = LayerConfig.from_file(str(config_path))
 
-        # Using BaseLLM because trying to create a useable Mock LLM is a nightmare.
+        # Using BaseLLM because trying to create a usable Mock LLM is a nightmare.
         assert isinstance(
             layer_config.routes[0].llm, BaseLLM
-        ), "LLM should be instantiated and associated with the route based on the config"
+        ), "LLM should be instantiated and associated with the route based on the "
+        "config"
         assert (
             layer_config.routes[0].llm.name == "fake-model-v1"
         ), "LLM instance should have the 'name' attribute set correctly"