JoeJoe1313 commited on
Commit
94498c7
·
1 Parent(s): fb1f8cd

commit from `quarto publish`

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. src/_freeze/posts/2025-01-04-fourier-method-fixed-string/index/execute-results/html.json +0 -0
  2. src/_freeze/posts/2025-01-06-chebyshev-polynomials/index/execute-results/html.json +0 -12
  3. src/_freeze/posts/wave-equation/index/execute-results/html.json +0 -12
  4. src/_freeze/site_libs/clipboard/clipboard.min.js +0 -7
  5. src/_freeze/site_libs/quarto-listing/list.min.js +0 -2
  6. src/_freeze/site_libs/quarto-listing/quarto-listing.js +0 -253
  7. src/_site/about.html +0 -559
  8. src/_site/index.html +0 -707
  9. src/_site/listings.json +0 -9
  10. src/_site/posts/2025-01-04-fourier-method-fixed-string/code/fixed_string_animation.html +0 -0
  11. src/_site/posts/2025-01-04-fourier-method-fixed-string/images/fixed_string.svg +0 -114
  12. src/_site/posts/2025-01-04-fourier-method-fixed-string/images/harmonics.svg +0 -227
  13. src/_site/posts/2025-01-04-fourier-method-fixed-string/images/odd_continuation.png +0 -3
  14. src/_site/posts/2025-01-04-fourier-method-fixed-string/index.html +0 -0
  15. src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_nodes.png +0 -3
  16. src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_nodes_visualization.svg +0 -55
  17. src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials.png +0 -3
  18. src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials_aliasing_even.png +0 -3
  19. src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials_aliasing_odd.png +0 -3
  20. src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials_stacked.png +0 -3
  21. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_0.png +0 -3
  22. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_1.png +0 -3
  23. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_10.png +0 -3
  24. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_11.png +0 -3
  25. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_2.png +0 -3
  26. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_3.png +0 -3
  27. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_4.png +0 -3
  28. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_5.png +0 -3
  29. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_6.png +0 -3
  30. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_7.png +0 -3
  31. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_8.png +0 -3
  32. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_9.png +0 -3
  33. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_init_1.png +0 -3
  34. src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_init_2.png +0 -3
  35. src/_site/posts/2025-01-06-chebyshev-polynomials/images/reduction.svg +0 -64
  36. src/_site/posts/2025-01-06-chebyshev-polynomials/images/unit_circle.svg +0 -36
  37. src/_site/posts/2025-01-06-chebyshev-polynomials/index.html +0 -1077
  38. src/_site/posts/fourier/index.html +0 -2
  39. src/_site/posts/post-with-code/index.html +0 -2
  40. src/_site/posts/wave-equation/index.html +0 -2
  41. src/_site/posts/welcome/index.html +0 -2
  42. src/_site/profile.jpg +0 -0
  43. src/_site/search.json +0 -58
  44. src/_site/site_libs/bootstrap/bootstrap-d1b12f2568ecbe55642fee6aa00bd082.min.css +0 -0
  45. src/_site/site_libs/bootstrap/bootstrap-icons.css +0 -0
  46. src/_site/site_libs/bootstrap/bootstrap-icons.woff +0 -3
  47. src/_site/site_libs/bootstrap/bootstrap.min.js +0 -7
  48. src/_site/site_libs/clipboard/clipboard.min.js +0 -7
  49. src/_site/site_libs/quarto-html/anchor.min.js +0 -9
  50. src/_site/site_libs/quarto-html/popper.min.js +0 -6
src/_freeze/posts/2025-01-04-fourier-method-fixed-string/index/execute-results/html.json DELETED
The diff for this file is too large to render. See raw diff
 
