{"version":3,"file":"component---src-templates-blog-post-template-js-1d12426834c2699edca4.js","mappings":"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","sources":["webpack://unwrangle-data-website/./src/components/AuthorBox.js","webpack://unwrangle-data-website/./src/components/RelatedPosts.js","webpack://unwrangle-data-website/./node_modules/@heroicons/react/20/solid/esm/ChevronDownIcon.js","webpack://unwrangle-data-website/./src/components/BlogToC.js","webpack://unwrangle-data-website/./src/templates/blogPostTemplate.js"],"sourcesContent":["import React from 'react';\nimport { GatsbyImage, getImage } from 'gatsby-plugin-image';\n\nconst AuthorBox = ({ author }) => {\n const authorImage = getImage(author.image);\n\n return (\n
\n
\n \n
\n

{author.name}

\n

{author.role}

\n
\n
\n

{author.bio}

\n
\n );\n};\n\nexport default AuthorBox;","import React from 'react';\nimport { useStaticQuery, graphql, Link } from 'gatsby';\n\nconst RelatedPosts = ({ currentPost }) => {\n const data = useStaticQuery(graphql`\n query {\n allMarkdownRemark(\n filter: { frontmatter: { template: { eq: \"blog\" } } }\n sort: { frontmatter: { date: DESC } }\n limit: 6\n ) {\n edges {\n node {\n frontmatter {\n title\n slug\n template\n }\n }\n }\n }\n }\n `);\n\n const relatedPosts = data.allMarkdownRemark.edges\n .filter(({ node }) => node.frontmatter.slug !== currentPost)\n .slice(0, 3);\n\n // Don't render anything if there are no related posts\n if (relatedPosts.length === 0) {\n return null;\n }\n\n return (\n
\n
\n

You might also like:

\n
\n {relatedPosts.map(({ node }) => (\n \n

{node.frontmatter.title}

\n Read more →\n \n ))}\n
\n
\n
\n );\n};\n\nexport default RelatedPosts;","import * as React from \"react\";\nfunction ChevronDownIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 20 20\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronDownIcon);\nexport default ForwardRef;","import React, { useState, useEffect } from 'react';\nimport { cn } from \"@/lib/utils\";\nimport { ChevronDownIcon } from '@heroicons/react/20/solid';\n\nconst BlogToC = ({ sections }) => {\n const [activeFragment, setActiveFragment] = useState('');\n const [isExpanded, setIsExpanded] = useState(false);\n\n const scrollToSection = (sectionId) => {\n const element = document.getElementById(sectionId);\n if (element) {\n window.history.pushState({}, '', `#${sectionId}`);\n element.scrollIntoView({ behavior: 'smooth' });\n setIsExpanded(false); // Close ToC after selection on mobile\n }\n };\n\n useEffect(() => {\n const handleScroll = () => {\n const sections = document.querySelectorAll('h2, h3');\n let currentActiveSection = '';\n \n for (const section of sections) {\n const sectionTop = section.offsetTop;\n if (window.scrollY >= sectionTop - 100) {\n currentActiveSection = section.id;\n } else {\n break;\n }\n }\n \n setActiveFragment(currentActiveSection);\n };\n\n window.addEventListener('scroll', handleScroll);\n return () => window.removeEventListener('scroll', handleScroll);\n }, []);\n\n useEffect(() => {\n const hash = window.location.hash.replace('#', '');\n if (hash) {\n setTimeout(() => {\n const element = document.getElementById(hash);\n if (element) {\n element.scrollIntoView({ behavior: 'smooth' });\n setActiveFragment(hash);\n }\n }, 100);\n }\n }, []);\n\n return (\n \n );\n};\n\nexport default BlogToC;","import React, { useState, useEffect } from 'react';\nimport ReactDOM from 'react-dom';\nimport { graphql } from 'gatsby';\nimport Layout from '../components/layout';\nimport SEO from '../components/seo';\nimport AuthorBox from '../components/AuthorBox';\nimport RelatedPosts from '../components/RelatedPosts';\nimport BlogToC from '../components/BlogToC';\nimport CodeBlock from '../components/CodeBlock';\n\n\nimport '../styles/global.css';\n\nconst useMediaQuery = (query) => {\n const [matches, setMatches] = useState(false);\n\n useEffect(() => {\n const media = window.matchMedia(query);\n setMatches(media.matches);\n\n const listener = (e) => setMatches(e.matches);\n media.addEventListener('change', listener);\n \n return () => media.removeEventListener('change', listener);\n }, [query]);\n\n return matches;\n};\n\nconst BlogPostTemplate = ({ data }) => {\n const isDesktop = useMediaQuery('(min-width: 768px)');\n const { markdownRemark } = data;\n const { frontmatter, html } = markdownRemark;\n const contentRef = React.useRef(null);\n\n // Extract headings from HTML for Table of Contents\n const extractHeadings = (html) => {\n const headings = html.match(/]*>(.*?)<\\/h[23]>/g) || [];\n return headings.map((heading) => {\n const text = heading.replace(/<[^>]+>/g, '');\n const id = text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/(^-|-$)/g, '');\n return {\n id,\n heading: text,\n type: heading.startsWith(' {\n const codeBlockRegex = /
([\\s\\S]*?)<\\/code><\\/pre>/g;\n    let processedHtml = html;\n    const codeBlocks = [];\n    \n    processedHtml = processedHtml.replace(codeBlockRegex, (match, lang, code) => {\n      const blockId = `code-block-${codeBlocks.length}`;\n      codeBlocks.push({\n        id: blockId,\n        language: lang,\n        code: code\n          .replace(/</g, '<')\n          .replace(/>/g, '>')\n          .replace(/&/g, '&')\n          .replace(/"/g, '\"')\n          .trim()\n      });\n      return `
`;\n });\n \n return { processedHtml, codeBlocks };\n };\n\n // Process headings to add IDs\n const processHeadings = (html) => {\n return html.replace(\n /]*>(.*?)<\\/h[23]>/g,\n (match, content) => {\n const id = content\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/(^-|-$)/g, '');\n return match.replace('>', ` id=\"${id}\">`);\n }\n );\n };\n\n const sections = extractHeadings(html);\n const { processedHtml, codeBlocks } = extractCodeBlocks(html);\n const finalHtml = processHeadings(processedHtml);\n\n React.useEffect(() => {\n if (!contentRef.current) return;\n \n codeBlocks.forEach(block => {\n const placeholder = document.getElementById(block.id);\n if (placeholder) {\n const codeBlockElement = (\n \n );\n ReactDOM.render(codeBlockElement, placeholder);\n }\n });\n\n return () => {\n codeBlocks.forEach(block => {\n const placeholder = document.getElementById(block.id);\n if (placeholder) {\n ReactDOM.unmountComponentAtNode(placeholder);\n }\n });\n };\n }, [codeBlocks]);\n\n if (frontmatter.template !== 'blog') {\n return null;\n }\n\n return (\n \n
\n {/* Title Section */}\n
\n

{frontmatter.title}

\n {frontmatter.author && (\n
\n {frontmatter.author.name}\n \n {frontmatter.date}\n {frontmatter.readingTime && (\n <>\n \n {frontmatter.readingTime} min read\n \n )}\n
\n )}\n
\n\n {/* Table of Contents - Conditionally render based on screen size */}\n {!isDesktop && (\n \n )}\n\n {/* Main Content Section */}\n
\n {/* Desktop ToC - Left Sidebar */}\n {isDesktop && (\n \n )}\n\n {/* Main Content */}\n
\n \n
\n\n {/* Desktop Author Box - Right Sidebar */}\n {frontmatter.author && (\n \n )}\n
\n\n {/* Mobile Author Box */}\n {frontmatter.author && (\n \n )}\n
\n\n {/* Related Posts Section */}\n
\n \n
\n
\n );\n};\n\nexport const pageQuery = graphql`\n query($slug: String!) {\n markdownRemark(frontmatter: { slug: { eq: $slug } }) {\n html\n frontmatter {\n date(formatString: \"MMMM DD, YYYY\")\n slug\n title\n description\n keywords\n template\n readingTime\n author {\n name\n role\n bio\n image {\n childImageSharp {\n gatsbyImageData(width: 64, height: 64)\n }\n }\n }\n }\n }\n }\n`;\n\nexport const Head = ({ data }) => {\n const { frontmatter } = data.markdownRemark;\n return (\n \n );\n};\n\nexport default BlogPostTemplate;\n"],"names":["_ref","author","authorImage","getImage","image","React","className","GatsbyImage","alt","name","role","bio","currentPost","relatedPosts","useStaticQuery","allMarkdownRemark","edges","filter","_ref2","node","frontmatter","slug","slice","length","map","_ref3","Link","to","key","title","ChevronDownIcon","titleId","props","svgRef","Object","assign","xmlns","viewBox","fill","ref","id","fillRule","d","clipRule","sections","activeFragment","setActiveFragment","useState","isExpanded","setIsExpanded","useEffect","handleScroll","document","querySelectorAll","currentActiveSection","section","sectionTop","offsetTop","window","scrollY","addEventListener","removeEventListener","hash","location","replace","setTimeout","element","getElementById","scrollIntoView","behavior","onClick","cn","index","type","href","e","preventDefault","sectionId","history","pushState","scrollToSection","heading","Head","data","markdownRemark","SEO","description","keywords","isDesktop","query","matches","setMatches","media","matchMedia","listener","useMediaQuery","html","contentRef","match","text","toLowerCase","startsWith","extractHeadings","processedHtml","codeBlocks","lang","code","blockId","push","language","trim","extractCodeBlocks","finalHtml","content","processHeadings","current","forEach","block","placeholder","codeBlockElement","CodeBlock","ReactDOM","template","Layout","date","readingTime","BlogToC","dangerouslySetInnerHTML","__html","AuthorBox","RelatedPosts"],"sourceRoot":""}