src/_freeze/posts/2025-01-06-chebyshev-polynomials/index/execute-results/html.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "hash": "aa583ba3ab0462ca32f88764351645de",
3
- "result": {
4
- "engine": "jupyter",
5
- "markdown": "---\ntitle: \"Chebyshev Polynomials: Part 1\"\nauthor: \"Joana Levtcheva\"\ndate: \"2025-01-06\"\ncategories: [mathematics, polynomials]\ndraft: false\n---\n\n\n\n\nChebyshev polynomials are a sequence of orthogonal polynomials that play a central role in numerical analysis, approximation theory, and applied mathematics. They are named after the Russian mathematician Pafnuty Chebyshev and come in two primary types: Chebyshev polynomials of the first kind ($T_n(x)$) and Chebyshev polynomials of the second kind ($U_n(x)$). In this post we are going to focus on the Chebyshev polynomials of the first kind.\n\n# Chebyshev Polynomials of the First Kind\n\nThere are many different ways to define the Chebyshev polynomials of the first kind. The one that seems most logical to me and most useful in terms of outlining various properties of the polynomials is\n\n$$\\label{eq:1}\nT_{n}(x) = \\cos{\\left(n \\arccos{x}\\right)}, \\quad x \\in [-1, 1].\\tag{1}\n$$\n\nLooking at \\eqref{eq:1} it is not obvious why $T_{n}(x)$ would be a polynomial. In order to show it is indeed a polynomial let's recall the de Moivre's formula\n\n$$\n\\cos{(n \\theta)} + i\\sin{(n \\theta)} = (\\cos(\\theta) + i \\sin{\\theta})^n.\n$$\n\nWe can apply binomial expansion and take the real part from it to obatin\n\n$$\\label{eq:2}\n\\cos(n \\theta) = \\sum_{k = 0}^{\\frac{n}{2}} C(n, 2k) (-1)^k \\cos^{n - 2k}\\theta \\sin^{2k}{\\theta}. \\tag{2}\n$$\n\nwhere \n\n$$\nC(n, 2k) = \\frac{n!}{(2k)!(n-2k)!}, \\quad n \\geq 2k, k \\in N, n \\in N\n$$ \n\ndenotes the binomal coefficient. We can also notice that\n\n$$\n\\sin^{2k}\\theta = (\\sin^2{\\theta})^k = (1 - \\cos^2{\\theta})^k,\n$$\n\nshowing that \\eqref{eq:2} is a polynomial of $\\cos{\\theta}$ of degree $n$. Now, let\n\n$$\n\\theta = \\arccos{x},\n$$\n\nand by utilising $\\cos{\\left(\\arccos{x}\\right)} = x$ we get\n\n$$\nx = \\cos{\\theta}.\n$$\n\nThis transforms \\eqref{eq:1} to \n\n$$\\label{eq:3}\nT_{n}(\\cos{\\theta}) = \\cos{\\left(n \\theta\\right)} \\tag{3}\n$$\n\nwhich we already showed is a polynomial of degree $n$. From here, because $\\cos(.)$ is an even function, we can note that\n\n$$\nT_{n}(x) = T_{-n}(x) = T_{|n|}(x.)\n$$\n\nFrom \\eqref{eq:3} it is also obvious that the values of $T_n$ in the interval $[-1, 1]$ are bounded in $[-1, 1]$ because of the cosine.\n\n## Chebyshev Nodes of the First Kind\n\nBefore we continue with exploring the roots of the polynomials, let's recall some trigonometry. \n\n---\n\nThe **unit circle** is a circle with a radius of 1, centered at the origin of the Cartesian coordinate system. Below is shown part of the unit circle corresponding to the region from $0$ to $\\frac{\\pi}{2}$.\n\n![Figure 1. Unit circle from $0$ to $\\frac{\\pi}{2}$](images/unit_circle.svg)\n\nThe cosine of an angle $\\theta$ corresponds to the $x$-coordinate of the point where the terminal side of the angle (measured counterclockwise from the positive $x$-axis) intersects the unit circle. In other words, $\\cos(\\theta)$ gives the horizontal distance from the origin to this intersection point. \n\nThe **arccosine** is the inverse function of cosine, and it maps a cosine value back to its corresponding angle in the range $[0, \\pi]$ radians. For a given $x$-coordinate on the unit circle, the arccosine gives the angle $\\theta$ such that $\\cos(\\theta) = x$, meaning\n\n$$\n\\arccos(x) = \\theta, \\quad \\text{where } \\theta \\in [0, \\pi].\n$$\n\nMoreover, a **radian** is defined as the angle subtended at the center of a circle by an arc whose length is equal to the radius of the circle. For any circle, the length of an arc $s$ is given by\n\n$$\ns = r \\cdot \\theta,\n$$\n\nwhere $r$ is the radius of the circle, $\\theta$ is the angle subtended by the arc at the center. This means that on the unit circle the length of the arc equals the measure of the angle in radians because $r = 1$, and hence\n\n$$\ns = \\theta.\n$$\n\n---\n\nNow, let's find the roots of the polynomial $T_{n}(x)$. If we take the definition in \\eqref{eq:1} we have to solve\n\n$$\n\\cos{\\left(n \\arccos{x}\\right)} = 0, k \\in N.\n$$\n\nThe solutions in the interval $(-1, 1)$ are given by\n\n$$\nx_k = \\cos{\\left(\\frac{2k - 1}{2n}\\pi\\right)}, n \\in N, k = 1, 2, ...n.\n$$\n\nThese roots are known as the **Chebyshev nodes of the first kind**, or the **Chebyshev zeros**. If we are working with an arbitrary interval $(a, b)$ the affine transformation \n\n$$\nx_k = \\frac{a + b}{2} + \\frac{b - a}{2}\\cos{\\left(\\frac{2k - 1}{2n}\\pi\\right)}, n \\in N, k = 1, 2, ...n\n$$\n\nis needed. From the cosine properties we can also note that the nodes are symmetric with respect to the midpoint of the interval, and that the extrema of $T_n(x)$ over the interval $[-1, 1]$ alternate between $-1$ and $1$. Also, a very useful fact is that these nodes are used in polynomial interpolation to minimize the **Runge phenomenon**.\n\nIn the figure below we have shown the roots of $T_{8}(x)$ in blue. We have also built the perpendiculars from the roots to their interesction with the upper half of the unit circle, and marked these points in red.\n\n![Tester](images/chebyshev_nodes_visualization.svg){ width=45% }![alt text](images/chebyshev_nodes.png){ width=45% }\n\nLooking at the figure we can notice that the arc lengths between the red points seem to be of the same length. Let's show that this is indeed the truth.\n\nWe showed the roots are the cosine functions $\\cos{\\left(\\frac{2k - 1}{2n}\\pi\\right)}, n \\in N, k = 1, 2, ...n$. Thus, in the unit circle we have that the length of the corresponding arcs are equal to $\\left( \\frac{2k - 1}{2n}\\pi \\right), n \\in N, k = 1, 2, ...n$. Let's take two red points which are direct neighbours, or in other words let's take two red points corresponding to the randomly chosen $m$ and $m + 1$ roots, $m \\in k = \\{1, 2, ..., n\\}$. If we subtract them we are going to determine the length of the arc between them. We have\n\n$$\n\\frac{2(m + 1) - 1}{2n}\\pi - \\frac{2m - 1}{2n}\\pi = \\frac{\\pi}{n},\n$$\n\nmeaning that between every two nodes the arc length is equal and has a value of $\\frac{\\pi}{n}$. A polynomial of degree $n$ has $n$ roots, which in our case are in the open interval $(-1, 1)$, meaning the arcs corresponding to every two neighbouring roots are $n - 1$, and the two arcs between the $x$-axis and the first and last roots due to the symmetry of roots have lenghts of\n\n$$\n\\frac{1}{2}\\left(\\pi - \\frac{n-1}{n}\\pi\\right) = \\frac{\\pi}{2n}.\n$$\n\n## Recurrence relation\n\nThis is probably a bit out of nowhere, but let's take a look at the following trigonometric identity\n\n$$\\label{eq:4}\n\\cos{\\left((n + 1)\\theta\\right)} + \\cos{\\left((n - 1)\\theta\\right)} = 2 \\cos{(\\theta)} \\cos{(n\\theta)},\\tag{4}\n$$\n\nand show that the left side indeed is equal to the right one. We are going to need the following two fundamental formulas of angle addition in trigonometry\n\n$$\n\\cos{(\\alpha + \\beta)} = \\cos{\\alpha} \\cos{\\beta} - \\sin{\\alpha} \\sin{\\beta},\n$$\n\nand\n\n$$\n\\cos{(\\alpha - \\beta)} = \\cos{\\alpha} \\cos{\\beta} + \\sin{\\alpha} \\sin{\\beta}.\n$$\n\nIn our case we have\n\n$$\n\\cos{\\left((n + 1)\\theta\\right)} = \\cos{\\left(n\\theta + \\theta\\right)} = \\cos{(n\\theta)} \\cos{\\theta} - \\sin{(n\\theta)} \\sin{\\theta},\n$$\n\nand\n\n$$\n\\cos{\\left((n - 1)\\theta\\right)} = \\cos{\\left(n\\theta - \\theta\\right)} = \\cos{(n\\theta)} \\cos{\\theta} + \\sin{(n\\theta)} \\sin{\\theta}.\n$$\n\nAdding the above equations leads to the wanted result.\n\nNow, we can see that the terms of \\eqref{eq:4} are exactly in the form of the right side of \\eqref{eq:1}, \\eqref{eq:3}, hence we get\n\n$$\nT_{n + 1}(x) + T_{n - 1}(x) = 2T_{n}(x)T_{1}(x),\n$$\n\nor we get the useful **recurrence relation**\n\n$$\\label{eq:5}\nT_{n + 1}(x) - 2xT_{n}(x) + T_{n - 1}(x) = 0.\\tag{5}\n$$\n\nThis relation along with adding $T_{0}(x) = 1$ and $T_{1}(x) = x$ is another famous way to define the Chebyshev polynomials of the first kind, or\n\n$$\n\\left\\{\\begin{align*}\nT_{0}(x) = 1, \\\\\nT_{1}(x) = x, \\\\\nT_{n + 1}(x) - 2xT_{n}(x) + T_{n - 1}(x) = 0.\n\\end{align*}\\right.\\label{eq:6}\\tag{6}\n$$\n\nLet's write the first $6$ polynomials by using \\eqref{eq:6}:\n\n$$\n\\left\\{\\begin{align*}\nT_{0}(x) = 1, \\quad \\text{(even)}\\\\\nT_{1}(x) = x, \\quad \\text{(odd)}\\\\\nT_{2}(x) = 2x^2 - 1, \\quad \\text{(even)}\\\\\nT_{3}(x) = 4x^3 - 3x, \\quad \\text{(odd)}\\\\\nT_{4}(x) = 8x^4 - 8x^2 + 1, \\quad \\text{(even)}\\\\\nT_{5}(x) = 16x^5 - 20x^3 + 5x. \\quad \\text{(odd)}\n\\end{align*}\\right.\n$$\n\nWe can notice that\n\n$$\nT_{k}(x) = 2^{k-1}x^k + ...,\n$$\n\nand $T_{k}(x)$ is alternating between an even and an odd polynomial depending on whether $k$ is even or odd respectively.\n\nBefore we continue with some visualisations and more facts, let's mention that an interesting way to represent the recurrence relation \\eqref{eq:5} is via the determinant\n\n$$\nT_{k}(x) = \\det \\begin{bmatrix}\nx & 1 & 0 & \\dots & 0 \\\\\n1 & 2x & 1 & \\ddots & \\vdots \\\\\n0 & 1 & 2x & \\ddots & 0 \\\\\n\\vdots & \\ddots & \\ddots & \\ddots & 1 \\\\\n0 & \\dots & 0 & 1 & 2x\n\\end{bmatrix}.\n$$\n\nNow, let's visualise the first $8$ polynomials.\n\n![Chebyshev Polynomials](images/chebyshev_polynomials.png)\n\nBut what can we notice if we stack them together?\n\n![Chebyshev Polynomials Stacked](images/chebyshev_polynomials_stacked.png)\n\nIt is quite obvious that at the roots of the $N$-th Chebyshev polynomial there is an **aliasing** effect, meaning higher order polynomials look like lower order ones. We can formally show it by fixing $N$, at the roots $x_k$ of $T_{N}(x) = 0$, and using the Chebyshev identity\n\n$$\n\\cos{\\left((m + N)\\theta\\right)} + \\cos{\\left((m - N)\\theta\\right)} = 2\\cos{(m\\theta)}\\cos{(N\\theta)},\n$$\n\nor equivalently\n\n$$\nT_{m + N}(x) + T_{m - N}(x) = 2T_{m}(x)T_{N}(x).\n$$\n\nNow, having $T_{N}(x) = 0$ leads to\n\n$$\nT_{m + N}(x) = -T_{m - N}(x).\n$$\n\nIf we consecutevly set $m = N$, $m = 2N$, ..., $m = 6N$, etc. we would get\n\n$$\n\\left\\{\\begin{align*}\nT_{2N}(x_k) = -T_{0}(x_k) = -1, \\\\\nT_{3N}(x_k) = 0, \\\\\nT_{4N}(x_k) = 1, \\\\\nT_{5N}(x_k) = 0, \\\\\nT_{6N}(x_k) = -1, \\\\\n\\text{etc}.\n\\end{align*}\\right.\n$$\n\nWe can safely say that any higher-order Chebyshev polynomial $T_{N}(x)$ can be reduced to a lower-order $j, 0 \\leq j \\leq N$ Chebyshev polynomial at the sample points $x_k$ which are the roots of $T_{N}(x)$. In the figure below we attempt to visualise this statement.\n\n![alt text](images/reduction.svg)\n\nThe horizontal axis represents the order of Chebyshev polynomials, and the blue wavy line represents a \"folded ribbon\". Think of it as taking the sequence of polynomial orders and folding it back and forth. This folding happens at specific points where higher-order polynomials can be reduced to lower-order ones, which are the red **x** marks showing the sample points: the roots of $T_n(x)$. The key insight is that at these special sample points, we don't need to work with the higher-order polynomials because we can use equivalent lower-order ones instead. This is incredibly useful in numerical computations as it can help reduce computational complexity, and makes the Chebyshev polynomials very computationally efficient.\n\nLet's illustarte this with a simple example. Let $N = 2$, then for even $m$ we have\n\n$$\n\\left\\{\\begin{align*}\nT_{4}(x_k) = -T_{0}(x_k) = -1, \\\\\nT_{6}(x_k) = - T_{2}(x_k) = 0, \\\\\nT_{8}(x_k) = - T_{4}(x_k) = 1, \\\\\nT_{10}(x_k) = -T_{6}(x_k) = 0, \\\\\n\\text{etc}.\n\\end{align*}\\right.\n$$\n\nIn the figure below we can see the even polynomials and that indeed $T_{10}(x)$ behaves like $-T_{6}(x)$ which behaves like $T_{2}(x)$ at the roots having value $0$, $T_{8}(x)$ behaves like $-T_{4}(x)$ at the roots with value $1$ as in $T_{0}(x)$, $T_{6}(x)$ behaves like $-T_{2}(x)$ with value $0$, and $T_{4}(x)$ behaves like $-T_{0}(x)$ with value $-1$.\n\n::: {#be218886 .cell execution_count=1}\n``` {.python .cell-code code-fold=\"true\" code-summary=\"Click to expand the code\"}\nfrom typing import Union\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\ndef chebyshev_polynomial(\n n: int, x: Union[float, np.ndarray]\n) -> Union[float, np.ndarray]:\n \"\"\"\n Calculate nth Chebyshev polynomial of the first kind T_n(x).\n\n Args:\n n: Order of polynomial (non-negative integer)\n x: Point(s) at which to evaluate polynomial\n\n Returns:\n Value of T_n(x)\n \"\"\"\n if n < 0:\n raise ValueError(\"Order must be non-negative\")\n\n if n == 0:\n return np.ones_like(x)\n elif n == 1:\n return x\n else:\n t_prev = np.ones_like(x) # T_0\n t_curr = x # T_1\n\n for _ in range(2, n + 1):\n t_next = 2 * x * t_curr - t_prev\n t_prev = t_curr\n t_curr = t_next\n\n return t_curr\n\n\ndef chebyshev_nodes(n):\n \"\"\"Generate n Chebyshev nodes in [-1,1]\"\"\"\n k = np.arange(1, n + 1)\n return np.cos((2 * k - 1) * np.pi / (2 * n))\n\n\nif __name__ == \"__main__\":\n\n x = np.linspace(-1, 1, 1000)\n plt.figure(figsize=(12, 6))\n plt.plot(x, -chebyshev_polynomial(0, x), \"--\", label=f\"-T_{0}(x)\", alpha=0.5)\n for n in [0, 2, 4, 6, 8, 10]:\n y = chebyshev_polynomial(n, x)\n plt.plot(x, y, label=f\"T_{n}(x)\")\n\n # plot nodes for n = 2\n n = 2\n nodes = chebyshev_nodes(n)\n y_nodes = np.cos(n * np.arccos(nodes))\n plt.plot(nodes, np.zeros_like(nodes), \"bo\", label=\"T_2(x) roots\")\n for node in nodes:\n plt.plot([node, node], [-1, 1], \"--\", color=\"gray\", alpha=0.5)\n\n # plt.grid(True)\n # Set aspect ratio to be equal\n # plt.gca().set_aspect('equal', adjustable='box')\n plt.xlabel(\"x\")\n plt.ylabel(\"T_n(x)\")\n plt.title(\"Chebyshev Polynomials Aliasing\")\n plt.legend(loc=\"center left\", bbox_to_anchor=(1, 0.5), fontsize=8)\n plt.xlim(-1.1, 1.1)\n plt.ylim(-1.1, 1.1)\n plt.axhline(y=0, color=\"k\", linestyle=\"-\", alpha=0.7)\n plt.savefig(\n \"content/images/2025-01-06-chebyshev-polynomials/chebyshev_polynomials_aliasing_even.png\"\n )\n plt.show()\n```\n:::\n\n\n![alt text](images/chebyshev_polynomials_aliasing_even.png)\n\nFor odd $m$ we have\n$$\n\\left\\{\\begin{align*}\nT_{3}(x_k) = - T_{1}(x_k) = - x\\\\\nT_{5}(x_k) = - T_{3}(x_k) = x\\\\\nT_{7}(x_k) = - T_{5}(x_k) = -x, \\\\\nT_{9}(x_k) = - T_{7}(x_k) = x, \\\\\n\\text{etc}.\n\\end{align*}\\right.\n$$\n\nIn the figure below we can see the odd polynomials and the aliasing as in the previous example.\n\n::: {#54809f08 .cell execution_count=2}\n``` {.python .cell-code code-fold=\"true\" code-summary=\"Click to expand the code\"}\nfrom typing import Union\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\ndef chebyshev_polynomial(\n n: int, x: Union[float, np.ndarray]\n) -> Union[float, np.ndarray]:\n \"\"\"\n Calculate nth Chebyshev polynomial of the first kind T_n(x).\n\n Args:\n n: Order of polynomial (non-negative integer)\n x: Point(s) at which to evaluate polynomial\n\n Returns:\n Value of T_n(x)\n \"\"\"\n if n < 0:\n raise ValueError(\"Order must be non-negative\")\n\n if n == 0:\n return np.ones_like(x)\n elif n == 1:\n return x\n else:\n t_prev = np.ones_like(x) # T_0\n t_curr = x # T_1\n\n for _ in range(2, n + 1):\n t_next = 2 * x * t_curr - t_prev\n t_prev = t_curr\n t_curr = t_next\n\n return t_curr\n\n\ndef chebyshev_nodes(n):\n \"\"\"Generate n Chebyshev nodes in [-1,1]\"\"\"\n k = np.arange(1, n + 1)\n return np.cos((2 * k - 1) * np.pi / (2 * n))\n\n\nif __name__ == \"__main__\":\n\n x = np.linspace(-1, 1, 1000)\n plt.figure(figsize=(12, 6))\n plt.plot(x, -chebyshev_polynomial(1, x), \"--\", label=f\"-T_{1}(x)\", alpha=0.5)\n for n in [1, 2, 3, 5, 7, 9]:\n y = chebyshev_polynomial(n, x)\n plt.plot(x, y, label=f\"T_{n}(x)\")\n\n # plot nodes for n = 2\n n = 2\n nodes = chebyshev_nodes(n)\n y_nodes = np.cos(n * np.arccos(nodes))\n plt.plot(nodes, np.zeros_like(nodes), \"bo\", label=\"T_2(x) roots\")\n for node in nodes:\n plt.plot([node, node], [-1, 1], \"--\", color=\"gray\", alpha=0.5)\n\n # plt.grid(True)\n # Set aspect ratio to be equal\n # plt.gca().set_aspect('equal', adjustable='box')\n plt.xlabel(\"x\")\n plt.ylabel(\"T_n(x)\")\n plt.title(\"Chebyshev Polynomials Aliasing\")\n plt.legend(loc=\"center left\", bbox_to_anchor=(1, 0.5), fontsize=8)\n plt.xlim(-1.1, 1.1)\n plt.ylim(-1.1, 1.1)\n plt.axhline(y=0, color=\"k\", linestyle=\"-\", alpha=0.7)\n plt.savefig(\n \"content/images/2025-01-06-chebyshev-polynomials/chebyshev_polynomials_aliasing_odd.png\"\n )\n plt.show()\n```\n:::\n\n\n![alt text](images/chebyshev_polynomials_aliasing_odd.png)\n\n## Radial Plots\n\nAn interesting plot can be observed by plotting $T_n(x)$ radially. This means that instead of evaluating the polynomials over $[-1, 1]$ in a Cartesian plane we are evaluating them at $\\frac{\\theta}{\\pi} - 1$, and plotting $r = n + T_n(\\frac{\\theta}{\\pi} - 1)$ on polar axes. In other words, the input domain has been shifted and extended, and the results are drawn as radial distances $r$ around a circle defined by $\\theta$. This creates a polar visualization where each $n$ produces a distinct spiral-like ornament. We are also filling in the areas between the curves for a visual effect.\n\n::: {#b2db675f .cell execution_count=3}\n``` {.python .cell-code code-fold=\"true\" code-summary=\"Click to expand the code\"}\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom numpy.polynomial.chebyshev import Chebyshev\n\ntheta = np.linspace(0, 2 * np.pi, 2000)\nfig, ax = plt.subplots(subplot_kw={\"projection\": \"polar\"})\n\n# Generate and fill between consecutive curves\nfor n in range(0, 19 * 2, 2):\n r1 = n + Chebyshev([0] * n + [1])(theta / np.pi - 1)\n r2 = (n + 2) + Chebyshev([0] * (n + 2) + [1])(theta / np.pi - 1)\n\n # Create black and white alternating pattern\n if n % 4 == 0:\n ax.fill_between(theta, r1, r2, color=\"black\")\n else:\n ax.fill_between(theta, r1, r2, color=\"white\")\nax.set_title(\"x = t/π - 1\", y=1)\nplt.axis(\"off\")\nplt.show()\n```\n:::\n\n\n![alt text](images/polar_init_1.png){ width=50% }![alt text](images/polar_init_2.png){ width=41% }\n\nMore visualusations can be achieved by doing other domain changes. They can be seen below.\n\n![alt text](images/polar_0.png){ width=25% }![alt text](images/polar_1.png){ width=25% }![alt text](images/polar_2.png){ width=25% }![alt text](images/polar_3.png){ width=25% }\n\n![alt text](images/polar_4.png){ width=25% }![alt text](images/polar_5.png){ width=25% }![alt text](images/polar_6.png){ width=25% }![alt text](images/polar_7.png){ width=25% }\n\n![alt text](images/polar_8.png){ width=25% }![alt text](images/polar_9.png){ width=25% }![alt text](images/polar_10.png){ width=25% }![alt text](images/polar_11.png){ width=25% }\n\nIn a separate post, Chebyshev Polynomials, Part 2, we are going to explore the Chebyshev polynomials of the second kind, and their relations to the polynomials of the first kind.\n\n",
6
- "supporting": [
7
- "index_files"
8
- ],
9
- "filters": [],
10
- "includes": {}
11
- }
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
src/_freeze/posts/wave-equation/index/execute-results/html.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "hash": "acdc50e3128605e35f826beed13579e3",
3
- "result": {
4
- "engine": "jupyter",
5
- "markdown": "---\ntitle: \"Wave Equation\"\nauthor: \"JoJo\"\ndate: \"2024-12-19\"\ncategories: [mathematics, python]\nimage: \"./images/rectangular_membrane_1_animation.gif\"\ndraft: true\n---\n\n\n\n\nPartial differential equations...\n\n# Introduction\n\nLet $u(x, y, t)$ be ...\n \nThe homogenous wave equation is given by\n\n$$\n\\frac{\\partial^2 u}{\\partial t^2} - c^2 (\\frac{\\partial^2 u}{\\partial x^2} + \\frac{\\partial^2 u}{\\partial y^2}) = 0\n$$\n\nor\n\n\\begin{equation}\nu_{tt} - c^2 (u_{xx} + u_{yy}) = 0.\n\\end{equation}\n\n# Physical interpretation\n\nThe wave equation is a simplified model for a vibrating\nstring (𝑛 = 1), membrane (𝑛 = 2), or elastic solid (𝑛 = 3). In these\nphysical interpretations 𝑢(𝑥, 𝑡) represents the displacement in some direction\nof the point 𝑥 at time 𝑡 ≥ 0.\n\n1D and 2D Equations\n\n# Rectangular Membrane\n\nPass\n\n$$\nD := \\{0 < x < a, 0 < y < b\\}\n$$\n\n...\n\n$$\n\\left\\{\\begin{align*}\nu_{tt} - c^2 (u_{xx} + u_{yy}) = 0, (x,y,t) \\in G = D \\times (0, +\\infty), \\\\ \nu|_{t=0} = \\varphi(x, y), u_t |_{t=0} = \\psi(x, y), (x, y) \\in \\bar{D}, \\\\\nu|_{\\partial D} = 0, t \\geq 0.\n\\end{align*}\\right.\n$$\n\n...\n\n$$\n\\varphi(x, y) \\in C^3 (\\bar{D}), \\psi(x, y) \\in C^2 (\\bar{D})\n$$\n\nand ...\n\n$$\n\\varphi |_{\\partial D} = \\varphi_{xx} |_{x = 0} = \\varphi_{xx} |_{x = a} = \\varphi_{yy} |_{y =0} = \\varphi_{yy} |_{y = b} = \\psi |_{\\partial D} = 0.\n$$\n\nSolution... :\n\n$$\nu(x, y, t) = \\sum_{n, m = 1}^{\\infty} \\left(A_{n, m} \\cos{\\sqrt{\\lambda_{n, m}} ct} + B_{n, m} \\sin{\\sqrt{\\lambda_{n, m}} ct} \\right) \\sin{\\frac{\\pi n}{a}} x \\sin{\\frac{\\pi m}{b}} y,\n$$\n\nwhere\n\n$$\n\\lambda_{n, m} = \\left(\\frac{\\pi n}{a} \\right)^2 + \\left(\\frac{\\pi m}{b} \\right)^2.\n$$\n\nFrom the initial conditions it follows\n\n$$\nA_{n, m} = \\frac{4}{ab} \\int_D \\varphi(x, y) \\sin{\\frac{\\pi n}{a}} x \\sin{\\frac{\\pi m}{b}} y \\mathrm{d}x \\mathrm{d}y,\n$$\n\nand\n\n$$\nB_{n, m} = \\frac{4}{abc\\sqrt{\\lambda_{n, m}}} \\int_D \\psi(x, y) \\sin{\\frac{\\pi n}{a}} x \\sin{\\frac{\\pi m}{b}} y \\mathrm{d}x \\mathrm{d}y.\n$$\n\n## Example 1\n\n...\n\n$$\n\\left\\{\\begin{align*}\nu_{tt} - u_{xx} - u_{yy} = 0, 0 < x < \\pi, 0 < y < \\pi, t > 0, \\\\\nu|_{t=0} = \\sin{x} \\sin{y}, u_t |_{t=0} = \\sin{4x} \\sin{3y}, x, y \\in (0, \\pi), \\\\\nu|_{x = 0} = 0, u|_{x = \\pi} = 0, 0 < y < \\pi, t > 0, \\\\\nu|_{y = 0} = 0, u|_{y = \\pi} = 0, 0 < x < \\pi, t > 0.\n\\end{align*}\\right.\n$$\n\nSolution:\n\n$$\nu(x, y, t) = \\sum_{n, m = 1}^{\\infty} \\left(A_{n, m} \\cos{\\sqrt{\\lambda_{n, m}} t} + B_{n, m} \\sin{\\sqrt{\\lambda_{n, m}} t} \\right) \\sin{n} x \\sin{m} y,\n$$\n\nwhere\n\n$$\n\\lambda_{n, m} = n^2 + m^2,\n$$\n\n$$\nA_{n, m} = \\frac{4}{\\pi^2} \\int_0^\\pi \\sin{x} \\sin{nx} \\mathrm{d}x \\int_0^\\pi \\sin{y} \\sin{my} \\mathrm{d}y,\n$$\n\n$$\nB_{n, m} = \\frac{4}{\\pi^2\\sqrt{\\lambda_{n, m}}} \\int_0^\\pi \\sin{4x} \\sin{nx} \\mathrm{d}x \\int_0^\\pi \\sin{3y} \\sin{my} \\mathrm{d}y.\n$$\n\nTherefore, $A_{1, 1} = 1$, $B_{4, 3} = \\frac{1}{5}$, and every other coefficients is equal to $0$. Finally, \n\n$$\nu(x, y, t) = \\cos{\\sqrt{2}t} \\sin{x} \\sin{y} + \\frac{1}{5} \\sin{5t} \\sin{4x} \\sin{3y}.\n$$\n\nFor $t \\in [0, 6]$:\n\nAnimation:\n\n![Rectangular Membrane 1](./images/rectangular_membrane_1_animation.gif)\n\n::: {#596976bd .cell execution_count=1}\n``` {.python .cell-code code-fold=\"true\" code-summary=\"Click to expand the code\"}\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.animation import FuncAnimation\n\n\ndef rectangular_membrane_1(t_max: int = 6):\n t = np.linspace(0, t_max, 100) # Time points for animation\n x = np.linspace(0, np.pi, 51) # x grid\n y = np.linspace(0, np.pi, 51) # y grid\n X, Y = np.meshgrid(x, y)\n\n # Define the solution function\n def solution(x, y, t):\n return (\n np.cos(np.sqrt(2) * t) * np.sin(x) * np.sin(y)\n + np.sin(5 * t) * np.sin(4 * x) * np.sin(3 * y) / 5\n )\n\n # Set up the figure and axis for animation\n fig = plt.figure()\n ax = fig.add_subplot(111, projection=\"3d\")\n ax.set_xlim(0, np.pi)\n ax.set_ylim(0, np.pi)\n ax.set_zlim(-1, 1)\n ax.set_xlabel(\"x\")\n ax.set_ylabel(\"y\")\n ax.set_zlabel(\"u(x,y,t)\")\n ax.set_title(\"Rectangular Membrane\")\n\n # Update function for FuncAnimation\n def update(frame):\n ax.clear() # Clear the previous frame\n Z = solution(X, Y, frame) # Compute the new Z values\n _ = ax.plot_surface(X, Y, Z, cmap=\"viridis\", vmin=-1, vmax=1)\n ax.set_xlim(0, np.pi)\n ax.set_ylim(0, np.pi)\n ax.set_zlim(-1, 1)\n ax.set_xlabel(\"x\")\n ax.set_ylabel(\"y\")\n ax.set_zlabel(\"u(x,y,t)\")\n ax.set_title(\"Rectangular Membrane\")\n\n # Create and save the animation\n anim = FuncAnimation(fig, update, frames=t, interval=50)\n anim.save(\"rectangular_membrane_1_animation.gif\", writer=\"imagemagick\", fps=20)\n\n plt.show()\n```\n:::\n\n\nSnapshots:\n\n![t0](./images/rectangular_membrane_1_t0.png){width=33%}![t10](./images/rectangular_membrane_1_t1.png){width=33%}![t30](./images/rectangular_membrane_1_t6.png){width=33%}\n\n## Example 2\n\n...\n\n$$\n\\left\\{\\begin{align*}\nu_{tt} - \\pi^2 (u_{xx} + u_{yy}) = 0, 0 < x < 1, 0 < y < 2, t > 0, \\\\\nu|_{t=0} = \\cos{\\left(\\left(x + \\frac{1}{2}\\right)\\pi\\right)} \\cos{\\left(\\frac{\\pi}{2}\\left(y + 1\\right)\\right)}, u_t |_{t=0} = 0, 0 \\leq x \\leq 1, 0 \\leq y \\leq 2, \\\\\nu|_{x = 0} = 0, u|_{x = 1} = 0, 0 \\leq y < 2, t \\geq 0, \\\\\nu|_{y = 0} = 0, u|_{y = 2} = 0, 0 \\leq x \\leq 1, t \\geq 0.\n\\end{align*}\\right.\n$$\n\nSolution with Fourier method:\n\n$$\nu(x, y, t) = \\sum_{n, m = 1}^{\\infty} \\left(A_{n, m} \\cos{\\sqrt{\\lambda_{n, m}} t} + B_{n, m} \\sin{\\sqrt{\\lambda_{n, m}} t} \\right) \\sin{\\pi n} x \\sin{\\pi m} y,\n$$\n\nwhere\n\n$$\n\\lambda_{n, m} = \\pi^2 (n^2 + m^2)\n$$\n\nand\n\n$$\nB_{n, m} = 0.\n$$\n\n$$\nA_{n, m} = 2 \\int_{0}^{1} \\cos{\\left(\\left(x + \\frac{1}{2}\\right)\\pi\\right)} \\sin{\\pi nx} \\mathrm{d}x \\int_0^2 \\cos{\\left(\\frac{\\pi}{2}\\left(y + 1\\right)\\right)} \\sin{\\pi my} \\mathrm{d}y.\n$$\n\nVisualising the solution for $t \\in [0, 6]$ with the partial sum\n\n$$\n\\tilde{u}(x, y, t) = \\sum_{n, m = 1}^{30} A_{n, m} \\cos{\\sqrt{\\lambda_{n, m}} t} \\sin{\\pi n} x \\sin{\\pi m} y.\n$$\n\nAnimation:\n\n![Rectangular Membrane 2](./images/rectangular_membrane_2_animation.gif)\n\n::: {#f1605c55 .cell execution_count=2}\n``` {.python .cell-code code-fold=\"true\" code-summary=\"Click to expand the code\"}\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.animation import FuncAnimation\n\n\ndef rectangular_membrane_2(a: float = 1, b: float = 2, c: float = np.pi, tmax: int = 6):\n t = np.linspace(0, tmax, 100) # Time points for animation\n x = np.linspace(0, a, 50) # x grid\n y = np.linspace(0, b, 50) # y grid\n X, Y = np.meshgrid(x, y)\n\n # Define the solution function\n def solution(x, y, t):\n z = 0\n for n in range(1, 31):\n for m in range(1, 31):\n lambda_nm = np.pi**2 * (n**2 / a**2 + m**2 / b**2)\n # Compute the coefficient Anm\n xx = np.linspace(0, a, 100)\n yy = np.linspace(0, b, 100)\n Anm = (\n 4\n * np.trapezoid(\n np.cos(np.pi / 2 + np.pi * xx / a) * np.sin(n * np.pi * xx / a),\n xx,\n )\n * np.trapezoid(\n np.cos(np.pi / 2 + np.pi * yy / b) * np.sin(m * np.pi * yy / b),\n yy,\n )\n / (a * b)\n )\n z += (\n Anm\n * np.cos(c * np.sqrt(lambda_nm) * t)\n * np.sin(n * np.pi * x / a)\n * np.sin(m * np.pi * y / b)\n )\n return z\n\n # Set up the figure and axis for animation\n fig = plt.figure()\n ax = fig.add_subplot(111, projection=\"3d\")\n ax.set_xlim(0, a)\n ax.set_ylim(0, b)\n ax.set_zlim(-1, 1)\n ax.set_xlabel(\"x\")\n ax.set_ylabel(\"y\")\n ax.set_zlabel(\"u(x,y,t)\")\n ax.set_title(\"Rectangular Membrane\")\n\n # Update function for FuncAnimation\n def update(frame):\n ax.clear()\n Z = solution(X, Y, frame) # Compute the new Z values\n ax.plot_surface(X, Y, Z, cmap=\"viridis\", vmin=-1, vmax=1)\n ax.set_xlim(0, a)\n ax.set_ylim(0, b)\n ax.set_zlim(-1, 1)\n ax.set_xlabel(\"x\")\n ax.set_ylabel(\"y\")\n ax.set_zlabel(\"u(x,y,t)\")\n ax.set_title(\"Rectangular Membrane\")\n\n # Create and save the animation\n anim = FuncAnimation(fig, update, frames=t, interval=50)\n anim.save(\"rectangular_membrane_2_animation.gif\", writer=\"imagemagick\", fps=20)\n\n plt.show()\n```\n:::\n\n\nSnapshots:\n\n![t0](./images/rectangular_membrane_2_t0.0.png){width=33%}![t10](./images/rectangular_membrane_2_t2.0.png){width=33%}![t30](./images/rectangular_membrane_2_t4.5.png){width=33%}\n\n# Circular Membrane\n\nPass\n\n$$\n\\left\\{\\begin{align*}\nu_{tt} - \\frac{1}{4} (u_{xx} + u_{yy}) = 0, x^2 + y^2 < 9, t > 0, \\\\ \nu|_{t=0} = (x^2 + y^2) \\sin^3(\\pi \\sqrt{x^2 + y^2}), u_t |_{t=0} = 0, x^2 + y^2 \\leq 9, \\\\\nu|_{x^2 + y^2 = 9} = 0, t \\geq 0.\n\\end{align*}\\right.\n$$\n\nFourier method: Change to polar coordinates\n\n$$\n\\left\\{\\begin{align*}\nx = \\rho \\cos(\\varphi), \\\\\ny = \\rho \\sin(\\varphi)\n\\end{align*}\\right.\n$$\n\n...\n\nThen the function in the first initial condition $u |_{t=0}$ becomes\n\n$$\n\\tau(\\rho) = \\rho^2 \\sin^3(\\pi \\rho)\n$$\n\nwhich is radially symmetric and hence the solution will be also radially symmetric. It is given by\n\n$$\nu(\\rho, t) = \\sum_{m=1}^{\\infty} A_m \\cos{\\frac{a \\mu_m^{(0)}t}{r}} J_0\\left(\\frac{\\mu_m^{(0)}}{r}\\rho\\right),\n$$\n\nwhere\n\n$$\nA_m = \\frac{4}{r^2 J_1^2(\\mu_m^{(0)})} \\int_0^r \\rho^3 \\sin^3(\\pi \\rho) J_0\\left(\\frac{\\mu_m^{(0)}}{r}\\rho\\right) d\\rho,\n$$\n\nand $\\mu_m^{(0)}$ are the positive solutions to $J_0(\\mu) = 0$.\n\n...\n\n![Bessel Functions](./images/BesselJ_800.svg)\n\n...\n\nAnimation:\n\n![Circular Membrane](./images/circular_membrane_animation.gif)\n\n::: {#d8e21121 .cell execution_count=3}\n``` {.python .cell-code code-fold=\"true\" code-summary=\"Click to expand the code\"}\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.animation import FuncAnimation\nfrom scipy.optimize import root_scalar\nfrom scipy.special import jv as besselj\n\n\ndef CircularMembrane(a=0.5, r=3, tmax=30, N=40):\n rho = np.linspace(0, r, 51) # Radial grid points\n phi = np.linspace(0, 2 * np.pi, 51) # Angular grid points\n t = np.linspace(0, tmax, 100) # Time steps\n\n # Find the first 40 positive zeros of the Bessel function J0\n mju = []\n for n in range(1, N + 1):\n zero = root_scalar(\n lambda x: besselj(0, x), bracket=[(n - 1) * np.pi, n * np.pi]\n )\n mju.append(zero.root)\n mju = np.array(mju)\n\n # Define the initial position function\n def tau(rho):\n return rho**2 * np.sin(np.pi * rho) ** 3\n\n # Compute the solution for given R and t\n def solution(R, t):\n y = np.zeros_like(R)\n for m in range(N):\n s = tau(R[0, :]) * R[0, :] * besselj(0, mju[m] * R[0, :] / r)\n A0m = 4 * np.trapezoid(s, R[0, :]) / ((r**2) * (besselj(1, mju[m]) ** 2))\n y += A0m * np.cos(a * mju[m] * t / r) * besselj(0, mju[m] * R / r)\n return y\n\n # Create a grid of points\n R, p = np.meshgrid(rho, phi)\n X = R * np.cos(p)\n Y = R * np.sin(p)\n\n # Set up the figure and axis for animation\n fig = plt.figure()\n ax = fig.add_subplot(111, projection=\"3d\")\n ax.set_xlim(-r, r)\n ax.set_ylim(-r, r)\n ax.set_zlim(-30, 30)\n ax.set_xlabel(\"x\")\n ax.set_ylabel(\"y\")\n ax.set_zlabel(\"u(x,y,t)\")\n ax.set_title(\"Circular Membrane\")\n\n # Update function for animation\n def update(frame):\n ax.clear()\n Z = solution(R, frame)\n ax.plot_surface(X, Y, Z, cmap=\"viridis\", vmin=-30, vmax=30)\n ax.set_xlim(-r, r)\n ax.set_ylim(-r, r)\n ax.set_zlim(-30, 30)\n ax.set_title(\"Circular Membrane\")\n ax.set_xlabel(\"x\")\n ax.set_ylabel(\"y\")\n ax.set_zlabel(\"u(x,y,t)\")\n\n # Create and save the animation\n anim = FuncAnimation(fig, update, frames=t, interval=50)\n anim.save(\"circular_membrane_animation.gif\", writer=\"imagemagick\", fps=20)\n\n plt.show()\n```\n:::\n\n\nSnapshots:\n\n![t0](./images/circular_membrane_t0.png){width=33%}![t10](./images/circular_membrane_t10.png){width=33%}![t30](./images/circular_membrane_t30.png){width=33%}\n\n# References\n\n- [1](https://www.amazon.co.uk/Partial-Differential-Equations-Graduate-Mathematics/dp/1470469421/ref=sr_1_3?crid=2BINQDJ5R7XUB&dib=eyJ2IjoiMSJ9.GgU4uQBUKYO960lL6EjVJjksjFysLhCJKEHP436_saFGnfKf4uvgqyl_3WBjV779K4AwonOY5XnkRxVFCIqqGZCCE3I8YEjIC7mzvLwUa2lBPvByBCoFxTvGhrSKGLiAKlAvTVFSlbwklqyWEj4o852csy80_D3G2Gk9pedHKz22vqyc8UI8HAxWZ1wfu5bNoaqOOEDhy0W2XLaSijLCENnzVXjxTLS5xZkMCXr72G0.NeT6LdhY-WV9xVA26fbGHp37FbAKGo7mLwpV9m_2Rdk&dib_tag=se&keywords=partial+differential+equations&nsdOptOutParam=true&qid=1734133658&sprefix=partial+diff%2Caps%2C129&sr=8-3)\n- [2](https://mathworld.wolfram.com/BesselFunctionoftheFirstKind.html)\n\n",
6
- "supporting": [
7
- "index_files"
8
- ],
9
- "filters": [],
10
- "includes": {}
11
- }
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
src/_freeze/site_libs/clipboard/clipboard.min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- * clipboard.js v2.0.11
3
- * https://clipboardjs.com/
4
- *
5
- * Licensed MIT © Zeno Rocha
6
- */
7
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body},n="";return"string"==typeof t?n=o(t,e):t instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(null==t?void 0:t.type)?n=o(t.value,e):(n=r()(t),c("copy")),n};function l(t){return(l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var s=function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},e=t.action,n=void 0===e?"copy":e,o=t.container,e=t.target,t=t.text;if("copy"!==n&&"cut"!==n)throw new Error('Invalid "action" value, use either "copy" or "cut"');if(void 0!==e){if(!e||"object"!==l(e)||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===n&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===n&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes')}return t?f(t,{container:o}):e?"cut"===n?a(e):f(e,{container:o}):void 0};function p(t){return(p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function d(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function y(t,e){return(y=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function h(n){var o=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}();return function(){var t,e=v(n);return t=o?(t=v(this).constructor,Reflect.construct(e,arguments,t)):e.apply(this,arguments),e=this,!(t=t)||"object"!==p(t)&&"function"!=typeof t?function(t){if(void 0!==t)return t;throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}(e):t}}function v(t){return(v=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function m(t,e){t="data-clipboard-".concat(t);if(e.hasAttribute(t))return e.getAttribute(t)}var b=function(){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&y(t,e)}(r,i());var t,e,n,o=h(r);function r(t,e){var n;return function(t){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}(this),(n=o.call(this)).resolveOptions(e),n.listenClick(t),n}return t=r,n=[{key:"copy",value:function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body};return f(t,e)}},{key:"cut",value:function(t){return a(t)}},{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof t?[t]:t,e=!!document.queryCommandSupported;return t.forEach(function(t){e=e&&!!document.queryCommandSupported(t)}),e}}],(e=[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===p(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=u()(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget,n=this.action(e)||"copy",t=s({action:n,container:this.container,target:this.target(e),text:this.text(e)});this.emit(t?"success":"error",{action:n,text:t,trigger:e,clearSelection:function(){e&&e.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(t){return m("action",t)}},{key:"defaultTarget",value:function(t){t=m("target",t);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(t){return m("text",t)}},{key:"destroy",value:function(){this.listener.destroy()}}])&&d(t.prototype,e),n&&d(t,n),r}()},828:function(t){var e;"undefined"==typeof Element||Element.prototype.matches||((e=Element.prototype).matches=e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector),t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}},438:function(t,e,n){var u=n(828);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=u(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},879:function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},370:function(t,e,n){var f=n(879),l=n(438);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!f.string(e))throw new TypeError("Second argument must be a String");if(!f.fn(n))throw new TypeError("Third argument must be a Function");if(f.node(t))return c=e,a=n,(u=t).addEventListener(c,a),{destroy:function(){u.removeEventListener(c,a)}};if(f.nodeList(t))return o=t,r=e,i=n,Array.prototype.forEach.call(o,function(t){t.addEventListener(r,i)}),{destroy:function(){Array.prototype.forEach.call(o,function(t){t.removeEventListener(r,i)})}};if(f.string(t))return t=t,e=e,n=n,l(document.body,t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,u,c,a}},817:function(t){t.exports=function(t){var e,n="SELECT"===t.nodeName?(t.focus(),t.value):"INPUT"===t.nodeName||"TEXTAREA"===t.nodeName?((e=t.hasAttribute("readonly"))||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),e||t.removeAttribute("readonly"),t.value):(t.hasAttribute("contenteditable")&&t.focus(),n=window.getSelection(),(e=document.createRange()).selectNodeContents(t),n.removeAllRanges(),n.addRange(e),n.toString());return n}},279:function(t){function e(){}e.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,u=o.length;i<u;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=e,t.exports.TinyEmitter=e}},r={},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,{a:e}),e},o.d=function(t,e){for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o(686).default;function o(t){if(r[t])return r[t].exports;var e=r[t]={exports:{}};return n[t](e,e.exports,o),e.exports}var n,r});
 
 
 
 
 
 
 
 
src/_freeze/site_libs/quarto-listing/list.min.js DELETED
@@ -1,2 +0,0 @@
1
- var List;List=function(){var t={"./src/add-async.js":function(t){t.exports=function(t){return function e(r,n,s){var i=r.splice(0,50);s=(s=s||[]).concat(t.add(i)),r.length>0?setTimeout((function(){e(r,n,s)}),1):(t.update(),n(s))}}},"./src/filter.js":function(t){t.exports=function(t){return t.handlers.filterStart=t.handlers.filterStart||[],t.handlers.filterComplete=t.handlers.filterComplete||[],function(e){if(t.trigger("filterStart"),t.i=1,t.reset.filter(),void 0===e)t.filtered=!1;else{t.filtered=!0;for(var r=t.items,n=0,s=r.length;n<s;n++){var i=r[n];e(i)?i.filtered=!0:i.filtered=!1}}return t.update(),t.trigger("filterComplete"),t.visibleItems}}},"./src/fuzzy-search.js":function(t,e,r){r("./src/utils/classes.js");var n=r("./src/utils/events.js"),s=r("./src/utils/extend.js"),i=r("./src/utils/to-string.js"),a=r("./src/utils/get-by-class.js"),o=r("./src/utils/fuzzy.js");t.exports=function(t,e){e=s({location:0,distance:100,threshold:.4,multiSearch:!0,searchClass:"fuzzy-search"},e=e||{});var r={search:function(n,s){for(var i=e.multiSearch?n.replace(/ +$/,"").split(/ +/):[n],a=0,o=t.items.length;a<o;a++)r.item(t.items[a],s,i)},item:function(t,e,n){for(var s=!0,i=0;i<n.length;i++){for(var a=!1,o=0,l=e.length;o<l;o++)r.values(t.values(),e[o],n[i])&&(a=!0);a||(s=!1)}t.found=s},values:function(t,r,n){if(t.hasOwnProperty(r)){var s=i(t[r]).toLowerCase();if(o(s,n,e))return!0}return!1}};return n.bind(a(t.listContainer,e.searchClass),"keyup",t.utils.events.debounce((function(e){var n=e.target||e.srcElement;t.search(n.value,r.search)}),t.searchDelay)),function(e,n){t.search(e,n,r.search)}}},"./src/index.js":function(t,e,r){var n=r("./node_modules/string-natural-compare/natural-compare.js"),s=r("./src/utils/get-by-class.js"),i=r("./src/utils/extend.js"),a=r("./src/utils/index-of.js"),o=r("./src/utils/events.js"),l=r("./src/utils/to-string.js"),u=r("./src/utils/classes.js"),c=r("./src/utils/get-attribute.js"),f=r("./src/utils/to-array.js");t.exports=function(t,e,h){var d,v=this,g=r("./src/item.js")(v),m=r("./src/add-async.js")(v),p=r("./src/pagination.js")(v);d={start:function(){v.listClass="list",v.searchClass="search",v.sortClass="sort",v.page=1e4,v.i=1,v.items=[],v.visibleItems=[],v.matchingItems=[],v.searched=!1,v.filtered=!1,v.searchColumns=void 0,v.searchDelay=0,v.handlers={updated:[]},v.valueNames=[],v.utils={getByClass:s,extend:i,indexOf:a,events:o,toString:l,naturalSort:n,classes:u,getAttribute:c,toArray:f},v.utils.extend(v,e),v.listContainer="string"==typeof t?document.getElementById(t):t,v.listContainer&&(v.list=s(v.listContainer,v.listClass,!0),v.parse=r("./src/parse.js")(v),v.templater=r("./src/templater.js")(v),v.search=r("./src/search.js")(v),v.filter=r("./src/filter.js")(v),v.sort=r("./src/sort.js")(v),v.fuzzySearch=r("./src/fuzzy-search.js")(v,e.fuzzySearch),this.handlers(),this.items(),this.pagination(),v.update())},handlers:function(){for(var t in v.handlers)v[t]&&v.handlers.hasOwnProperty(t)&&v.on(t,v[t])},items:function(){v.parse(v.list),void 0!==h&&v.add(h)},pagination:function(){if(void 0!==e.pagination){!0===e.pagination&&(e.pagination=[{}]),void 0===e.pagination[0]&&(e.pagination=[e.pagination]);for(var t=0,r=e.pagination.length;t<r;t++)p(e.pagination[t])}}},this.reIndex=function(){v.items=[],v.visibleItems=[],v.matchingItems=[],v.searched=!1,v.filtered=!1,v.parse(v.list)},this.toJSON=function(){for(var t=[],e=0,r=v.items.length;e<r;e++)t.push(v.items[e].values());return t},this.add=function(t,e){if(0!==t.length){if(!e){var r=[],n=!1;void 0===t[0]&&(t=[t]);for(var s=0,i=t.length;s<i;s++){var a;n=v.items.length>v.page,a=new g(t[s],void 0,n),v.items.push(a),r.push(a)}return v.update(),r}m(t.slice(0),e)}},this.show=function(t,e){return this.i=t,this.page=e,v.update(),v},this.remove=function(t,e,r){for(var n=0,s=0,i=v.items.length;s<i;s++)v.items[s].values()[t]==e&&(v.templater.remove(v.items[s],r),v.items.splice(s,1),i--,s--,n++);return v.update(),n},this.get=function(t,e){for(var r=[],n=0,s=v.items.length;n<s;n++){var i=v.items[n];i.values()[t]==e&&r.push(i)}return r},this.size=function(){return v.items.length},this.clear=function(){return v.templater.clear(),v.items=[],v},this.on=function(t,e){return v.handlers[t].push(e),v},this.off=function(t,e){var r=v.handlers[t],n=a(r,e);return n>-1&&r.splice(n,1),v},this.trigger=function(t){for(var e=v.handlers[t].length;e--;)v.handlers[t][e](v);return v},this.reset={filter:function(){for(var t=v.items,e=t.length;e--;)t[e].filtered=!1;return v},search:function(){for(var t=v.items,e=t.length;e--;)t[e].found=!1;return v}},this.update=function(){var t=v.items,e=t.length;v.visibleItems=[],v.matchingItems=[],v.templater.clear();for(var r=0;r<e;r++)t[r].matching()&&v.matchingItems.length+1>=v.i&&v.visibleItems.length<v.page?(t[r].show(),v.visibleItems.push(t[r]),v.matchingItems.push(t[r])):t[r].matching()?(v.matchingItems.push(t[r]),t[r].hide()):t[r].hide();return v.trigger("updated"),v},d.start()}},"./src/item.js":function(t){t.exports=function(t){return function(e,r,n){var s=this;this._values={},this.found=!1,this.filtered=!1;this.values=function(e,r){if(void 0===e)return s._values;for(var n in e)s._values[n]=e[n];!0!==r&&t.templater.set(s,s.values())},this.show=function(){t.templater.show(s)},this.hide=function(){t.templater.hide(s)},this.matching=function(){return t.filtered&&t.searched&&s.found&&s.filtered||t.filtered&&!t.searched&&s.filtered||!t.filtered&&t.searched&&s.found||!t.filtered&&!t.searched},this.visible=function(){return!(!s.elm||s.elm.parentNode!=t.list)},function(e,r,n){if(void 0===r)n?s.values(e,n):s.values(e);else{s.elm=r;var i=t.templater.get(s,e);s.values(i)}}(e,r,n)}}},"./src/pagination.js":function(t,e,r){var n=r("./src/utils/classes.js"),s=r("./src/utils/events.js"),i=r("./src/index.js");t.exports=function(t){var e=!1,r=function(r,s){if(t.page<1)return t.listContainer.style.display="none",void(e=!0);e&&(t.listContainer.style.display="block");var i,o=t.matchingItems.length,l=t.i,u=t.page,c=Math.ceil(o/u),f=Math.ceil(l/u),h=s.innerWindow||2,d=s.left||s.outerWindow||0,v=s.right||s.outerWindow||0;v=c-v,r.clear();for(var g=1;g<=c;g++){var m=f===g?"active":"";a.number(g,d,v,f,h)?(i=r.add({page:g,dotted:!1})[0],m&&n(i.elm).add(m),i.elm.firstChild.setAttribute("data-i",g),i.elm.firstChild.setAttribute("data-page",u)):a.dotted(r,g,d,v,f,h,r.size())&&(i=r.add({page:"...",dotted:!0})[0],n(i.elm).add("disabled"))}},a={number:function(t,e,r,n,s){return this.left(t,e)||this.right(t,r)||this.innerWindow(t,n,s)},left:function(t,e){return t<=e},right:function(t,e){return t>e},innerWindow:function(t,e,r){return t>=e-r&&t<=e+r},dotted:function(t,e,r,n,s,i,a){return this.dottedLeft(t,e,r,n,s,i)||this.dottedRight(t,e,r,n,s,i,a)},dottedLeft:function(t,e,r,n,s,i){return e==r+1&&!this.innerWindow(e,s,i)&&!this.right(e,n)},dottedRight:function(t,e,r,n,s,i,a){return!t.items[a-1].values().dotted&&(e==n&&!this.innerWindow(e,s,i)&&!this.right(e,n))}};return function(e){var n=new i(t.listContainer.id,{listClass:e.paginationClass||"pagination",item:e.item||"<li><a class='page' href='#'></a></li>",valueNames:["page","dotted"],searchClass:"pagination-search-that-is-not-supposed-to-exist",sortClass:"pagination-sort-that-is-not-supposed-to-exist"});s.bind(n.listContainer,"click",(function(e){var r=e.target||e.srcElement,n=t.utils.getAttribute(r,"data-page"),s=t.utils.getAttribute(r,"data-i");s&&t.show((s-1)*n+1,n)})),t.on("updated",(function(){r(n,e)})),r(n,e)}}},"./src/parse.js":function(t,e,r){t.exports=function(t){var e=r("./src/item.js")(t),n=function(r,n){for(var s=0,i=r.length;s<i;s++)t.items.push(new e(n,r[s]))},s=function e(r,s){var i=r.splice(0,50);n(i,s),r.length>0?setTimeout((function(){e(r,s)}),1):(t.update(),t.trigger("parseComplete"))};return t.handlers.parseComplete=t.handlers.parseComplete||[],function(){var e=function(t){for(var e=t.childNodes,r=[],n=0,s=e.length;n<s;n++)void 0===e[n].data&&r.push(e[n]);return r}(t.list),r=t.valueNames;t.indexAsync?s(e,r):n(e,r)}}},"./src/search.js":function(t){t.exports=function(t){var e,r,n,s={resetList:function(){t.i=1,t.templater.clear(),n=void 0},setOptions:function(t){2==t.length&&t[1]instanceof Array?e=t[1]:2==t.length&&"function"==typeof t[1]?(e=void 0,n=t[1]):3==t.length?(e=t[1],n=t[2]):e=void 0},setColumns:function(){0!==t.items.length&&void 0===e&&(e=void 0===t.searchColumns?s.toArray(t.items[0].values()):t.searchColumns)},setSearchString:function(e){e=(e=t.utils.toString(e).toLowerCase()),r=e},toArray:function(t){var e=[];for(var r in t)e.push(r);return e}},i=function(){for(var n,s=[],i=r;null!==(n=i.match(/"([^"]+)"/));)s.push(n[1]),i=i.substring(0,n.index)+i.substring(n.index+n[0].length);(i=i.trim()).length&&(s=s.concat(i.split(/\s+/)));for(var a=0,o=t.items.length;a<o;a++){var l=t.items[a];if(l.found=!1,s.length){for(var u=0,c=s.length;u<c;u++){for(var f=!1,h=0,d=e.length;h<d;h++){var v=l.values(),g=e[h];if(v.hasOwnProperty(g)&&void 0!==v[g]&&null!==v[g])if(-1!==("string"!=typeof v[g]?v[g].toString():v[g]).toLowerCase().indexOf(s[u])){f=!0;break}}if(!f)break}l.found=f}}},a=function(){t.reset.search(),t.searched=!1},o=function(o){return t.trigger("searchStart"),s.resetList(),s.setSearchString(o),s.setOptions(arguments),s.setColumns(),""===r?a():(t.searched=!0,n?n(r,e):i()),t.update(),t.trigger("searchComplete"),t.visibleItems};return t.handlers.searchStart=t.handlers.searchStart||[],t.handlers.searchComplete=t.handlers.searchComplete||[],t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"keyup",t.utils.events.debounce((function(e){var r=e.target||e.srcElement;""===r.value&&!t.searched||o(r.value)}),t.searchDelay)),t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"input",(function(t){""===(t.target||t.srcElement).value&&o("")})),o}},"./src/sort.js":function(t){t.exports=function(t){var e={els:void 0,clear:function(){for(var r=0,n=e.els.length;r<n;r++)t.utils.classes(e.els[r]).remove("asc"),t.utils.classes(e.els[r]).remove("desc")},getOrder:function(e){var r=t.utils.getAttribute(e,"data-order");return"asc"==r||"desc"==r?r:t.utils.classes(e).has("desc")?"asc":t.utils.classes(e).has("asc")?"desc":"asc"},getInSensitive:function(e,r){var n=t.utils.getAttribute(e,"data-insensitive");r.insensitive="false"!==n},setOrder:function(r){for(var n=0,s=e.els.length;n<s;n++){var i=e.els[n];if(t.utils.getAttribute(i,"data-sort")===r.valueName){var a=t.utils.getAttribute(i,"data-order");"asc"==a||"desc"==a?a==r.order&&t.utils.classes(i).add(r.order):t.utils.classes(i).add(r.order)}}}},r=function(){t.trigger("sortStart");var r={},n=arguments[0].currentTarget||arguments[0].srcElement||void 0;n?(r.valueName=t.utils.getAttribute(n,"data-sort"),e.getInSensitive(n,r),r.order=e.getOrder(n)):((r=arguments[1]||r).valueName=arguments[0],r.order=r.order||"asc",r.insensitive=void 0===r.insensitive||r.insensitive),e.clear(),e.setOrder(r);var s,i=r.sortFunction||t.sortFunction||null,a="desc"===r.order?-1:1;s=i?function(t,e){return i(t,e,r)*a}:function(e,n){var s=t.utils.naturalSort;return s.alphabet=t.alphabet||r.alphabet||void 0,!s.alphabet&&r.insensitive&&(s=t.utils.naturalSort.caseInsensitive),s(e.values()[r.valueName],n.values()[r.valueName])*a},t.items.sort(s),t.update(),t.trigger("sortComplete")};return t.handlers.sortStart=t.handlers.sortStart||[],t.handlers.sortComplete=t.handlers.sortComplete||[],e.els=t.utils.getByClass(t.listContainer,t.sortClass),t.utils.events.bind(e.els,"click",r),t.on("searchStart",e.clear),t.on("filterStart",e.clear),r}},"./src/templater.js":function(t){var e=function(t){var e,r=this,n=function(e,r){var n=e.cloneNode(!0);n.removeAttribute("id");for(var s=0,i=r.length;s<i;s++){var a=void 0,o=r[s];if(o.data)for(var l=0,u=o.data.length;l<u;l++)n.setAttribute("data-"+o.data[l],"");else o.attr&&o.name?(a=t.utils.getByClass(n,o.name,!0))&&a.setAttribute(o.attr,""):(a=t.utils.getByClass(n,o,!0))&&(a.innerHTML="")}return n},s=function(){for(var e=t.list.childNodes,r=0,n=e.length;r<n;r++)if(void 0===e[r].data)return e[r].cloneNode(!0)},i=function(t){if("string"==typeof t){if(/<tr[\s>]/g.exec(t)){var e=document.createElement("tbody");return e.innerHTML=t,e.firstElementChild}if(-1!==t.indexOf("<")){var r=document.createElement("div");return r.innerHTML=t,r.firstElementChild}}},a=function(e,r,n){var s=void 0,i=function(e){for(var r=0,n=t.valueNames.length;r<n;r++){var s=t.valueNames[r];if(s.data){for(var i=s.data,a=0,o=i.length;a<o;a++)if(i[a]===e)return{data:e}}else{if(s.attr&&s.name&&s.name==e)return s;if(s===e)return e}}}(r);i&&(i.data?e.elm.setAttribute("data-"+i.data,n):i.attr&&i.name?(s=t.utils.getByClass(e.elm,i.name,!0))&&s.setAttribute(i.attr,n):(s=t.utils.getByClass(e.elm,i,!0))&&(s.innerHTML=n))};this.get=function(e,n){r.create(e);for(var s={},i=0,a=n.length;i<a;i++){var o=void 0,l=n[i];if(l.data)for(var u=0,c=l.data.length;u<c;u++)s[l.data[u]]=t.utils.getAttribute(e.elm,"data-"+l.data[u]);else l.attr&&l.name?(o=t.utils.getByClass(e.elm,l.name,!0),s[l.name]=o?t.utils.getAttribute(o,l.attr):""):(o=t.utils.getByClass(e.elm,l,!0),s[l]=o?o.innerHTML:"")}return s},this.set=function(t,e){if(!r.create(t))for(var n in e)e.hasOwnProperty(n)&&a(t,n,e[n])},this.create=function(t){return void 0===t.elm&&(t.elm=e(t.values()),r.set(t,t.values()),!0)},this.remove=function(e){e.elm.parentNode===t.list&&t.list.removeChild(e.elm)},this.show=function(e){r.create(e),t.list.appendChild(e.elm)},this.hide=function(e){void 0!==e.elm&&e.elm.parentNode===t.list&&t.list.removeChild(e.elm)},this.clear=function(){if(t.list.hasChildNodes())for(;t.list.childNodes.length>=1;)t.list.removeChild(t.list.firstChild)},function(){var r;if("function"!=typeof t.item){if(!(r="string"==typeof t.item?-1===t.item.indexOf("<")?document.getElementById(t.item):i(t.item):s()))throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template.");r=n(r,t.valueNames),e=function(){return r.cloneNode(!0)}}else e=function(e){var r=t.item(e);return i(r)}}()};t.exports=function(t){return new e(t)}},"./src/utils/classes.js":function(t,e,r){var n=r("./src/utils/index-of.js"),s=/\s+/;Object.prototype.toString;function i(t){if(!t||!t.nodeType)throw new Error("A DOM element reference is required");this.el=t,this.list=t.classList}t.exports=function(t){return new i(t)},i.prototype.add=function(t){if(this.list)return this.list.add(t),this;var e=this.array();return~n(e,t)||e.push(t),this.el.className=e.join(" "),this},i.prototype.remove=function(t){if(this.list)return this.list.remove(t),this;var e=this.array(),r=n(e,t);return~r&&e.splice(r,1),this.el.className=e.join(" "),this},i.prototype.toggle=function(t,e){return this.list?(void 0!==e?e!==this.list.toggle(t,e)&&this.list.toggle(t):this.list.toggle(t),this):(void 0!==e?e?this.add(t):this.remove(t):this.has(t)?this.remove(t):this.add(t),this)},i.prototype.array=function(){var t=(this.el.getAttribute("class")||"").replace(/^\s+|\s+$/g,"").split(s);return""===t[0]&&t.shift(),t},i.prototype.has=i.prototype.contains=function(t){return this.list?this.list.contains(t):!!~n(this.array(),t)}},"./src/utils/events.js":function(t,e,r){var n=window.addEventListener?"addEventListener":"attachEvent",s=window.removeEventListener?"removeEventListener":"detachEvent",i="addEventListener"!==n?"on":"",a=r("./src/utils/to-array.js");e.bind=function(t,e,r,s){for(var o=0,l=(t=a(t)).length;o<l;o++)t[o][n](i+e,r,s||!1)},e.unbind=function(t,e,r,n){for(var o=0,l=(t=a(t)).length;o<l;o++)t[o][s](i+e,r,n||!1)},e.debounce=function(t,e,r){var n;return e?function(){var s=this,i=arguments,a=function(){n=null,r||t.apply(s,i)},o=r&&!n;clearTimeout(n),n=setTimeout(a,e),o&&t.apply(s,i)}:t}},"./src/utils/extend.js":function(t){t.exports=function(t){for(var e,r=Array.prototype.slice.call(arguments,1),n=0;e=r[n];n++)if(e)for(var s in e)t[s]=e[s];return t}},"./src/utils/fuzzy.js":function(t){t.exports=function(t,e,r){var n=r.location||0,s=r.distance||100,i=r.threshold||.4;if(e===t)return!0;if(e.length>32)return!1;var a=n,o=function(){var t,r={};for(t=0;t<e.length;t++)r[e.charAt(t)]=0;for(t=0;t<e.length;t++)r[e.charAt(t)]|=1<<e.length-t-1;return r}();function l(t,r){var n=t/e.length,i=Math.abs(a-r);return s?n+i/s:i?1:n}var u=i,c=t.indexOf(e,a);-1!=c&&(u=Math.min(l(0,c),u),-1!=(c=t.lastIndexOf(e,a+e.length))&&(u=Math.min(l(0,c),u)));var f,h,d=1<<e.length-1;c=-1;for(var v,g=e.length+t.length,m=0;m<e.length;m++){for(f=0,h=g;f<h;)l(m,a+h)<=u?f=h:g=h,h=Math.floor((g-f)/2+f);g=h;var p=Math.max(1,a-h+1),y=Math.min(a+h,t.length)+e.length,C=Array(y+2);C[y+1]=(1<<m)-1;for(var b=y;b>=p;b--){var j=o[t.charAt(b-1)];if(C[b]=0===m?(C[b+1]<<1|1)&j:(C[b+1]<<1|1)&j|(v[b+1]|v[b])<<1|1|v[b+1],C[b]&d){var x=l(m,b-1);if(x<=u){if(u=x,!((c=b-1)>a))break;p=Math.max(1,2*a-c)}}}if(l(m+1,a)>u)break;v=C}return!(c<0)}},"./src/utils/get-attribute.js":function(t){t.exports=function(t,e){var r=t.getAttribute&&t.getAttribute(e)||null;if(!r)for(var n=t.attributes,s=n.length,i=0;i<s;i++)void 0!==n[i]&&n[i].nodeName===e&&(r=n[i].nodeValue);return r}},"./src/utils/get-by-class.js":function(t){t.exports=function(t,e,r,n){return(n=n||{}).test&&n.getElementsByClassName||!n.test&&document.getElementsByClassName?function(t,e,r){return r?t.getElementsByClassName(e)[0]:t.getElementsByClassName(e)}(t,e,r):n.test&&n.querySelector||!n.test&&document.querySelector?function(t,e,r){return e="."+e,r?t.querySelector(e):t.querySelectorAll(e)}(t,e,r):function(t,e,r){for(var n=[],s=t.getElementsByTagName("*"),i=s.length,a=new RegExp("(^|\\s)"+e+"(\\s|$)"),o=0,l=0;o<i;o++)if(a.test(s[o].className)){if(r)return s[o];n[l]=s[o],l++}return n}(t,e,r)}},"./src/utils/index-of.js":function(t){var e=[].indexOf;t.exports=function(t,r){if(e)return t.indexOf(r);for(var n=0,s=t.length;n<s;++n)if(t[n]===r)return n;return-1}},"./src/utils/to-array.js":function(t){t.exports=function(t){if(void 0===t)return[];if(null===t)return[null];if(t===window)return[window];if("string"==typeof t)return[t];if(function(t){return"[object Array]"===Object.prototype.toString.call(t)}(t))return t;if("number"!=typeof t.length)return[t];if("function"==typeof t&&t instanceof Function)return[t];for(var e=[],r=0,n=t.length;r<n;r++)(Object.prototype.hasOwnProperty.call(t,r)||r in t)&&e.push(t[r]);return e.length?e:[]}},"./src/utils/to-string.js":function(t){t.exports=function(t){return t=(t=null===(t=void 0===t?"":t)?"":t).toString()}},"./node_modules/string-natural-compare/natural-compare.js":function(t){"use strict";var e,r,n=0;function s(t){return t>=48&&t<=57}function i(t,e){for(var i=(t+="").length,a=(e+="").length,o=0,l=0;o<i&&l<a;){var u=t.charCodeAt(o),c=e.charCodeAt(l);if(s(u)){if(!s(c))return u-c;for(var f=o,h=l;48===u&&++f<i;)u=t.charCodeAt(f);for(;48===c&&++h<a;)c=e.charCodeAt(h);for(var d=f,v=h;d<i&&s(t.charCodeAt(d));)++d;for(;v<a&&s(e.charCodeAt(v));)++v;var g=d-f-v+h;if(g)return g;for(;f<d;)if(g=t.charCodeAt(f++)-e.charCodeAt(h++))return g;o=d,l=v}else{if(u!==c)return u<n&&c<n&&-1!==r[u]&&-1!==r[c]?r[u]-r[c]:u-c;++o,++l}}return o>=i&&l<a&&i>=a?-1:l>=a&&o<i&&a>=i?1:i-a}i.caseInsensitive=i.i=function(t,e){return i((""+t).toLowerCase(),(""+e).toLowerCase())},Object.defineProperties(i,{alphabet:{get:function(){return e},set:function(t){r=[];var s=0;if(e=t)for(;s<e.length;s++)r[e.charCodeAt(s)]=s;for(n=r.length,s=0;s<n;s++)void 0===r[s]&&(r[s]=-1)}}}),t.exports=i}},e={};return function r(n){if(e[n])return e[n].exports;var s=e[n]={exports:{}};return t[n](s,s.exports,r),s.exports}("./src/index.js")}();
2
- //# sourceMappingURL=list.min.js.map
 
 
 
src/_freeze/site_libs/quarto-listing/quarto-listing.js DELETED
@@ -1,253 +0,0 @@
1
- const kProgressiveAttr = "data-src";
2
- let categoriesLoaded = false;
3
-
4
- window.quartoListingCategory = (category) => {
5
- category = atob(category);
6
- if (categoriesLoaded) {
7
- activateCategory(category);
8
- setCategoryHash(category);
9
- }
10
- };
11
-
12
- window["quarto-listing-loaded"] = () => {
13
- // Process any existing hash
14
- const hash = getHash();
15
-
16
- if (hash) {
17
- // If there is a category, switch to that
18
- if (hash.category) {
19
- // category hash are URI encoded so we need to decode it before processing
20
- // so that we can match it with the category element processed in JS
21
- activateCategory(decodeURIComponent(hash.category));
22
- }
23
- // Paginate a specific listing
24
- const listingIds = Object.keys(window["quarto-listings"]);
25
- for (const listingId of listingIds) {
26
- const page = hash[getListingPageKey(listingId)];
27
- if (page) {
28
- showPage(listingId, page);
29
- }
30
- }
31
- }
32
-
33
- const listingIds = Object.keys(window["quarto-listings"]);
34
- for (const listingId of listingIds) {
35
- // The actual list
36
- const list = window["quarto-listings"][listingId];
37
-
38
- // Update the handlers for pagination events
39
- refreshPaginationHandlers(listingId);
40
-
41
- // Render any visible items that need it
42
- renderVisibleProgressiveImages(list);
43
-
44
- // Whenever the list is updated, we also need to
45
- // attach handlers to the new pagination elements
46
- // and refresh any newly visible items.
47
- list.on("updated", function () {
48
- renderVisibleProgressiveImages(list);
49
- setTimeout(() => refreshPaginationHandlers(listingId));
50
-
51
- // Show or hide the no matching message
52
- toggleNoMatchingMessage(list);
53
- });
54
- }
55
- };
56
-
57
- window.document.addEventListener("DOMContentLoaded", function (_event) {
58
- // Attach click handlers to categories
59
- const categoryEls = window.document.querySelectorAll(
60
- ".quarto-listing-category .category"
61
- );
62
-
63
- for (const categoryEl of categoryEls) {
64
- // category needs to support non ASCII characters
65
- const category = decodeURIComponent(
66
- atob(categoryEl.getAttribute("data-category"))
67
- );
68
- categoryEl.onclick = () => {
69
- activateCategory(category);
70
- setCategoryHash(category);
71
- };
72
- }
73
-
74
- // Attach a click handler to the category title
75
- // (there should be only one, but since it is a class name, handle N)
76
- const categoryTitleEls = window.document.querySelectorAll(
77
- ".quarto-listing-category-title"
78
- );
79
- for (const categoryTitleEl of categoryTitleEls) {
80
- categoryTitleEl.onclick = () => {
81
- activateCategory("");
82
- setCategoryHash("");
83
- };
84
- }
85
-
86
- categoriesLoaded = true;
87
- });
88
-
89
- function toggleNoMatchingMessage(list) {
90
- const selector = `#${list.listContainer.id} .listing-no-matching`;
91
- const noMatchingEl = window.document.querySelector(selector);
92
- if (noMatchingEl) {
93
- if (list.visibleItems.length === 0) {
94
- noMatchingEl.classList.remove("d-none");
95
- } else {
96
- if (!noMatchingEl.classList.contains("d-none")) {
97
- noMatchingEl.classList.add("d-none");
98
- }
99
- }
100
- }
101
- }
102
-
103
- function setCategoryHash(category) {
104
- setHash({ category });
105
- }
106
-
107
- function setPageHash(listingId, page) {
108
- const currentHash = getHash() || {};
109
- currentHash[getListingPageKey(listingId)] = page;
110
- setHash(currentHash);
111
- }
112
-
113
- function getListingPageKey(listingId) {
114
- return `${listingId}-page`;
115
- }
116
-
117
- function refreshPaginationHandlers(listingId) {
118
- const listingEl = window.document.getElementById(listingId);
119
- const paginationEls = listingEl.querySelectorAll(
120
- ".pagination li.page-item:not(.disabled) .page.page-link"
121
- );
122
- for (const paginationEl of paginationEls) {
123
- paginationEl.onclick = (sender) => {
124
- setPageHash(listingId, sender.target.getAttribute("data-i"));
125
- showPage(listingId, sender.target.getAttribute("data-i"));
126
- return false;
127
- };
128
- }
129
- }
130
-
131
- function renderVisibleProgressiveImages(list) {
132
- // Run through the visible items and render any progressive images
133
- for (const item of list.visibleItems) {
134
- const itemEl = item.elm;
135
- if (itemEl) {
136
- const progressiveImgs = itemEl.querySelectorAll(
137
- `img[${kProgressiveAttr}]`
138
- );
139
- for (const progressiveImg of progressiveImgs) {
140
- const srcValue = progressiveImg.getAttribute(kProgressiveAttr);
141
- if (srcValue) {
142
- progressiveImg.setAttribute("src", srcValue);
143
- }
144
- progressiveImg.removeAttribute(kProgressiveAttr);
145
- }
146
- }
147
- }
148
- }
149
-
150
- function getHash() {
151
- // Hashes are of the form
152
- // #name:value|name1:value1|name2:value2
153
- const currentUrl = new URL(window.location);
154
- const hashRaw = currentUrl.hash ? currentUrl.hash.slice(1) : undefined;
155
- return parseHash(hashRaw);
156
- }
157
-
158
- const kAnd = "&";
159
- const kEquals = "=";
160
-
161
- function parseHash(hash) {
162
- if (!hash) {
163
- return undefined;
164
- }
165
- const hasValuesStrs = hash.split(kAnd);
166
- const hashValues = hasValuesStrs
167
- .map((hashValueStr) => {
168
- const vals = hashValueStr.split(kEquals);
169
- if (vals.length === 2) {
170
- return { name: vals[0], value: vals[1] };
171
- } else {
172
- return undefined;
173
- }
174
- })
175
- .filter((value) => {
176
- return value !== undefined;
177
- });
178
-
179
- const hashObj = {};
180
- hashValues.forEach((hashValue) => {
181
- hashObj[hashValue.name] = decodeURIComponent(hashValue.value);
182
- });
183
- return hashObj;
184
- }
185
-
186
- function makeHash(obj) {
187
- return Object.keys(obj)
188
- .map((key) => {
189
- return `${key}${kEquals}${obj[key]}`;
190
- })
191
- .join(kAnd);
192
- }
193
-
194
- function setHash(obj) {
195
- const hash = makeHash(obj);
196
- window.history.pushState(null, null, `#${hash}`);
197
- }
198
-
199
- function showPage(listingId, page) {
200
- const list = window["quarto-listings"][listingId];
201
- if (list) {
202
- list.show((page - 1) * list.page + 1, list.page);
203
- }
204
- }
205
-
206
- function activateCategory(category) {
207
- // Deactivate existing categories
208
- const activeEls = window.document.querySelectorAll(
209
- ".quarto-listing-category .category.active"
210
- );
211
- for (const activeEl of activeEls) {
212
- activeEl.classList.remove("active");
213
- }
214
-
215
- // Activate this category
216
- const categoryEl = window.document.querySelector(
217
- `.quarto-listing-category .category[data-category='${btoa(
218
- encodeURIComponent(category)
219
- )}']`
220
- );
221
- if (categoryEl) {
222
- categoryEl.classList.add("active");
223
- }
224
-
225
- // Filter the listings to this category
226
- filterListingCategory(category);
227
- }
228
-
229
- function filterListingCategory(category) {
230
- const listingIds = Object.keys(window["quarto-listings"]);
231
- for (const listingId of listingIds) {
232
- const list = window["quarto-listings"][listingId];
233
- if (list) {
234
- if (category === "") {
235
- // resets the filter
236
- list.filter();
237
- } else {
238
- // filter to this category
239
- list.filter(function (item) {
240
- const itemValues = item.values();
241
- if (itemValues.categories !== null) {
242
- const categories = decodeURIComponent(
243
- atob(itemValues.categories)
244
- ).split(",");
245
- return categories.includes(category);
246
- } else {
247
- return false;
248
- }
249
- });
250
- }
251
- }
252
- }
253
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/_site/about.html DELETED
@@ -1,559 +0,0 @@
1
- <!DOCTYPE html>
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
-
4
- <meta charset="utf-8">
5
- <meta name="generator" content="quarto-1.6.39">
6
-
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
-
9
-
10
- <title>About – quarto-blog</title>
11
- <style>
12
- code{white-space: pre-wrap;}
13
- span.smallcaps{font-variant: small-caps;}
14
- div.columns{display: flex; gap: min(4vw, 1.5em);}
15
- div.column{flex: auto; overflow-x: auto;}
16
- div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
17
- ul.task-list{list-style: none;}
18
- ul.task-list li input[type="checkbox"] {
19
- width: 0.8em;
20
- margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
21
- vertical-align: middle;
22
- }
23
- </style>
24
-
25
-
26
- <script src="site_libs/quarto-nav/quarto-nav.js"></script>
27
- <script src="site_libs/quarto-nav/headroom.min.js"></script>
28
- <script src="site_libs/clipboard/clipboard.min.js"></script>
29
- <script src="site_libs/quarto-search/autocomplete.umd.js"></script>
30
- <script src="site_libs/quarto-search/fuse.min.js"></script>
31
- <script src="site_libs/quarto-search/quarto-search.js"></script>
32
- <meta name="quarto:offset" content="./">
33
- <script src="site_libs/quarto-html/quarto.js"></script>
34
- <script src="site_libs/quarto-html/popper.min.js"></script>
35
- <script src="site_libs/quarto-html/tippy.umd.min.js"></script>
36
- <link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
37
- <link href="site_libs/quarto-html/quarto-syntax-highlighting-e26003cea8cd680ca0c55a263523d882.css" rel="stylesheet" id="quarto-text-highlighting-styles">
38
- <script src="site_libs/bootstrap/bootstrap.min.js"></script>
39
- <link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
40
- <link href="site_libs/bootstrap/bootstrap-d1b12f2568ecbe55642fee6aa00bd082.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
41
- <script id="quarto-search-options" type="application/json">{
42
- "location": "navbar",
43
- "copy-button": false,
44
- "collapse-after": 3,
45
- "panel-placement": "end",
46
- "type": "overlay",
47
- "limit": 50,
48
- "keyboard-shortcut": [
49
- "f",
50
- "/",
51
- "s"
52
- ],
53
- "show-item-context": false,
54
- "language": {
55
- "search-no-results-text": "No results",
56
- "search-matching-documents-text": "matching documents",
57
- "search-copy-link-title": "Copy link to search",
58
- "search-hide-matches-text": "Hide additional matches",
59
- "search-more-match-text": "more match in this document",
60
- "search-more-matches-text": "more matches in this document",
61
- "search-clear-button-title": "Clear",
62
- "search-text-placeholder": "",
63
- "search-detached-cancel-button-title": "Cancel",
64
- "search-submit-button-title": "Submit",
65
- "search-label": "Search"
66
- }
67
- }</script>
68
-
69
-
70
- <link rel="stylesheet" href="styles.css">
71
- </head>
72
-
73
- <body class="nav-fixed fullcontent">
74
-
75
- <div id="quarto-search-results"></div>
76
- <header id="quarto-header" class="headroom fixed-top">
77
- <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
78
- <div class="navbar-container container-fluid">
79
- <div class="navbar-brand-container mx-auto">
80
- <a class="navbar-brand" href="./index.html">
81
- <span class="navbar-title">quarto-blog</span>
82
- </a>
83
- </div>
84
- <div id="quarto-search" class="" title="Search"></div>
85
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
86
- <span class="navbar-toggler-icon"></span>
87
- </button>
88
- <div class="collapse navbar-collapse" id="navbarCollapse">
89
- <ul class="navbar-nav navbar-nav-scroll ms-auto">
90
- <li class="nav-item">
91
- <a class="nav-link active" href="./about.html" aria-current="page">
92
- <span class="menu-text">About</span></a>
93
- </li>
94
- <li class="nav-item compact">
95
- <a class="nav-link" href="https://github.com/"> <i class="bi bi-github" role="img">
96
- </i>
97
- <span class="menu-text"></span></a>
98
- </li>
99
- <li class="nav-item compact">
100
- <a class="nav-link" href="https://twitter.com"> <i class="bi bi-twitter" role="img">
101
- </i>
102
- <span class="menu-text"></span></a>
103
- </li>
104
- </ul>
105
- </div> <!-- /navcollapse -->
106
- <div class="quarto-navbar-tools">
107
- </div>
108
- </div> <!-- /container-fluid -->
109
- </nav>
110
- </header>
111
- <!-- content -->
112
- <div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
113
- <!-- sidebar -->
114
- <!-- margin-sidebar -->
115
-
116
- <!-- main -->
117
- <div class="quarto-about-jolla">
118
- <img src="profile.jpg" class="about-image
119
- round " style="height: 15em; width: 15em;">
120
- <header id="title-block-header" class="quarto-title-block default">
121
- <div class="quarto-title">
122
- <h1 class="title">About</h1>
123
- </div>
124
- <div class="quarto-title-meta">
125
- </div>
126
- </header><main class="content" id="quarto-document-content">
127
- <p>About this blog</p>
128
-
129
-
130
- </main>
131
- <hr class="about-sep">
132
- <div class="about-links">
133
- <a href="https://www.linkedin.com/in/joana-levtcheva-479844164/" class="about-link" rel="" target="">
134
- <i class="bi bi-linkedin"></i>
135
- <span class="about-link-text">LinkedIn</span>
136
- </a>
137
- <a href="https://github.com/JoeJoe1313" class="about-link" rel="" target="">
138
- <i class="bi bi-github"></i>
139
- <span class="about-link-text">Github</span>
140
- </a>
141
- </div>
142
- </div>
143
- <!-- /main -->
144
- <script id="quarto-html-after-body" type="application/javascript">
145
- window.document.addEventListener("DOMContentLoaded", function (event) {
146
- const toggleBodyColorMode = (bsSheetEl) => {
147
- const mode = bsSheetEl.getAttribute("data-mode");
148
- const bodyEl = window.document.querySelector("body");
149
- if (mode === "dark") {
150
- bodyEl.classList.add("quarto-dark");
151
- bodyEl.classList.remove("quarto-light");
152
- } else {
153
- bodyEl.classList.add("quarto-light");
154
- bodyEl.classList.remove("quarto-dark");
155
- }
156
- }
157
- const toggleBodyColorPrimary = () => {
158
- const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
159
- if (bsSheetEl) {
160
- toggleBodyColorMode(bsSheetEl);
161
- }
162
- }
163
- toggleBodyColorPrimary();
164
- const isCodeAnnotation = (el) => {
165
- for (const clz of el.classList) {
166
- if (clz.startsWith('code-annotation-')) {
167
- return true;
168
- }
169
- }
170
- return false;
171
- }
172
- const onCopySuccess = function(e) {
173
- // button target
174
- const button = e.trigger;
175
- // don't keep focus
176
- button.blur();
177
- // flash "checked"
178
- button.classList.add('code-copy-button-checked');
179
- var currentTitle = button.getAttribute("title");
180
- button.setAttribute("title", "Copied!");
181
- let tooltip;
182
- if (window.bootstrap) {
183
- button.setAttribute("data-bs-toggle", "tooltip");
184
- button.setAttribute("data-bs-placement", "left");
185
- button.setAttribute("data-bs-title", "Copied!");
186
- tooltip = new bootstrap.Tooltip(button,
187
- { trigger: "manual",
188
- customClass: "code-copy-button-tooltip",
189
- offset: [0, -8]});
190
- tooltip.show();
191
- }
192
- setTimeout(function() {
193
- if (tooltip) {
194
- tooltip.hide();
195
- button.removeAttribute("data-bs-title");
196
- button.removeAttribute("data-bs-toggle");
197
- button.removeAttribute("data-bs-placement");
198
- }
199
- button.setAttribute("title", currentTitle);
200
- button.classList.remove('code-copy-button-checked');
201
- }, 1000);
202
- // clear code selection
203
- e.clearSelection();
204
- }
205
- const getTextToCopy = function(trigger) {
206
- const codeEl = trigger.previousElementSibling.cloneNode(true);
207
- for (const childEl of codeEl.children) {
208
- if (isCodeAnnotation(childEl)) {
209
- childEl.remove();
210
- }
211
- }
212
- return codeEl.innerText;
213
- }
214
- const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
215
- text: getTextToCopy
216
- });
217
- clipboard.on('success', onCopySuccess);
218
- if (window.document.getElementById('quarto-embedded-source-code-modal')) {
219
- const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
220
- text: getTextToCopy,
221
- container: window.document.getElementById('quarto-embedded-source-code-modal')
222
- });
223
- clipboardModal.on('success', onCopySuccess);
224
- }
225
- var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
226
- var mailtoRegex = new RegExp(/^mailto:/);
227
- var filterRegex = new RegExp('/' + window.location.host + '/');
228
- var isInternal = (href) => {
229
- return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
230
- }
231
- // Inspect non-navigation links and adorn them if external
232
- var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
233
- for (var i=0; i<links.length; i++) {
234
- const link = links[i];
235
- if (!isInternal(link.href)) {
236
- // undo the damage that might have been done by quarto-nav.js in the case of
237
- // links that we want to consider external
238
- if (link.dataset.originalHref !== undefined) {
239
- link.href = link.dataset.originalHref;
240
- }
241
- }
242
- }
243
- function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
244
- const config = {
245
- allowHTML: true,
246
- maxWidth: 500,
247
- delay: 100,
248
- arrow: false,
249
- appendTo: function(el) {
250
- return el.parentElement;
251
- },
252
- interactive: true,
253
- interactiveBorder: 10,
254
- theme: 'quarto',
255
- placement: 'bottom-start',
256
- };
257
- if (contentFn) {
258
- config.content = contentFn;
259
- }
260
- if (onTriggerFn) {
261
- config.onTrigger = onTriggerFn;
262
- }
263
- if (onUntriggerFn) {
264
- config.onUntrigger = onUntriggerFn;
265
- }
266
- window.tippy(el, config);
267
- }
268
- const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
269
- for (var i=0; i<noterefs.length; i++) {
270
- const ref = noterefs[i];
271
- tippyHover(ref, function() {
272
- // use id or data attribute instead here
273
- let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
274
- try { href = new URL(href).hash; } catch {}
275
- const id = href.replace(/^#\/?/, "");
276
- const note = window.document.getElementById(id);
277
- if (note) {
278
- return note.innerHTML;
279
- } else {
280
- return "";
281
- }
282
- });
283
- }
284
- const xrefs = window.document.querySelectorAll('a.quarto-xref');
285
- const processXRef = (id, note) => {
286
- // Strip column container classes
287
- const stripColumnClz = (el) => {
288
- el.classList.remove("page-full", "page-columns");
289
- if (el.children) {
290
- for (const child of el.children) {
291
- stripColumnClz(child);
292
- }
293
- }
294
- }
295
- stripColumnClz(note)
296
- if (id === null || id.startsWith('sec-')) {
297
- // Special case sections, only their first couple elements
298
- const container = document.createElement("div");
299
- if (note.children && note.children.length > 2) {
300
- container.appendChild(note.children[0].cloneNode(true));
301
- for (let i = 1; i < note.children.length; i++) {
302
- const child = note.children[i];
303
- if (child.tagName === "P" && child.innerText === "") {
304
- continue;
305
- } else {
306
- container.appendChild(child.cloneNode(true));
307
- break;
308
- }
309
- }
310
- if (window.Quarto?.typesetMath) {
311
- window.Quarto.typesetMath(container);
312
- }
313
- return container.innerHTML
314
- } else {
315
- if (window.Quarto?.typesetMath) {
316
- window.Quarto.typesetMath(note);
317
- }
318
- return note.innerHTML;
319
- }
320
- } else {
321
- // Remove any anchor links if they are present
322
- const anchorLink = note.querySelector('a.anchorjs-link');
323
- if (anchorLink) {
324
- anchorLink.remove();
325
- }
326
- if (window.Quarto?.typesetMath) {
327
- window.Quarto.typesetMath(note);
328
- }
329
- if (note.classList.contains("callout")) {
330
- return note.outerHTML;
331
- } else {
332
- return note.innerHTML;
333
- }
334
- }
335
- }
336
- for (var i=0; i<xrefs.length; i++) {
337
- const xref = xrefs[i];
338
- tippyHover(xref, undefined, function(instance) {
339
- instance.disable();
340
- let url = xref.getAttribute('href');
341
- let hash = undefined;
342
- if (url.startsWith('#')) {
343
- hash = url;
344
- } else {
345
- try { hash = new URL(url).hash; } catch {}
346
- }
347
- if (hash) {
348
- const id = hash.replace(/^#\/?/, "");
349
- const note = window.document.getElementById(id);
350
- if (note !== null) {
351
- try {
352
- const html = processXRef(id, note.cloneNode(true));
353
- instance.setContent(html);
354
- } finally {
355
- instance.enable();
356
- instance.show();
357
- }
358
- } else {
359
- // See if we can fetch this
360
- fetch(url.split('#')[0])
361
- .then(res => res.text())
362
- .then(html => {
363
- const parser = new DOMParser();
364
- const htmlDoc = parser.parseFromString(html, "text/html");
365
- const note = htmlDoc.getElementById(id);
366
- if (note !== null) {
367
- const html = processXRef(id, note);
368
- instance.setContent(html);
369
- }
370
- }).finally(() => {
371
- instance.enable();
372
- instance.show();
373
- });
374
- }
375
- } else {
376
- // See if we can fetch a full url (with no hash to target)
377
- // This is a special case and we should probably do some content thinning / targeting
378
- fetch(url)
379
- .then(res => res.text())
380
- .then(html => {
381
- const parser = new DOMParser();
382
- const htmlDoc = parser.parseFromString(html, "text/html");
383
- const note = htmlDoc.querySelector('main.content');
384
- if (note !== null) {
385
- // This should only happen for chapter cross references
386
- // (since there is no id in the URL)
387
- // remove the first header
388
- if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
389
- note.children[0].remove();
390
- }
391
- const html = processXRef(null, note);
392
- instance.setContent(html);
393
- }
394
- }).finally(() => {
395
- instance.enable();
396
- instance.show();
397
- });
398
- }
399
- }, function(instance) {
400
- });
401
- }
402
- let selectedAnnoteEl;
403
- const selectorForAnnotation = ( cell, annotation) => {
404
- let cellAttr = 'data-code-cell="' + cell + '"';
405
- let lineAttr = 'data-code-annotation="' + annotation + '"';
406
- const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
407
- return selector;
408
- }
409
- const selectCodeLines = (annoteEl) => {
410
- const doc = window.document;
411
- const targetCell = annoteEl.getAttribute("data-target-cell");
412
- const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
413
- const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
414
- const lines = annoteSpan.getAttribute("data-code-lines").split(",");
415
- const lineIds = lines.map((line) => {
416
- return targetCell + "-" + line;
417
- })
418
- let top = null;
419
- let height = null;
420
- let parent = null;
421
- if (lineIds.length > 0) {
422
- //compute the position of the single el (top and bottom and make a div)
423
- const el = window.document.getElementById(lineIds[0]);
424
- top = el.offsetTop;
425
- height = el.offsetHeight;
426
- parent = el.parentElement.parentElement;
427
- if (lineIds.length > 1) {
428
- const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
429
- const bottom = lastEl.offsetTop + lastEl.offsetHeight;
430
- height = bottom - top;
431
- }
432
- if (top !== null && height !== null && parent !== null) {
433
- // cook up a div (if necessary) and position it
434
- let div = window.document.getElementById("code-annotation-line-highlight");
435
- if (div === null) {
436
- div = window.document.createElement("div");
437
- div.setAttribute("id", "code-annotation-line-highlight");
438
- div.style.position = 'absolute';
439
- parent.appendChild(div);
440
- }
441
- div.style.top = top - 2 + "px";
442
- div.style.height = height + 4 + "px";
443
- div.style.left = 0;
444
- let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
445
- if (gutterDiv === null) {
446
- gutterDiv = window.document.createElement("div");
447
- gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
448
- gutterDiv.style.position = 'absolute';
449
- const codeCell = window.document.getElementById(targetCell);
450
- const gutter = codeCell.querySelector('.code-annotation-gutter');
451
- gutter.appendChild(gutterDiv);
452
- }
453
- gutterDiv.style.top = top - 2 + "px";
454
- gutterDiv.style.height = height + 4 + "px";
455
- }
456
- selectedAnnoteEl = annoteEl;
457
- }
458
- };
459
- const unselectCodeLines = () => {
460
- const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
461
- elementsIds.forEach((elId) => {
462
- const div = window.document.getElementById(elId);
463
- if (div) {
464
- div.remove();
465
- }
466
- });
467
- selectedAnnoteEl = undefined;
468
- };
469
- // Handle positioning of the toggle
470
- window.addEventListener(
471
- "resize",
472
- throttle(() => {
473
- elRect = undefined;
474
- if (selectedAnnoteEl) {
475
- selectCodeLines(selectedAnnoteEl);
476
- }
477
- }, 10)
478
- );
479
- function throttle(fn, ms) {
480
- let throttle = false;
481
- let timer;
482
- return (...args) => {
483
- if(!throttle) { // first call gets through
484
- fn.apply(this, args);
485
- throttle = true;
486
- } else { // all the others get throttled
487
- if(timer) clearTimeout(timer); // cancel #2
488
- timer = setTimeout(() => {
489
- fn.apply(this, args);
490
- timer = throttle = false;
491
- }, ms);
492
- }
493
- };
494
- }
495
- // Attach click handler to the DT
496
- const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
497
- for (const annoteDlNode of annoteDls) {
498
- annoteDlNode.addEventListener('click', (event) => {
499
- const clickedEl = event.target;
500
- if (clickedEl !== selectedAnnoteEl) {
501
- unselectCodeLines();
502
- const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
503
- if (activeEl) {
504
- activeEl.classList.remove('code-annotation-active');
505
- }
506
- selectCodeLines(clickedEl);
507
- clickedEl.classList.add('code-annotation-active');
508
- } else {
509
- // Unselect the line
510
- unselectCodeLines();
511
- clickedEl.classList.remove('code-annotation-active');
512
- }
513
- });
514
- }
515
- const findCites = (el) => {
516
- const parentEl = el.parentElement;
517
- if (parentEl) {
518
- const cites = parentEl.dataset.cites;
519
- if (cites) {
520
- return {
521
- el,
522
- cites: cites.split(' ')
523
- };
524
- } else {
525
- return findCites(el.parentElement)
526
- }
527
- } else {
528
- return undefined;
529
- }
530
- };
531
- var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
532
- for (var i=0; i<bibliorefs.length; i++) {
533
- const ref = bibliorefs[i];
534
- const citeInfo = findCites(ref);
535
- if (citeInfo) {
536
- tippyHover(citeInfo.el, function() {
537
- var popup = window.document.createElement('div');
538
- citeInfo.cites.forEach(function(cite) {
539
- var citeDiv = window.document.createElement('div');
540
- citeDiv.classList.add('hanging-indent');
541
- citeDiv.classList.add('csl-entry');
542
- var biblioDiv = window.document.getElementById('ref-' + cite);
543
- if (biblioDiv) {
544
- citeDiv.innerHTML = biblioDiv.innerHTML;
545
- }
546
- popup.appendChild(citeDiv);
547
- });
548
- return popup.innerHTML;
549
- });
550
- }
551
- }
552
- });
553
- </script>
554
- </div> <!-- /content -->
555
-
556
-
557
-
558
-
559
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/_site/index.html DELETED
@@ -1,707 +0,0 @@
1
- <!DOCTYPE html>
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
-
4
- <meta charset="utf-8">
5
- <meta name="generator" content="quarto-1.6.39">
6
-
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
-
9
-
10
- <title>quarto-blog</title>
11
- <style>
12
- code{white-space: pre-wrap;}
13
- span.smallcaps{font-variant: small-caps;}
14
- div.columns{display: flex; gap: min(4vw, 1.5em);}
15
- div.column{flex: auto; overflow-x: auto;}
16
- div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
17
- ul.task-list{list-style: none;}
18
- ul.task-list li input[type="checkbox"] {
19
- width: 0.8em;
20
- margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
21
- vertical-align: middle;
22
- }
23
- </style>
24
-
25
-
26
- <script src="site_libs/quarto-nav/quarto-nav.js"></script>
27
- <script src="site_libs/quarto-nav/headroom.min.js"></script>
28
- <script src="site_libs/clipboard/clipboard.min.js"></script>
29
- <script src="site_libs/quarto-search/autocomplete.umd.js"></script>
30
- <script src="site_libs/quarto-search/fuse.min.js"></script>
31
- <script src="site_libs/quarto-search/quarto-search.js"></script>
32
- <meta name="quarto:offset" content="./">
33
- <script src="site_libs/quarto-listing/list.min.js"></script>
34
- <script src="site_libs/quarto-listing/quarto-listing.js"></script>
35
- <script src="site_libs/quarto-html/quarto.js"></script>
36
- <script src="site_libs/quarto-html/popper.min.js"></script>
37
- <script src="site_libs/quarto-html/tippy.umd.min.js"></script>
38
- <script src="site_libs/quarto-html/anchor.min.js"></script>
39
- <link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
40
- <link href="site_libs/quarto-html/quarto-syntax-highlighting-e26003cea8cd680ca0c55a263523d882.css" rel="stylesheet" id="quarto-text-highlighting-styles">
41
- <script src="site_libs/bootstrap/bootstrap.min.js"></script>
42
- <link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
43
- <link href="site_libs/bootstrap/bootstrap-d1b12f2568ecbe55642fee6aa00bd082.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
44
- <script id="quarto-search-options" type="application/json">{
45
- "location": "navbar",
46
- "copy-button": false,
47
- "collapse-after": 3,
48
- "panel-placement": "end",
49
- "type": "overlay",
50
- "limit": 50,
51
- "keyboard-shortcut": [
52
- "f",
53
- "/",
54
- "s"
55
- ],
56
- "show-item-context": false,
57
- "language": {
58
- "search-no-results-text": "No results",
59
- "search-matching-documents-text": "matching documents",
60
- "search-copy-link-title": "Copy link to search",
61
- "search-hide-matches-text": "Hide additional matches",
62
- "search-more-match-text": "more match in this document",
63
- "search-more-matches-text": "more matches in this document",
64
- "search-clear-button-title": "Clear",
65
- "search-text-placeholder": "",
66
- "search-detached-cancel-button-title": "Cancel",
67
- "search-submit-button-title": "Submit",
68
- "search-label": "Search"
69
- }
70
- }</script>
71
- <script>
72
-
73
- window.document.addEventListener("DOMContentLoaded", function (_event) {
74
- const listingTargetEl = window.document.querySelector('#listing-listing .list');
75
- if (!listingTargetEl) {
76
- // No listing discovered, do not attach.
77
- return;
78
- }
79
-
80
- const options = {
81
- valueNames: ['listing-date','listing-title','listing-author','listing-image','listing-description','listing-categories',{ data: ['index'] },{ data: ['categories'] },{ data: ['listing-date-sort'] },{ data: ['listing-file-modified-sort'] }],
82
-
83
- searchColumns: ["listing-date","listing-title","listing-author","listing-image","listing-description","listing-categories"],
84
- };
85
-
86
- window['quarto-listings'] = window['quarto-listings'] || {};
87
- window['quarto-listings']['listing-listing'] = new List('listing-listing', options);
88
-
89
- if (window['quarto-listing-loaded']) {
90
- window['quarto-listing-loaded']();
91
- }
92
- });
93
-
94
- window.addEventListener('hashchange',() => {
95
- if (window['quarto-listing-loaded']) {
96
- window['quarto-listing-loaded']();
97
- }
98
- })
99
- </script>
100
-
101
- <script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
102
- <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
103
-
104
- <script type="text/javascript">
105
- const typesetMath = (el) => {
106
- if (window.MathJax) {
107
- // MathJax Typeset
108
- window.MathJax.typeset([el]);
109
- } else if (window.katex) {
110
- // KaTeX Render
111
- var mathElements = el.getElementsByClassName("math");
112
- var macros = [];
113
- for (var i = 0; i < mathElements.length; i++) {
114
- var texText = mathElements[i].firstChild;
115
- if (mathElements[i].tagName == "SPAN") {
116
- window.katex.render(texText.data, mathElements[i], {
117
- displayMode: mathElements[i].classList.contains('display'),
118
- throwOnError: false,
119
- macros: macros,
120
- fleqn: false
121
- });
122
- }
123
- }
124
- }
125
- }
126
- window.Quarto = {
127
- typesetMath
128
- };
129
- </script>
130
-
131
- <link rel="stylesheet" href="styles.css">
132
- </head>
133
-
134
- <body class="nav-fixed">
135
-
136
- <div id="quarto-search-results"></div>
137
- <header id="quarto-header" class="headroom fixed-top quarto-banner">
138
- <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
139
- <div class="navbar-container container-fluid">
140
- <div class="navbar-brand-container mx-auto">
141
- <a class="navbar-brand" href="./index.html">
142
- <span class="navbar-title">quarto-blog</span>
143
- </a>
144
- </div>
145
- <div id="quarto-search" class="" title="Search"></div>
146
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
147
- <span class="navbar-toggler-icon"></span>
148
- </button>
149
- <div class="collapse navbar-collapse" id="navbarCollapse">
150
- <ul class="navbar-nav navbar-nav-scroll ms-auto">
151
- <li class="nav-item">
152
- <a class="nav-link" href="./about.html">
153
- <span class="menu-text">About</span></a>
154
- </li>
155
- <li class="nav-item compact">
156
- <a class="nav-link" href="https://github.com/"> <i class="bi bi-github" role="img">
157
- </i>
158
- <span class="menu-text"></span></a>
159
- </li>
160
- <li class="nav-item compact">
161
- <a class="nav-link" href="https://twitter.com"> <i class="bi bi-twitter" role="img">
162
- </i>
163
- <span class="menu-text"></span></a>
164
- </li>
165
- </ul>
166
- </div> <!-- /navcollapse -->
167
- <div class="quarto-navbar-tools">
168
- </div>
169
- </div> <!-- /container-fluid -->
170
- </nav>
171
- </header>
172
- <!-- content -->
173
- <header id="title-block-header" class="quarto-title-block default page-columns page-full">
174
- <div class="quarto-title-banner page-columns page-full">
175
- <div class="quarto-title column-page-left">
176
- <h1 class="title">quarto-blog</h1>
177
- </div>
178
- </div>
179
-
180
-
181
- <div class="quarto-title-meta column-page-left">
182
-
183
-
184
-
185
-
186
- </div>
187
-
188
-
189
- </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-full page-navbar">
190
- <!-- sidebar -->
191
- <!-- margin-sidebar -->
192
- <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
193
-
194
- <h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(2)</span></div><div class="category" data-category="bWF0aGVtYXRpY3M=">mathematics <span class="quarto-category-count">(2)</span></div><div class="category" data-category="cGRl">pde <span class="quarto-category-count">(1)</span></div><div class="category" data-category="cG9seW5vbWlhbHM=">polynomials <span class="quarto-category-count">(1)</span></div></div></div>
195
- <!-- main -->
196
- <main class="content quarto-banner-title-block column-page-left" id="quarto-document-content">
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
- <div class="quarto-listing quarto-listing-container-default" id="listing-listing">
207
- <div class="list quarto-listing-default">
208
- <div class="quarto-post image-right" data-index="0" data-categories="bWF0aGVtYXRpY3MlMkNwb2x5bm9taWFscw==" data-listing-date-sort="1736114400000" data-listing-file-modified-sort="1748623629839" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="10" data-listing-word-count-sort="1915">
209
- <div class="thumbnail">
210
- <p><a href="./posts/2025-01-06-chebyshev-polynomials/index.html" class="no-external"></a></p><a href="./posts/2025-01-06-chebyshev-polynomials/index.html" class="no-external">
211
- <p class="card-img-top"><img src="posts/2025-01-06-chebyshev-polynomials/images/unit_circle.svg" class="thumbnail-image card-img"/></p>
212
- </a><p><a href="./posts/2025-01-06-chebyshev-polynomials/index.html" class="no-external"></a></p>
213
- </div>
214
- <div class="body">
215
- <h3 class="no-anchor listing-title">
216
- <a href="./posts/2025-01-06-chebyshev-polynomials/index.html" class="no-external">Chebyshev Polynomials: Part 1</a>
217
- </h3>
218
- <div class="listing-subtitle">
219
- <a href="./posts/2025-01-06-chebyshev-polynomials/index.html" class="no-external"></a>
220
- </div>
221
- <div class="listing-categories">
222
- <div class="listing-category" onclick="window.quartoListingCategory('bWF0aGVtYXRpY3M='); return false;">
223
- mathematics
224
- </div>
225
- <div class="listing-category" onclick="window.quartoListingCategory('cG9seW5vbWlhbHM='); return false;">
226
- polynomials
227
- </div>
228
- </div>
229
- <div class="listing-description">
230
- <a href="./posts/2025-01-06-chebyshev-polynomials/index.html" class="no-external">Chebyshev polynomials are a sequence of orthogonal polynomials that play a central role in numerical analysis, approximation theory, and applied mathematics. They are named…<span class="math inline"></span><span class="math inline"></span></a>
231
- </div>
232
- </div>
233
- <div class="metadata">
234
- <a href="./posts/2025-01-06-chebyshev-polynomials/index.html" class="no-external">
235
- <div class="listing-date">
236
- Jan 6, 2025
237
- </div>
238
- <div class="listing-author">
239
- Joana Levtcheva
240
- </div>
241
- </a>
242
- </div>
243
- </div>
244
- <div class="quarto-post image-right" data-index="1" data-categories="bWF0aGVtYXRpY3MlMkNwZGU=" data-listing-date-sort="1735941600000" data-listing-file-modified-sort="1748623629822" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="17" data-listing-word-count-sort="3389">
245
- <div class="thumbnail">
246
- <p><a href="./posts/2025-01-04-fourier-method-fixed-string/index.html" class="no-external"></a></p><a href="./posts/2025-01-04-fourier-method-fixed-string/index.html" class="no-external">
247
- <p class="card-img-top"><img src="posts/2025-01-04-fourier-method-fixed-string/images/fixed_string.svg" class="thumbnail-image card-img"/></p>
248
- </a><p><a href="./posts/2025-01-04-fourier-method-fixed-string/index.html" class="no-external"></a></p>
249
- </div>
250
- <div class="body">
251
- <h3 class="no-anchor listing-title">
252
- <a href="./posts/2025-01-04-fourier-method-fixed-string/index.html" class="no-external">Fourier Method for the 1D Wave Equation: Fixed String</a>
253
- </h3>
254
- <div class="listing-subtitle">
255
- <a href="./posts/2025-01-04-fourier-method-fixed-string/index.html" class="no-external"></a>
256
- </div>
257
- <div class="listing-categories">
258
- <div class="listing-category" onclick="window.quartoListingCategory('bWF0aGVtYXRpY3M='); return false;">
259
- mathematics
260
- </div>
261
- <div class="listing-category" onclick="window.quartoListingCategory('cGRl'); return false;">
262
- pde
263
- </div>
264
- </div>
265
- <div class="listing-description">
266
- <a href="./posts/2025-01-04-fourier-method-fixed-string/index.html" class="no-external">In this post we are going to explore the Fourier method for solving the 1D wave equation. The method is more known under the name of the <strong>method of separation of variables</strong>.…</a>
267
- </div>
268
- </div>
269
- <div class="metadata">
270
- <a href="./posts/2025-01-04-fourier-method-fixed-string/index.html" class="no-external">
271
- <div class="listing-date">
272
- Jan 4, 2025
273
- </div>
274
- <div class="listing-author">
275
- Joana Levtcheva
276
- </div>
277
- </a>
278
- </div>
279
- </div>
280
- </div>
281
- <div class="listing-no-matching d-none">
282
- No matching items
283
- </div>
284
- </div></main> <!-- /main -->
285
- <script id="quarto-html-after-body" type="application/javascript">
286
- window.document.addEventListener("DOMContentLoaded", function (event) {
287
- const toggleBodyColorMode = (bsSheetEl) => {
288
- const mode = bsSheetEl.getAttribute("data-mode");
289
- const bodyEl = window.document.querySelector("body");
290
- if (mode === "dark") {
291
- bodyEl.classList.add("quarto-dark");
292
- bodyEl.classList.remove("quarto-light");
293
- } else {
294
- bodyEl.classList.add("quarto-light");
295
- bodyEl.classList.remove("quarto-dark");
296
- }
297
- }
298
- const toggleBodyColorPrimary = () => {
299
- const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
300
- if (bsSheetEl) {
301
- toggleBodyColorMode(bsSheetEl);
302
- }
303
- }
304
- toggleBodyColorPrimary();
305
- const icon = "";
306
- const anchorJS = new window.AnchorJS();
307
- anchorJS.options = {
308
- placement: 'right',
309
- icon: icon
310
- };
311
- anchorJS.add('.anchored');
312
- const isCodeAnnotation = (el) => {
313
- for (const clz of el.classList) {
314
- if (clz.startsWith('code-annotation-')) {
315
- return true;
316
- }
317
- }
318
- return false;
319
- }
320
- const onCopySuccess = function(e) {
321
- // button target
322
- const button = e.trigger;
323
- // don't keep focus
324
- button.blur();
325
- // flash "checked"
326
- button.classList.add('code-copy-button-checked');
327
- var currentTitle = button.getAttribute("title");
328
- button.setAttribute("title", "Copied!");
329
- let tooltip;
330
- if (window.bootstrap) {
331
- button.setAttribute("data-bs-toggle", "tooltip");
332
- button.setAttribute("data-bs-placement", "left");
333
- button.setAttribute("data-bs-title", "Copied!");
334
- tooltip = new bootstrap.Tooltip(button,
335
- { trigger: "manual",
336
- customClass: "code-copy-button-tooltip",
337
- offset: [0, -8]});
338
- tooltip.show();
339
- }
340
- setTimeout(function() {
341
- if (tooltip) {
342
- tooltip.hide();
343
- button.removeAttribute("data-bs-title");
344
- button.removeAttribute("data-bs-toggle");
345
- button.removeAttribute("data-bs-placement");
346
- }
347
- button.setAttribute("title", currentTitle);
348
- button.classList.remove('code-copy-button-checked');
349
- }, 1000);
350
- // clear code selection
351
- e.clearSelection();
352
- }
353
- const getTextToCopy = function(trigger) {
354
- const codeEl = trigger.previousElementSibling.cloneNode(true);
355
- for (const childEl of codeEl.children) {
356
- if (isCodeAnnotation(childEl)) {
357
- childEl.remove();
358
- }
359
- }
360
- return codeEl.innerText;
361
- }
362
- const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
363
- text: getTextToCopy
364
- });
365
- clipboard.on('success', onCopySuccess);
366
- if (window.document.getElementById('quarto-embedded-source-code-modal')) {
367
- const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
368
- text: getTextToCopy,
369
- container: window.document.getElementById('quarto-embedded-source-code-modal')
370
- });
371
- clipboardModal.on('success', onCopySuccess);
372
- }
373
- var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
374
- var mailtoRegex = new RegExp(/^mailto:/);
375
- var filterRegex = new RegExp('/' + window.location.host + '/');
376
- var isInternal = (href) => {
377
- return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
378
- }
379
- // Inspect non-navigation links and adorn them if external
380
- var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
381
- for (var i=0; i<links.length; i++) {
382
- const link = links[i];
383
- if (!isInternal(link.href)) {
384
- // undo the damage that might have been done by quarto-nav.js in the case of
385
- // links that we want to consider external
386
- if (link.dataset.originalHref !== undefined) {
387
- link.href = link.dataset.originalHref;
388
- }
389
- }
390
- }
391
- function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
392
- const config = {
393
- allowHTML: true,
394
- maxWidth: 500,
395
- delay: 100,
396
- arrow: false,
397
- appendTo: function(el) {
398
- return el.parentElement;
399
- },
400
- interactive: true,
401
- interactiveBorder: 10,
402
- theme: 'quarto',
403
- placement: 'bottom-start',
404
- };
405
- if (contentFn) {
406
- config.content = contentFn;
407
- }
408
- if (onTriggerFn) {
409
- config.onTrigger = onTriggerFn;
410
- }
411
- if (onUntriggerFn) {
412
- config.onUntrigger = onUntriggerFn;
413
- }
414
- window.tippy(el, config);
415
- }
416
- const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
417
- for (var i=0; i<noterefs.length; i++) {
418
- const ref = noterefs[i];
419
- tippyHover(ref, function() {
420
- // use id or data attribute instead here
421
- let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
422
- try { href = new URL(href).hash; } catch {}
423
- const id = href.replace(/^#\/?/, "");
424
- const note = window.document.getElementById(id);
425
- if (note) {
426
- return note.innerHTML;
427
- } else {
428
- return "";
429
- }
430
- });
431
- }
432
- const xrefs = window.document.querySelectorAll('a.quarto-xref');
433
- const processXRef = (id, note) => {
434
- // Strip column container classes
435
- const stripColumnClz = (el) => {
436
- el.classList.remove("page-full", "page-columns");
437
- if (el.children) {
438
- for (const child of el.children) {
439
- stripColumnClz(child);
440
- }
441
- }
442
- }
443
- stripColumnClz(note)
444
- if (id === null || id.startsWith('sec-')) {
445
- // Special case sections, only their first couple elements
446
- const container = document.createElement("div");
447
- if (note.children && note.children.length > 2) {
448
- container.appendChild(note.children[0].cloneNode(true));
449
- for (let i = 1; i < note.children.length; i++) {
450
- const child = note.children[i];
451
- if (child.tagName === "P" && child.innerText === "") {
452
- continue;
453
- } else {
454
- container.appendChild(child.cloneNode(true));
455
- break;
456
- }
457
- }
458
- if (window.Quarto?.typesetMath) {
459
- window.Quarto.typesetMath(container);
460
- }
461
- return container.innerHTML
462
- } else {
463
- if (window.Quarto?.typesetMath) {
464
- window.Quarto.typesetMath(note);
465
- }
466
- return note.innerHTML;
467
- }
468
- } else {
469
- // Remove any anchor links if they are present
470
- const anchorLink = note.querySelector('a.anchorjs-link');
471
- if (anchorLink) {
472
- anchorLink.remove();
473
- }
474
- if (window.Quarto?.typesetMath) {
475
- window.Quarto.typesetMath(note);
476
- }
477
- if (note.classList.contains("callout")) {
478
- return note.outerHTML;
479
- } else {
480
- return note.innerHTML;
481
- }
482
- }
483
- }
484
- for (var i=0; i<xrefs.length; i++) {
485
- const xref = xrefs[i];
486
- tippyHover(xref, undefined, function(instance) {
487
- instance.disable();
488
- let url = xref.getAttribute('href');
489
- let hash = undefined;
490
- if (url.startsWith('#')) {
491
- hash = url;
492
- } else {
493
- try { hash = new URL(url).hash; } catch {}
494
- }
495
- if (hash) {
496
- const id = hash.replace(/^#\/?/, "");
497
- const note = window.document.getElementById(id);
498
- if (note !== null) {
499
- try {
500
- const html = processXRef(id, note.cloneNode(true));
501
- instance.setContent(html);
502
- } finally {
503
- instance.enable();
504
- instance.show();
505
- }
506
- } else {
507
- // See if we can fetch this
508
- fetch(url.split('#')[0])
509
- .then(res => res.text())
510
- .then(html => {
511
- const parser = new DOMParser();
512
- const htmlDoc = parser.parseFromString(html, "text/html");
513
- const note = htmlDoc.getElementById(id);
514
- if (note !== null) {
515
- const html = processXRef(id, note);
516
- instance.setContent(html);
517
- }
518
- }).finally(() => {
519
- instance.enable();
520
- instance.show();
521
- });
522
- }
523
- } else {
524
- // See if we can fetch a full url (with no hash to target)
525
- // This is a special case and we should probably do some content thinning / targeting
526
- fetch(url)
527
- .then(res => res.text())
528
- .then(html => {
529
- const parser = new DOMParser();
530
- const htmlDoc = parser.parseFromString(html, "text/html");
531
- const note = htmlDoc.querySelector('main.content');
532
- if (note !== null) {
533
- // This should only happen for chapter cross references
534
- // (since there is no id in the URL)
535
- // remove the first header
536
- if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
537
- note.children[0].remove();
538
- }
539
- const html = processXRef(null, note);
540
- instance.setContent(html);
541
- }
542
- }).finally(() => {
543
- instance.enable();
544
- instance.show();
545
- });
546
- }
547
- }, function(instance) {
548
- });
549
- }
550
- let selectedAnnoteEl;
551
- const selectorForAnnotation = ( cell, annotation) => {
552
- let cellAttr = 'data-code-cell="' + cell + '"';
553
- let lineAttr = 'data-code-annotation="' + annotation + '"';
554
- const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
555
- return selector;
556
- }
557
- const selectCodeLines = (annoteEl) => {
558
- const doc = window.document;
559
- const targetCell = annoteEl.getAttribute("data-target-cell");
560
- const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
561
- const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
562
- const lines = annoteSpan.getAttribute("data-code-lines").split(",");
563
- const lineIds = lines.map((line) => {
564
- return targetCell + "-" + line;
565
- })
566
- let top = null;
567
- let height = null;
568
- let parent = null;
569
- if (lineIds.length > 0) {
570
- //compute the position of the single el (top and bottom and make a div)
571
- const el = window.document.getElementById(lineIds[0]);
572
- top = el.offsetTop;
573
- height = el.offsetHeight;
574
- parent = el.parentElement.parentElement;
575
- if (lineIds.length > 1) {
576
- const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
577
- const bottom = lastEl.offsetTop + lastEl.offsetHeight;
578
- height = bottom - top;
579
- }
580
- if (top !== null && height !== null && parent !== null) {
581
- // cook up a div (if necessary) and position it
582
- let div = window.document.getElementById("code-annotation-line-highlight");
583
- if (div === null) {
584
- div = window.document.createElement("div");
585
- div.setAttribute("id", "code-annotation-line-highlight");
586
- div.style.position = 'absolute';
587
- parent.appendChild(div);
588
- }
589
- div.style.top = top - 2 + "px";
590
- div.style.height = height + 4 + "px";
591
- div.style.left = 0;
592
- let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
593
- if (gutterDiv === null) {
594
- gutterDiv = window.document.createElement("div");
595
- gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
596
- gutterDiv.style.position = 'absolute';
597
- const codeCell = window.document.getElementById(targetCell);
598
- const gutter = codeCell.querySelector('.code-annotation-gutter');
599
- gutter.appendChild(gutterDiv);
600
- }
601
- gutterDiv.style.top = top - 2 + "px";
602
- gutterDiv.style.height = height + 4 + "px";
603
- }
604
- selectedAnnoteEl = annoteEl;
605
- }
606
- };
607
- const unselectCodeLines = () => {
608
- const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
609
- elementsIds.forEach((elId) => {
610
- const div = window.document.getElementById(elId);
611
- if (div) {
612
- div.remove();
613
- }
614
- });
615
- selectedAnnoteEl = undefined;
616
- };
617
- // Handle positioning of the toggle
618
- window.addEventListener(
619
- "resize",
620
- throttle(() => {
621
- elRect = undefined;
622
- if (selectedAnnoteEl) {
623
- selectCodeLines(selectedAnnoteEl);
624
- }
625
- }, 10)
626
- );
627
- function throttle(fn, ms) {
628
- let throttle = false;
629
- let timer;
630
- return (...args) => {
631
- if(!throttle) { // first call gets through
632
- fn.apply(this, args);
633
- throttle = true;
634
- } else { // all the others get throttled
635
- if(timer) clearTimeout(timer); // cancel #2
636
- timer = setTimeout(() => {
637
- fn.apply(this, args);
638
- timer = throttle = false;
639
- }, ms);
640
- }
641
- };
642
- }
643
- // Attach click handler to the DT
644
- const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
645
- for (const annoteDlNode of annoteDls) {
646
- annoteDlNode.addEventListener('click', (event) => {
647
- const clickedEl = event.target;
648
- if (clickedEl !== selectedAnnoteEl) {
649
- unselectCodeLines();
650
- const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
651
- if (activeEl) {
652
- activeEl.classList.remove('code-annotation-active');
653
- }
654
- selectCodeLines(clickedEl);
655
- clickedEl.classList.add('code-annotation-active');
656
- } else {
657
- // Unselect the line
658
- unselectCodeLines();
659
- clickedEl.classList.remove('code-annotation-active');
660
- }
661
- });
662
- }
663
- const findCites = (el) => {
664
- const parentEl = el.parentElement;
665
- if (parentEl) {
666
- const cites = parentEl.dataset.cites;
667
- if (cites) {
668
- return {
669
- el,
670
- cites: cites.split(' ')
671
- };
672
- } else {
673
- return findCites(el.parentElement)
674
- }
675
- } else {
676
- return undefined;
677
- }
678
- };
679
- var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
680
- for (var i=0; i<bibliorefs.length; i++) {
681
- const ref = bibliorefs[i];
682
- const citeInfo = findCites(ref);
683
- if (citeInfo) {
684
- tippyHover(citeInfo.el, function() {
685
- var popup = window.document.createElement('div');
686
- citeInfo.cites.forEach(function(cite) {
687
- var citeDiv = window.document.createElement('div');
688
- citeDiv.classList.add('hanging-indent');
689
- citeDiv.classList.add('csl-entry');
690
- var biblioDiv = window.document.getElementById('ref-' + cite);
691
- if (biblioDiv) {
692
- citeDiv.innerHTML = biblioDiv.innerHTML;
693
- }
694
- popup.appendChild(citeDiv);
695
- });
696
- return popup.innerHTML;
697
- });
698
- }
699
- }
700
- });
701
- </script>
702
- </div> <!-- /content -->
703
-
704
-
705
-
706
-
707
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/_site/listings.json DELETED
@@ -1,9 +0,0 @@
1
- [
2
- {
3
- "listing": "/index.html",
4
- "items": [
5
- "/posts/2025-01-06-chebyshev-polynomials/index.html",
6
- "/posts/2025-01-04-fourier-method-fixed-string/index.html"
7
- ]
8
- }
9
- ]
 
 
 
 
 
 
 
 
 
 
src/_site/posts/2025-01-04-fourier-method-fixed-string/code/fixed_string_animation.html DELETED
The diff for this file is too large to render. See raw diff
 
src/_site/posts/2025-01-04-fourier-method-fixed-string/images/fixed_string.svg DELETED
src/_site/posts/2025-01-04-fourier-method-fixed-string/images/harmonics.svg DELETED
src/_site/posts/2025-01-04-fourier-method-fixed-string/images/odd_continuation.png DELETED

Git LFS Details

  • SHA256: 9d765e2b941c2e72ed8273ebd9e6ec52f02b9520957fc38d570b1dace71226dd
  • Pointer size: 130 Bytes
  • Size of remote file: 93.2 kB
src/_site/posts/2025-01-04-fourier-method-fixed-string/index.html DELETED
The diff for this file is too large to render. See raw diff
 
src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_nodes.png DELETED

Git LFS Details

  • SHA256: d1def3252ced48f4d10ec88aefb67945b4374625b791096913ebb58f7c550217
  • Pointer size: 130 Bytes
  • Size of remote file: 33.1 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_nodes_visualization.svg DELETED
src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials.png DELETED

Git LFS Details

  • SHA256: 4046f5d2389a7385509957a1486e618d4a2dac9327efb6ce65a15a24ab7da6f3
  • Pointer size: 130 Bytes
  • Size of remote file: 61.2 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials_aliasing_even.png DELETED

Git LFS Details

  • SHA256: fd3f60e5d8884350c9b0285cf9ea04ec21f903452fd59a00adc44a07418d23dd
  • Pointer size: 131 Bytes
  • Size of remote file: 171 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials_aliasing_odd.png DELETED

Git LFS Details

  • SHA256: f83d607ee245bcd737cdd4331dcee6032981db4bb17907f85a3bb302da657a6f
  • Pointer size: 131 Bytes
  • Size of remote file: 183 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/chebyshev_polynomials_stacked.png DELETED

Git LFS Details

  • SHA256: d78de9856b19d57b6753968352f276579f8f7f9374f27e2a4f02fabb1e687e2d
  • Pointer size: 131 Bytes
  • Size of remote file: 126 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_0.png DELETED

Git LFS Details

  • SHA256: f3dce08e75380f5df5b2f63b560399524ef98f14c5d8536cd0cb079a8fb34def
  • Pointer size: 130 Bytes
  • Size of remote file: 36.8 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_1.png DELETED

Git LFS Details

  • SHA256: 10a1a42d8e2d2ff77fea79f03609e8ebf028194afb4d7fa7d4524d17033c2ffa
  • Pointer size: 130 Bytes
  • Size of remote file: 41.3 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_10.png DELETED

Git LFS Details

  • SHA256: 3924a9bb31d5a0cc481108ac641c65370fefab7559586df9f7d0060a385c2b48
  • Pointer size: 130 Bytes
  • Size of remote file: 37.5 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_11.png DELETED

Git LFS Details

  • SHA256: 2aee64310ca123e729a7cf899e271c9efde8f61986e8bb27146da8f613a1ecf9
  • Pointer size: 130 Bytes
  • Size of remote file: 37.3 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_2.png DELETED

Git LFS Details

  • SHA256: d0c29955d00d92cff7c6c757cffde2203a423b0c70db7d415bbc4339132bdd78
  • Pointer size: 130 Bytes
  • Size of remote file: 36.7 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_3.png DELETED

Git LFS Details

  • SHA256: 86a4acc0e4d5fa1192518060807d30d9d62dcc40d12697f2c01bbee6110edf46
  • Pointer size: 130 Bytes
  • Size of remote file: 53.5 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_4.png DELETED

Git LFS Details

  • SHA256: 98052488a1dd6c419200e63743cee9569ef00a97c4c84f10165f42bdf2e25976
  • Pointer size: 130 Bytes
  • Size of remote file: 66 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_5.png DELETED

Git LFS Details

  • SHA256: 8f16bbf8dd48c5282a43d1a7f4118422a9a441abcc9cac220df05fa68b0c02a2
  • Pointer size: 130 Bytes
  • Size of remote file: 36.3 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_6.png DELETED

Git LFS Details

  • SHA256: ca926854111a50bf1f6f601cfaff8e34e0efb352ca42a6ae9a067ffa7eef0666
  • Pointer size: 130 Bytes
  • Size of remote file: 35 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_7.png DELETED

Git LFS Details

  • SHA256: 3e0dd60a31de8677c4b1964cd90abe68aa25903bf22f5b77c5d25d5ee34d07e6
  • Pointer size: 130 Bytes
  • Size of remote file: 91.5 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_8.png DELETED

Git LFS Details

  • SHA256: b6f58761575775996f9ed6196d37a52a6a2f907c5d6230fd550dbf716d5b5ce7
  • Pointer size: 130 Bytes
  • Size of remote file: 38.4 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_9.png DELETED

Git LFS Details

  • SHA256: ad55791b1281d7c42baea2a41ec090ff93c318c1f0f43e9e80983cec20d06f1e
  • Pointer size: 130 Bytes
  • Size of remote file: 38 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_init_1.png DELETED

Git LFS Details

  • SHA256: 5ba014f51ba0dd47d11cd051f199684e9bb42057ed33cbb239a9f152cdffbd4a
  • Pointer size: 130 Bytes
  • Size of remote file: 83.4 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/polar_init_2.png DELETED

Git LFS Details

  • SHA256: f5008af937de86d40338a0731a4195d7da9257e0c1b849095221abf6d4d3ff5f
  • Pointer size: 130 Bytes
  • Size of remote file: 65.5 kB
src/_site/posts/2025-01-06-chebyshev-polynomials/images/reduction.svg DELETED
src/_site/posts/2025-01-06-chebyshev-polynomials/images/unit_circle.svg DELETED
src/_site/posts/2025-01-06-chebyshev-polynomials/index.html DELETED
@@ -1,1077 +0,0 @@
1
- <!DOCTYPE html>
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
-
4
- <meta charset="utf-8">
5
- <meta name="generator" content="quarto-1.6.39">
6
-
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
-
9
- <meta name="author" content="Joana Levtcheva">
10
- <meta name="dcterms.date" content="2025-01-06">
11
-
12
- <title>Chebyshev Polynomials: Part 1 – quarto-blog</title>
13
- <style>
14
- code{white-space: pre-wrap;}
15
- span.smallcaps{font-variant: small-caps;}
16
- div.columns{display: flex; gap: min(4vw, 1.5em);}
17
- div.column{flex: auto; overflow-x: auto;}
18
- div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19
- ul.task-list{list-style: none;}
20
- ul.task-list li input[type="checkbox"] {
21
- width: 0.8em;
22
- margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
23
- vertical-align: middle;
24
- }
25
- /* CSS for syntax highlighting */
26
- pre > code.sourceCode { white-space: pre; position: relative; }
27
- pre > code.sourceCode > span { line-height: 1.25; }
28
- pre > code.sourceCode > span:empty { height: 1.2em; }
29
- .sourceCode { overflow: visible; }
30
- code.sourceCode > span { color: inherit; text-decoration: inherit; }
31
- div.sourceCode { margin: 1em 0; }
32
- pre.sourceCode { margin: 0; }
33
- @media screen {
34
- div.sourceCode { overflow: auto; }
35
- }
36
- @media print {
37
- pre > code.sourceCode { white-space: pre-wrap; }
38
- pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; }
39
- }
40
- pre.numberSource code
41
- { counter-reset: source-line 0; }
42
- pre.numberSource code > span
43
- { position: relative; left: -4em; counter-increment: source-line; }
44
- pre.numberSource code > span > a:first-child::before
45
- { content: counter(source-line);
46
- position: relative; left: -1em; text-align: right; vertical-align: baseline;
47
- border: none; display: inline-block;
48
- -webkit-touch-callout: none; -webkit-user-select: none;
49
- -khtml-user-select: none; -moz-user-select: none;
50
- -ms-user-select: none; user-select: none;
51
- padding: 0 4px; width: 4em;
52
- }
53
- pre.numberSource { margin-left: 3em; padding-left: 4px; }
54
- div.sourceCode
55
- { }
56
- @media screen {
57
- pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
58
- }
59
- </style>
60
-
61
-
62
- <script src="../../site_libs/quarto-nav/quarto-nav.js"></script>
63
- <script src="../../site_libs/quarto-nav/headroom.min.js"></script>
64
- <script src="../../site_libs/clipboard/clipboard.min.js"></script>
65
- <script src="../../site_libs/quarto-search/autocomplete.umd.js"></script>
66
- <script src="../../site_libs/quarto-search/fuse.min.js"></script>
67
- <script src="../../site_libs/quarto-search/quarto-search.js"></script>
68
- <meta name="quarto:offset" content="../../">
69
- <script src="../../site_libs/quarto-html/quarto.js"></script>
70
- <script src="../../site_libs/quarto-html/popper.min.js"></script>
71
- <script src="../../site_libs/quarto-html/tippy.umd.min.js"></script>
72
- <script src="../../site_libs/quarto-html/anchor.min.js"></script>
73
- <link href="../../site_libs/quarto-html/tippy.css" rel="stylesheet">
74
- <link href="../../site_libs/quarto-html/quarto-syntax-highlighting-e26003cea8cd680ca0c55a263523d882.css" rel="stylesheet" id="quarto-text-highlighting-styles">
75
- <script src="../../site_libs/bootstrap/bootstrap.min.js"></script>
76
- <link href="../../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
77
- <link href="../../site_libs/bootstrap/bootstrap-d1b12f2568ecbe55642fee6aa00bd082.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
78
- <script id="quarto-search-options" type="application/json">{
79
- "location": "navbar",
80
- "copy-button": false,
81
- "collapse-after": 3,
82
- "panel-placement": "end",
83
- "type": "overlay",
84
- "limit": 50,
85
- "keyboard-shortcut": [
86
- "f",
87
- "/",
88
- "s"
89
- ],
90
- "show-item-context": false,
91
- "language": {
92
- "search-no-results-text": "No results",
93
- "search-matching-documents-text": "matching documents",
94
- "search-copy-link-title": "Copy link to search",
95
- "search-hide-matches-text": "Hide additional matches",
96
- "search-more-match-text": "more match in this document",
97
- "search-more-matches-text": "more matches in this document",
98
- "search-clear-button-title": "Clear",
99
- "search-text-placeholder": "",
100
- "search-detached-cancel-button-title": "Cancel",
101
- "search-submit-button-title": "Submit",
102
- "search-label": "Search"
103
- }
104
- }</script>
105
-
106
- <script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
107
- <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
108
-
109
- <script type="text/javascript">
110
- const typesetMath = (el) => {
111
- if (window.MathJax) {
112
- // MathJax Typeset
113
- window.MathJax.typeset([el]);
114
- } else if (window.katex) {
115
- // KaTeX Render
116
- var mathElements = el.getElementsByClassName("math");
117
- var macros = [];
118
- for (var i = 0; i < mathElements.length; i++) {
119
- var texText = mathElements[i].firstChild;
120
- if (mathElements[i].tagName == "SPAN") {
121
- window.katex.render(texText.data, mathElements[i], {
122
- displayMode: mathElements[i].classList.contains('display'),
123
- throwOnError: false,
124
- macros: macros,
125
- fleqn: false
126
- });
127
- }
128
- }
129
- }
130
- }
131
- window.Quarto = {
132
- typesetMath
133
- };
134
- </script>
135
-
136
- <link rel="stylesheet" href="../../styles.css">
137
- </head>
138
-
139
- <body class="nav-fixed fullcontent">
140
-
141
- <div id="quarto-search-results"></div>
142
- <header id="quarto-header" class="headroom fixed-top quarto-banner">
143
- <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
144
- <div class="navbar-container container-fluid">
145
- <div class="navbar-brand-container mx-auto">
146
- <a class="navbar-brand" href="../../index.html">
147
- <span class="navbar-title">quarto-blog</span>
148
- </a>
149
- </div>
150
- <div id="quarto-search" class="" title="Search"></div>
151
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
152
- <span class="navbar-toggler-icon"></span>
153
- </button>
154
- <div class="collapse navbar-collapse" id="navbarCollapse">
155
- <ul class="navbar-nav navbar-nav-scroll ms-auto">
156
- <li class="nav-item">
157
- <a class="nav-link" href="../../about.html">
158
- <span class="menu-text">About</span></a>
159
- </li>
160
- <li class="nav-item compact">
161
- <a class="nav-link" href="https://github.com/"> <i class="bi bi-github" role="img">
162
- </i>
163
- <span class="menu-text"></span></a>
164
- </li>
165
- <li class="nav-item compact">
166
- <a class="nav-link" href="https://twitter.com"> <i class="bi bi-twitter" role="img">
167
- </i>
168
- <span class="menu-text"></span></a>
169
- </li>
170
- </ul>
171
- </div> <!-- /navcollapse -->
172
- <div class="quarto-navbar-tools">
173
- </div>
174
- </div> <!-- /container-fluid -->
175
- </nav>
176
- </header>
177
- <!-- content -->
178
- <header id="title-block-header" class="quarto-title-block default page-columns page-full">
179
- <div class="quarto-title-banner page-columns page-full">
180
- <div class="quarto-title column-body">
181
- <h1 class="title">Chebyshev Polynomials: Part 1</h1>
182
- <div class="quarto-categories">
183
- <div class="quarto-category">mathematics</div>
184
- <div class="quarto-category">polynomials</div>
185
- </div>
186
- </div>
187
- </div>
188
-
189
-
190
- <div class="quarto-title-meta">
191
-
192
- <div>
193
- <div class="quarto-title-meta-heading">Author</div>
194
- <div class="quarto-title-meta-contents">
195
- <p>Joana Levtcheva </p>
196
- </div>
197
- </div>
198
-
199
- <div>
200
- <div class="quarto-title-meta-heading">Published</div>
201
- <div class="quarto-title-meta-contents">
202
- <p class="date">January 6, 2025</p>
203
- </div>
204
- </div>
205
-
206
-
207
- </div>
208
-
209
-
210
- </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
211
- <!-- sidebar -->
212
- <!-- margin-sidebar -->
213
-
214
- <!-- main -->
215
- <main class="content quarto-banner-title-block" id="quarto-document-content">
216
-
217
-
218
-
219
-
220
-
221
- <p>Chebyshev polynomials are a sequence of orthogonal polynomials that play a central role in numerical analysis, approximation theory, and applied mathematics. They are named after the Russian mathematician Pafnuty Chebyshev and come in two primary types: Chebyshev polynomials of the first kind (<span class="math inline">\(T_n(x)\)</span>) and Chebyshev polynomials of the second kind (<span class="math inline">\(U_n(x)\)</span>). In this post we are going to focus on the Chebyshev polynomials of the first kind.</p>
222
- <section id="chebyshev-polynomials-of-the-first-kind" class="level1">
223
- <h1>Chebyshev Polynomials of the First Kind</h1>
224
- <p>There are many different ways to define the Chebyshev polynomials of the first kind. The one that seems most logical to me and most useful in terms of outlining various properties of the polynomials is</p>
225
- <p><span class="math display">\[\label{eq:1}
226
- T_{n}(x) = \cos{\left(n \arccos{x}\right)}, \quad x \in [-1, 1].\tag{1}
227
- \]</span></p>
228
- <p>Looking at <span class="math inline">\(\eqref{eq:1}\)</span> it is not obvious why <span class="math inline">\(T_{n}(x)\)</span> would be a polynomial. In order to show it is indeed a polynomial let’s recall the de Moivre’s formula</p>
229
- <p><span class="math display">\[
230
- \cos{(n \theta)} + i\sin{(n \theta)} = (\cos(\theta) + i \sin{\theta})^n.
231
- \]</span></p>
232
- <p>We can apply binomial expansion and take the real part from it to obatin</p>
233
- <p><span class="math display">\[\label{eq:2}
234
- \cos(n \theta) = \sum_{k = 0}^{\frac{n}{2}} C(n, 2k) (-1)^k \cos^{n - 2k}\theta \sin^{2k}{\theta}. \tag{2}
235
- \]</span></p>
236
- <p>where</p>
237
- <p><span class="math display">\[
238
- C(n, 2k) = \frac{n!}{(2k)!(n-2k)!}, \quad n \geq 2k, k \in N, n \in N
239
- \]</span></p>
240
- <p>denotes the binomal coefficient. We can also notice that</p>
241
- <p><span class="math display">\[
242
- \sin^{2k}\theta = (\sin^2{\theta})^k = (1 - \cos^2{\theta})^k,
243
- \]</span></p>
244
- <p>showing that <span class="math inline">\(\eqref{eq:2}\)</span> is a polynomial of <span class="math inline">\(\cos{\theta}\)</span> of degree <span class="math inline">\(n\)</span>. Now, let</p>
245
- <p><span class="math display">\[
246
- \theta = \arccos{x},
247
- \]</span></p>
248
- <p>and by utilising <span class="math inline">\(\cos{\left(\arccos{x}\right)} = x\)</span> we get</p>
249
- <p><span class="math display">\[
250
- x = \cos{\theta}.
251
- \]</span></p>
252
- <p>This transforms <span class="math inline">\(\eqref{eq:1}\)</span> to</p>
253
- <p><span class="math display">\[\label{eq:3}
254
- T_{n}(\cos{\theta}) = \cos{\left(n \theta\right)} \tag{3}
255
- \]</span></p>
256
- <p>which we already showed is a polynomial of degree <span class="math inline">\(n\)</span>. From here, because <span class="math inline">\(\cos(.)\)</span> is an even function, we can note that</p>
257
- <p><span class="math display">\[
258
- T_{n}(x) = T_{-n}(x) = T_{|n|}(x.)
259
- \]</span></p>
260
- <p>From <span class="math inline">\(\eqref{eq:3}\)</span> it is also obvious that the values of <span class="math inline">\(T_n\)</span> in the interval <span class="math inline">\([-1, 1]\)</span> are bounded in <span class="math inline">\([-1, 1]\)</span> because of the cosine.</p>
261
- <section id="chebyshev-nodes-of-the-first-kind" class="level2">
262
- <h2 class="anchored" data-anchor-id="chebyshev-nodes-of-the-first-kind">Chebyshev Nodes of the First Kind</h2>
263
- <p>Before we continue with exploring the roots of the polynomials, let’s recall some trigonometry.</p>
264
- <hr>
265
- <p>The <strong>unit circle</strong> is a circle with a radius of 1, centered at the origin of the Cartesian coordinate system. Below is shown part of the unit circle corresponding to the region from <span class="math inline">\(0\)</span> to <span class="math inline">\(\frac{\pi}{2}\)</span>.</p>
266
- <div class="quarto-figure quarto-figure-center">
267
- <figure class="figure">
268
- <p><img src="images/unit_circle.svg" class="img-fluid figure-img"></p>
269
- <figcaption>Figure 1. Unit circle from <span class="math inline">\(0\)</span> to <span class="math inline">\(\frac{\pi}{2}\)</span></figcaption>
270
- </figure>
271
- </div>
272
- <p>The cosine of an angle <span class="math inline">\(\theta\)</span> corresponds to the <span class="math inline">\(x\)</span>-coordinate of the point where the terminal side of the angle (measured counterclockwise from the positive <span class="math inline">\(x\)</span>-axis) intersects the unit circle. In other words, <span class="math inline">\(\cos(\theta)\)</span> gives the horizontal distance from the origin to this intersection point.</p>
273
- <p>The <strong>arccosine</strong> is the inverse function of cosine, and it maps a cosine value back to its corresponding angle in the range <span class="math inline">\([0, \pi]\)</span> radians. For a given <span class="math inline">\(x\)</span>-coordinate on the unit circle, the arccosine gives the angle <span class="math inline">\(\theta\)</span> such that <span class="math inline">\(\cos(\theta) = x\)</span>, meaning</p>
274
- <p><span class="math display">\[
275
- \arccos(x) = \theta, \quad \text{where } \theta \in [0, \pi].
276
- \]</span></p>
277
- <p>Moreover, a <strong>radian</strong> is defined as the angle subtended at the center of a circle by an arc whose length is equal to the radius of the circle. For any circle, the length of an arc <span class="math inline">\(s\)</span> is given by</p>
278
- <p><span class="math display">\[
279
- s = r \cdot \theta,
280
- \]</span></p>
281
- <p>where <span class="math inline">\(r\)</span> is the radius of the circle, <span class="math inline">\(\theta\)</span> is the angle subtended by the arc at the center. This means that on the unit circle the length of the arc equals the measure of the angle in radians because <span class="math inline">\(r = 1\)</span>, and hence</p>
282
- <p><span class="math display">\[
283
- s = \theta.
284
- \]</span></p>
285
- <hr>
286
- <p>Now, let’s find the roots of the polynomial <span class="math inline">\(T_{n}(x)\)</span>. If we take the definition in <span class="math inline">\(\eqref{eq:1}\)</span> we have to solve</p>
287
- <p><span class="math display">\[
288
- \cos{\left(n \arccos{x}\right)} = 0, k \in N.
289
- \]</span></p>
290
- <p>The solutions in the interval <span class="math inline">\((-1, 1)\)</span> are given by</p>
291
- <p><span class="math display">\[
292
- x_k = \cos{\left(\frac{2k - 1}{2n}\pi\right)}, n \in N, k = 1, 2, ...n.
293
- \]</span></p>
294
- <p>These roots are known as the <strong>Chebyshev nodes of the first kind</strong>, or the <strong>Chebyshev zeros</strong>. If we are working with an arbitrary interval <span class="math inline">\((a, b)\)</span> the affine transformation</p>
295
- <p><span class="math display">\[
296
- x_k = \frac{a + b}{2} + \frac{b - a}{2}\cos{\left(\frac{2k - 1}{2n}\pi\right)}, n \in N, k = 1, 2, ...n
297
- \]</span></p>
298
- <p>is needed. From the cosine properties we can also note that the nodes are symmetric with respect to the midpoint of the interval, and that the extrema of <span class="math inline">\(T_n(x)\)</span> over the interval <span class="math inline">\([-1, 1]\)</span> alternate between <span class="math inline">\(-1\)</span> and <span class="math inline">\(1\)</span>. Also, a very useful fact is that these nodes are used in polynomial interpolation to minimize the <strong>Runge phenomenon</strong>.</p>
299
- <p>In the figure below we have shown the roots of <span class="math inline">\(T_{8}(x)\)</span> in blue. We have also built the perpendiculars from the roots to their interesction with the upper half of the unit circle, and marked these points in red.</p>
300
- <p><img src="images/chebyshev_nodes_visualization.svg" class="img-fluid" style="width:45.0%" alt="Tester"><img src="images/chebyshev_nodes.png" class="img-fluid" style="width:45.0%" alt="alt text"></p>
301
- <p>Looking at the figure we can notice that the arc lengths between the red points seem to be of the same length. Let’s show that this is indeed the truth.</p>
302
- <p>We showed the roots are the cosine functions <span class="math inline">\(\cos{\left(\frac{2k - 1}{2n}\pi\right)}, n \in N, k = 1, 2, ...n\)</span>. Thus, in the unit circle we have that the length of the corresponding arcs are equal to <span class="math inline">\(\left( \frac{2k - 1}{2n}\pi \right), n \in N, k = 1, 2, ...n\)</span>. Let’s take two red points which are direct neighbours, or in other words let’s take two red points corresponding to the randomly chosen <span class="math inline">\(m\)</span> and <span class="math inline">\(m + 1\)</span> roots, <span class="math inline">\(m \in k = \{1, 2, ..., n\}\)</span>. If we subtract them we are going to determine the length of the arc between them. We have</p>
303
- <p><span class="math display">\[
304
- \frac{2(m + 1) - 1}{2n}\pi - \frac{2m - 1}{2n}\pi = \frac{\pi}{n},
305
- \]</span></p>
306
- <p>meaning that between every two nodes the arc length is equal and has a value of <span class="math inline">\(\frac{\pi}{n}\)</span>. A polynomial of degree <span class="math inline">\(n\)</span> has <span class="math inline">\(n\)</span> roots, which in our case are in the open interval <span class="math inline">\((-1, 1)\)</span>, meaning the arcs corresponding to every two neighbouring roots are <span class="math inline">\(n - 1\)</span>, and the two arcs between the <span class="math inline">\(x\)</span>-axis and the first and last roots due to the symmetry of roots have lenghts of</p>
307
- <p><span class="math display">\[
308
- \frac{1}{2}\left(\pi - \frac{n-1}{n}\pi\right) = \frac{\pi}{2n}.
309
- \]</span></p>
310
- </section>
311
- <section id="recurrence-relation" class="level2">
312
- <h2 class="anchored" data-anchor-id="recurrence-relation">Recurrence relation</h2>
313
- <p>This is probably a bit out of nowhere, but let’s take a look at the following trigonometric identity</p>
314
- <p><span class="math display">\[\label{eq:4}
315
- \cos{\left((n + 1)\theta\right)} + \cos{\left((n - 1)\theta\right)} = 2 \cos{(\theta)} \cos{(n\theta)},\tag{4}
316
- \]</span></p>
317
- <p>and show that the left side indeed is equal to the right one. We are going to need the following two fundamental formulas of angle addition in trigonometry</p>
318
- <p><span class="math display">\[
319
- \cos{(\alpha + \beta)} = \cos{\alpha} \cos{\beta} - \sin{\alpha} \sin{\beta},
320
- \]</span></p>
321
- <p>and</p>
322
- <p><span class="math display">\[
323
- \cos{(\alpha - \beta)} = \cos{\alpha} \cos{\beta} + \sin{\alpha} \sin{\beta}.
324
- \]</span></p>
325
- <p>In our case we have</p>
326
- <p><span class="math display">\[
327
- \cos{\left((n + 1)\theta\right)} = \cos{\left(n\theta + \theta\right)} = \cos{(n\theta)} \cos{\theta} - \sin{(n\theta)} \sin{\theta},
328
- \]</span></p>
329
- <p>and</p>
330
- <p><span class="math display">\[
331
- \cos{\left((n - 1)\theta\right)} = \cos{\left(n\theta - \theta\right)} = \cos{(n\theta)} \cos{\theta} + \sin{(n\theta)} \sin{\theta}.
332
- \]</span></p>
333
- <p>Adding the above equations leads to the wanted result.</p>
334
- <p>Now, we can see that the terms of <span class="math inline">\(\eqref{eq:4}\)</span> are exactly in the form of the right side of <span class="math inline">\(\eqref{eq:1}\)</span>, <span class="math inline">\(\eqref{eq:3}\)</span>, hence we get</p>
335
- <p><span class="math display">\[
336
- T_{n + 1}(x) + T_{n - 1}(x) = 2T_{n}(x)T_{1}(x),
337
- \]</span></p>
338
- <p>or we get the useful <strong>recurrence relation</strong></p>
339
- <p><span class="math display">\[\label{eq:5}
340
- T_{n + 1}(x) - 2xT_{n}(x) + T_{n - 1}(x) = 0.\tag{5}
341
- \]</span></p>
342
- <p>This relation along with adding <span class="math inline">\(T_{0}(x) = 1\)</span> and <span class="math inline">\(T_{1}(x) = x\)</span> is another famous way to define the Chebyshev polynomials of the first kind, or</p>
343
- <p><span class="math display">\[
344
- \left\{\begin{align*}
345
- T_{0}(x) = 1, \\
346
- T_{1}(x) = x, \\
347
- T_{n + 1}(x) - 2xT_{n}(x) + T_{n - 1}(x) = 0.
348
- \end{align*}\right.\label{eq:6}\tag{6}
349
- \]</span></p>
350
- <p>Let’s write the first <span class="math inline">\(6\)</span> polynomials by using <span class="math inline">\(\eqref{eq:6}\)</span>:</p>
351
- <p><span class="math display">\[
352
- \left\{\begin{align*}
353
- T_{0}(x) = 1, \quad \text{(even)}\\
354
- T_{1}(x) = x, \quad \text{(odd)}\\
355
- T_{2}(x) = 2x^2 - 1, \quad \text{(even)}\\
356
- T_{3}(x) = 4x^3 - 3x, \quad \text{(odd)}\\
357
- T_{4}(x) = 8x^4 - 8x^2 + 1, \quad \text{(even)}\\
358
- T_{5}(x) = 16x^5 - 20x^3 + 5x. \quad \text{(odd)}
359
- \end{align*}\right.
360
- \]</span></p>
361
- <p>We can notice that</p>
362
- <p><span class="math display">\[
363
- T_{k}(x) = 2^{k-1}x^k + ...,
364
- \]</span></p>
365
- <p>and <span class="math inline">\(T_{k}(x)\)</span> is alternating between an even and an odd polynomial depending on whether <span class="math inline">\(k\)</span> is even or odd respectively.</p>
366
- <p>Before we continue with some visualisations and more facts, let’s mention that an interesting way to represent the recurrence relation <span class="math inline">\(\eqref{eq:5}\)</span> is via the determinant</p>
367
- <p><span class="math display">\[
368
- T_{k}(x) = \det \begin{bmatrix}
369
- x &amp; 1 &amp; 0 &amp; \dots &amp; 0 \\
370
- 1 &amp; 2x &amp; 1 &amp; \ddots &amp; \vdots \\
371
- 0 &amp; 1 &amp; 2x &amp; \ddots &amp; 0 \\
372
- \vdots &amp; \ddots &amp; \ddots &amp; \ddots &amp; 1 \\
373
- 0 &amp; \dots &amp; 0 &amp; 1 &amp; 2x
374
- \end{bmatrix}.
375
- \]</span></p>
376
- <p>Now, let’s visualise the first <span class="math inline">\(8\)</span> polynomials.</p>
377
- <div class="quarto-figure quarto-figure-center">
378
- <figure class="figure">
379
- <p><img src="images/chebyshev_polynomials.png" class="img-fluid figure-img"></p>
380
- <figcaption>Chebyshev Polynomials</figcaption>
381
- </figure>
382
- </div>
383
- <p>But what can we notice if we stack them together?</p>
384
- <div class="quarto-figure quarto-figure-center">
385
- <figure class="figure">
386
- <p><img src="images/chebyshev_polynomials_stacked.png" class="img-fluid figure-img"></p>
387
- <figcaption>Chebyshev Polynomials Stacked</figcaption>
388
- </figure>
389
- </div>
390
- <p>It is quite obvious that at the roots of the <span class="math inline">\(N\)</span>-th Chebyshev polynomial there is an <strong>aliasing</strong> effect, meaning higher order polynomials look like lower order ones. We can formally show it by fixing <span class="math inline">\(N\)</span>, at the roots <span class="math inline">\(x_k\)</span> of <span class="math inline">\(T_{N}(x) = 0\)</span>, and using the Chebyshev identity</p>
391
- <p><span class="math display">\[
392
- \cos{\left((m + N)\theta\right)} + \cos{\left((m - N)\theta\right)} = 2\cos{(m\theta)}\cos{(N\theta)},
393
- \]</span></p>
394
- <p>or equivalently</p>
395
- <p><span class="math display">\[
396
- T_{m + N}(x) + T_{m - N}(x) = 2T_{m}(x)T_{N}(x).
397
- \]</span></p>
398
- <p>Now, having <span class="math inline">\(T_{N}(x) = 0\)</span> leads to</p>
399
- <p><span class="math display">\[
400
- T_{m + N}(x) = -T_{m - N}(x).
401
- \]</span></p>
402
- <p>If we consecutevly set <span class="math inline">\(m = N\)</span>, <span class="math inline">\(m = 2N\)</span>, …, <span class="math inline">\(m = 6N\)</span>, etc. we would get</p>
403
- <p><span class="math display">\[
404
- \left\{\begin{align*}
405
- T_{2N}(x_k) = -T_{0}(x_k) = -1, \\
406
- T_{3N}(x_k) = 0, \\
407
- T_{4N}(x_k) = 1, \\
408
- T_{5N}(x_k) = 0, \\
409
- T_{6N}(x_k) = -1, \\
410
- \text{etc}.
411
- \end{align*}\right.
412
- \]</span></p>
413
- <p>We can safely say that any higher-order Chebyshev polynomial <span class="math inline">\(T_{N}(x)\)</span> can be reduced to a lower-order <span class="math inline">\(j, 0 \leq j \leq N\)</span> Chebyshev polynomial at the sample points <span class="math inline">\(x_k\)</span> which are the roots of <span class="math inline">\(T_{N}(x)\)</span>. In the figure below we attempt to visualise this statement.</p>
414
- <div class="quarto-figure quarto-figure-center">
415
- <figure class="figure">
416
- <p><img src="images/reduction.svg" class="img-fluid figure-img"></p>
417
- <figcaption>alt text</figcaption>
418
- </figure>
419
- </div>
420
- <p>The horizontal axis represents the order of Chebyshev polynomials, and the blue wavy line represents a “folded ribbon”. Think of it as taking the sequence of polynomial orders and folding it back and forth. This folding happens at specific points where higher-order polynomials can be reduced to lower-order ones, which are the red <strong>x</strong> marks showing the sample points: the roots of <span class="math inline">\(T_n(x)\)</span>. The key insight is that at these special sample points, we don’t need to work with the higher-order polynomials because we can use equivalent lower-order ones instead. This is incredibly useful in numerical computations as it can help reduce computational complexity, and makes the Chebyshev polynomials very computationally efficient.</p>
421
- <p>Let’s illustarte this with a simple example. Let <span class="math inline">\(N = 2\)</span>, then for even <span class="math inline">\(m\)</span> we have</p>
422
- <p><span class="math display">\[
423
- \left\{\begin{align*}
424
- T_{4}(x_k) = -T_{0}(x_k) = -1, \\
425
- T_{6}(x_k) = - T_{2}(x_k) = 0, \\
426
- T_{8}(x_k) = - T_{4}(x_k) = 1, \\
427
- T_{10}(x_k) = -T_{6}(x_k) = 0, \\
428
- \text{etc}.
429
- \end{align*}\right.
430
- \]</span></p>
431
- <p>In the figure below we can see the even polynomials and that indeed <span class="math inline">\(T_{10}(x)\)</span> behaves like <span class="math inline">\(-T_{6}(x)\)</span> which behaves like <span class="math inline">\(T_{2}(x)\)</span> at the roots having value <span class="math inline">\(0\)</span>, <span class="math inline">\(T_{8}(x)\)</span> behaves like <span class="math inline">\(-T_{4}(x)\)</span> at the roots with value <span class="math inline">\(1\)</span> as in <span class="math inline">\(T_{0}(x)\)</span>, <span class="math inline">\(T_{6}(x)\)</span> behaves like <span class="math inline">\(-T_{2}(x)\)</span> with value <span class="math inline">\(0\)</span>, and <span class="math inline">\(T_{4}(x)\)</span> behaves like <span class="math inline">\(-T_{0}(x)\)</span> with value <span class="math inline">\(-1\)</span>.</p>
432
- <div id="be218886" class="cell" data-execution_count="1">
433
- <details class="code-fold">
434
- <summary>Click to expand the code</summary>
435
- <div class="sourceCode cell-code" id="cb1"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> typing <span class="im">import</span> Union</span>
436
- <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
437
- <span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> matplotlib.pyplot <span class="im">as</span> plt</span>
438
- <span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> numpy <span class="im">as</span> np</span>
439
- <span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
440
- <span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
441
- <span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> chebyshev_polynomial(</span>
442
- <span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a> n: <span class="bu">int</span>, x: Union[<span class="bu">float</span>, np.ndarray]</span>
443
- <span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>) <span class="op">-&gt;</span> Union[<span class="bu">float</span>, np.ndarray]:</span>
444
- <span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a> <span class="co">"""</span></span>
445
- <span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="co"> Calculate nth Chebyshev polynomial of the first kind T_n(x).</span></span>
446
- <span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a></span>
447
- <span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="co"> Args:</span></span>
448
- <span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="co"> n: Order of polynomial (non-negative integer)</span></span>
449
- <span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="co"> x: Point(s) at which to evaluate polynomial</span></span>
450
- <span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a></span>
451
- <span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="co"> Returns:</span></span>
452
- <span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="co"> Value of T_n(x)</span></span>
453
- <span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="co"> """</span></span>
454
- <span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> n <span class="op">&lt;</span> <span class="dv">0</span>:</span>
455
- <span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">ValueError</span>(<span class="st">"Order must be non-negative"</span>)</span>
456
- <span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a></span>
457
- <span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> n <span class="op">==</span> <span class="dv">0</span>:</span>
458
- <span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> np.ones_like(x)</span>
459
- <span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> n <span class="op">==</span> <span class="dv">1</span>:</span>
460
- <span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> x</span>
461
- <span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span>
462
- <span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a> t_prev <span class="op">=</span> np.ones_like(x) <span class="co"># T_0</span></span>
463
- <span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a> t_curr <span class="op">=</span> x <span class="co"># T_1</span></span>
464
- <span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a></span>
465
- <span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> _ <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">2</span>, n <span class="op">+</span> <span class="dv">1</span>):</span>
466
- <span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a> t_next <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> x <span class="op">*</span> t_curr <span class="op">-</span> t_prev</span>
467
- <span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a> t_prev <span class="op">=</span> t_curr</span>
468
- <span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a> t_curr <span class="op">=</span> t_next</span>
469
- <span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a></span>
470
- <span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> t_curr</span>
471
- <span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a></span>
472
- <span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a></span>
473
- <span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> chebyshev_nodes(n):</span>
474
- <span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a> <span class="co">"""Generate n Chebyshev nodes in [-1,1]"""</span></span>
475
- <span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a> k <span class="op">=</span> np.arange(<span class="dv">1</span>, n <span class="op">+</span> <span class="dv">1</span>)</span>
476
- <span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> np.cos((<span class="dv">2</span> <span class="op">*</span> k <span class="op">-</span> <span class="dv">1</span>) <span class="op">*</span> np.pi <span class="op">/</span> (<span class="dv">2</span> <span class="op">*</span> n))</span>
477
- <span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a></span>
478
- <span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a></span>
479
- <span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
480
- <span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a></span>
481
- <span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a> x <span class="op">=</span> np.linspace(<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>, <span class="dv">1000</span>)</span>
482
- <span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a> plt.figure(figsize<span class="op">=</span>(<span class="dv">12</span>, <span class="dv">6</span>))</span>
483
- <span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a> plt.plot(x, <span class="op">-</span>chebyshev_polynomial(<span class="dv">0</span>, x), <span class="st">"--"</span>, label<span class="op">=</span><span class="ss">f"-T_</span><span class="sc">{</span><span class="dv">0</span><span class="sc">}</span><span class="ss">(x)"</span>, alpha<span class="op">=</span><span class="fl">0.5</span>)</span>
484
- <span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> n <span class="kw">in</span> [<span class="dv">0</span>, <span class="dv">2</span>, <span class="dv">4</span>, <span class="dv">6</span>, <span class="dv">8</span>, <span class="dv">10</span>]:</span>
485
- <span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a> y <span class="op">=</span> chebyshev_polynomial(n, x)</span>
486
- <span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a> plt.plot(x, y, label<span class="op">=</span><span class="ss">f"T_</span><span class="sc">{</span>n<span class="sc">}</span><span class="ss">(x)"</span>)</span>
487
- <span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a></span>
488
- <span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a> <span class="co"># plot nodes for n = 2</span></span>
489
- <span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a> n <span class="op">=</span> <span class="dv">2</span></span>
490
- <span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a> nodes <span class="op">=</span> chebyshev_nodes(n)</span>
491
- <span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a> y_nodes <span class="op">=</span> np.cos(n <span class="op">*</span> np.arccos(nodes))</span>
492
- <span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a> plt.plot(nodes, np.zeros_like(nodes), <span class="st">"bo"</span>, label<span class="op">=</span><span class="st">"T_2(x) roots"</span>)</span>
493
- <span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> node <span class="kw">in</span> nodes:</span>
494
- <span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a> plt.plot([node, node], [<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>], <span class="st">"--"</span>, color<span class="op">=</span><span class="st">"gray"</span>, alpha<span class="op">=</span><span class="fl">0.5</span>)</span>
495
- <span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a></span>
496
- <span id="cb1-62"><a href="#cb1-62" aria-hidden="true" tabindex="-1"></a> <span class="co"># plt.grid(True)</span></span>
497
- <span id="cb1-63"><a href="#cb1-63" aria-hidden="true" tabindex="-1"></a> <span class="co"># Set aspect ratio to be equal</span></span>
498
- <span id="cb1-64"><a href="#cb1-64" aria-hidden="true" tabindex="-1"></a> <span class="co"># plt.gca().set_aspect('equal', adjustable='box')</span></span>
499
- <span id="cb1-65"><a href="#cb1-65" aria-hidden="true" tabindex="-1"></a> plt.xlabel(<span class="st">"x"</span>)</span>
500
- <span id="cb1-66"><a href="#cb1-66" aria-hidden="true" tabindex="-1"></a> plt.ylabel(<span class="st">"T_n(x)"</span>)</span>
501
- <span id="cb1-67"><a href="#cb1-67" aria-hidden="true" tabindex="-1"></a> plt.title(<span class="st">"Chebyshev Polynomials Aliasing"</span>)</span>
502
- <span id="cb1-68"><a href="#cb1-68" aria-hidden="true" tabindex="-1"></a> plt.legend(loc<span class="op">=</span><span class="st">"center left"</span>, bbox_to_anchor<span class="op">=</span>(<span class="dv">1</span>, <span class="fl">0.5</span>), fontsize<span class="op">=</span><span class="dv">8</span>)</span>
503
- <span id="cb1-69"><a href="#cb1-69" aria-hidden="true" tabindex="-1"></a> plt.xlim(<span class="op">-</span><span class="fl">1.1</span>, <span class="fl">1.1</span>)</span>
504
- <span id="cb1-70"><a href="#cb1-70" aria-hidden="true" tabindex="-1"></a> plt.ylim(<span class="op">-</span><span class="fl">1.1</span>, <span class="fl">1.1</span>)</span>
505
- <span id="cb1-71"><a href="#cb1-71" aria-hidden="true" tabindex="-1"></a> plt.axhline(y<span class="op">=</span><span class="dv">0</span>, color<span class="op">=</span><span class="st">"k"</span>, linestyle<span class="op">=</span><span class="st">"-"</span>, alpha<span class="op">=</span><span class="fl">0.7</span>)</span>
506
- <span id="cb1-72"><a href="#cb1-72" aria-hidden="true" tabindex="-1"></a> plt.savefig(</span>
507
- <span id="cb1-73"><a href="#cb1-73" aria-hidden="true" tabindex="-1"></a> <span class="st">"content/images/2025-01-06-chebyshev-polynomials/chebyshev_polynomials_aliasing_even.png"</span></span>
508
- <span id="cb1-74"><a href="#cb1-74" aria-hidden="true" tabindex="-1"></a> )</span>
509
- <span id="cb1-75"><a href="#cb1-75" aria-hidden="true" tabindex="-1"></a> plt.show()</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
510
- </details>
511
- </div>
512
- <div class="quarto-figure quarto-figure-center">
513
- <figure class="figure">
514
- <p><img src="images/chebyshev_polynomials_aliasing_even.png" class="img-fluid figure-img"></p>
515
- <figcaption>alt text</figcaption>
516
- </figure>
517
- </div>
518
- <p>For odd <span class="math inline">\(m\)</span> we have <span class="math display">\[
519
- \left\{\begin{align*}
520
- T_{3}(x_k) = - T_{1}(x_k) = - x\\
521
- T_{5}(x_k) = - T_{3}(x_k) = x\\
522
- T_{7}(x_k) = - T_{5}(x_k) = -x, \\
523
- T_{9}(x_k) = - T_{7}(x_k) = x, \\
524
- \text{etc}.
525
- \end{align*}\right.
526
- \]</span></p>
527
- <p>In the figure below we can see the odd polynomials and the aliasing as in the previous example.</p>
528
- <div id="54809f08" class="cell" data-execution_count="2">
529
- <details class="code-fold">
530
- <summary>Click to expand the code</summary>
531
- <div class="sourceCode cell-code" id="cb2"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> typing <span class="im">import</span> Union</span>
532
- <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
533
- <span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> matplotlib.pyplot <span class="im">as</span> plt</span>
534
- <span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> numpy <span class="im">as</span> np</span>
535
- <span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
536
- <span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
537
- <span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> chebyshev_polynomial(</span>
538
- <span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> n: <span class="bu">int</span>, x: Union[<span class="bu">float</span>, np.ndarray]</span>
539
- <span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>) <span class="op">-&gt;</span> Union[<span class="bu">float</span>, np.ndarray]:</span>
540
- <span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a> <span class="co">"""</span></span>
541
- <span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="co"> Calculate nth Chebyshev polynomial of the first kind T_n(x).</span></span>
542
- <span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a></span>
543
- <span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="co"> Args:</span></span>
544
- <span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="co"> n: Order of polynomial (non-negative integer)</span></span>
545
- <span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="co"> x: Point(s) at which to evaluate polynomial</span></span>
546
- <span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a></span>
547
- <span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="co"> Returns:</span></span>
548
- <span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a><span class="co"> Value of T_n(x)</span></span>
549
- <span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a><span class="co"> """</span></span>
550
- <span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> n <span class="op">&lt;</span> <span class="dv">0</span>:</span>
551
- <span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">ValueError</span>(<span class="st">"Order must be non-negative"</span>)</span>
552
- <span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a></span>
553
- <span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> n <span class="op">==</span> <span class="dv">0</span>:</span>
554
- <span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> np.ones_like(x)</span>
555
- <span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> n <span class="op">==</span> <span class="dv">1</span>:</span>
556
- <span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> x</span>
557
- <span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span>
558
- <span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a> t_prev <span class="op">=</span> np.ones_like(x) <span class="co"># T_0</span></span>
559
- <span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a> t_curr <span class="op">=</span> x <span class="co"># T_1</span></span>
560
- <span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a></span>
561
- <span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> _ <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">2</span>, n <span class="op">+</span> <span class="dv">1</span>):</span>
562
- <span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a> t_next <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> x <span class="op">*</span> t_curr <span class="op">-</span> t_prev</span>
563
- <span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a> t_prev <span class="op">=</span> t_curr</span>
564
- <span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a> t_curr <span class="op">=</span> t_next</span>
565
- <span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a></span>
566
- <span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> t_curr</span>
567
- <span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a></span>
568
- <span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a></span>
569
- <span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> chebyshev_nodes(n):</span>
570
- <span id="cb2-40"><a href="#cb2-40" aria-hidden="true" tabindex="-1"></a> <span class="co">"""Generate n Chebyshev nodes in [-1,1]"""</span></span>
571
- <span id="cb2-41"><a href="#cb2-41" aria-hidden="true" tabindex="-1"></a> k <span class="op">=</span> np.arange(<span class="dv">1</span>, n <span class="op">+</span> <span class="dv">1</span>)</span>
572
- <span id="cb2-42"><a href="#cb2-42" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> np.cos((<span class="dv">2</span> <span class="op">*</span> k <span class="op">-</span> <span class="dv">1</span>) <span class="op">*</span> np.pi <span class="op">/</span> (<span class="dv">2</span> <span class="op">*</span> n))</span>
573
- <span id="cb2-43"><a href="#cb2-43" aria-hidden="true" tabindex="-1"></a></span>
574
- <span id="cb2-44"><a href="#cb2-44" aria-hidden="true" tabindex="-1"></a></span>
575
- <span id="cb2-45"><a href="#cb2-45" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
576
- <span id="cb2-46"><a href="#cb2-46" aria-hidden="true" tabindex="-1"></a></span>
577
- <span id="cb2-47"><a href="#cb2-47" aria-hidden="true" tabindex="-1"></a> x <span class="op">=</span> np.linspace(<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>, <span class="dv">1000</span>)</span>
578
- <span id="cb2-48"><a href="#cb2-48" aria-hidden="true" tabindex="-1"></a> plt.figure(figsize<span class="op">=</span>(<span class="dv">12</span>, <span class="dv">6</span>))</span>
579
- <span id="cb2-49"><a href="#cb2-49" aria-hidden="true" tabindex="-1"></a> plt.plot(x, <span class="op">-</span>chebyshev_polynomial(<span class="dv">1</span>, x), <span class="st">"--"</span>, label<span class="op">=</span><span class="ss">f"-T_</span><span class="sc">{</span><span class="dv">1</span><span class="sc">}</span><span class="ss">(x)"</span>, alpha<span class="op">=</span><span class="fl">0.5</span>)</span>
580
- <span id="cb2-50"><a href="#cb2-50" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> n <span class="kw">in</span> [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">5</span>, <span class="dv">7</span>, <span class="dv">9</span>]:</span>
581
- <span id="cb2-51"><a href="#cb2-51" aria-hidden="true" tabindex="-1"></a> y <span class="op">=</span> chebyshev_polynomial(n, x)</span>
582
- <span id="cb2-52"><a href="#cb2-52" aria-hidden="true" tabindex="-1"></a> plt.plot(x, y, label<span class="op">=</span><span class="ss">f"T_</span><span class="sc">{</span>n<span class="sc">}</span><span class="ss">(x)"</span>)</span>
583
- <span id="cb2-53"><a href="#cb2-53" aria-hidden="true" tabindex="-1"></a></span>
584
- <span id="cb2-54"><a href="#cb2-54" aria-hidden="true" tabindex="-1"></a> <span class="co"># plot nodes for n = 2</span></span>
585
- <span id="cb2-55"><a href="#cb2-55" aria-hidden="true" tabindex="-1"></a> n <span class="op">=</span> <span class="dv">2</span></span>
586
- <span id="cb2-56"><a href="#cb2-56" aria-hidden="true" tabindex="-1"></a> nodes <span class="op">=</span> chebyshev_nodes(n)</span>
587
- <span id="cb2-57"><a href="#cb2-57" aria-hidden="true" tabindex="-1"></a> y_nodes <span class="op">=</span> np.cos(n <span class="op">*</span> np.arccos(nodes))</span>
588
- <span id="cb2-58"><a href="#cb2-58" aria-hidden="true" tabindex="-1"></a> plt.plot(nodes, np.zeros_like(nodes), <span class="st">"bo"</span>, label<span class="op">=</span><span class="st">"T_2(x) roots"</span>)</span>
589
- <span id="cb2-59"><a href="#cb2-59" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> node <span class="kw">in</span> nodes:</span>
590
- <span id="cb2-60"><a href="#cb2-60" aria-hidden="true" tabindex="-1"></a> plt.plot([node, node], [<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>], <span class="st">"--"</span>, color<span class="op">=</span><span class="st">"gray"</span>, alpha<span class="op">=</span><span class="fl">0.5</span>)</span>
591
- <span id="cb2-61"><a href="#cb2-61" aria-hidden="true" tabindex="-1"></a></span>
592
- <span id="cb2-62"><a href="#cb2-62" aria-hidden="true" tabindex="-1"></a> <span class="co"># plt.grid(True)</span></span>
593
- <span id="cb2-63"><a href="#cb2-63" aria-hidden="true" tabindex="-1"></a> <span class="co"># Set aspect ratio to be equal</span></span>
594
- <span id="cb2-64"><a href="#cb2-64" aria-hidden="true" tabindex="-1"></a> <span class="co"># plt.gca().set_aspect('equal', adjustable='box')</span></span>
595
- <span id="cb2-65"><a href="#cb2-65" aria-hidden="true" tabindex="-1"></a> plt.xlabel(<span class="st">"x"</span>)</span>
596
- <span id="cb2-66"><a href="#cb2-66" aria-hidden="true" tabindex="-1"></a> plt.ylabel(<span class="st">"T_n(x)"</span>)</span>
597
- <span id="cb2-67"><a href="#cb2-67" aria-hidden="true" tabindex="-1"></a> plt.title(<span class="st">"Chebyshev Polynomials Aliasing"</span>)</span>
598
- <span id="cb2-68"><a href="#cb2-68" aria-hidden="true" tabindex="-1"></a> plt.legend(loc<span class="op">=</span><span class="st">"center left"</span>, bbox_to_anchor<span class="op">=</span>(<span class="dv">1</span>, <span class="fl">0.5</span>), fontsize<span class="op">=</span><span class="dv">8</span>)</span>
599
- <span id="cb2-69"><a href="#cb2-69" aria-hidden="true" tabindex="-1"></a> plt.xlim(<span class="op">-</span><span class="fl">1.1</span>, <span class="fl">1.1</span>)</span>
600
- <span id="cb2-70"><a href="#cb2-70" aria-hidden="true" tabindex="-1"></a> plt.ylim(<span class="op">-</span><span class="fl">1.1</span>, <span class="fl">1.1</span>)</span>
601
- <span id="cb2-71"><a href="#cb2-71" aria-hidden="true" tabindex="-1"></a> plt.axhline(y<span class="op">=</span><span class="dv">0</span>, color<span class="op">=</span><span class="st">"k"</span>, linestyle<span class="op">=</span><span class="st">"-"</span>, alpha<span class="op">=</span><span class="fl">0.7</span>)</span>
602
- <span id="cb2-72"><a href="#cb2-72" aria-hidden="true" tabindex="-1"></a> plt.savefig(</span>
603
- <span id="cb2-73"><a href="#cb2-73" aria-hidden="true" tabindex="-1"></a> <span class="st">"content/images/2025-01-06-chebyshev-polynomials/chebyshev_polynomials_aliasing_odd.png"</span></span>
604
- <span id="cb2-74"><a href="#cb2-74" aria-hidden="true" tabindex="-1"></a> )</span>
605
- <span id="cb2-75"><a href="#cb2-75" aria-hidden="true" tabindex="-1"></a> plt.show()</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
606
- </details>
607
- </div>
608
- <div class="quarto-figure quarto-figure-center">
609
- <figure class="figure">
610
- <p><img src="images/chebyshev_polynomials_aliasing_odd.png" class="img-fluid figure-img"></p>
611
- <figcaption>alt text</figcaption>
612
- </figure>
613
- </div>
614
- </section>
615
- <section id="radial-plots" class="level2">
616
- <h2 class="anchored" data-anchor-id="radial-plots">Radial Plots</h2>
617
- <p>An interesting plot can be observed by plotting <span class="math inline">\(T_n(x)\)</span> radially. This means that instead of evaluating the polynomials over <span class="math inline">\([-1, 1]\)</span> in a Cartesian plane we are evaluating them at <span class="math inline">\(\frac{\theta}{\pi} - 1\)</span>, and plotting <span class="math inline">\(r = n + T_n(\frac{\theta}{\pi} - 1)\)</span> on polar axes. In other words, the input domain has been shifted and extended, and the results are drawn as radial distances <span class="math inline">\(r\)</span> around a circle defined by <span class="math inline">\(\theta\)</span>. This creates a polar visualization where each <span class="math inline">\(n\)</span> produces a distinct spiral-like ornament. We are also filling in the areas between the curves for a visual effect.</p>
618
- <div id="b2db675f" class="cell" data-execution_count="3">
619
- <details class="code-fold">
620
- <summary>Click to expand the code</summary>
621
- <div class="sourceCode cell-code" id="cb3"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> matplotlib.pyplot <span class="im">as</span> plt</span>
622
- <span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> numpy <span class="im">as</span> np</span>
623
- <span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> numpy.polynomial.chebyshev <span class="im">import</span> Chebyshev</span>
624
- <span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
625
- <span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>theta <span class="op">=</span> np.linspace(<span class="dv">0</span>, <span class="dv">2</span> <span class="op">*</span> np.pi, <span class="dv">2000</span>)</span>
626
- <span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>fig, ax <span class="op">=</span> plt.subplots(subplot_kw<span class="op">=</span>{<span class="st">"projection"</span>: <span class="st">"polar"</span>})</span>
627
- <span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
628
- <span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="co"># Generate and fill between consecutive curves</span></span>
629
- <span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> n <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">0</span>, <span class="dv">19</span> <span class="op">*</span> <span class="dv">2</span>, <span class="dv">2</span>):</span>
630
- <span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a> r1 <span class="op">=</span> n <span class="op">+</span> Chebyshev([<span class="dv">0</span>] <span class="op">*</span> n <span class="op">+</span> [<span class="dv">1</span>])(theta <span class="op">/</span> np.pi <span class="op">-</span> <span class="dv">1</span>)</span>
631
- <span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a> r2 <span class="op">=</span> (n <span class="op">+</span> <span class="dv">2</span>) <span class="op">+</span> Chebyshev([<span class="dv">0</span>] <span class="op">*</span> (n <span class="op">+</span> <span class="dv">2</span>) <span class="op">+</span> [<span class="dv">1</span>])(theta <span class="op">/</span> np.pi <span class="op">-</span> <span class="dv">1</span>)</span>
632
- <span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
633
- <span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a> <span class="co"># Create black and white alternating pattern</span></span>
634
- <span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> n <span class="op">%</span> <span class="dv">4</span> <span class="op">==</span> <span class="dv">0</span>:</span>
635
- <span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a> ax.fill_between(theta, r1, r2, color<span class="op">=</span><span class="st">"black"</span>)</span>
636
- <span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span>
637
- <span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a> ax.fill_between(theta, r1, r2, color<span class="op">=</span><span class="st">"white"</span>)</span>
638
- <span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>ax.set_title(<span class="st">"x = t/π - 1"</span>, y<span class="op">=</span><span class="dv">1</span>)</span>
639
- <span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>plt.axis(<span class="st">"off"</span>)</span>
640
- <span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>plt.show()</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
641
- </details>
642
- </div>
643
- <p><img src="images/polar_init_1.png" class="img-fluid" style="width:50.0%" alt="alt text"><img src="images/polar_init_2.png" class="img-fluid" style="width:41.0%" alt="alt text"></p>
644
- <p>More visualusations can be achieved by doing other domain changes. They can be seen below.</p>
645
- <p><img src="images/polar_0.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_1.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_2.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_3.png" class="img-fluid" style="width:25.0%" alt="alt text"></p>
646
- <p><img src="images/polar_4.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_5.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_6.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_7.png" class="img-fluid" style="width:25.0%" alt="alt text"></p>
647
- <p><img src="images/polar_8.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_9.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_10.png" class="img-fluid" style="width:25.0%" alt="alt text"><img src="images/polar_11.png" class="img-fluid" style="width:25.0%" alt="alt text"></p>
648
- <p>In a separate post, Chebyshev Polynomials, Part 2, we are going to explore the Chebyshev polynomials of the second kind, and their relations to the polynomials of the first kind.</p>
649
-
650
-
651
- </section>
652
- </section>
653
-
654
- </main> <!-- /main -->
655
- <script id="quarto-html-after-body" type="application/javascript">
656
- window.document.addEventListener("DOMContentLoaded", function (event) {
657
- const toggleBodyColorMode = (bsSheetEl) => {
658
- const mode = bsSheetEl.getAttribute("data-mode");
659
- const bodyEl = window.document.querySelector("body");
660
- if (mode === "dark") {
661
- bodyEl.classList.add("quarto-dark");
662
- bodyEl.classList.remove("quarto-light");
663
- } else {
664
- bodyEl.classList.add("quarto-light");
665
- bodyEl.classList.remove("quarto-dark");
666
- }
667
- }
668
- const toggleBodyColorPrimary = () => {
669
- const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
670
- if (bsSheetEl) {
671
- toggleBodyColorMode(bsSheetEl);
672
- }
673
- }
674
- toggleBodyColorPrimary();
675
- const icon = "";
676
- const anchorJS = new window.AnchorJS();
677
- anchorJS.options = {
678
- placement: 'right',
679
- icon: icon
680
- };
681
- anchorJS.add('.anchored');
682
- const isCodeAnnotation = (el) => {
683
- for (const clz of el.classList) {
684
- if (clz.startsWith('code-annotation-')) {
685
- return true;
686
- }
687
- }
688
- return false;
689
- }
690
- const onCopySuccess = function(e) {
691
- // button target
692
- const button = e.trigger;
693
- // don't keep focus
694
- button.blur();
695
- // flash "checked"
696
- button.classList.add('code-copy-button-checked');
697
- var currentTitle = button.getAttribute("title");
698
- button.setAttribute("title", "Copied!");
699
- let tooltip;
700
- if (window.bootstrap) {
701
- button.setAttribute("data-bs-toggle", "tooltip");
702
- button.setAttribute("data-bs-placement", "left");
703
- button.setAttribute("data-bs-title", "Copied!");
704
- tooltip = new bootstrap.Tooltip(button,
705
- { trigger: "manual",
706
- customClass: "code-copy-button-tooltip",
707
- offset: [0, -8]});
708
- tooltip.show();
709
- }
710
- setTimeout(function() {
711
- if (tooltip) {
712
- tooltip.hide();
713
- button.removeAttribute("data-bs-title");
714
- button.removeAttribute("data-bs-toggle");
715
- button.removeAttribute("data-bs-placement");
716
- }
717
- button.setAttribute("title", currentTitle);
718
- button.classList.remove('code-copy-button-checked');
719
- }, 1000);
720
- // clear code selection
721
- e.clearSelection();
722
- }
723
- const getTextToCopy = function(trigger) {
724
- const codeEl = trigger.previousElementSibling.cloneNode(true);
725
- for (const childEl of codeEl.children) {
726
- if (isCodeAnnotation(childEl)) {
727
- childEl.remove();
728
- }
729
- }
730
- return codeEl.innerText;
731
- }
732
- const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
733
- text: getTextToCopy
734
- });
735
- clipboard.on('success', onCopySuccess);
736
- if (window.document.getElementById('quarto-embedded-source-code-modal')) {
737
- const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
738
- text: getTextToCopy,
739
- container: window.document.getElementById('quarto-embedded-source-code-modal')
740
- });
741
- clipboardModal.on('success', onCopySuccess);
742
- }
743
- var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
744
- var mailtoRegex = new RegExp(/^mailto:/);
745
- var filterRegex = new RegExp('/' + window.location.host + '/');
746
- var isInternal = (href) => {
747
- return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
748
- }
749
- // Inspect non-navigation links and adorn them if external
750
- var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
751
- for (var i=0; i<links.length; i++) {
752
- const link = links[i];
753
- if (!isInternal(link.href)) {
754
- // undo the damage that might have been done by quarto-nav.js in the case of
755
- // links that we want to consider external
756
- if (link.dataset.originalHref !== undefined) {
757
- link.href = link.dataset.originalHref;
758
- }
759
- }
760
- }
761
- function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
762
- const config = {
763
- allowHTML: true,
764
- maxWidth: 500,
765
- delay: 100,
766
- arrow: false,
767
- appendTo: function(el) {
768
- return el.parentElement;
769
- },
770
- interactive: true,
771
- interactiveBorder: 10,
772
- theme: 'quarto',
773
- placement: 'bottom-start',
774
- };
775
- if (contentFn) {
776
- config.content = contentFn;
777
- }
778
- if (onTriggerFn) {
779
- config.onTrigger = onTriggerFn;
780
- }
781
- if (onUntriggerFn) {
782
- config.onUntrigger = onUntriggerFn;
783
- }
784
- window.tippy(el, config);
785
- }
786
- const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
787
- for (var i=0; i<noterefs.length; i++) {
788
- const ref = noterefs[i];
789
- tippyHover(ref, function() {
790
- // use id or data attribute instead here
791
- let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
792
- try { href = new URL(href).hash; } catch {}
793
- const id = href.replace(/^#\/?/, "");
794
- const note = window.document.getElementById(id);
795
- if (note) {
796
- return note.innerHTML;
797
- } else {
798
- return "";
799
- }
800
- });
801
- }
802
- const xrefs = window.document.querySelectorAll('a.quarto-xref');
803
- const processXRef = (id, note) => {
804
- // Strip column container classes
805
- const stripColumnClz = (el) => {
806
- el.classList.remove("page-full", "page-columns");
807
- if (el.children) {
808
- for (const child of el.children) {
809
- stripColumnClz(child);
810
- }
811
- }
812
- }
813
- stripColumnClz(note)
814
- if (id === null || id.startsWith('sec-')) {
815
- // Special case sections, only their first couple elements
816
- const container = document.createElement("div");
817
- if (note.children && note.children.length > 2) {
818
- container.appendChild(note.children[0].cloneNode(true));
819
- for (let i = 1; i < note.children.length; i++) {
820
- const child = note.children[i];
821
- if (child.tagName === "P" && child.innerText === "") {
822
- continue;
823
- } else {
824
- container.appendChild(child.cloneNode(true));
825
- break;
826
- }
827
- }
828
- if (window.Quarto?.typesetMath) {
829
- window.Quarto.typesetMath(container);
830
- }
831
- return container.innerHTML
832
- } else {
833
- if (window.Quarto?.typesetMath) {
834
- window.Quarto.typesetMath(note);
835
- }
836
- return note.innerHTML;
837
- }
838
- } else {
839
- // Remove any anchor links if they are present
840
- const anchorLink = note.querySelector('a.anchorjs-link');
841
- if (anchorLink) {
842
- anchorLink.remove();
843
- }
844
- if (window.Quarto?.typesetMath) {
845
- window.Quarto.typesetMath(note);
846
- }
847
- if (note.classList.contains("callout")) {
848
- return note.outerHTML;
849
- } else {
850
- return note.innerHTML;
851
- }
852
- }
853
- }
854
- for (var i=0; i<xrefs.length; i++) {
855
- const xref = xrefs[i];
856
- tippyHover(xref, undefined, function(instance) {
857
- instance.disable();
858
- let url = xref.getAttribute('href');
859
- let hash = undefined;
860
- if (url.startsWith('#')) {
861
- hash = url;
862
- } else {
863
- try { hash = new URL(url).hash; } catch {}
864
- }
865
- if (hash) {
866
- const id = hash.replace(/^#\/?/, "");
867
- const note = window.document.getElementById(id);
868
- if (note !== null) {
869
- try {
870
- const html = processXRef(id, note.cloneNode(true));
871
- instance.setContent(html);
872
- } finally {
873
- instance.enable();
874
- instance.show();
875
- }
876
- } else {
877
- // See if we can fetch this
878
- fetch(url.split('#')[0])
879
- .then(res => res.text())
880
- .then(html => {
881
- const parser = new DOMParser();
882
- const htmlDoc = parser.parseFromString(html, "text/html");
883
- const note = htmlDoc.getElementById(id);
884
- if (note !== null) {
885
- const html = processXRef(id, note);
886
- instance.setContent(html);
887
- }
888
- }).finally(() => {
889
- instance.enable();
890
- instance.show();
891
- });
892
- }
893
- } else {
894
- // See if we can fetch a full url (with no hash to target)
895
- // This is a special case and we should probably do some content thinning / targeting
896
- fetch(url)
897
- .then(res => res.text())
898
- .then(html => {
899
- const parser = new DOMParser();
900
- const htmlDoc = parser.parseFromString(html, "text/html");
901
- const note = htmlDoc.querySelector('main.content');
902
- if (note !== null) {
903
- // This should only happen for chapter cross references
904
- // (since there is no id in the URL)
905
- // remove the first header
906
- if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
907
- note.children[0].remove();
908
- }
909
- const html = processXRef(null, note);
910
- instance.setContent(html);
911
- }
912
- }).finally(() => {
913
- instance.enable();
914
- instance.show();
915
- });
916
- }
917
- }, function(instance) {
918
- });
919
- }
920
- let selectedAnnoteEl;
921
- const selectorForAnnotation = ( cell, annotation) => {
922
- let cellAttr = 'data-code-cell="' + cell + '"';
923
- let lineAttr = 'data-code-annotation="' + annotation + '"';
924
- const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
925
- return selector;
926
- }
927
- const selectCodeLines = (annoteEl) => {
928
- const doc = window.document;
929
- const targetCell = annoteEl.getAttribute("data-target-cell");
930
- const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
931
- const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
932
- const lines = annoteSpan.getAttribute("data-code-lines").split(",");
933
- const lineIds = lines.map((line) => {
934
- return targetCell + "-" + line;
935
- })
936
- let top = null;
937
- let height = null;
938
- let parent = null;
939
- if (lineIds.length > 0) {
940
- //compute the position of the single el (top and bottom and make a div)
941
- const el = window.document.getElementById(lineIds[0]);
942
- top = el.offsetTop;
943
- height = el.offsetHeight;
944
- parent = el.parentElement.parentElement;
945
- if (lineIds.length > 1) {
946
- const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
947
- const bottom = lastEl.offsetTop + lastEl.offsetHeight;
948
- height = bottom - top;
949
- }
950
- if (top !== null && height !== null && parent !== null) {
951
- // cook up a div (if necessary) and position it
952
- let div = window.document.getElementById("code-annotation-line-highlight");
953
- if (div === null) {
954
- div = window.document.createElement("div");
955
- div.setAttribute("id", "code-annotation-line-highlight");
956
- div.style.position = 'absolute';
957
- parent.appendChild(div);
958
- }
959
- div.style.top = top - 2 + "px";
960
- div.style.height = height + 4 + "px";
961
- div.style.left = 0;
962
- let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
963
- if (gutterDiv === null) {
964
- gutterDiv = window.document.createElement("div");
965
- gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
966
- gutterDiv.style.position = 'absolute';
967
- const codeCell = window.document.getElementById(targetCell);
968
- const gutter = codeCell.querySelector('.code-annotation-gutter');
969
- gutter.appendChild(gutterDiv);
970
- }
971
- gutterDiv.style.top = top - 2 + "px";
972
- gutterDiv.style.height = height + 4 + "px";
973
- }
974
- selectedAnnoteEl = annoteEl;
975
- }
976
- };
977
- const unselectCodeLines = () => {
978
- const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
979
- elementsIds.forEach((elId) => {
980
- const div = window.document.getElementById(elId);
981
- if (div) {
982
- div.remove();
983
- }
984
- });
985
- selectedAnnoteEl = undefined;
986
- };
987
- // Handle positioning of the toggle
988
- window.addEventListener(
989
- "resize",
990
- throttle(() => {
991
- elRect = undefined;
992
- if (selectedAnnoteEl) {
993
- selectCodeLines(selectedAnnoteEl);
994
- }
995
- }, 10)
996
- );
997
- function throttle(fn, ms) {
998
- let throttle = false;
999
- let timer;
1000
- return (...args) => {
1001
- if(!throttle) { // first call gets through
1002
- fn.apply(this, args);
1003
- throttle = true;
1004
- } else { // all the others get throttled
1005
- if(timer) clearTimeout(timer); // cancel #2
1006
- timer = setTimeout(() => {
1007
- fn.apply(this, args);
1008
- timer = throttle = false;
1009
- }, ms);
1010
- }
1011
- };
1012
- }
1013
- // Attach click handler to the DT
1014
- const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
1015
- for (const annoteDlNode of annoteDls) {
1016
- annoteDlNode.addEventListener('click', (event) => {
1017
- const clickedEl = event.target;
1018
- if (clickedEl !== selectedAnnoteEl) {
1019
- unselectCodeLines();
1020
- const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
1021
- if (activeEl) {
1022
- activeEl.classList.remove('code-annotation-active');
1023
- }
1024
- selectCodeLines(clickedEl);
1025
- clickedEl.classList.add('code-annotation-active');
1026
- } else {
1027
- // Unselect the line
1028
- unselectCodeLines();
1029
- clickedEl.classList.remove('code-annotation-active');
1030
- }
1031
- });
1032
- }
1033
- const findCites = (el) => {
1034
- const parentEl = el.parentElement;
1035
- if (parentEl) {
1036
- const cites = parentEl.dataset.cites;
1037
- if (cites) {
1038
- return {
1039
- el,
1040
- cites: cites.split(' ')
1041
- };
1042
- } else {
1043
- return findCites(el.parentElement)
1044
- }
1045
- } else {
1046
- return undefined;
1047
- }
1048
- };
1049
- var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
1050
- for (var i=0; i<bibliorefs.length; i++) {
1051
- const ref = bibliorefs[i];
1052
- const citeInfo = findCites(ref);
1053
- if (citeInfo) {
1054
- tippyHover(citeInfo.el, function() {
1055
- var popup = window.document.createElement('div');
1056
- citeInfo.cites.forEach(function(cite) {
1057
- var citeDiv = window.document.createElement('div');
1058
- citeDiv.classList.add('hanging-indent');
1059
- citeDiv.classList.add('csl-entry');
1060
- var biblioDiv = window.document.getElementById('ref-' + cite);
1061
- if (biblioDiv) {
1062
- citeDiv.innerHTML = biblioDiv.innerHTML;
1063
- }
1064
- popup.appendChild(citeDiv);
1065
- });
1066
- return popup.innerHTML;
1067
- });
1068
- }
1069
- }
1070
- });
1071
- </script>
1072
- </div> <!-- /content -->
1073
-
1074
-
1075
-
1076
-
1077
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/_site/posts/fourier/index.html DELETED
@@ -1,2 +0,0 @@
1
- <!DOCTYPE html>
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"></html>
 
 
 
src/_site/posts/post-with-code/index.html DELETED
@@ -1,2 +0,0 @@
1
- <!DOCTYPE html>
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"></html>
 
 
 
src/_site/posts/wave-equation/index.html DELETED
@@ -1,2 +0,0 @@
1
- <!DOCTYPE html>
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"></html>
 
 
 
src/_site/posts/welcome/index.html DELETED
@@ -1,2 +0,0 @@
1
- <!DOCTYPE html>
2
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"></html>
 
 
 
src/_site/profile.jpg DELETED
Binary file (60.5 kB)
 
src/_site/search.json DELETED
@@ -1,58 +0,0 @@
1
- [
2
- {
3
- "objectID": "about.html",
4
- "href": "about.html",
5
- "title": "About",
6
- "section": "",
7
- "text": "About this blog"
8
- },
9
- {
10
- "objectID": "posts/2025-01-06-chebyshev-polynomials/index.html",
11
- "href": "posts/2025-01-06-chebyshev-polynomials/index.html",
12
- "title": "Chebyshev Polynomials: Part 1",
13
- "section": "",
14
- "text": "Chebyshev polynomials are a sequence of orthogonal polynomials that play a central role in numerical analysis, approximation theory, and applied mathematics. They are named after the Russian mathematician Pafnuty Chebyshev and come in two primary types: Chebyshev polynomials of the first kind (\\(T_n(x)\\)) and Chebyshev polynomials of the second kind (\\(U_n(x)\\)). In this post we are going to focus on the Chebyshev polynomials of the first kind."
15
- },
16
- {
17
- "objectID": "posts/2025-01-06-chebyshev-polynomials/index.html#chebyshev-nodes-of-the-first-kind",
18
- "href": "posts/2025-01-06-chebyshev-polynomials/index.html#chebyshev-nodes-of-the-first-kind",
19
- "title": "Chebyshev Polynomials: Part 1",
20
- "section": "Chebyshev Nodes of the First Kind",
21
- "text": "Chebyshev Nodes of the First Kind\nBefore we continue with exploring the roots of the polynomials, let’s recall some trigonometry.\n\nThe unit circle is a circle with a radius of 1, centered at the origin of the Cartesian coordinate system. Below is shown part of the unit circle corresponding to the region from \\(0\\) to \\(\\frac{\\pi}{2}\\).\n\n\n\nFigure 1. Unit circle from \\(0\\) to \\(\\frac{\\pi}{2}\\)\n\n\nThe cosine of an angle \\(\\theta\\) corresponds to the \\(x\\)-coordinate of the point where the terminal side of the angle (measured counterclockwise from the positive \\(x\\)-axis) intersects the unit circle. In other words, \\(\\cos(\\theta)\\) gives the horizontal distance from the origin to this intersection point.\nThe arccosine is the inverse function of cosine, and it maps a cosine value back to its corresponding angle in the range \\([0, \\pi]\\) radians. For a given \\(x\\)-coordinate on the unit circle, the arccosine gives the angle \\(\\theta\\) such that \\(\\cos(\\theta) = x\\), meaning\n\\[\n\\arccos(x) = \\theta, \\quad \\text{where } \\theta \\in [0, \\pi].\n\\]\nMoreover, a radian is defined as the angle subtended at the center of a circle by an arc whose length is equal to the radius of the circle. For any circle, the length of an arc \\(s\\) is given by\n\\[\ns = r \\cdot \\theta,\n\\]\nwhere \\(r\\) is the radius of the circle, \\(\\theta\\) is the angle subtended by the arc at the center. This means that on the unit circle the length of the arc equals the measure of the angle in radians because \\(r = 1\\), and hence\n\\[\ns = \\theta.\n\\]\n\nNow, let’s find the roots of the polynomial \\(T_{n}(x)\\). If we take the definition in \\(\\eqref{eq:1}\\) we have to solve\n\\[\n\\cos{\\left(n \\arccos{x}\\right)} = 0, k \\in N.\n\\]\nThe solutions in the interval \\((-1, 1)\\) are given by\n\\[\nx_k = \\cos{\\left(\\frac{2k - 1}{2n}\\pi\\right)}, n \\in N, k = 1, 2, ...n.\n\\]\nThese roots are known as the Chebyshev nodes of the first kind, or the Chebyshev zeros. If we are working with an arbitrary interval \\((a, b)\\) the affine transformation\n\\[\nx_k = \\frac{a + b}{2} + \\frac{b - a}{2}\\cos{\\left(\\frac{2k - 1}{2n}\\pi\\right)}, n \\in N, k = 1, 2, ...n\n\\]\nis needed. From the cosine properties we can also note that the nodes are symmetric with respect to the midpoint of the interval, and that the extrema of \\(T_n(x)\\) over the interval \\([-1, 1]\\) alternate between \\(-1\\) and \\(1\\). Also, a very useful fact is that these nodes are used in polynomial interpolation to minimize the Runge phenomenon.\nIn the figure below we have shown the roots of \\(T_{8}(x)\\) in blue. We have also built the perpendiculars from the roots to their interesction with the upper half of the unit circle, and marked these points in red.\n\nLooking at the figure we can notice that the arc lengths between the red points seem to be of the same length. Let’s show that this is indeed the truth.\nWe showed the roots are the cosine functions \\(\\cos{\\left(\\frac{2k - 1}{2n}\\pi\\right)}, n \\in N, k = 1, 2, ...n\\). Thus, in the unit circle we have that the length of the corresponding arcs are equal to \\(\\left( \\frac{2k - 1}{2n}\\pi \\right), n \\in N, k = 1, 2, ...n\\). Let’s take two red points which are direct neighbours, or in other words let’s take two red points corresponding to the randomly chosen \\(m\\) and \\(m + 1\\) roots, \\(m \\in k = \\{1, 2, ..., n\\}\\). If we subtract them we are going to determine the length of the arc between them. We have\n\\[\n\\frac{2(m + 1) - 1}{2n}\\pi - \\frac{2m - 1}{2n}\\pi = \\frac{\\pi}{n},\n\\]\nmeaning that between every two nodes the arc length is equal and has a value of \\(\\frac{\\pi}{n}\\). A polynomial of degree \\(n\\) has \\(n\\) roots, which in our case are in the open interval \\((-1, 1)\\), meaning the arcs corresponding to every two neighbouring roots are \\(n - 1\\), and the two arcs between the \\(x\\)-axis and the first and last roots due to the symmetry of roots have lenghts of\n\\[\n\\frac{1}{2}\\left(\\pi - \\frac{n-1}{n}\\pi\\right) = \\frac{\\pi}{2n}.\n\\]"
22
- },
23
- {
24
- "objectID": "posts/2025-01-06-chebyshev-polynomials/index.html#recurrence-relation",
25
- "href": "posts/2025-01-06-chebyshev-polynomials/index.html#recurrence-relation",
26
- "title": "Chebyshev Polynomials: Part 1",
27
- "section": "Recurrence relation",
28
- "text": "Recurrence relation\nThis is probably a bit out of nowhere, but let’s take a look at the following trigonometric identity\n\\[\\label{eq:4}\n\\cos{\\left((n + 1)\\theta\\right)} + \\cos{\\left((n - 1)\\theta\\right)} = 2 \\cos{(\\theta)} \\cos{(n\\theta)},\\tag{4}\n\\]\nand show that the left side indeed is equal to the right one. We are going to need the following two fundamental formulas of angle addition in trigonometry\n\\[\n\\cos{(\\alpha + \\beta)} = \\cos{\\alpha} \\cos{\\beta} - \\sin{\\alpha} \\sin{\\beta},\n\\]\nand\n\\[\n\\cos{(\\alpha - \\beta)} = \\cos{\\alpha} \\cos{\\beta} + \\sin{\\alpha} \\sin{\\beta}.\n\\]\nIn our case we have\n\\[\n\\cos{\\left((n + 1)\\theta\\right)} = \\cos{\\left(n\\theta + \\theta\\right)} = \\cos{(n\\theta)} \\cos{\\theta} - \\sin{(n\\theta)} \\sin{\\theta},\n\\]\nand\n\\[\n\\cos{\\left((n - 1)\\theta\\right)} = \\cos{\\left(n\\theta - \\theta\\right)} = \\cos{(n\\theta)} \\cos{\\theta} + \\sin{(n\\theta)} \\sin{\\theta}.\n\\]\nAdding the above equations leads to the wanted result.\nNow, we can see that the terms of \\(\\eqref{eq:4}\\) are exactly in the form of the right side of \\(\\eqref{eq:1}\\), \\(\\eqref{eq:3}\\), hence we get\n\\[\nT_{n + 1}(x) + T_{n - 1}(x) = 2T_{n}(x)T_{1}(x),\n\\]\nor we get the useful recurrence relation\n\\[\\label{eq:5}\nT_{n + 1}(x) - 2xT_{n}(x) + T_{n - 1}(x) = 0.\\tag{5}\n\\]\nThis relation along with adding \\(T_{0}(x) = 1\\) and \\(T_{1}(x) = x\\) is another famous way to define the Chebyshev polynomials of the first kind, or\n\\[\n\\left\\{\\begin{align*}\nT_{0}(x) = 1, \\\\\nT_{1}(x) = x, \\\\\nT_{n + 1}(x) - 2xT_{n}(x) + T_{n - 1}(x) = 0.\n\\end{align*}\\right.\\label{eq:6}\\tag{6}\n\\]\nLet’s write the first \\(6\\) polynomials by using \\(\\eqref{eq:6}\\):\n\\[\n\\left\\{\\begin{align*}\nT_{0}(x) = 1, \\quad \\text{(even)}\\\\\nT_{1}(x) = x, \\quad \\text{(odd)}\\\\\nT_{2}(x) = 2x^2 - 1, \\quad \\text{(even)}\\\\\nT_{3}(x) = 4x^3 - 3x, \\quad \\text{(odd)}\\\\\nT_{4}(x) = 8x^4 - 8x^2 + 1, \\quad \\text{(even)}\\\\\nT_{5}(x) = 16x^5 - 20x^3 + 5x. \\quad \\text{(odd)}\n\\end{align*}\\right.\n\\]\nWe can notice that\n\\[\nT_{k}(x) = 2^{k-1}x^k + ...,\n\\]\nand \\(T_{k}(x)\\) is alternating between an even and an odd polynomial depending on whether \\(k\\) is even or odd respectively.\nBefore we continue with some visualisations and more facts, let’s mention that an interesting way to represent the recurrence relation \\(\\eqref{eq:5}\\) is via the determinant\n\\[\nT_{k}(x) = \\det \\begin{bmatrix}\nx & 1 & 0 & \\dots & 0 \\\\\n1 & 2x & 1 & \\ddots & \\vdots \\\\\n0 & 1 & 2x & \\ddots & 0 \\\\\n\\vdots & \\ddots & \\ddots & \\ddots & 1 \\\\\n0 & \\dots & 0 & 1 & 2x\n\\end{bmatrix}.\n\\]\nNow, let’s visualise the first \\(8\\) polynomials.\n\n\n\nChebyshev Polynomials\n\n\nBut what can we notice if we stack them together?\n\n\n\nChebyshev Polynomials Stacked\n\n\nIt is quite obvious that at the roots of the \\(N\\)-th Chebyshev polynomial there is an aliasing effect, meaning higher order polynomials look like lower order ones. We can formally show it by fixing \\(N\\), at the roots \\(x_k\\) of \\(T_{N}(x) = 0\\), and using the Chebyshev identity\n\\[\n\\cos{\\left((m + N)\\theta\\right)} + \\cos{\\left((m - N)\\theta\\right)} = 2\\cos{(m\\theta)}\\cos{(N\\theta)},\n\\]\nor equivalently\n\\[\nT_{m + N}(x) + T_{m - N}(x) = 2T_{m}(x)T_{N}(x).\n\\]\nNow, having \\(T_{N}(x) = 0\\) leads to\n\\[\nT_{m + N}(x) = -T_{m - N}(x).\n\\]\nIf we consecutevly set \\(m = N\\), \\(m = 2N\\), …, \\(m = 6N\\), etc. we would get\n\\[\n\\left\\{\\begin{align*}\nT_{2N}(x_k) = -T_{0}(x_k) = -1, \\\\\nT_{3N}(x_k) = 0, \\\\\nT_{4N}(x_k) = 1, \\\\\nT_{5N}(x_k) = 0, \\\\\nT_{6N}(x_k) = -1, \\\\\n\\text{etc}.\n\\end{align*}\\right.\n\\]\nWe can safely say that any higher-order Chebyshev polynomial \\(T_{N}(x)\\) can be reduced to a lower-order \\(j, 0 \\leq j \\leq N\\) Chebyshev polynomial at the sample points \\(x_k\\) which are the roots of \\(T_{N}(x)\\). In the figure below we attempt to visualise this statement.\n\n\n\nalt text\n\n\nThe horizontal axis represents the order of Chebyshev polynomials, and the blue wavy line represents a “folded ribbon”. Think of it as taking the sequence of polynomial orders and folding it back and forth. This folding happens at specific points where higher-order polynomials can be reduced to lower-order ones, which are the red x marks showing the sample points: the roots of \\(T_n(x)\\). The key insight is that at these special sample points, we don’t need to work with the higher-order polynomials because we can use equivalent lower-order ones instead. This is incredibly useful in numerical computations as it can help reduce computational complexity, and makes the Chebyshev polynomials very computationally efficient.\nLet’s illustarte this with a simple example. Let \\(N = 2\\), then for even \\(m\\) we have\n\\[\n\\left\\{\\begin{align*}\nT_{4}(x_k) = -T_{0}(x_k) = -1, \\\\\nT_{6}(x_k) = - T_{2}(x_k) = 0, \\\\\nT_{8}(x_k) = - T_{4}(x_k) = 1, \\\\\nT_{10}(x_k) = -T_{6}(x_k) = 0, \\\\\n\\text{etc}.\n\\end{align*}\\right.\n\\]\nIn the figure below we can see the even polynomials and that indeed \\(T_{10}(x)\\) behaves like \\(-T_{6}(x)\\) which behaves like \\(T_{2}(x)\\) at the roots having value \\(0\\), \\(T_{8}(x)\\) behaves like \\(-T_{4}(x)\\) at the roots with value \\(1\\) as in \\(T_{0}(x)\\), \\(T_{6}(x)\\) behaves like \\(-T_{2}(x)\\) with value \\(0\\), and \\(T_{4}(x)\\) behaves like \\(-T_{0}(x)\\) with value \\(-1\\).\n\n\nClick to expand the code\nfrom typing import Union\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\ndef chebyshev_polynomial(\n n: int, x: Union[float, np.ndarray]\n) -&gt; Union[float, np.ndarray]:\n \"\"\"\n Calculate nth Chebyshev polynomial of the first kind T_n(x).\n\n Args:\n n: Order of polynomial (non-negative integer)\n x: Point(s) at which to evaluate polynomial\n\n Returns:\n Value of T_n(x)\n \"\"\"\n if n &lt; 0:\n raise ValueError(\"Order must be non-negative\")\n\n if n == 0:\n return np.ones_like(x)\n elif n == 1:\n return x\n else:\n t_prev = np.ones_like(x) # T_0\n t_curr = x # T_1\n\n for _ in range(2, n + 1):\n t_next = 2 * x * t_curr - t_prev\n t_prev = t_curr\n t_curr = t_next\n\n return t_curr\n\n\ndef chebyshev_nodes(n):\n \"\"\"Generate n Chebyshev nodes in [-1,1]\"\"\"\n k = np.arange(1, n + 1)\n return np.cos((2 * k - 1) * np.pi / (2 * n))\n\n\nif __name__ == \"__main__\":\n\n x = np.linspace(-1, 1, 1000)\n plt.figure(figsize=(12, 6))\n plt.plot(x, -chebyshev_polynomial(0, x), \"--\", label=f\"-T_{0}(x)\", alpha=0.5)\n for n in [0, 2, 4, 6, 8, 10]:\n y = chebyshev_polynomial(n, x)\n plt.plot(x, y, label=f\"T_{n}(x)\")\n\n # plot nodes for n = 2\n n = 2\n nodes = chebyshev_nodes(n)\n y_nodes = np.cos(n * np.arccos(nodes))\n plt.plot(nodes, np.zeros_like(nodes), \"bo\", label=\"T_2(x) roots\")\n for node in nodes:\n plt.plot([node, node], [-1, 1], \"--\", color=\"gray\", alpha=0.5)\n\n # plt.grid(True)\n # Set aspect ratio to be equal\n # plt.gca().set_aspect('equal', adjustable='box')\n plt.xlabel(\"x\")\n plt.ylabel(\"T_n(x)\")\n plt.title(\"Chebyshev Polynomials Aliasing\")\n plt.legend(loc=\"center left\", bbox_to_anchor=(1, 0.5), fontsize=8)\n plt.xlim(-1.1, 1.1)\n plt.ylim(-1.1, 1.1)\n plt.axhline(y=0, color=\"k\", linestyle=\"-\", alpha=0.7)\n plt.savefig(\n \"content/images/2025-01-06-chebyshev-polynomials/chebyshev_polynomials_aliasing_even.png\"\n )\n plt.show()\n\n\n\n\n\nalt text\n\n\nFor odd \\(m\\) we have \\[\n\\left\\{\\begin{align*}\nT_{3}(x_k) = - T_{1}(x_k) = - x\\\\\nT_{5}(x_k) = - T_{3}(x_k) = x\\\\\nT_{7}(x_k) = - T_{5}(x_k) = -x, \\\\\nT_{9}(x_k) = - T_{7}(x_k) = x, \\\\\n\\text{etc}.\n\\end{align*}\\right.\n\\]\nIn the figure below we can see the odd polynomials and the aliasing as in the previous example.\n\n\nClick to expand the code\nfrom typing import Union\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\ndef chebyshev_polynomial(\n n: int, x: Union[float, np.ndarray]\n) -&gt; Union[float, np.ndarray]:\n \"\"\"\n Calculate nth Chebyshev polynomial of the first kind T_n(x).\n\n Args:\n n: Order of polynomial (non-negative integer)\n x: Point(s) at which to evaluate polynomial\n\n Returns:\n Value of T_n(x)\n \"\"\"\n if n &lt; 0:\n raise ValueError(\"Order must be non-negative\")\n\n if n == 0:\n return np.ones_like(x)\n elif n == 1:\n return x\n else:\n t_prev = np.ones_like(x) # T_0\n t_curr = x # T_1\n\n for _ in range(2, n + 1):\n t_next = 2 * x * t_curr - t_prev\n t_prev = t_curr\n t_curr = t_next\n\n return t_curr\n\n\ndef chebyshev_nodes(n):\n \"\"\"Generate n Chebyshev nodes in [-1,1]\"\"\"\n k = np.arange(1, n + 1)\n return np.cos((2 * k - 1) * np.pi / (2 * n))\n\n\nif __name__ == \"__main__\":\n\n x = np.linspace(-1, 1, 1000)\n plt.figure(figsize=(12, 6))\n plt.plot(x, -chebyshev_polynomial(1, x), \"--\", label=f\"-T_{1}(x)\", alpha=0.5)\n for n in [1, 2, 3, 5, 7, 9]:\n y = chebyshev_polynomial(n, x)\n plt.plot(x, y, label=f\"T_{n}(x)\")\n\n # plot nodes for n = 2\n n = 2\n nodes = chebyshev_nodes(n)\n y_nodes = np.cos(n * np.arccos(nodes))\n plt.plot(nodes, np.zeros_like(nodes), \"bo\", label=\"T_2(x) roots\")\n for node in nodes:\n plt.plot([node, node], [-1, 1], \"--\", color=\"gray\", alpha=0.5)\n\n # plt.grid(True)\n # Set aspect ratio to be equal\n # plt.gca().set_aspect('equal', adjustable='box')\n plt.xlabel(\"x\")\n plt.ylabel(\"T_n(x)\")\n plt.title(\"Chebyshev Polynomials Aliasing\")\n plt.legend(loc=\"center left\", bbox_to_anchor=(1, 0.5), fontsize=8)\n plt.xlim(-1.1, 1.1)\n plt.ylim(-1.1, 1.1)\n plt.axhline(y=0, color=\"k\", linestyle=\"-\", alpha=0.7)\n plt.savefig(\n \"content/images/2025-01-06-chebyshev-polynomials/chebyshev_polynomials_aliasing_odd.png\"\n )\n plt.show()\n\n\n\n\n\nalt text"
29
- },
30
- {
31
- "objectID": "posts/2025-01-06-chebyshev-polynomials/index.html#radial-plots",
32
- "href": "posts/2025-01-06-chebyshev-polynomials/index.html#radial-plots",
33
- "title": "Chebyshev Polynomials: Part 1",
34
- "section": "Radial Plots",
35
- "text": "Radial Plots\nAn interesting plot can be observed by plotting \\(T_n(x)\\) radially. This means that instead of evaluating the polynomials over \\([-1, 1]\\) in a Cartesian plane we are evaluating them at \\(\\frac{\\theta}{\\pi} - 1\\), and plotting \\(r = n + T_n(\\frac{\\theta}{\\pi} - 1)\\) on polar axes. In other words, the input domain has been shifted and extended, and the results are drawn as radial distances \\(r\\) around a circle defined by \\(\\theta\\). This creates a polar visualization where each \\(n\\) produces a distinct spiral-like ornament. We are also filling in the areas between the curves for a visual effect.\n\n\nClick to expand the code\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom numpy.polynomial.chebyshev import Chebyshev\n\ntheta = np.linspace(0, 2 * np.pi, 2000)\nfig, ax = plt.subplots(subplot_kw={\"projection\": \"polar\"})\n\n# Generate and fill between consecutive curves\nfor n in range(0, 19 * 2, 2):\n r1 = n + Chebyshev([0] * n + [1])(theta / np.pi - 1)\n r2 = (n + 2) + Chebyshev([0] * (n + 2) + [1])(theta / np.pi - 1)\n\n # Create black and white alternating pattern\n if n % 4 == 0:\n ax.fill_between(theta, r1, r2, color=\"black\")\n else:\n ax.fill_between(theta, r1, r2, color=\"white\")\nax.set_title(\"x = t/π - 1\", y=1)\nplt.axis(\"off\")\nplt.show()\n\n\n\nMore visualusations can be achieved by doing other domain changes. They can be seen below.\n\n\n\nIn a separate post, Chebyshev Polynomials, Part 2, we are going to explore the Chebyshev polynomials of the second kind, and their relations to the polynomials of the first kind."
36
- },
37
- {
38
- "objectID": "posts/2025-01-04-fourier-method-fixed-string/index.html",
39
- "href": "posts/2025-01-04-fourier-method-fixed-string/index.html",
40
- "title": "Fourier Method for the 1D Wave Equation: Fixed String",
41
- "section": "",
42
- "text": "In this post we are going to explore the Fourier method for solving the 1D wave equation. The method is more known under the name of the method of separation of variables. For the 1D wave equation we are going to show the application of the method to a fixed string. We are also going to attempt to outline some of the physical interpretations of the fixed string."
43
- },
44
- {
45
- "objectID": "posts/2025-01-04-fourier-method-fixed-string/index.html#fixed-string",
46
- "href": "posts/2025-01-04-fourier-method-fixed-string/index.html#fixed-string",
47
- "title": "Fourier Method for the 1D Wave Equation: Fixed String",
48
- "section": "Fixed String",
49
- "text": "Fixed String\nFirst, let’s take a look at the model of a string with length \\(l\\) which is also fixed at both ends:\n\\[\n\\left\\{\\begin{aligned}\nu_{tt} = a^2 u_{xx}, \\\\\nu(x, 0) = \\varphi_1(x),\\\\\nu_t(x, 0) = \\varphi_2(x), \\\\\nu(0, t) = u(l, t) = 0.\n\\end{aligned}\\right.\n\\]\nA visualisation of the string can be seen in the figure below.\n\n\n\nFigure 1. Fixed String\n\n\nWe start solving the equation by taking into account only the boundary conditions \\(u(0, t) = u(l, t) = 0\\). The idea is to find solution \\(u(x, t)\\) of the form\n\\[\nu(x, t) = X(x)T(t).\n\\]\nWe substitute this form of the solution into the wave equation and get\n\\[\n\\frac{1}{a^2} T^{\\prime\\prime}(t)X(x) = T(t)X^{\\prime\\prime}(x),\n\\]\nfurther divding by \\(X(x)T(t)\\) leads to\n\\[\n\\frac{1}{a^2} \\frac{T^{\\prime\\prime}(t)}{T(t)} = \\frac{X^{\\prime\\prime}(x)}{X(x)}.\n\\]\nWe have two functions of independent variables which are equal. This is only possible if they are equal to the same constant. Therefore, let\n\\[\n\\frac{1}{a^2} \\frac{T^{\\prime\\prime}(t)}{T(t)} = \\frac{X^{\\prime\\prime}(x)}{X(x)} = -\\lambda,\n\\]\nproducing the following two equeations:\n\\[\nT^{\\prime\\prime}(t) + a^2 \\lambda T(t) = 0\n\\]\nand\n\\[\\label{eq:ref}\nX^{\\prime\\prime}(x) + \\lambda X(x) = 0. \\tag{*}\n\\]\nLet’s begin with solving the second equation. The boundary conditions give\n\\[\nX(0)T(t) = 0 \\quad \\text{and} \\quad X(l)T(t) = 0.\n\\]\nBecause we are interested only in non-trivial solutions and thus \\(T \\neq 0\\), we have\n\\[\\label{eq:ref2}\nX(0) = 0 \\quad \\text{and} \\quad X(l) = 0. \\tag{**}\n\\]\nNow, we have to find the non-trivial solutions for \\(X(x)\\) satisfying\n\\[\n\\left\\{\\begin{align*}\nX^{\\prime\\prime}(x) + \\lambda X(x) = 0, \\\\\nX(0) = 0, \\quad X(l) = 0.\n\\end{align*}\\right.\n\\]\nThe above problem is an example of the so called Sturm-Liouville problem. In order to find the general solution of the second order linear homogeneous differential equation with constant coefficients \\(\\eqref{eq:ref}\\) we should solve its characteristic equation\n\\[\nr^2 + \\lambda = 0.\n\\]\n\nIf \\(\\lambda &lt; 0\\), then \\(r_{1, 2} = \\pm \\sqrt{-\\lambda}\\), hence the general solution is \\[\nX(x) = c_1 e^{\\sqrt{-\\lambda}x} + c_2 e^{-\\sqrt{-\\lambda}x}\n\\] for some constants \\(c_1\\) and \\(c_2\\). In order to determine the constants we substitute the above solution into the boundary conditions \\(\\eqref{eq:ref2}\\) and get the system \\[\n\\left\\{\\begin{align*}\nc_1 + c_2 = 0, \\\\\nc_1 e^{\\sqrt{-\\lambda}l} + c_2 e^{-\\sqrt{-\\lambda}l} = 0.\n\\end{align*}\\right.\n\\] This results in \\(c_1 = c_2 = 0\\), meaning our Sturm-Liouville problem doesn’t have a non-zero solution for \\(\\lambda &lt; 0\\).\nIf \\(\\lambda = 0\\), then \\(r_1 = r_2 = 0\\) and the general solution is \\[\nX(x) = c_1 + c_2 x.\n\\] Substituing it into the boundary conditions \\(\\eqref{eq:ref2}\\) again lead to \\(c_1 = c_2 = 0\\), hence no non-zero solutions of our Sturm-Liouville problem for \\(\\lambda \\leq 0\\).\nIf \\(\\lambda &gt; 0\\), then \\(r_{1, 2} = \\pm i \\sqrt{\\lambda}\\), and the general solution becomes \\[\nX(x) = c_1 \\cos{\\left( \\sqrt{\\lambda} x \\right)} + c_2 \\sin{\\left(\\sqrt{\\lambda}x\\right)}.\n\\] Substituting into the boundary conditions \\(\\eqref{eq:ref2}\\) results in \\[\n\\left\\{\\begin{align*}\nc_1 = 0, \\\\\nc_2 \\sin{\\left(\\sqrt{\\lambda}l\\right)} = 0\n\\end{align*}\\right.\n\\] If \\(c_2 = 0\\), then \\(X(x) \\equiv 0\\) which is a trivial solution. Therefore, we set \\(c_2 \\neq 0\\) and hence \\[\n\\sin{\\left(\\sqrt{\\lambda}l\\right)} = 0,\n\\] giving \\(\\sqrt{\\lambda}l = k \\pi\\), \\(k = \\pm 1, \\pm 2, ...\\). Theerfore, \\[\n\\lambda = \\lambda_k = \\left(\\frac{k \\pi}{l}\\right)^2,\n\\] meaning eigenvalues exist when \\(\\lambda &gt; 0\\). The eigenfunctions corresponding to the above eigenvalues are \\[\nX_k(x) = \\sin{\\left(\\frac{k \\pi x}{l}\\right)}, \\quad k &gt; 0, k \\in N.\n\\]\n\nGoing back to \\(T^{\\prime\\prime}(t) + a^2 \\lambda T(t) = 0\\), solving in analogical way, when \\(\\lambda = \\lambda_k\\) the solution becomes\n\\[\nT_k(t) = A_k \\cos{\\left(\\frac{ak\\pi}{l}t\\right)} + B_k \\sin{\\left(\\frac{ak\\pi}{l}t\\right)}\n\\]\nfor some constants \\(A_k\\) and \\(B_k\\). Hence,\n\\[\nu_k(x,t) = X_k(x) T_k(t) = \\left(A_k \\cos{\\left(\\frac{ak\\pi}{l}t\\right)} + B_k \\sin{\\left(\\frac{ak\\pi}{l}t\\right)}\\right) \\sin{\\left(\\frac{k \\pi x}{l}\\right)}, \\quad k &gt; 0, k \\in N\n\\]\nare solutions to our wave equation, also satisfying the boundary conditions. Since our equation is linear, forming a linear system with its conditions, the principle of superposition is valid. In other words, if \\(u_1, u_2, ..., u_n\\) are solutions of our system, then\n\\[\n\\alpha_1 u_1 + \\alpha_2 u_2 + ... + \\alpha_n u_n\n\\]\nfor some constants \\(\\alpha_1, \\alpha_2, ..., \\alpha_n\\) is also a solution of the system. But in our case we have an infinite number of functions \\(u_1, u_2, ...\\) which satisfy the linear system. Therefore, we need the generalised superposition principle stating that in such case\n\\[\nu = \\sum_n^{\\infty} \\alpha_n u_n\n\\]\nfor some arbitrary constants \\(\\alpha_n\\) is a solution to the system if the series converges uniformly and is twice differentiable termwise. This generalisation is a Lemma and should be prooved. The proof can be found in …\nAssuming we have prooved the said Lemma, we can state that our system has a solution of the form\n\\[\nu(x, t) = \\sum_{k=1}\n^{\\infty} u_k(x, t) = \\sum_{k=1}^{\\infty} \\left(A_k \\cos{\\left(\\frac{ak\\pi}{l}t\\right)} + B_k \\sin{\\left(\\frac{ak\\pi}{l}t\\right)}\\right) \\sin{\\left(\\frac{k \\pi x}{l}\\right)}.\n\\]\nThe next task we have to tackle is to determine the coefficients \\(A_k\\) and \\(B_k\\). We can achieve this by using the initial conditions\n\\[\nu(x, 0) = \\varphi_1(x), \\quad \\text{and} \\quad u_t(x, 0) = \\varphi_2(x).\n\\]\nWe get\n\\[\nu(x, 0) = \\sum_{k=1}\n^{\\infty} A_k \\sin{\\left(\\frac{k \\pi x}{l}\\right)} = \\varphi_1(x)\n\\]\nand\n\\[\nu_t(x, 0) = \\sum_{k=1}^{\\infty} \\frac{ak\\pi}{l} B_k \\sin{\\left(\\frac{k \\pi x}{l}\\right)} = \\varphi_2(x).\n\\]\nNow, we have to expand both \\(\\varphi_1(x)\\) and \\(\\varphi_2(x)\\) into series in terms of sines only (why?). We have\n\\[\n\\varphi_1(x) = \\sum_{k=1}^{\\infty} \\varphi_k^{(1)} \\sin{\\left(\\frac{k \\pi}{l}x\\right)}\n\\]\nand\n\\[\n\\varphi_2(x) = \\sum_{k=1}^{\\infty} \\varphi_k^{(2)} \\sin{\\left(\\frac{k \\pi}{l}x\\right)}.\n\\]\nBy the Fourier series theroem of uniqueness, we get\n\\[\nA_k = \\varphi_k^{(1)} \\quad \\text{and} \\quad B_k = \\frac{l}{ak\\pi} \\varphi_k^{(2)},\n\\]\nor (why?)\n\\[\nA_k = \\frac{2}{l} \\int_{0}^{l} \\varphi_1(x) \\sin{\\left(\\frac{k \\pi}{l}x\\right)} \\mathrm{d}x\n\\]\nand\n\\[\nB_k = \\frac{2}{ak\\pi} \\int_{0}^{l} \\varphi_2(x) \\sin{\\left(\\frac{k \\pi}{l}x\\right)} \\mathrm{d}x.\n\\]\nWe are left with the task of the covergence of the infinite series. We have to explore the following series\n\\[\n|u(x, t)| \\leq \\sum_{k=1}^{\\infty}(|A_k| + |B_k|),\n\\]\n\\[\n|u_t(x, t)| \\leq \\sum_{k=1}^{\\infty}\\frac{ak\\pi}{l}(|A_k| + |B_k|),\n\\]\n\\[\n|u_x(x, t)| \\leq \\sum_{k=1}^{\\infty}\\frac{k\\pi}{l}(|A_k| + |B_k|),\n\\]\n\\[\n|u_{tt}(x, t)| \\leq \\sum_{k=1}^{\\infty}\\frac{a^2 k^2 \\pi^2}{l^2}(|A_k| + |B_k|),\n\\]\n\\[\n|u_{xx}(x, t)| \\leq \\sum_{k=1}^{\\infty}\\frac{k^2 \\pi^2}{l^2}(|A_k| + |B_k|).\n\\]\nIf the series on the right side (majorizing series) converge then the series on the left would also converge and the needed differentiation would exist. It is enough (why?) for the following series to converge\n\\[\n\\sum_{k=1}^{\\infty} k^j \\left(|\\varphi_k^{(1)}| + \\frac{2}{ak\\pi}|\\varphi_k^{(2)}|\\right), j = 0, 1, 2.\n\\]\nThis is possible only if\n\\[\n\\left\\{\\begin{align*}\n\\sum_{k=1}^{\\infty} k^j |\\varphi_k^{(1)}|, \\\\\n\\sum_{k=1}^{\\infty} k^{j-1} |\\varphi_k^{(2)}|,\n\\end{align*}\\right. \\quad j = 0, 1, 2.\n\\]\nconverge. From Calculus we know (theorem) that if \\(\\varphi(x)\\) is \\(m\\)-times differentiable then\n\\[\n\\sum_{k=1}^{\\infty} k^{m-1} |\\varphi_k|\n\\]\nconvergres. Therefore, in order for all the majorzing series to converge it is enough \\(\\varphi_1(x)\\) to be \\(3\\)-times differentiable, and \\(\\varphi_2(x)\\) to be \\(2\\)-times differentiable.\nFinally, we should note a few things about the expansion of \\(\\varphi_1(x)\\) and \\(\\varphi_2(x)\\) into sine series. We have to note that in order to do that the function needs to be continued as an odd function which my lead to loss of the regularity of the lower derivatives. Let \\(\\tilde{\\varphi}_1(x)\\) be the continuation of \\(\\varphi_1(x)\\) as an odd function (see the Figure below) defined as\n\n\n\nFigur2. Odd continuation of a function\n\n\n\n\\[\n\\tilde{\\varphi}_1(x) = \\left\\{\\begin{align*}\n\\varphi_1(x), \\quad 0 \\leq x \\leq l, \\\\\n-\\varphi_1(-x), \\quad -l \\leq x \\leq 0.\n\\end{align*}\\right.\n\\]\nHence, in order for it to be continous and continously differentibale we need to enforce the following condition\n\\[\n\\varphi_1(0) = \\varphi_1(l) = 0.\n\\]\nTo summarise, in order for \\(\\sum_{k=1}^{\\infty} \\varphi_k^{(1)} \\sin{\\left( \\frac{k\\pi}{l}x\\right)}\\) to converge in \\([0, l]\\) it is necessary to enforce the above conditions to have zero values at both ends of the interval. As for the second derivative, if it exists it would be continuous as well. Similarly, for the third derivative to exist we enforce\n\\[\n\\varphi_1^{\\prime\\prime}(0) = \\varphi_1^{\\prime\\prime}(l) = 0\n\\]\nand obtain the corresponding necessary condition\n\\[\n\\varphi_2(0) = \\varphi_2(l) = 0.\n\\]\nFinally, after these enforced conditions we can conclude that (tehorem)\n\\[\nu(x, t) = \\sum_{k=1}^{\\infty} \\left(A_k \\cos{\\left(\\frac{ak\\pi}{l}t\\right)} + B_k \\sin{\\left(\\frac{ak\\pi}{l}t\\right)}\\right) \\sin{\\left(\\frac{k \\pi x}{l}\\right)}\n\\]\nis a regular solution of the problem.\nPhysical interpretation:\nIf we go back to the eigenfunction\n\\[\nu_k(x,t) = \\left(A_k \\cos{\\left(\\frac{ak\\pi}{l}t\\right)} + B_k \\sin{\\left(\\frac{ak\\pi}{l}t\\right)}\\right) \\sin{\\left(\\frac{k \\pi}{l}x\\right)}, \\quad k &gt; 0, k \\in N\n\\]\nwe can rewrite it as\n\\[\nu_k(x,t) = \\sqrt{A_k^2 + B_k^2} \\sin{\\left(\\frac{k \\pi}{l}x\\right)} \\sin{\\left(\\frac{ak\\pi}{l}t + \\phi_k\\right)}, \\quad k \\in N,\n\\]\nwhere\n\\[\n\\tan{(\\phi_k)} = \\frac{A_k}{B_k}.\n\\]\nWe can translate this as the points of the string to oscillate at the frequency \\(\\omega_k = \\frac{ak\\pi}{l}\\) with phase \\(\\phi_k\\). The amplitude is dependant on \\(x\\) and is given by \\[\nF_k = \\sqrt{A_k^2 + B_k^2} \\sin{\\left(\\frac{k\\pi}{l}x\\right)}.\n\\]\nThe \\(u_k(x, t)\\) waves are called standing-waves. Depending on the values of \\(k\\) we have the following scenarios:\n\nWhen \\(k = 1\\) there are \\(2\\) motionless points which are the ends of the (fixed) string\nWhen \\(k = 2\\) a third moitonless point \\(x = \\frac{l}{2}\\) is added\n\nThese motionless points are called nodes of the standing wave. In general, \\(u_k(x, t)\\) has \\((k + 1)\\) nodes located ate \\(0, \\frac{1}{k}l, \\frac{2}{k}l, ..., \\frac{k-1}{k}l, l\\). The maximum amplitude is achieved in the middle points between two nodes. These points are called crests. The fundamental tone, or the lowest tone, has frequency of \\(\\omega_1 = \\frac{a\\pi}{l}\\). The frequencies \\(\\omega_k\\) are called harmonics, while the higher tones corresponding to \\(\\omega_k\\), \\(k = 2, 3, ...\\) are called overtones. It is quite natural to notice that the higher the value of \\(k\\) the rapidly lower the amplitude of \\(u_k(x, t)\\) becomes. Meaning, the effect from the higher harmonics all combined influences the quality of the sound. The below figure shows the harmonics for \\(k = 1, 2, 3\\).\n\n\n\nFigure 3. Fixed Strings\n\n\n\nExample\nHere, we are going to show an example of a fixed string. We are going to show an animated solution with the help of Python. The fixed string problem is given by\n\\[\n\\left\\{\\begin{aligned}\nu_{tt} = \\left(\\frac{2}{3}\\right)^2 u_{xx}, \\\\\nu(x, 0) = \\left\\{\\begin{align*}\n\\sin^3{(\\pi x)}, \\quad 1 \\leq x \\leq3, \\\\\n0, \\quad x \\in R \\backslash [1, 3],\n\\end{align*}\\right.,\\\\\nu_t(x, 0) = 0, \\\\\nu(0, t) = u(\\pi \\sqrt{5}, t) = 0.\n\\end{aligned}\\right.\n\\]\nUsing the \\(100\\)-th partial Fourier sum, below is shown the animated solution for \\(t \\in [0, 30]\\).\n\n\nClick to expand the code\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\n\n# Define constants\nL = np.pi * np.sqrt(5)\na = 2 / 3\ntmax = 30\nx = np.linspace(0, L, 101)\nt = np.linspace(0, tmax, 31) # Fewer points for smoother interaction\n\n\n# Define the initial condition phi(x)\ndef phi(x):\n y = np.zeros_like(x)\n y[(1 &lt; x) & (x &lt; 3)] = np.sin(np.pi * x[(1 &lt; x) & (x &lt; 3)]) ** 3\n return y\n\n\n# Define the initial velocity psi(x)\ndef psi(x):\n return np.zeros_like(x)\n\n\n# Define the Fourier solution for u(x, t)\ndef fourier_u(x, t):\n y = np.zeros_like(x)\n for k in range(1, 101):\n Xk = np.sin(k * np.pi * x / L)\n Ak = (2 / L) * np.trapezoid(phi(x) * Xk, x)\n Bk = (2 / (a * k * np.pi)) * np.trapezoid(psi(x) * Xk, x)\n Tk = Ak * np.cos(a * k * np.pi * t / L) + Bk * np.sin(a * k * np.pi * t / L)\n y += Tk * Xk\n return y\n\n\n# Create animation data\ndata = []\nfor t_val in t:\n y = fourier_u(x, t_val)\n for x_val, y_val in zip(x, y):\n data.append({\"x\": x_val, \"y\": y_val, \"t\": f\"t = {t_val:.2f}\"})\n\n# Create DataFrame and plot\ndf = pd.DataFrame(data)\nfig = px.line(\n df,\n x=\"x\",\n y=\"y\",\n animation_frame=\"t\",\n # title=\"String Motion\",\n labels={\"x\": \"x\", \"y\": \"u(x, t)\"},\n range_x=[-0.06, L + 0.06],\n range_y=[-1.1, 1.1],\n color_discrete_sequence=[\"red\"],\n)\n\n# Add fixed points as black dots\nfixed_points = pd.DataFrame(\n {\n \"x\": [0, L],\n \"y\": [0, 0],\n }\n)\n\nfig.add_scatter(\n x=fixed_points[\"x\"],\n y=fixed_points[\"y\"],\n mode=\"markers\",\n marker=dict(color=\"black\", size=10),\n showlegend=False,\n)\n\nfig.update_layout(\n showlegend=False,\n height=280,\n margin=dict(l=10, r=30, t=30, b=10),\n updatemenus=[\n {\n \"buttons\": [\n {\n \"args\": [\n None,\n {\n \"frame\": {\"duration\": 200, \"redraw\": True},\n \"fromcurrent\": True,\n \"mode\": \"immediate\",\n \"transition\": {\"duration\": 0},\n },\n ],\n \"label\": \"Play\",\n \"method\": \"animate\",\n },\n {\n \"args\": [\n [None],\n {\n \"frame\": {\"duration\": 0, \"redraw\": True},\n \"mode\": \"immediate\",\n \"transition\": {\"duration\": 0},\n },\n ],\n \"label\": \"Pause\",\n \"method\": \"animate\",\n },\n ],\n \"type\": \"buttons\",\n \"direction\": \"left\",\n \"showactive\": True,\n \"x\": 0.2,\n \"y\": 0.3,\n \"xanchor\": \"right\",\n \"yanchor\": \"top\",\n }\n ],\n sliders=[\n {\n \"active\": 0,\n \"yanchor\": \"top\",\n \"xanchor\": \"left\",\n \"currentvalue\": {\"font\": {\"size\": 16}, \"visible\": True, \"xanchor\": \"right\"},\n \"transition\": {\"duration\": 500, \"easing\": \"cubic-in-out\"},\n \"pad\": {\"b\": 10, \"t\": 50},\n \"len\": 1,\n \"x\": 0,\n \"y\": 0,\n \"steps\": [\n {\n \"args\": [\n [f\"t = {t:.2f}\"],\n {\n \"frame\": {\n \"duration\": 500,\n \"easing\": \"cubic-in-out\",\n \"redraw\": True,\n },\n \"mode\": \"immediate\",\n \"transition\": {\"duration\": 0},\n },\n ],\n \"label\": f\"{t:.0f}\",\n \"method\": \"animate\",\n }\n for t in t\n ],\n }\n ],\n)\n\nconfig = {\n \"displayModeBar\": True, # Show the toolbar\n # \"modeBarButtonsToRemove\": [\"lasso2d\", \"select2d\"], # Remove unused buttons\n \"displaylogo\": False,\n \"toImageButtonOptions\": {\"height\": 500, \"width\": 800}, # Image export size\n}\nfig.write_html(\n \"content/code/2025-01-04-fourier-method-fixed-string/fixed_string_animation.html\",\n include_plotlyjs=True,\n full_html=True,\n auto_play=False,\n config=config,\n)\n\n\n\n\nTest\n\nimport plotly.io as pio\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\n\npio.renderers.default = \"plotly_mimetype+notebook_connected\"\n\n# Define constants\nL = np.pi * np.sqrt(5)\na = 2 / 3\ntmax = 30\nx = np.linspace(0, L, 101)\nt = np.linspace(0, tmax, 31) # Fewer points for smoother interaction\n\n\n# Define the initial condition phi(x)\ndef phi(x):\n y = np.zeros_like(x)\n y[(1 &lt; x) & (x &lt; 3)] = np.sin(np.pi * x[(1 &lt; x) & (x &lt; 3)]) ** 3\n return y\n\n\n# Define the initial velocity psi(x)\ndef psi(x):\n return np.zeros_like(x)\n\n\n# Define the Fourier solution for u(x, t)\ndef fourier_u(x, t):\n y = np.zeros_like(x)\n for k in range(1, 101):\n Xk = np.sin(k * np.pi * x / L)\n Ak = (2 / L) * np.trapezoid(phi(x) * Xk, x)\n Bk = (2 / (a * k * np.pi)) * np.trapezoid(psi(x) * Xk, x)\n Tk = Ak * np.cos(a * k * np.pi * t / L) + Bk * np.sin(a * k * np.pi * t / L)\n y += Tk * Xk\n return y\n\n\n# Create animation data\ndata = []\nfor t_val in t:\n y = fourier_u(x, t_val)\n for x_val, y_val in zip(x, y):\n data.append({\"x\": x_val, \"y\": y_val, \"t\": f\"t = {t_val:.2f}\"})\n\n# Create DataFrame and plot\ndf = pd.DataFrame(data)\nfig = px.line(\n df,\n x=\"x\",\n y=\"y\",\n animation_frame=\"t\",\n # title=\"String Motion\",\n labels={\"x\": \"x\", \"y\": \"u(x, t)\"},\n range_x=[-0.06, L + 0.06],\n range_y=[-1.1, 1.1],\n color_discrete_sequence=[\"red\"],\n)\n\n# Add fixed points as black dots\nfixed_points = pd.DataFrame(\n {\n \"x\": [0, L],\n \"y\": [0, 0],\n }\n)\n\nfig.add_scatter(\n x=fixed_points[\"x\"],\n y=fixed_points[\"y\"],\n mode=\"markers\",\n marker=dict(color=\"black\", size=10),\n showlegend=False,\n)\n\nfig.update_layout(\n showlegend=False,\n height=280,\n margin=dict(l=10, r=30, t=30, b=10),\n updatemenus=[\n {\n \"buttons\": [\n {\n \"args\": [\n None,\n {\n \"frame\": {\"duration\": 200, \"redraw\": True},\n \"fromcurrent\": True,\n \"mode\": \"immediate\",\n \"transition\": {\"duration\": 0},\n },\n ],\n \"label\": \"Play\",\n \"method\": \"animate\",\n },\n {\n \"args\": [\n [None],\n {\n \"frame\": {\"duration\": 0, \"redraw\": True},\n \"mode\": \"immediate\",\n \"transition\": {\"duration\": 0},\n },\n ],\n \"label\": \"Pause\",\n \"method\": \"animate\",\n },\n ],\n \"type\": \"buttons\",\n \"direction\": \"left\",\n \"showactive\": True,\n \"x\": 0.2,\n \"y\": 0.3,\n \"xanchor\": \"right\",\n \"yanchor\": \"top\",\n }\n ],\n sliders=[\n {\n \"active\": 0,\n \"yanchor\": \"top\",\n \"xanchor\": \"left\",\n \"currentvalue\": {\"font\": {\"size\": 16}, \"visible\": True, \"xanchor\": \"right\"},\n \"transition\": {\"duration\": 500, \"easing\": \"cubic-in-out\"},\n \"pad\": {\"b\": 10, \"t\": 50},\n \"len\": 1,\n \"x\": 0,\n \"y\": 0,\n \"steps\": [\n {\n \"args\": [\n [f\"t = {t:.2f}\"],\n {\n \"frame\": {\n \"duration\": 500,\n \"easing\": \"cubic-in-out\",\n \"redraw\": True,\n },\n \"mode\": \"immediate\",\n \"transition\": {\"duration\": 0},\n },\n ],\n \"label\": f\"{t:.0f}\",\n \"method\": \"animate\",\n }\n for t in t\n ],\n }\n ],\n)\n\nfig.show()\n\n \n \n \n\n\n \n \n\n\n\nimport plotly.express as px\nimport plotly.io as pio\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\n\npio.renderers.default = \"plotly_mimetype+notebook_connected\"\n\ndf = px.data.iris()\nfig = px.scatter(df, x=\"sepal_width\", y=\"sepal_length\", \n color=\"species\", \n marginal_y=\"violin\", marginal_x=\"box\", \n trendline=\"ols\", template=\"simple_white\")\nfig.show()\n\n \n \n \n\n\n \n \n\n\nTest"
50
- },
51
- {
52
- "objectID": "index.html",
53
- "href": "index.html",
54
- "title": "quarto-blog",
55
- "section": "",
56
- "text": "Chebyshev Polynomials: Part 1\n\n\n\n\n\n\nmathematics\n\n\npolynomials\n\n\n\n\n\n\n\n\n\nJan 6, 2025\n\n\nJoana Levtcheva\n\n\n\n\n\n\n\n\n\n\n\n\nFourier Method for the 1D Wave Equation: Fixed String\n\n\n\n\n\n\nmathematics\n\n\npde\n\n\n\n\n\n\n\n\n\nJan 4, 2025\n\n\nJoana Levtcheva\n\n\n\n\n\n\nNo matching items"
57
- }
58
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/_site/site_libs/bootstrap/bootstrap-d1b12f2568ecbe55642fee6aa00bd082.min.css DELETED
The diff for this file is too large to render. See raw diff
 
src/_site/site_libs/bootstrap/bootstrap-icons.css DELETED
The diff for this file is too large to render. See raw diff
 
src/_site/site_libs/bootstrap/bootstrap-icons.woff DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:4d4572ef314e1b734cdd6485f913b0396d81bedf4d216a47cfde0cdf32a9316e
3
- size 176200
 
 
 
 
src/_site/site_libs/bootstrap/bootstrap.min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- * Bootstrap v5.3.1 (https://getbootstrap.com/)
3
- * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
- */
6
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function j(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${j(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${j(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${j(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return n(e)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="next",lt="prev",ct="left",ht="right",dt=`slide${ot}`,ut=`slid${ot}`,ft=`keydown${ot}`,pt=`mouseenter${ot}`,mt=`mouseleave${ot}`,gt=`dragstart${ot}`,_t=`load${ot}${rt}`,bt=`click${ot}${rt}`,vt="carousel",yt="active",wt=".active",At=".carousel-item",Et=wt+At,Tt={ArrowLeft:ht,ArrowRight:ct},Ct={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class xt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===vt&&this.cycle()}static get Default(){return Ct}static get DefaultType(){return Ot}static get NAME(){return"carousel"}next(){this._slide(at)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(lt)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,ut,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,ut,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?at:lt;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,ft,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,pt,(()=>this.pause())),N.on(this._element,mt,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,gt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ct)),rightCallback:()=>this._slide(this._directionToOrder(ht)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Tt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(wt,this._indicatorsElement);e.classList.remove(yt),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(yt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===at,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(dt).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(yt),i.classList.remove(yt,c,l),this._isSliding=!1,r(ut)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Et,this._element)}_getItems(){return z.find(At,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===ct?lt:at:t===ct?at:lt}_orderToDirection(t){return p()?t===lt?ct:ht:t===lt?ht:ct}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,bt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(vt))return;t.preventDefault();const i=xt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,_t,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)xt.getOrCreateInstance(e)})),m(xt);const kt=".bs.collapse",Lt=`show${kt}`,St=`shown${kt}`,Dt=`hide${kt}`,$t=`hidden${kt}`,It=`click${kt}.data-api`,Nt="show",Pt="collapse",Mt="collapsing",jt=`:scope .${Pt} .${Pt}`,Ft='[data-bs-toggle="collapse"]',Ht={parent:null,toggle:!0},Wt={parent:"(null|element)",toggle:"boolean"};class Bt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Ft);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Ht}static get DefaultType(){return Wt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Bt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Lt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Pt),this._element.classList.add(Mt),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt,Nt),this._element.style[e]="",N.trigger(this._element,St)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,Dt).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Mt),this._element.classList.remove(Pt,Nt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt),N.trigger(this._element,$t)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(Nt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Ft);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(jt,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Bt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,It,Ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Bt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Bt);var zt="top",Rt="bottom",qt="right",Vt="left",Kt="auto",Qt=[zt,Rt,qt,Vt],Xt="start",Yt="end",Ut="clippingParents",Gt="viewport",Jt="popper",Zt="reference",te=Qt.reduce((function(t,e){return t.concat([e+"-"+Xt,e+"-"+Yt])}),[]),ee=[].concat(Qt,[Kt]).reduce((function(t,e){return t.concat([e,e+"-"+Xt,e+"-"+Yt])}),[]),ie="beforeRead",ne="read",se="afterRead",oe="beforeMain",re="main",ae="afterMain",le="beforeWrite",ce="write",he="afterWrite",de=[ie,ne,se,oe,re,ae,le,ce,he];function ue(t){return t?(t.nodeName||"").toLowerCase():null}function fe(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function pe(t){return t instanceof fe(t).Element||t instanceof Element}function me(t){return t instanceof fe(t).HTMLElement||t instanceof HTMLElement}function ge(t){return"undefined"!=typeof ShadowRoot&&(t instanceof fe(t).ShadowRoot||t instanceof ShadowRoot)}const _e={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];me(s)&&ue(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});me(n)&&ue(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function be(t){return t.split("-")[0]}var ve=Math.max,ye=Math.min,we=Math.round;function Ae(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ee(){return!/^((?!chrome|android).)*safari/i.test(Ae())}function Te(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&me(t)&&(s=t.offsetWidth>0&&we(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&we(n.height)/t.offsetHeight||1);var r=(pe(t)?fe(t):window).visualViewport,a=!Ee()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Ce(t){var e=Te(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Oe(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ge(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function xe(t){return fe(t).getComputedStyle(t)}function ke(t){return["table","td","th"].indexOf(ue(t))>=0}function Le(t){return((pe(t)?t.ownerDocument:t.document)||window.document).documentElement}function Se(t){return"html"===ue(t)?t:t.assignedSlot||t.parentNode||(ge(t)?t.host:null)||Le(t)}function De(t){return me(t)&&"fixed"!==xe(t).position?t.offsetParent:null}function $e(t){for(var e=fe(t),i=De(t);i&&ke(i)&&"static"===xe(i).position;)i=De(i);return i&&("html"===ue(i)||"body"===ue(i)&&"static"===xe(i).position)?e:i||function(t){var e=/firefox/i.test(Ae());if(/Trident/i.test(Ae())&&me(t)&&"fixed"===xe(t).position)return null;var i=Se(t);for(ge(i)&&(i=i.host);me(i)&&["html","body"].indexOf(ue(i))<0;){var n=xe(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Ie(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Ne(t,e,i){return ve(t,ye(e,i))}function Pe(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Me(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const je={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=be(i.placement),l=Ie(a),c=[Vt,qt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Pe("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Me(t,Qt))}(s.padding,i),d=Ce(o),u="y"===l?zt:Vt,f="y"===l?Rt:qt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=$e(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=Ne(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Oe(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Fe(t){return t.split("-")[1]}var He={top:"auto",right:"auto",bottom:"auto",left:"auto"};function We(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Vt,y=zt,w=window;if(c){var A=$e(i),E="clientHeight",T="clientWidth";A===fe(i)&&"static"!==xe(A=Le(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===zt||(s===Vt||s===qt)&&o===Yt)&&(y=Rt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Vt&&(s!==zt&&s!==Rt||o!==Yt)||(v=qt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&He),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:we(i*s)/s||0,y:we(n*s)/s||0}}({x:f,y:m},fe(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Be={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:be(e.placement),variation:Fe(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,We(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,We(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ze={passive:!0};const Re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=fe(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ze)})),a&&l.addEventListener("resize",i.update,ze),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ze)})),a&&l.removeEventListener("resize",i.update,ze)}},data:{}};var qe={left:"right",right:"left",bottom:"top",top:"bottom"};function Ve(t){return t.replace(/left|right|bottom|top/g,(function(t){return qe[t]}))}var Ke={start:"end",end:"start"};function Qe(t){return t.replace(/start|end/g,(function(t){return Ke[t]}))}function Xe(t){var e=fe(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ye(t){return Te(Le(t)).left+Xe(t).scrollLeft}function Ue(t){var e=xe(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ge(t){return["html","body","#document"].indexOf(ue(t))>=0?t.ownerDocument.body:me(t)&&Ue(t)?t:Ge(Se(t))}function Je(t,e){var i;void 0===e&&(e=[]);var n=Ge(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=fe(n),r=s?[o].concat(o.visualViewport||[],Ue(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Je(Se(r)))}function Ze(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ti(t,e,i){return e===Gt?Ze(function(t,e){var i=fe(t),n=Le(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ee();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ye(t),y:l}}(t,i)):pe(e)?function(t,e){var i=Te(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ze(function(t){var e,i=Le(t),n=Xe(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ve(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ve(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ye(t),l=-n.scrollTop;return"rtl"===xe(s||i).direction&&(a+=ve(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Le(t)))}function ei(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?be(s):null,r=s?Fe(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case zt:e={x:a,y:i.y-n.height};break;case Rt:e={x:a,y:i.y+i.height};break;case qt:e={x:i.x+i.width,y:l};break;case Vt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Ie(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Xt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Yt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ii(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Ut:a,c=i.rootBoundary,h=void 0===c?Gt:c,d=i.elementContext,u=void 0===d?Jt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Pe("number"!=typeof g?g:Me(g,Qt)),b=u===Jt?Zt:Jt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Je(Se(t)),i=["absolute","fixed"].indexOf(xe(t).position)>=0&&me(t)?$e(t):t;return pe(i)?e.filter((function(t){return pe(t)&&Oe(t,i)&&"body"!==ue(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ti(t,i,n);return e.top=ve(s.top,e.top),e.right=ye(s.right,e.right),e.bottom=ye(s.bottom,e.bottom),e.left=ve(s.left,e.left),e}),ti(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(pe(y)?y:y.contextElement||Le(t.elements.popper),l,h,r),A=Te(t.elements.reference),E=ei({reference:A,element:v,strategy:"absolute",placement:s}),T=Ze(Object.assign({},v,E)),C=u===Jt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Jt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[qt,Rt].indexOf(t)>=0?1:-1,i=[zt,Rt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function ni(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ee:l,h=Fe(n),d=h?a?te:te.filter((function(t){return Fe(t)===h})):Qt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ii(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[be(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const si={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=be(g),b=l||(_!==g&&p?function(t){if(be(t)===Kt)return[];var e=Ve(t);return[Qe(t),e,Qe(e)]}(g):[Ve(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(be(i)===Kt?ni(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C<v.length;C++){var O=v[C],x=be(O),k=Fe(O)===Xt,L=[zt,Rt].indexOf(x)>=0,S=L?"width":"height",D=ii(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?qt:Vt:k?Rt:zt;y[S]>w[S]&&($=Ve($));var I=Ve($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function oi(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ri(t){return[zt,qt,Rt,Vt].some((function(e){return t[e]>=0}))}const ai={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ii(e,{elementContext:"reference"}),a=ii(e,{altBoundary:!0}),l=oi(r,n),c=oi(a,s,o),h=ri(l),d=ri(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},li={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ee.reduce((function(t,i){return t[i]=function(t,e,i){var n=be(t),s=[Vt,zt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Vt,qt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ci={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ei({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},hi={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ii(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=be(e.placement),b=Fe(e.placement),v=!b,y=Ie(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?zt:Vt,D="y"===y?Rt:qt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],M=f?-T[$]/2:0,j=b===Xt?E[$]:T[$],F=b===Xt?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?Ce(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=Ne(0,E[$],W[$]),V=v?E[$]/2-M-q-z-O.mainAxis:j-q-z-O.mainAxis,K=v?-E[$]/2+M+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&$e(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=Ne(f?ye(N,I+V-Y-X):N,I,f?ve(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?zt:Vt,tt="x"===y?Rt:qt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[zt,Vt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=Ne(t,e,i);return n>i?i:n}(at,et,lt):Ne(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function di(t,e,i){void 0===i&&(i=!1);var n,s,o=me(e),r=me(e)&&function(t){var e=t.getBoundingClientRect(),i=we(e.width)/t.offsetWidth||1,n=we(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Le(e),l=Te(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==ue(e)||Ue(a))&&(c=(n=e)!==fe(n)&&me(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Xe(n)),me(e)?((h=Te(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function ui(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var fi={placement:"bottom",modifiers:[],strategy:"absolute"};function pi(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];return!e.some((function(t){return!(t&&"function"==typeof t.getBoundingClientRect)}))}function mi(t){void 0===t&&(t={});var e=t,i=e.defaultModifiers,n=void 0===i?[]:i,s=e.defaultOptions,o=void 0===s?fi:s;return function(t,e,i){void 0===i&&(i=o);var s,r,a={placement:"bottom",orderedModifiers:[],options:Object.assign({},fi,o),modifiersData:{},elements:{reference:t,popper:e},attributes:{},styles:{}},l=[],c=!1,h={state:a,setOptions:function(i){var s="function"==typeof i?i(a.options):i;d(),a.options=Object.assign({},o,a.options,s),a.scrollParents={reference:pe(t)?Je(t):t.contextElement?Je(t.contextElement):[],popper:Je(e)};var r,c,u=function(t){var e=ui(t);return de.reduce((function(t,i){return t.concat(e.filter((function(t){return t.phase===i})))}),[])}((r=[].concat(n,a.options.modifiers),c=r.reduce((function(t,e){var i=t[e.name];return t[e.name]=i?Object.assign({},i,e,{options:Object.assign({},i.options,e.options),data:Object.assign({},i.data,e.data)}):e,t}),{}),Object.keys(c).map((function(t){return c[t]}))));return a.orderedModifiers=u.filter((function(t){return t.enabled})),a.orderedModifiers.forEach((function(t){var e=t.name,i=t.options,n=void 0===i?{}:i,s=t.effect;if("function"==typeof s){var o=s({state:a,name:e,instance:h,options:n});l.push(o||function(){})}})),h.update()},forceUpdate:function(){if(!c){var t=a.elements,e=t.reference,i=t.popper;if(pi(e,i)){a.rects={reference:di(e,$e(i),"fixed"===a.options.strategy),popper:Ce(i)},a.reset=!1,a.placement=a.options.placement,a.orderedModifiers.forEach((function(t){return a.modifiersData[t.name]=Object.assign({},t.data)}));for(var n=0;n<a.orderedModifiers.length;n++)if(!0!==a.reset){var s=a.orderedModifiers[n],o=s.fn,r=s.options,l=void 0===r?{}:r,d=s.name;"function"==typeof o&&(a=o({state:a,options:l,name:d,instance:h})||a)}else a.reset=!1,n=-1}}},update:(s=function(){return new Promise((function(t){h.forceUpdate(),t(a)}))},function(){return r||(r=new Promise((function(t){Promise.resolve().then((function(){r=void 0,t(s())}))}))),r}),destroy:function(){d(),c=!0}};if(!pi(t,e))return h;function d(){l.forEach((function(t){return t()})),l=[]}return h.setOptions(i).then((function(t){!c&&i.onFirstUpdate&&i.onFirstUpdate(t)})),h}}var gi=mi(),_i=mi({defaultModifiers:[Re,ci,Be,_e]}),bi=mi({defaultModifiers:[Re,ci,Be,_e,li,si,hi,je,ai]});const vi=Object.freeze(Object.defineProperty({__proto__:null,afterMain:ae,afterRead:se,afterWrite:he,applyStyles:_e,arrow:je,auto:Kt,basePlacements:Qt,beforeMain:oe,beforeRead:ie,beforeWrite:le,bottom:Rt,clippingParents:Ut,computeStyles:Be,createPopper:bi,createPopperBase:gi,createPopperLite:_i,detectOverflow:ii,end:Yt,eventListeners:Re,flip:si,hide:ai,left:Vt,main:re,modifierPhases:de,offset:li,placements:ee,popper:Jt,popperGenerator:mi,popperOffsets:ci,preventOverflow:hi,read:ne,reference:Zt,right:qt,start:Xt,top:zt,variationPlacements:te,viewport:Gt,write:ce},Symbol.toStringTag,{value:"Module"})),yi="dropdown",wi=".bs.dropdown",Ai=".data-api",Ei="ArrowUp",Ti="ArrowDown",Ci=`hide${wi}`,Oi=`hidden${wi}`,xi=`show${wi}`,ki=`shown${wi}`,Li=`click${wi}${Ai}`,Si=`keydown${wi}${Ai}`,Di=`keyup${wi}${Ai}`,$i="show",Ii='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Ni=`${Ii}.${$i}`,Pi=".dropdown-menu",Mi=p()?"top-end":"top-start",ji=p()?"top-start":"top-end",Fi=p()?"bottom-end":"bottom-start",Hi=p()?"bottom-start":"bottom-end",Wi=p()?"left-start":"right-start",Bi=p()?"right-start":"left-start",zi={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Ri={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class qi extends W{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=z.next(this._element,Pi)[0]||z.prev(this._element,Pi)[0]||z.findOne(Pi,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return zi}static get DefaultType(){return Ri}static get NAME(){return yi}toggle(){return this._isShown()?this.hide():this.show()}show(){if(l(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!N.trigger(this._element,xi,t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add($i),this._element.classList.add($i),N.trigger(this._element,ki,t)}}hide(){if(l(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!N.trigger(this._element,Ci,t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._popper&&this._popper.destroy(),this._menu.classList.remove($i),this._element.classList.remove($i),this._element.setAttribute("aria-expanded","false"),F.removeDataAttribute(this._menu,"popper"),N.trigger(this._element,Oi,t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${yi.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===vi)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:o(this._config.reference)?t=r(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const e=this._getPopperConfig();this._popper=bi(t,this._menu,e)}_isShown(){return this._menu.classList.contains($i)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return Wi;if(t.classList.contains("dropstart"))return Bi;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ji:Mi:e?Hi:Fi}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ei,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:z.prev(this,Ii)[0]||z.next(this,Ii)[0]||z.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,Si,Ii,qi.dataApiKeydownHandler),N.on(document,Si,Pi,qi.dataApiKeydownHandler),N.on(document,Li,qi.clearMenus),N.on(document,Di,qi.clearMenus),N.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),m(qi);const Vi="backdrop",Ki="show",Qi=`mousedown.bs.${Vi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Yi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Ki),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Qi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Gi),N.on(document,Ji,(t=>this._handleFocusin(t))),N.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",An="show",En="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,hn),N.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,bn,(t=>{N.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(En)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(En),this._queueCallback((()=>{this._element.classList.remove(En),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,pn,(t=>{t.defaultPrevented||N.one(e,fn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),R(On),m(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Wn=`click${xn}${kn}`,Bn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),N.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),N.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Bn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Fn,(()=>{a(this)&&this.focus()}));const i=z.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),N.on(window,Ln,(()=>{for(const t of z.find(In))qn.getOrCreateInstance(t).show()})),N.on(window,Hn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),R(qn),m(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Yn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"<div></div>"},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Yn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends W{constructor(t,e){if(void 0===vi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return bi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Es extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ms),N.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(bs,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),N.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=z.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=Es.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,gs,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))Es.getOrCreateInstance(t)})),m(Es);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Ws="show",Bs=":not(.dropdown-toggle)",zs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Rs=`.nav-link${Bs}, .list-group-item${Bs}, [role="tab"]${Bs}, ${zs}`,qs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Vs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Cs,{relatedTarget:t}):null;N.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,ks,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Vs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Rs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",Fs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(Rs)?t:z.findOne(Rs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Vs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ls,zs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Vs.getOrCreateInstance(this).show()})),N.on(window,Ds,(()=>{for(const t of z.find(qs))Vs.getOrCreateInstance(t)})),m(Vs);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Ys=`focusin${Ks}`,Us=`focusout${Ks}`,Gs=`hide${Ks}`,Js=`hidden${Ks}`,Zs=`show${Ks}`,to=`shown${Ks}`,eo="hide",io="show",no="showing",so={animation:"boolean",autohide:"boolean",delay:"number"},oo={animation:!0,autohide:!0,delay:5e3};class ro extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return oo}static get DefaultType(){return so}static get NAME(){return"toast"}show(){N.trigger(this._element,Zs).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(eo),d(this._element),this._element.classList.add(io,no),this._queueCallback((()=>{this._element.classList.remove(no),N.trigger(this._element,to),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,Gs).defaultPrevented||(this._element.classList.add(no),this._queueCallback((()=>{this._element.classList.add(eo),this._element.classList.remove(no,io),N.trigger(this._element,Js)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(io),super.dispose()}isShown(){return this._element.classList.contains(io)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Qs,(t=>this._onInteraction(t,!0))),N.on(this._element,Xs,(t=>this._onInteraction(t,!1))),N.on(this._element,Ys,(t=>this._onInteraction(t,!0))),N.on(this._element,Us,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ro.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(ro),m(ro),{Alert:Q,Button:Y,Carousel:xt,Collapse:Bt,Dropdown:qi,Modal:On,Offcanvas:qn,Popover:us,ScrollSpy:Es,Tab:Vs,Toast:ro,Tooltip:cs}}));
7
- //# sourceMappingURL=bootstrap.bundle.min.js.map
 
 
 
 
 
 
 
 
src/_site/site_libs/clipboard/clipboard.min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- * clipboard.js v2.0.11
3
- * https://clipboardjs.com/
4
- *
5
- * Licensed MIT © Zeno Rocha
6
- */
7
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body},n="";return"string"==typeof t?n=o(t,e):t instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(null==t?void 0:t.type)?n=o(t.value,e):(n=r()(t),c("copy")),n};function l(t){return(l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var s=function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},e=t.action,n=void 0===e?"copy":e,o=t.container,e=t.target,t=t.text;if("copy"!==n&&"cut"!==n)throw new Error('Invalid "action" value, use either "copy" or "cut"');if(void 0!==e){if(!e||"object"!==l(e)||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===n&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===n&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes')}return t?f(t,{container:o}):e?"cut"===n?a(e):f(e,{container:o}):void 0};function p(t){return(p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function d(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function y(t,e){return(y=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function h(n){var o=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}();return function(){var t,e=v(n);return t=o?(t=v(this).constructor,Reflect.construct(e,arguments,t)):e.apply(this,arguments),e=this,!(t=t)||"object"!==p(t)&&"function"!=typeof t?function(t){if(void 0!==t)return t;throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}(e):t}}function v(t){return(v=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function m(t,e){t="data-clipboard-".concat(t);if(e.hasAttribute(t))return e.getAttribute(t)}var b=function(){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&y(t,e)}(r,i());var t,e,n,o=h(r);function r(t,e){var n;return function(t){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}(this),(n=o.call(this)).resolveOptions(e),n.listenClick(t),n}return t=r,n=[{key:"copy",value:function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body};return f(t,e)}},{key:"cut",value:function(t){return a(t)}},{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof t?[t]:t,e=!!document.queryCommandSupported;return t.forEach(function(t){e=e&&!!document.queryCommandSupported(t)}),e}}],(e=[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===p(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=u()(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget,n=this.action(e)||"copy",t=s({action:n,container:this.container,target:this.target(e),text:this.text(e)});this.emit(t?"success":"error",{action:n,text:t,trigger:e,clearSelection:function(){e&&e.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(t){return m("action",t)}},{key:"defaultTarget",value:function(t){t=m("target",t);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(t){return m("text",t)}},{key:"destroy",value:function(){this.listener.destroy()}}])&&d(t.prototype,e),n&&d(t,n),r}()},828:function(t){var e;"undefined"==typeof Element||Element.prototype.matches||((e=Element.prototype).matches=e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector),t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}},438:function(t,e,n){var u=n(828);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=u(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},879:function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},370:function(t,e,n){var f=n(879),l=n(438);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!f.string(e))throw new TypeError("Second argument must be a String");if(!f.fn(n))throw new TypeError("Third argument must be a Function");if(f.node(t))return c=e,a=n,(u=t).addEventListener(c,a),{destroy:function(){u.removeEventListener(c,a)}};if(f.nodeList(t))return o=t,r=e,i=n,Array.prototype.forEach.call(o,function(t){t.addEventListener(r,i)}),{destroy:function(){Array.prototype.forEach.call(o,function(t){t.removeEventListener(r,i)})}};if(f.string(t))return t=t,e=e,n=n,l(document.body,t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,u,c,a}},817:function(t){t.exports=function(t){var e,n="SELECT"===t.nodeName?(t.focus(),t.value):"INPUT"===t.nodeName||"TEXTAREA"===t.nodeName?((e=t.hasAttribute("readonly"))||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),e||t.removeAttribute("readonly"),t.value):(t.hasAttribute("contenteditable")&&t.focus(),n=window.getSelection(),(e=document.createRange()).selectNodeContents(t),n.removeAllRanges(),n.addRange(e),n.toString());return n}},279:function(t){function e(){}e.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,u=o.length;i<u;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=e,t.exports.TinyEmitter=e}},r={},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,{a:e}),e},o.d=function(t,e){for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o(686).default;function o(t){if(r[t])return r[t].exports;var e=r[t]={exports:{}};return n[t](e,e.exports,o),e.exports}var n,r});
 
 
 
 
 
 
 
 
src/_site/site_libs/quarto-html/anchor.min.js DELETED
@@ -1,9 +0,0 @@
1
- // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat
2
- //
3
- // AnchorJS - v5.0.0 - 2023-01-18
4
- // https://www.bryanbraun.com/anchorjs/
5
- // Copyright (c) 2023 Bryan Braun; Licensed MIT
6
- //
7
- // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat
8
- !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(globalThis,function(){"use strict";return function(A){function u(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function d(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],u(this.options),this.add=function(A){var e,t,o,i,n,s,a,r,l,c,h,p=[];if(u(this.options),0!==(e=d(A=A||"h2, h3, h4, h5, h6")).length){for(null===document.head.querySelector("style.anchorjs")&&((A=document.createElement("style")).className="anchorjs",A.appendChild(document.createTextNode("")),void 0===(h=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(A):document.head.insertBefore(A,h),A.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",A.sheet.cssRules.length),A.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i<e.length;i++)if(this.hasAnchorJSLink(e[i]))p.push(i);else{if(e[i].hasAttribute("id"))o=e[i].getAttribute("id");else if(e[i].hasAttribute("data-anchor-id"))o=e[i].getAttribute("data-anchor-id");else{for(r=a=this.urlify(e[i].textContent),s=0;n=t.indexOf(r=void 0!==n?a+"-"+s:r),s+=1,-1!==n;);n=void 0,t.push(r),e[i].setAttribute("id",r),o=r}(l=document.createElement("a")).className="anchorjs-link "+this.options.class,l.setAttribute("aria-label",this.options.ariaLabel),l.setAttribute("data-anchorjs-icon",this.options.icon),this.options.titleText&&(l.title=this.options.titleText),c=document.querySelector("base")?window.location.pathname+window.location.search:"",c=this.options.base||c,l.href=c+"#"+o,"always"===this.options.visible&&(l.style.opacity="1"),""===this.options.icon&&(l.style.font="1em/1 anchorjs-icons","left"===this.options.placement)&&(l.style.lineHeight="inherit"),"left"===this.options.placement?(l.style.position="absolute",l.style.marginLeft="-1.25em",l.style.paddingRight=".25em",l.style.paddingLeft=".25em",e[i].insertBefore(l,e[i].firstChild)):(l.style.marginLeft=".1875em",l.style.paddingRight=".1875em",l.style.paddingLeft=".1875em",e[i].appendChild(l))}for(i=0;i<p.length;i++)e.splice(p[i]-i,1);this.elements=this.elements.concat(e)}return this},this.remove=function(A){for(var e,t,o=d(A),i=0;i<o.length;i++)(t=o[i].querySelector(".anchorjs-link"))&&(-1!==(e=this.elements.indexOf(o[i]))&&this.elements.splice(e,1),o[i].removeChild(t));return this},this.removeAll=function(){this.remove(this.elements)},this.urlify=function(A){var e=document.createElement("textarea");return e.innerHTML=A,A=e.value,this.options.truncate||u(this.options),A.trim().replace(/'/gi,"").replace(/[& +$,:;=?@"#{}|^~[`%!'<>\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}});
9
- // @license-end
 
 
 
 
 
 
 
 
 
 
src/_site/site_libs/quarto-html/popper.min.js DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * @popperjs/core v2.11.7 - MIT License
3
- */
4
-
5
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function c(){return!/^((?!chrome|android).)*safari/i.test(f())}function p(e,o,i){void 0===o&&(o=!1),void 0===i&&(i=!1);var a=e.getBoundingClientRect(),f=1,p=1;o&&r(e)&&(f=e.offsetWidth>0&&s(a.width)/e.offsetWidth||1,p=e.offsetHeight>0&&s(a.height)/e.offsetHeight||1);var u=(n(e)?t(e):window).visualViewport,l=!c()&&i,d=(a.left+(l&&u?u.offsetLeft:0))/f,h=(a.top+(l&&u?u.offsetTop:0))/p,m=a.width/f,v=a.height/p;return{width:m,height:v,top:h,right:d+m,bottom:h+v,left:d,x:d,y:h}}function u(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function l(e){return e?(e.nodeName||"").toLowerCase():null}function d(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function h(e){return p(d(e)).left+u(e).scrollLeft}function m(e){return t(e).getComputedStyle(e)}function v(e){var t=m(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function y(e,n,o){void 0===o&&(o=!1);var i,a,f=r(n),c=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),m=d(n),y=p(e,c,o),g={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(f||!f&&!o)&&(("body"!==l(n)||v(m))&&(g=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:u(i)),r(n)?((b=p(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):m&&(b.x=h(m))),{x:y.left+g.scrollLeft-b.x,y:y.top+g.scrollTop-b.y,width:y.width,height:y.height}}function g(e){var t=p(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function b(e){return"html"===l(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||d(e)}function x(e){return["html","body","#document"].indexOf(l(e))>=0?e.ownerDocument.body:r(e)&&v(e)?e:x(b(e))}function w(e,n){var r;void 0===n&&(n=[]);var o=x(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],v(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(w(b(s)))}function O(e){return["table","td","th"].indexOf(l(e))>=0}function j(e){return r(e)&&"fixed"!==m(e).position?e.offsetParent:null}function E(e){for(var n=t(e),i=j(e);i&&O(i)&&"static"===m(i).position;)i=j(i);return i&&("html"===l(i)||"body"===l(i)&&"static"===m(i).position)?n:i||function(e){var t=/firefox/i.test(f());if(/Trident/i.test(f())&&r(e)&&"fixed"===m(e).position)return null;var n=b(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(l(n))<0;){var i=m(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var D="top",A="bottom",L="right",P="left",M="auto",k=[D,A,L,P],W="start",B="end",H="viewport",T="popper",R=k.reduce((function(e,t){return e.concat([t+"-"+W,t+"-"+B])}),[]),S=[].concat(k,[M]).reduce((function(e,t){return e.concat([t,t+"-"+W,t+"-"+B])}),[]),V=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function q(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function N(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function I(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function _(e,r,o){return r===H?I(function(e,n){var r=t(e),o=d(e),i=r.visualViewport,a=o.clientWidth,s=o.clientHeight,f=0,p=0;if(i){a=i.width,s=i.height;var u=c();(u||!u&&"fixed"===n)&&(f=i.offsetLeft,p=i.offsetTop)}return{width:a,height:s,x:f+h(e),y:p}}(e,o)):n(r)?function(e,t){var n=p(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(r,o):I(function(e){var t,n=d(e),r=u(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+h(e),c=-r.scrollTop;return"rtl"===m(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:c}}(d(e)))}function F(e,t,o,s){var f="clippingParents"===t?function(e){var t=w(b(e)),o=["absolute","fixed"].indexOf(m(e).position)>=0&&r(e)?E(e):e;return n(o)?t.filter((function(e){return n(e)&&N(e,o)&&"body"!==l(e)})):[]}(e):[].concat(t),c=[].concat(f,[o]),p=c[0],u=c.reduce((function(t,n){var r=_(e,n,s);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),_(e,p,s));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function U(e){return e.split("-")[1]}function z(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function X(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?U(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case D:t={x:s,y:n.y-r.height};break;case A:t={x:s,y:n.y+n.height};break;case L:t={x:n.x+n.width,y:f};break;case P:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?z(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case W:t[c]=t[c]-(n[p]/2-r[p]/2);break;case B:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function Y(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function G(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function J(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.strategy,s=void 0===a?e.strategy:a,f=r.boundary,c=void 0===f?"clippingParents":f,u=r.rootBoundary,l=void 0===u?H:u,h=r.elementContext,m=void 0===h?T:h,v=r.altBoundary,y=void 0!==v&&v,g=r.padding,b=void 0===g?0:g,x=Y("number"!=typeof b?b:G(b,k)),w=m===T?"reference":T,O=e.rects.popper,j=e.elements[y?w:m],E=F(n(j)?j:j.contextElement||d(e.elements.popper),c,l,s),P=p(e.elements.reference),M=X({reference:P,element:O,strategy:"absolute",placement:i}),W=I(Object.assign({},O,M)),B=m===T?W:P,R={top:E.top-B.top+x.top,bottom:B.bottom-E.bottom+x.bottom,left:E.left-B.left+x.left,right:B.right-E.right+x.right},S=e.modifiersData.offset;if(m===T&&S){var V=S[i];Object.keys(R).forEach((function(e){var t=[L,A].indexOf(e)>=0?1:-1,n=[D,A].indexOf(e)>=0?"y":"x";R[e]+=V[n]*t}))}return R}var K={placement:"bottom",modifiers:[],strategy:"absolute"};function Q(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return!t.some((function(e){return!(e&&"function"==typeof e.getBoundingClientRect)}))}function Z(e){void 0===e&&(e={});var t=e,r=t.defaultModifiers,o=void 0===r?[]:r,i=t.defaultOptions,a=void 0===i?K:i;return function(e,t,r){void 0===r&&(r=a);var i,s,f={placement:"bottom",orderedModifiers:[],options:Object.assign({},K,a),modifiersData:{},elements:{reference:e,popper:t},attributes:{},styles:{}},c=[],p=!1,u={state:f,setOptions:function(r){var i="function"==typeof r?r(f.options):r;l(),f.options=Object.assign({},a,f.options,i),f.scrollParents={reference:n(e)?w(e):e.contextElement?w(e.contextElement):[],popper:w(t)};var s,p,d=function(e){var t=q(e);return V.reduce((function(e,n){return e.concat(t.filter((function(e){return e.phase===n})))}),[])}((s=[].concat(o,f.options.modifiers),p=s.reduce((function(e,t){var n=e[t.name];return e[t.name]=n?Object.assign({},n,t,{options:Object.assign({},n.options,t.options),data:Object.assign({},n.data,t.data)}):t,e}),{}),Object.keys(p).map((function(e){return p[e]}))));return f.orderedModifiers=d.filter((function(e){return e.enabled})),f.orderedModifiers.forEach((function(e){var t=e.name,n=e.options,r=void 0===n?{}:n,o=e.effect;if("function"==typeof o){var i=o({state:f,name:t,instance:u,options:r}),a=function(){};c.push(i||a)}})),u.update()},forceUpdate:function(){if(!p){var e=f.elements,t=e.reference,n=e.popper;if(Q(t,n)){f.rects={reference:y(t,E(n),"fixed"===f.options.strategy),popper:g(n)},f.reset=!1,f.placement=f.options.placement,f.orderedModifiers.forEach((function(e){return f.modifiersData[e.name]=Object.assign({},e.data)}));for(var r=0;r<f.orderedModifiers.length;r++)if(!0!==f.reset){var o=f.orderedModifiers[r],i=o.fn,a=o.options,s=void 0===a?{}:a,c=o.name;"function"==typeof i&&(f=i({state:f,options:s,name:c,instance:u})||f)}else f.reset=!1,r=-1}}},update:(i=function(){return new Promise((function(e){u.forceUpdate(),e(f)}))},function(){return s||(s=new Promise((function(e){Promise.resolve().then((function(){s=void 0,e(i())}))}))),s}),destroy:function(){l(),p=!0}};if(!Q(e,t))return u;function l(){c.forEach((function(e){return e()})),c=[]}return u.setOptions(r).then((function(e){!p&&r.onFirstUpdate&&r.onFirstUpdate(e)})),u}}var $={passive:!0};var ee={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var n=e.state,r=e.instance,o=e.options,i=o.scroll,a=void 0===i||i,s=o.resize,f=void 0===s||s,c=t(n.elements.popper),p=[].concat(n.scrollParents.reference,n.scrollParents.popper);return a&&p.forEach((function(e){e.addEventListener("scroll",r.update,$)})),f&&c.addEventListener("resize",r.update,$),function(){a&&p.forEach((function(e){e.removeEventListener("scroll",r.update,$)})),f&&c.removeEventListener("resize",r.update,$)}},data:{}};var te={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=X({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},ne={top:"auto",right:"auto",bottom:"auto",left:"auto"};function re(e){var n,r=e.popper,o=e.popperRect,i=e.placement,a=e.variation,f=e.offsets,c=e.position,p=e.gpuAcceleration,u=e.adaptive,l=e.roundOffsets,h=e.isFixed,v=f.x,y=void 0===v?0:v,g=f.y,b=void 0===g?0:g,x="function"==typeof l?l({x:y,y:b}):{x:y,y:b};y=x.x,b=x.y;var w=f.hasOwnProperty("x"),O=f.hasOwnProperty("y"),j=P,M=D,k=window;if(u){var W=E(r),H="clientHeight",T="clientWidth";if(W===t(r)&&"static"!==m(W=d(r)).position&&"absolute"===c&&(H="scrollHeight",T="scrollWidth"),W=W,i===D||(i===P||i===L)&&a===B)M=A,b-=(h&&W===k&&k.visualViewport?k.visualViewport.height:W[H])-o.height,b*=p?1:-1;if(i===P||(i===D||i===A)&&a===B)j=L,y-=(h&&W===k&&k.visualViewport?k.visualViewport.width:W[T])-o.width,y*=p?1:-1}var R,S=Object.assign({position:c},u&&ne),V=!0===l?function(e,t){var n=e.x,r=e.y,o=t.devicePixelRatio||1;return{x:s(n*o)/o||0,y:s(r*o)/o||0}}({x:y,y:b},t(r)):{x:y,y:b};return y=V.x,b=V.y,p?Object.assign({},S,((R={})[M]=O?"0":"",R[j]=w?"0":"",R.transform=(k.devicePixelRatio||1)<=1?"translate("+y+"px, "+b+"px)":"translate3d("+y+"px, "+b+"px, 0)",R)):Object.assign({},S,((n={})[M]=O?b+"px":"",n[j]=w?y+"px":"",n.transform="",n))}var oe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,r=n.gpuAcceleration,o=void 0===r||r,i=n.adaptive,a=void 0===i||i,s=n.roundOffsets,f=void 0===s||s,c={placement:C(t.placement),variation:U(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:o,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,re(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:a,roundOffsets:f})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,re(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:f})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}};var ie={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},i=t.elements[e];r(i)&&l(i)&&(Object.assign(i.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],i=t.attributes[e]||{},a=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});r(o)&&l(o)&&(Object.assign(o.style,a),Object.keys(i).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]};var ae={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.offset,i=void 0===o?[0,0]:o,a=S.reduce((function(e,n){return e[n]=function(e,t,n){var r=C(e),o=[P,D].indexOf(r)>=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[P,L].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},se={left:"right",right:"left",bottom:"top",top:"bottom"};function fe(e){return e.replace(/left|right|bottom|top/g,(function(e){return se[e]}))}var ce={start:"end",end:"start"};function pe(e){return e.replace(/start|end/g,(function(e){return ce[e]}))}function ue(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?S:f,p=U(r),u=p?s?R:R.filter((function(e){return U(e)===p})):k,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=J(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var le={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,y=C(v),g=f||(y===v||!h?[fe(v)]:function(e){if(C(e)===M)return[];var t=fe(e);return[pe(e),t,pe(t)]}(v)),b=[v].concat(g).reduce((function(e,n){return e.concat(C(n)===M?ue(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,j=!0,E=b[0],k=0;k<b.length;k++){var B=b[k],H=C(B),T=U(B)===W,R=[D,A].indexOf(H)>=0,S=R?"width":"height",V=J(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),q=R?T?L:P:T?A:D;x[S]>w[S]&&(q=fe(q));var N=fe(q),I=[];if(i&&I.push(V[H]<=0),s&&I.push(V[q]<=0,V[N]<=0),I.every((function(e){return e}))){E=B,j=!1;break}O.set(B,I)}if(j)for(var _=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return E=t,"break"},F=h?3:1;F>0;F--){if("break"===_(F))break}t.placement!==E&&(t.modifiersData[r]._skip=!0,t.placement=E,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function de(e,t,n){return i(e,a(t,n))}var he={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,v=n.tetherOffset,y=void 0===v?0:v,b=J(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=U(t.placement),O=!w,j=z(x),M="x"===j?"y":"x",k=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,V={x:0,y:0};if(k){if(s){var q,N="y"===j?D:P,I="y"===j?A:L,_="y"===j?"height":"width",F=k[j],X=F+b[N],Y=F-b[I],G=m?-H[_]/2:0,K=w===W?B[_]:H[_],Q=w===W?-H[_]:-B[_],Z=t.elements.arrow,$=m&&Z?g(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=de(0,B[_],$[_]),oe=O?B[_]/2-G-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=O?-B[_]/2+G+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&E(t.elements.arrow),se=ae?"y"===j?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(q=null==S?void 0:S[j])?q:0,ce=F+ie-fe,pe=de(m?a(X,F+oe-fe-se):X,F,m?i(Y,ce):Y);k[j]=pe,V[j]=pe-F}if(c){var ue,le="x"===j?D:P,he="x"===j?A:L,me=k[M],ve="y"===M?"height":"width",ye=me+b[le],ge=me-b[he],be=-1!==[D,P].indexOf(x),xe=null!=(ue=null==S?void 0:S[M])?ue:0,we=be?ye:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ge,je=m&&be?function(e,t,n){var r=de(e,t,n);return r>n?n:r}(we,me,Oe):de(m?we:ye,me,m?Oe:ge);k[M]=je,V[M]=je-me}t.modifiersData[r]=V}},requiresIfExists:["offset"]};var me={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=z(s),c=[P,L].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return Y("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:G(e,k))}(o.padding,n),u=g(i),l="y"===f?D:P,d="y"===f?A:L,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],v=E(i),y=v?"y"===f?v.clientHeight||0:v.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],O=y/2-u[c]/2+b,j=de(x,O,w),M=f;n.modifiersData[r]=((t={})[M]=j,t.centerOffset=j-O,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&N(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ve(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function ye(e){return[D,L,A,P].some((function(t){return e[t]>=0}))}var ge={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=J(t,{elementContext:"reference"}),s=J(t,{altBoundary:!0}),f=ve(a,r),c=ve(s,o,i),p=ye(f),u=ye(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},be=Z({defaultModifiers:[ee,te,oe,ie]}),xe=[ee,te,oe,ie,ae,le,he,me,ge],we=Z({defaultModifiers:xe});e.applyStyles=ie,e.arrow=me,e.computeStyles=oe,e.createPopper=we,e.createPopperLite=be,e.defaultModifiers=xe,e.detectOverflow=J,e.eventListeners=ee,e.flip=le,e.hide=ge,e.offset=ae,e.popperGenerator=Z,e.popperOffsets=te,e.preventOverflow=he,Object.defineProperty(e,"__esModule",{value:!0})}));
6
-