heartwood every commit a ring

Modernize site design, update content, and remove SQLite dependency

70716e6c by Isaac Bythewood · 1 month ago

Modernize site design, update content, and remove SQLite dependency

- Update all dependencies, remove sequelize/sqlite3
- Add Makefile with run and push targets
- Add allowedDevOrigins for container dev, add no-op sw.js
- Redesign code page: static project list with ISR commit fetching,
  dark theme cards with tech tags, add Taproot and darkfurrow.com
- Redesign home page: large typography with gradient name, monospace
  role line mentioning Craftmaster Furniture, updated rotating words
- Update about page: new bio with Craftmaster Furniture, two decades
  experience, AI agent workflows focus, fix word swap animation
- Redesign art page: improved card styling, portal-based lightbox,
  remove particle flow, expanded descriptions
- Redesign contact page: interactive chat tree with branching
  conversations, updated messaging and employer info
- Add sizes prop to menu image, fix various CSS bugs
- Delay loader curtain until home page background image loads
added CLAUDE.md
@@ -0,0 +1,50 @@# isaacbythewood.com## What is this project?Personal portfolio website for Isaac Bythewood, a Senior Solutions Architect.A visually rich, animation-heavy single-page-style site built with Next.js.The site lives at https://isaacbythewood.com/.## Technical notes- Next.js 16 with React 19, file-based routing under `pages/`.- Styling uses CSS Modules (`styles/components/` and `styles/pages/`).  Global CSS variables are defined in `styles/globals.css`.- Path alias: `@styles/*` maps to `styles/*` (see `jsconfig.json`).- Site-wide theme config (colors, breakpoints, animation timing) lives in  `site.config.js`.- Package manager is yarn. Use `yarn install` with frozen lockfile.- `yarn start` runs the dev server on port 8000.- `yarn next:build` builds for production.- Docker deployment via Alpine-based image. See `Dockerfile` and  `docker-compose.yml`. Port is bound to localhost only.- No test framework is configured.- No ESLint or Prettier configuration.## Development tools- Playwright MCP is available for browser testing. Use it to take  screenshots and verify visual changes after modifying styles,  templates, or content. Start the dev server first with `yarn start`.- Always clean up screenshot files (*.png) after reviewing them. Delete  them once you have confirmed the result to avoid clutter in the project  directory.## Project structure- `pages/` - Next.js pages: index, about, code, art, contact- `components/` - React components (menu, sidebar, loader, mouse cursor,  canvas animations like constellations, synthwave, particleflow, retrostars)- `styles/` - CSS Modules organized by components and pages- `public/` - Static assets (images, PDFs, manifest, sitemap)- `site.config.js` - Theme configuration (colors, breakpoints, timing)## Design philosophy- Dark aesthetic with primary color #20232e, blue #0e3ff4, purple #842bff.- Heavy use of CSS animations and transitions (250ms transitions, 1500ms  animations with ease-in-out).- Custom cursor, page transition loader, background grid overlay.- Responsive with mobile and tablet breakpoints.
added Makefile
@@ -0,0 +1,8 @@.PHONY: run pushrun:	yarn startpush:	git push origin	git push server
modified components/loader.js
@@ -1,7 +1,17 @@import React from "react";import React, { useState, useEffect } from "react";import { useRouter } from "next/router";import styles from "@styles/components/loader.module.css";const Loader = () => {  const router = useRouter();  const [ready, setReady] = useState(router.pathname !== "/");  useEffect(() => {    const handler = () => setReady(true);    window.addEventListener("loaderReady", handler);    return () => window.removeEventListener("loaderReady", handler);  }, []);  return (    <>      <div className={styles.grid}>
@@ -16,6 +26,7 @@ const Loader = () => {                style={{                  gridColumn: column,                  ["--delay"]: `${column * 100}ms`,                  ["--play-state"]: ready ? "running" : "paused",                }}              />            );
modified components/menu.js
@@ -138,6 +138,7 @@ const Menu = () => {                  alt="#006 Molten Copper"                  loading="lazy"                  fill                  sizes="40vw"                  style={{ objectFit: "cover", objectPosition: "center" }}                />              </div>
deleted components/particleflow.js
@@ -1,168 +0,0 @@import React, { useEffect, useRef } from "react";import styles from "@styles/components/canvas.module.css";import PropTypes from "prop-types";const ParticleFlow = ({ options }) => {  const isActive = options.isActive !== undefined ? options.isActive : true;  const canvas = useRef(null);  useEffect(() => {    const cvs = canvas.current;    cvs.width = cvs.offsetWidth;    cvs.height = cvs.offsetHeight;    const resizeCanvas = () => {      cvs.width = cvs.offsetWidth;      cvs.height = cvs.offsetHeight;    };    window.addEventListener("resize", resizeCanvas);    return () => {      window.removeEventListener("resize", resizeCanvas);    };  }, []);  useEffect(() => {    const cvs = canvas.current;    const ctx = cvs.getContext("2d");    const cols = Math.floor(cvs.width / 20);    const rows = Math.floor(cvs.height / 20);    let time = 0;    const noise = (x, y, z) => {      return Math.sin(x * 0.01 + z) * Math.cos(y * 0.01 + z) * 0.5 + 0.5;    };    const generateFlowField = () => {      const field = [];      for (let y = 0; y < rows; y++) {        field[y] = [];        for (let x = 0; x < cols; x++) {          const angle = noise(x, y, time * 0.01) * Math.PI * 2;          field[y][x] = {            x: Math.cos(angle),            y: Math.sin(angle),          };        }      }      return field;    };    class Particle {      constructor() {        this.x = Math.random() * cvs.width;        this.y = Math.random() * cvs.height;        this.vx = 0;        this.vy = 0;        this.maxSpeed = 2;        this.maxForce = 0.1;        this.hue = Math.random() * 360;        this.alpha = 0.8;        this.trail = [];        this.maxTrailLength = 20;      }      follow(flowField) {        const col = Math.floor(this.x / 20);        const row = Math.floor(this.y / 20);        if (col >= 0 && col < cols && row >= 0 && row < rows) {          const desired = flowField[row][col];          const force = {            x: desired.x * this.maxSpeed - this.vx,            y: desired.y * this.maxSpeed - this.vy,          };          const mag = Math.sqrt(force.x * force.x + force.y * force.y);          if (mag > this.maxForce) {            force.x = (force.x / mag) * this.maxForce;            force.y = (force.y / mag) * this.maxForce;          }          this.vx += force.x;          this.vy += force.y;        }      }      update() {        this.trail.push({ x: this.x, y: this.y });        if (this.trail.length > this.maxTrailLength) {          this.trail.shift();        }        this.x += this.vx;        this.y += this.vy;        if (this.x > cvs.width) this.x = 0;        if (this.x < 0) this.x = cvs.width;        if (this.y > cvs.height) this.y = 0;        if (this.y < 0) this.y = cvs.height;        this.hue += 0.5;        if (this.hue > 360) this.hue = 0;      }      draw(ctx) {        for (let i = 0; i < this.trail.length; i++) {          const alpha = (i / this.trail.length) * this.alpha;          const size = (i / this.trail.length) * 3;          ctx.beginPath();          ctx.arc(this.trail[i].x, this.trail[i].y, size, 0, Math.PI * 2);          ctx.fillStyle = `hsla(${this.hue}, 70%, 60%, ${alpha})`;          ctx.fill();          ctx.closePath();        }        ctx.beginPath();        ctx.arc(this.x, this.y, 3, 0, Math.PI * 2);        ctx.fillStyle = `hsla(${this.hue}, 80%, 70%, ${this.alpha})`;        ctx.fill();        ctx.closePath();      }    }    const particles = [];    const numParticles = options.numParticles || 100;    for (let i = 0; i < numParticles; i++) {      particles.push(new Particle());    }    let animationFrame = null;    const animate = () => {      ctx.fillStyle = "rgba(0, 0, 0, 0.05)";      ctx.fillRect(0, 0, cvs.width, cvs.height);      const flowField = generateFlowField();      particles.forEach((particle) => {        particle.follow(flowField);        particle.update();        particle.draw(ctx);      });      time++;      if (isActive) {        animationFrame = window.requestAnimationFrame(animate);      }    };    if (isActive) {      animationFrame = window.requestAnimationFrame(animate);    }    return () => {      window.cancelAnimationFrame(animationFrame);    };  }, [isActive]);  return <canvas ref={canvas} className={styles.canvas} />;};ParticleFlow.propTypes = {  options: PropTypes.object,};export default ParticleFlow;
modified next.config.js
@@ -3,6 +3,7 @@ const nextConfig = {  devIndicators: {    position: 'bottom-right',  },  allowedDevOrigins: ['127.0.0.1'],}module.exports = nextConfig
modified package.json
@@ -7,13 +7,11 @@  },  "dependencies": {    "@babel/core": "^7.29.0",    "next": "^16.1.6",    "next": "^16.2.2",    "react": "^19.2.4",    "react-dom": "^19.2.4",    "react-is": "^19.2.4",    "react-transition-group": "^4.4.5",    "sequelize": "^6.37.7",    "sharp": "^0.34.5",    "sqlite3": "^5.1.7"    "sharp": "^0.34.5"  }}
modified pages/about.js
@@ -4,20 +4,25 @@ import { TransitionGroup, CSSTransition } from "react-transition-group";import Page from "../components/page";import styles from "@styles/pages/about.module.css";const INITIAL_WORDS = [  "AI Agents",  "DevOps",  "Full-Stack",  "Testing",  "Cloud",  "Security",  "Developer",  "Automation",  "Architecture",];const About = () => {  const [words, setWords] = useState([    "DevOps",    "Social Media",    "SEO",    "Cloud",    "Security",    "HIPAA & PCI",    "Developer",    "SysAdmin",    "Full-Stack",  ]);  const [words, setWords] = useState(INITIAL_WORDS);  const wordsRef = useRef(words);  wordsRef.current = words;  const slots = useRef(    Object.fromEntries(INITIAL_WORDS.map((word, i) => [word, i]))  );  const wordRefs = useRef(new Map());  const getWordRef = (key) => {    if (!wordRefs.current.has(key)) {
@@ -40,9 +45,13 @@ const About = () => {      }      const firstWord = wordsRef.current[firstWordIndex];      const secondWord = wordsRef.current[secondWordIndex];      const firstSlot = slots.current[firstWord];      const secondSlot = slots.current[secondWord];      slots.current[firstWord] = secondSlot;      slots.current[secondWord] = firstSlot;      setWords(        wordsRef.current.filter((word, index) => {          return index != firstWordIndex && index != secondWordIndex;          return index !== firstWordIndex && index !== secondWordIndex;        })      );      setTimeout(() => {
@@ -79,7 +88,11 @@ const About = () => {                }}                nodeRef={nodeRef}              >                <h2 className={styles.word} ref={nodeRef}>                <h2                  className={styles.word}                  ref={nodeRef}                  style={{ top: `${slots.current[word] * 11}vh` }}                >                  <span className={styles.wordText}>{word}</span>                </h2>              </CSSTransition>
@@ -88,16 +101,21 @@ const About = () => {        </TransitionGroup>      </div>      <p className={styles.paragraph}>        I am a <span className={styles.strong}>senior solutions architect</span>        . I enjoy working on everything from linux kernel modules to website        front-ends. My first job was{" "}        <span className={styles.strong}>modifying kernel modules</span> for        Digium Telephony Cards to work on CentOS. I am currently doing a bit of        everything — chiefly creating{" "}        <span className={styles.strong}>custom software</span> on a variety of        platforms, mostly the web. I have done consulting for many companies on        SEO, Online Advertising, Social Media, Cloud Services, Security, HIPAA        &amp; PCI Compliance, and myriad other topics.        I am a{" "}        <span className={styles.strong}>senior solutions architect</span>{" "}        at Craftmaster Furniture with{" "}        <span className={styles.strong}>two decades in tech</span>.{" "}        I got my start{" "}        <span className={styles.strong}>modifying kernel modules</span>{" "}        for Digium Telephony Cards on CentOS and have been building across the{" "}        <span className={styles.strong}>full stack</span>{" "}        ever since, from DevOps and server infrastructure to{" "}        <span className={styles.strong}>highly regulated</span>{" "}        healthcare environments, leading teams through tight deadlines and        demanding delivery schedules. Today I focus on{" "}        <span className={styles.strong}>AI agent workflows</span>,{" "}        automated testing infrastructure, and tooling that keeps release cycles        fast without sacrificing stability or security.        <a          className={styles.resume}          href="/static/pdfs/resume-isaac-bythewood.pdf"
modified pages/art.js
@@ -1,16 +1,21 @@import React, { useState } from "react";import React, { useState, useEffect, useRef } from "react";import { createPortal } from "react-dom";import styles from "@styles/pages/art.module.css";import Image from "next/image";import Page from "../components/page";import Constellations from "../components/constellations";import RetroStars from "../components/retrostars";import ParticleFlow from "../components/particleflow";const Art = () => {  const [lightboxImage, setLightboxImage] = useState(null);  const [lightboxLoaded, setLightboxLoaded] = useState(false);  const [activeArt, setActiveArt] = useState("constellations");  const [mounted, setMounted] = useState(false);  useEffect(() => {    setMounted(true);  }, []);  const openLightbox = (image) => {    setLightboxImage(image);
@@ -33,8 +38,11 @@ const Art = () => {      <div className={styles.background} />      <h1 className={styles.heading}>Acrylic Pours</h1>      <p className={styles.paragraph}>        A bit more traditional than my usual art, acrylics mixed with water,        glue, and silicone on canvas and hit with a heat gun.        A bit more traditional than my usual art. Each piece starts as a mix of        acrylic paint, water, glue, and silicone oil poured onto canvas, then        manipulated with a heat gun to bring out cells and organic patterns. No        two pours come out the same and the process is as much about letting go        of control as it is about technique.      </p>      <div className={styles.artGrid}>        <div
@@ -177,16 +185,19 @@ const Art = () => {      </div>      <h1 className={styles.heading}>Emergent Generative Art</h1>      <p className={styles.paragraph}>        Autonomously generated entities that are observed to have qualities in a        group that they do not have on their own.        Code as a creative medium. These pieces are built entirely in JavaScript        on HTML canvas, each one a small system of simple rules that produces        complex, unpredictable behavior. The art emerges from the interaction of        autonomous entities rather than being explicitly drawn.      </p>      <h2 className={styles.subheading}>        <span>000</span> Constellations      </h2>      <p className={styles.paragraph}>        Moving stars, circles, on a canvas that attach to nearby stars, with a        line, to generate constellations. Line opacity is based on star        distance.        Drifting points on a dark canvas that form connections with their nearest        neighbors. As stars wander closer together lines appear between them,        brighter the nearer they get, building and dissolving constellations        that never repeat.      </p>      <div className={styles.artContainer}>        <Constellations
@@ -212,8 +223,9 @@ const Art = () => {        <span>001</span> Retro Stars      </h2>      <p className={styles.paragraph}>        Multiple parallax planes of stars that shift based on cursor position.        Inspired by the retro art style of Celeste.        Layered star fields at different depths that drift in response to your        cursor, creating a parallax effect. Inspired by the pixel art aesthetic        of Celeste and the feeling of staring into a sky that moves with you.      </p>      <div className={styles.artContainer}>        <RetroStars
@@ -235,44 +247,20 @@ const Art = () => {      >        See the Code      </a>      <h2 className={styles.subheading}>        <span>002</span> Particle Flow      </h2>      <p className={styles.paragraph}>        Colorful particles flowing through an invisible force field, creating        organic, flowing patterns with trailing effects. Each particle follows        the field while leaving a colorful trail that slowly fades.      </p>      <div className={styles.artContainer}>        <ParticleFlow          options={{ numParticles: 80, isActive: activeArt === "particleflow" }}        />        <button          className={styles.playButton}          onClick={() => handleArtToggle("particleflow")}          data-active={activeArt === "particleflow"}        >          {activeArt === "particleflow" ? "⏸" : "▶"}        </button>      </div>      <a        className={styles.artItemButton}        href="https://github.com/overshard/isaacbythewood.com/blob/master/components/particleflow.js"        rel="noopener noreferrer"        target="_blank"      >        See the Code      </a>      {lightboxImage !== null && (      {mounted && lightboxImage !== null && createPortal(        <div className={styles.lightboxOverlay} onClick={() => closeLightbox()}>          <div            className={              styles.lightboxLoading + (lightboxLoaded ? " " + styles.hide : "")            }          <span            className={styles.lightboxImageWrapper}            onClick={(e) => e.stopPropagation()}          >            Loading...          </div>          <span className={styles.lightboxImageWrapper}>            <div              className={                styles.lightboxLoading +                (lightboxLoaded ? " " + styles.hide : "")              }            >              Loading...            </div>            <Image              className={                styles.lightboxImage + (lightboxLoaded ? " " + styles.show : "")
@@ -284,8 +272,15 @@ const Art = () => {              style={{ objectFit: "contain" }}              onLoad={() => setLightboxLoaded(true)}            />            <button              className={styles.lightboxClose}              onClick={() => closeLightbox()}            >            </button>          </span>        </div>        </div>,        document.body      )}    </Page>  );
modified pages/code.js
@@ -18,345 +18,150 @@ const GitHubIcon = () => {  );};const PROJECTS = [  {    name: "Taproot",    slug: "taproot",    description:      "Dotfiles, containers, and the configs that make a machine mine.",    tech: ["Docker", "Shell"],  },  {    name: "darkfurrow.com",    slug: "darkfurrow.com",    description:      "A living almanac of seasons, soil, and the quiet knowledge that used to be common.",    tech: ["Python", "Flask"],  },  {    name: "Analytics",    slug: "analytics",    description:      "A self-hostable analytics service with a straightforward API to track events from any source.",    tech: ["Python", "Django", "API"],  },  {    name: "Status",    slug: "status",    description: "A self-hosted status monitoring service.",    tech: ["Python", "Django"],  },  {    name: "Blog",    slug: "blog",    description:      "A self-hostable blog built on Wagtail with code blocks, syntax highlighting, live search, and a clean customizable UI.",    tech: ["Python", "Wagtail"],  },  {    name: "Timelite",    slug: "timelite",    description:      "A simple time tracking progressive web app. Uses local storage and service workers to remain accessible offline.",    tech: ["JavaScript", "PWA"],  },  {    name: "isaacbythewood.com",    slug: "isaacbythewood.com",    description: "The personal website you are looking at right now.",    tech: ["Next.js", "React", "CSS"],  },];const Code = ({ commits }) => {  return (    <Page title="Code" description="Some of my most recent coding projects.">      <div className={styles.background} />      <h1 className={styles.heading}>Code</h1>      <p className={styles.paragraph}>        A probably not entirely up-to-date list of my current side projects...        There is plenty more to see on{" "}        Outside of work I build self-hosted tools, personal websites, and        whatever else catches my interest. Side projects are where I experiment        with new technology and stay sharp since at work I stick to stable,        mature frameworks. There is plenty more to see on{" "}        <a          href="https://github.com/overshard"          rel="noopener noreferrer"          target="_blank"        >          my GitHub account        </a>{" "}        and generally around the internet if you are interested.        </a>        .      </p>      <div className={styles.projects}>        <div className={styles.project}>          <h1 className={styles.projectHeading}>Analytics</h1>          <p className={styles.projectParagraph}>            A self-hostable analytics service with a straightforward API to            track events from any source.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.analytics.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/analytics"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>Status</h1>          <p className={styles.projectParagraph}>            A self-hosted status monitoring service.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.status.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/status"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>Blog</h1>          <p className={styles.projectParagraph}>            A self-hostable blog built on Wagtail targeted towards developers            with code blocks, syntax highlighting, live search, great SEO, and a            clean customizable UI.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.blog.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/blog"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>Timelite</h1>          <p className={styles.projectParagraph}>            A simple time tracking progressive web app. Uses local storage and            service workers to remain accessible offline. Sometimes you just            need the essentials when you are busy.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.timelite.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/timelite"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>Timestrap</h1>          <p className={styles.projectParagraph}>            A full feature time tracking web app. Supports multiple users and            exporting reports in multiple formats. Makes use of websockets to            maintain state across clients.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.timestrap.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/timestrap"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>isaacbythewood.com</h1>          <p className={styles.projectParagraph}>            The personal website of Isaac Bythewood. So this site...          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.isaacbythewood.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/isaacbythewood.com"            rel="noopener noreferrer"            target="_blank"        {PROJECTS.map((project, index) => (          <div            key={project.slug}            className={styles.project}            style={{ animationDelay: `${index * 100}ms` }}          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>New Tab</h1>          <p className={styles.projectParagraph}>            A clean new tab page extension for Chrome.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.newtab.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/newtab"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>dockerfiles</h1>          <p className={styles.projectParagraph}>            All the Dockerfiles I use for various purposes. More detailed usage            instructions are at the top of each Dockerfile.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.dockerfiles.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/dockerfiles"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>alpinefiles</h1>          <p className={styles.projectParagraph}>            Some of the files that I use on my Alpine Linux servers.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.alpinefiles.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/alpinefiles"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>        <div className={styles.project}>          <h1 className={styles.projectHeading}>dotfiles</h1>          <p className={styles.projectParagraph}>            A variety of config files for setting up new systems.          </p>          <pre className={styles.projectCommit}>            {JSON.stringify(commits.dotfiles.data, null, 2)}          </pre>          <a            className={styles.projectButton}            href="https://www.github.com/overshard/dotfiles"            rel="noopener noreferrer"            target="_blank"          >            <GitHubIcon />            GitHub          </a>        </div>            <h2 className={styles.projectHeading}>{project.name}</h2>            <div className={styles.tags}>              {project.tech.map((tag) => (                <span key={tag} className={styles.tag}>                  {tag}                </span>              ))}            </div>            <p className={styles.projectParagraph}>{project.description}</p>            {commits[project.slug] && (              <pre className={styles.projectCommit}>                {JSON.stringify(commits[project.slug], null, 2)}              </pre>            )}            <a              className={styles.projectButton}              href={`https://github.com/overshard/${project.slug}`}              rel="noopener noreferrer"              target="_blank"            >              <GitHubIcon />              GitHub            </a>          </div>        ))}      </div>    </Page>  );};export async function getServerSideProps() {  const { Sequelize } = eval("require('sequelize')");  const sequelize = new Sequelize("sqlite://db.sqlite3");  const Commit = sequelize.define("commit", {    repo: {      type: Sequelize.STRING,      allowNull: false,    },    createdAt: {      type: Sequelize.DATE,      allowNull: false,    },    data: {      type: Sequelize.JSON,      allowNull: false,    },  });export async function getStaticProps() {  const getCommit = async (repo) => {    const storedCommit = await Commit.findOne({      where: {        repo,        createdAt: {          [Sequelize.Op.gte]: new Date(Date.now() - 24 * 60 * 60 * 1000),        },      },    });    if (storedCommit) {      return storedCommit;    }    const commitsFetch = await fetch(      `https://api.github.com/repos/overshard/${repo}/commits`    );    const commits = await commitsFetch.json();    if (!commitsFetch.ok) {      console.error(        `GitHub API fetch failed for ${repo}:`,        commitsFetch.status,        commits    try {      const res = await fetch(        `https://api.github.com/repos/overshard/${repo}/commits?per_page=1`      );      if (!res.ok) {        console.error(`GitHub API failed for ${repo}: ${res.status}`);        return null;      }      const commits = await res.json();      if (!Array.isArray(commits) || commits.length === 0) return null;      const commit = commits[0];      return {        sha: commit.sha ? commit.sha.substring(0, 7) : null,        message: commit.commit?.message || null,        date: commit.commit?.author?.date || null,        author: commit.commit?.author?.name || null,      };    } catch (err) {      console.error(`Failed to fetch commits for ${repo}:`, err);      return null;    }    let commit = null;    if (Array.isArray(commits) && commits.length > 0) {      commit = commits[0];    }    if (!commit) {      console.error(`No commit data found for ${repo}. Response:`, commits);    }    const commitData = {      repo: repo,      createdAt: new Date(),      data: {        sha: commit ? commit.sha : null,        commit: {          message:            commit &&            commit.commit &&            typeof commit.commit.message !== "undefined"              ? commit.commit.message              : null,          date:            commit &&            commit.commit &&            commit.commit.author &&            typeof commit.commit.author.date !== "undefined"              ? commit.commit.author.date              : null,        },        author: {          name:            commit &&            commit.commit &&            commit.commit.author &&            typeof commit.commit.author.name !== "undefined"              ? commit.commit.author.name              : null,          email:            commit &&            commit.commit &&            commit.commit.author &&            typeof commit.commit.author.email !== "undefined"              ? commit.commit.author.email              : null,        },      },    };    await Commit.create(commitData);    return commitData;  };  const getCommits = async () => {    const alpinefiles = await getCommit("alpinefiles");    const analytics = await getCommit("analytics");    const blog = await getCommit("blog");    const dockerfiles = await getCommit("dockerfiles");    const dotfiles = await getCommit("dotfiles");    const isaacbythewood = await getCommit("isaacbythewood.com");    const status = await getCommit("status");    const timelite = await getCommit("timelite");    const timestrap = await getCommit("timestrap");    const newtab = await getCommit("newtab");    return {      alpinefiles: alpinefiles,      analytics: analytics,      blog: blog,      dockerfiles: dockerfiles,      dotfiles: dotfiles,      isaacbythewood: isaacbythewood,      status: status,      timelite: timelite,      timestrap: timestrap,      newtab: newtab,    };  };  const results = await Promise.all(    PROJECTS.map(async (project) => [      project.slug,      await getCommit(project.slug),    ])  );  await Commit.sync();  const commits = Object.fromEntries(results);  return getCommits().then((commits) => {    return {      props: {        commits: JSON.parse(JSON.stringify(commits)),      },    };  });  return {    props: { commits },    revalidate: 3600,  };}Code.propTypes = {
modified pages/contact.js
@@ -1,25 +1,147 @@import React, { useRef } from "react";import { TransitionGroup, CSSTransition } from "react-transition-group";import React, { useState, useRef, useEffect } from "react";import styles from "@styles/pages/contact.module.css";import Image from "next/image";import Page from "../components/page";const CHAT_TREE = {  start: {    messages: ["Hey there!", "What brings you here?"],    options: [      { label: "I want to work together", next: "collab" },      { label: "Just checking out your work", next: "browsing" },      { label: "Job opportunity", next: "job" },    ],  },  collab: {    messages: [      "Nice! I'm always open to side projects and open source collabs.",      "Best way to reach me is email. Drop me a line and tell me what you're thinking.",    ],    options: [      { label: "What's your email?", next: "email" },      { label: "What kind of projects?", next: "projects" },    ],  },  browsing: {    messages: [      "Welcome! Feel free to look around.",      "If anything catches your eye or you want to chat, I'm easy to reach.",    ],    options: [      { label: "How do I reach you?", next: "email" },      { label: "What are you working on?", next: "projects" },    ],  },  job: {    messages: [      "I appreciate the interest.",      "I'm currently at Craftmaster Furniture as a Senior Solutions Architect and not actively looking.",      "That said, feel free to reach out if it's compelling.",    ],    options: [      { label: "What's the best way to reach you?", next: "email" },      { label: "What do you do there?", next: "work" },    ],  },  email: {    messages: [      "Email is best: isaac@bythewood.me",      "You can also find me on GitHub as /overshard or on Discord as Overshard#4907.",    ],    options: [{ label: "Thanks!", next: "end" }],  },  projects: {    messages: [      "Lately I've been deep into AI agent workflows, automated testing infrastructure, and tooling for fast release cycles.",      "On the side I build self-hosted tools and experiment with whatever is new. Check out the Code page for more.",    ],    options: [      { label: "How do I reach you?", next: "email" },      { label: "Cool, thanks!", next: "end" },    ],  },  work: {    messages: [      "I focus on AI agent workflows, automated integration testing, and building systems for rapid releases without sacrificing stability or security.",      "Two decades of experience across the full stack, from kernel modules to regulated healthcare environments.",    ],    options: [      { label: "How do I reach you?", next: "email" },      { label: "Interesting, thanks!", next: "end" },    ],  },  end: {    messages: ["Anytime! Take care."],    options: [],  },};const Contact = () => {  const lineRefs = useRef(new Map());  const getLineRef = (key) => {    if (!lineRefs.current.has(key)) {      lineRefs.current.set(key, React.createRef());  const [chatHistory, setChatHistory] = useState([]);  const [currentNode, setCurrentNode] = useState(null);  const [typing, setTyping] = useState(false);  const [messageQueue, setMessageQueue] = useState([]);  useEffect(() => {    // Start the chat after a brief delay    const timer = setTimeout(() => {      queueMessages("start");    }, 800);    return () => clearTimeout(timer);  }, []);  const processingRef = useRef(false);  useEffect(() => {    if (messageQueue.length === 0 || processingRef.current) return;    processingRef.current = true;    setTyping(true);    const delay = 600 + messageQueue[0].length * 15;    const timer = setTimeout(() => {      setChatHistory((prev) => [        ...prev,        { type: "isaac", text: messageQueue[0] },      ]);      setMessageQueue((prev) => prev.slice(1));      setTyping(false);      processingRef.current = false;    }, delay);    return () => clearTimeout(timer);  }, [messageQueue]);  const chatContainerRef = useRef(null);  useEffect(() => {    if (chatContainerRef.current) {      chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;    }  }, [chatHistory, typing]);  const queueMessages = (nodeKey) => {    const node = CHAT_TREE[nodeKey];    setCurrentNode(nodeKey);    setMessageQueue(node.messages);  };  const handleOption = (option) => {    setChatHistory((prev) => [      ...prev,      { type: "user", text: option.label },    ]);    if (option.next) {      setTimeout(() => queueMessages(option.next), 400);    }    return lineRefs.current.get(key);  };  const chatMessages = [    "Hello!",    "I prefer people reach out to me via email.",    "If you'd like to get in touch with me about a new project I'm currently only working on open source stuff in my spare time.",    "If you're trying to contact me about a job opportunity I'm currently employed with VanNoppen Marketing.",    "If you just want to chat then I'm almost always on Discord!",  ];  const node = CHAT_TREE[currentNode];  const showOptions =    node &&    node.options.length > 0 &&    messageQueue.length === 0 &&    !typing &&    chatHistory.length > 0 &&    chatHistory[chatHistory.length - 1].type === "isaac";  return (    <Page
@@ -32,8 +154,10 @@ const Contact = () => {        <div className={styles.gridLeft}>          <div className={styles.contactWrapper}>            <h1 className={styles.heading}>Contact Me</h1>            <h2 className={styles.shoutOut}>I love chatting</h2>            <h2 className={styles.shoutOut}>with other developers!</h2>            <h2 className={styles.shoutOut}>Shoot me a message.</h2>            <h2 className={styles.shoutOut}>              If it&#39;s interesting, I&#39;ll respond.            </h2>            <dl className={styles.contactList}>              <dt className={styles.contactKey}>Email</dt>              <dd className={styles.contactValue}>
@@ -41,7 +165,7 @@ const Contact = () => {                  className={styles.contactLink}                  href="mailto:isaac@bythewood.me"                >                  isaac@bythewood.com                  isaac@bythewood.me                </a>              </dd>              <dt className={styles.contactKey}>LinkedIn</dt>
@@ -80,43 +204,68 @@ const Contact = () => {            </dl>          </div>        </div>        <div className={styles.gridRight}>        <div className={styles.gridRight} ref={chatContainerRef}>          <div className={styles.chat}>            <TransitionGroup component={null}>              {chatMessages.map((message, index) => {                const transitionTimeout = (index + 2) * 2000;                const transitionDelay = (index + 1) * 2000;                const nodeRef = getLineRef(index);                return (                  <CSSTransition                    key={index}                    appear                    timeout={{ appear: transitionTimeout }}                    classNames="fade"                    nodeRef={nodeRef}            {chatHistory.map((msg, i) => (              <div                key={i}                className={`${styles.chatLine} ${                  msg.type === "user" ? styles.chatLineUser : ""                }`}              >                {msg.type === "isaac" && (                  <span className={styles.chatAvatar}>                    <Image                      src="/static/images/avatar.webp"                      alt="Isaac"                      width={40}                      height={40}                    />                  </span>                )}                <div                  className={`${styles.chatBubble} ${                    msg.type === "user" ? styles.chatBubbleUser : ""                  }`}                >                  {msg.text}                  {msg.type === "isaac" && <span>Isaac</span>}                </div>              </div>            ))}            {typing && (              <div className={styles.chatLine}>                <span className={styles.chatAvatar}>                  <Image                    src="/static/images/avatar.webp"                    alt="Isaac"                    width={40}                    height={40}                  />                </span>                <div className={styles.chatBubble}>                  <span className={styles.typingDots}>                    <span />                    <span />                    <span />                  </span>                </div>              </div>            )}            {showOptions && (              <div className={styles.chatOptions}>                {node.options.map((opt, i) => (                  <button                    key={i}                    className={styles.chatOption}                    onClick={() => handleOption(opt)}                  >                    <div                      className={styles.chatLine}                      ref={nodeRef}                      style={{ transitionDelay: `${transitionDelay}ms` }}                    >                      <span className={styles.chatAvatar}>                        <Image                          src="/static/images/avatar.webp"                          alt="Chat Avatar"                          width={50}                          height={50}                        />                      </span>                      <div className={styles.chatBubble}>                        {message}                        <span>Isaac</span>                      </div>                    </div>                  </CSSTransition>                );              })}            </TransitionGroup>                    {opt.label}                  </button>                ))}              </div>            )}          </div>        </div>      </div>
modified pages/index.js
@@ -6,7 +6,7 @@ import Page from "../components/page";import styles from "@styles/pages/index.module.css";const Index = () => {  const words = ["Developer", "SysAdmin", "DevOps", "Consultant"];  const words = ["AI Agents", "Automation", "DevOps", "Architecture"];  const [currentWords, setCurrentWord] = useState([words[0]]);  const [imageLoaded, setImageLoaded] = useState(false);  const currentWordsRef = useRef(currentWords);
@@ -30,8 +30,10 @@ const Index = () => {    };  }, []);  const playState = imageLoaded ? "running" : "paused";  return (    <Page title="Senior Solutions Architect located in Elkin, NC">    <Page title="Senior Solutions Architect at Craftmaster Furniture">      <div className={styles.imageWrapper}>        <Image          src="/static/images/art/acrylic-pours/005.webp"
@@ -40,7 +42,10 @@ const Index = () => {          priority={true}          fill          style={{ objectFit: "cover", objectPosition: "center" }}          onLoad={() => setImageLoaded(true)}          onLoad={() => {            setImageLoaded(true);            window.dispatchEvent(new Event("loaderReady"));          }}        />      </div>      <TransitionGroup component="div" className={styles.words}>
@@ -70,13 +75,17 @@ const Index = () => {          );        })}      </TransitionGroup>      <h1 className={styles.description} style={{ animationPlayState: imageLoaded ? "running" : "paused" }}>        Senior Solutions Architect located in Elkin, NC      </h1>      <h2 className={styles.name} style={{ animationPlayState: imageLoaded ? "running" : "paused" }}>Isaac</h2>      <h2 className={styles.name} style={{ animationDelay: "100ms", animationPlayState: imageLoaded ? "running" : "paused" }}>        Bythewood      </h2>      <div className={styles.hero} style={{ animationPlayState: playState }}>        <h1 className={styles.name}>          <span className={styles.firstName}>Isaac</span>          <span className={styles.lastName}>Bythewood</span>        </h1>        <div className={styles.role}>          <span className={styles.roleTitle}>Senior Solutions Architect</span>          <span className={styles.roleAt}>at</span>          <span className={styles.roleCompany}>Craftmaster Furniture</span>        </div>      </div>    </Page>  );};
added public/sw.js
@@ -0,0 +1 @@// No-op service worker to prevent 404
modified site.config.js
@@ -1,8 +1,8 @@const strings = {  title: "Isaac Bythewood",  description:    "Isaac Bythewood is a Senior Solutions Architect and Consultant located " +    "in Elkin, NC.",    "Isaac Bythewood is a Senior Solutions Architect at Craftmaster Furniture " +    "located in Elkin, NC.",};const theme = {
modified styles/components/loader.module.css
@@ -26,6 +26,7 @@  height: 100vh;  animation: foldUp 1000ms normal forwards;  animation-delay: var(--delay, 0ms);  animation-play-state: var(--play-state, running);}.gridColumn::before {
modified styles/pages/about.module.css
@@ -53,6 +53,7 @@  top: 0;  bottom: 0;  left: 60px;  right: 0;  opacity: 0.05;  font-size: 5vh;  line-height: 11vh;
@@ -73,6 +74,8 @@.word {  margin: 0;  position: absolute;  left: 0;}.wordText {
@@ -98,6 +101,7 @@.wordEnterActive > .wordText {  animation-name: quickFadeIn;  animation-duration: 1000ms;  animation-fill-mode: forwards;}.wordAppearActive > .wordText::before,
@@ -126,7 +130,6 @@.paragraph {  font-size: 1.8em;  font-weight: 300;  color: black;  position: relative;  color: rgba(0, 0, 0, 0);  animation-name: fadeIn;
@@ -173,7 +176,9 @@}.resume {  display: block;  display: flex;  align-items: center;  width: fit-content;  text-decoration: none;  margin-top: 20px;  font-weight: 700;
modified styles/pages/art.module.css
@@ -16,6 +16,35 @@  }}@keyframes lightboxFadeIn {  from {    opacity: 0;  }  to {    opacity: 1;  }}@keyframes lightboxScaleIn {  from {    opacity: 0;    transform: scale(0.92);  }  to {    opacity: 1;    transform: scale(1);  }}@keyframes lightboxPulse {  0%, 100% {    opacity: 0.4;  }  50% {    opacity: 1;  }}.background {  position: absolute;  top: 0;
@@ -29,7 +58,7 @@.heading {  font-weight: 700;  margin-top: 60px;  margin-bottom: 20px;  margin-bottom: 10px;  font-size: 2.5em;  color: black;}
@@ -40,42 +69,45 @@  width: 50px;  height: 5px;  margin-bottom: 20px;  background-color: var(--color-blue);  background-image: linear-gradient(    to right,    var(--color-blue) 0,    var(--color-purple) 100%  );}.paragraph {  font-size: 1.5em;  font-size: 1.3em;  margin-top: 0;  margin-bottom: 20px;  margin-bottom: 24px;  font-weight: 300;  color: black;  color: rgba(0, 0, 0, 0.7);  line-height: 1.6;}.subheading {  font-weight: 700;  margin-top: 60px;  margin-bottom: 20px;  font-size: 2em;  margin-top: 48px;  margin-bottom: 12px;  font-size: 1.6em;  color: black;  position: relative;  display: flex;  align-items: center;  gap: 12px;}.subheading > span {  font-family: monospace;  font-size: 0.8em;  padding: 3px 9px;  background-color: black;  font-size: 0.7em;  padding: 2px 8px;  background-image: linear-gradient(    to right,    var(--color-blue) 0,    var(--color-purple) 100%  );  color: white;  position: absolute;  right: 100%;  margin-right: 10px;  top: 20%;}@media (max-width: 1023.98px) {  .subheading > span {    display: none;  }  border-radius: var(--radius-2);  letter-spacing: 1px;}.paragraph a {
@@ -114,13 +146,7 @@.artGrid {  display: grid;  grid-template-columns: repeat(2, 1fr);  gap: 20px;}@media (max-width: 1023.98px) {  .artGrid {    grid-template-columns: repeat(2, 1fr);  }  gap: 16px;}@media (max-width: 767.98px) {
@@ -130,47 +156,50 @@}.artItem {  background-color: black;  color: white;  box-shadow: 0 5px 0 rgba(0, 0, 0, 0);  transition-duration: 200ms;  transition-property: box-shadow;  transition-timing-function: ease-in;  position: relative;  overflow: hidden;  border-radius: var(--radius-2);  transition: transform 300ms, box-shadow 300ms;}.artItem:hover {  box-shadow: 0 5px 25px rgba(0, 0, 0, 0.4);  transform: translateY(-3px);  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);}.cardImage img {  object-fit: cover;  object-position: center;  width: 100%;  height: auto;  aspect-ratio: 16 / 9;  display: block;}.artItemHeader {  margin: 0;  margin-top: -5px;  padding: 10px;  padding: 10px 14px;  display: flex;  justify-content: space-between;  align-items: center;  font-weight: 900;  font-weight: 700;  font-size: 0.95em;  background: black;  color: white;}.artItemHeader > span {  color: black;  font-family: monospace;  font-weight: 100;  font-size: 0.9em;  background-color: white;  padding: 3px 7px;}.artItemTitle {  font-weight: 700;  font-weight: 400;  font-size: 1em;  color: rgba(255, 255, 255, 0.8);  letter-spacing: 1px;}.artItemButton {  padding: 10px 15px;  font-size: 1.2em;  padding: 8px 14px;  font-size: 0.9em;  text-decoration: none;  background-color: black;  margin-bottom: 20px;  font-weight: 700;  text-transform: uppercase;  display: inline-block;
@@ -181,35 +210,14 @@    var(--color-blue) 0,    var(--color-purple) 100%  );  border-radius: var(--radius-2);  transform: scale(1);  transition-duration: var(--transition-250);  transition-property: transform;  transition: transform 250ms;  margin-bottom: 20px;}.artItemButton:hover {  transform: scale(1.2);}.artItemImageWrapper {  position: relative;  width: 100%;  padding-top: 66.6667%;}.artItemImage {  position: absolute;  top: 0;  left: 0;  width: 100%;  height: 100%;  object-fit: cover;}.cardImage img {  object-fit: cover;  object-position: center;  width: 100%;  height: 360px;  transform: scale(1.1);}.artContainer {
@@ -217,73 +225,85 @@  height: 500px;  max-height: 100vh;  background: black;  margin-bottom: 20px;  margin-bottom: 16px;  position: relative;  overflow: hidden;  border-radius: var(--radius-2);}.playButton {  position: absolute;  top: 20px;  right: 20px;  width: 60px;  height: 60px;  border: none;  background: transparent;  top: 16px;  right: 16px;  width: 44px;  height: 44px;  border: 1px solid rgba(255, 255, 255, 0.2);  border-radius: var(--radius-2);  background: rgba(0, 0, 0, 0.5);  color: white;  font-size: 32px;  font-size: 20px;  line-height: 1;  padding: 0;  cursor: pointer;  display: flex;  align-items: center;  justify-content: center;  transition: all 0.3s ease;  transition: border-color 200ms, background 200ms;  z-index: 5;  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);}.playButton:hover {  transform: scale(1.1);  text-shadow: 0 4px 8px rgba(0, 0, 0, 0.9);  border-color: var(--color-blue);  background: rgba(14, 63, 244, 0.2);}.playButton:active {  transform: scale(0.95);}/* Lightbox */.lightboxOverlay {  position: fixed;  top: 0;  left: 0;  right: 0;  bottom: 0;  background: rgba(0, 0, 0, 0.85);  background: rgba(0, 0, 0, 0.92);  display: flex;  align-items: center;  justify-content: center;  z-index: 1000;  opacity: 1;  pointer-events: auto;  z-index: 99999;  animation: lightboxFadeIn 300ms ease-out;}.lightboxImageWrapper {  position: relative;  width: 90vw;  height: 90vh;  animation: lightboxScaleIn 400ms cubic-bezier(0.16, 1, 0.3, 1);  background: black;  border-radius: var(--radius-2);  overflow: hidden;}.lightboxImage {  visibility: hidden;  opacity: 0;  transition-property: opacity;  transition-duration: var(--transition-250);  transition: opacity 300ms ease-out;}.lightboxLoading {  position: absolute;  max-width: 100%;  max-height: 100%;  box-sizing: border-box;  color: white;  top: 50%;  left: 50%;  transform: translate(-50%, -50%);  color: var(--color-blue);  font-family: monospace;  font-size: 3em;  visibility: visible;  opacity: 1;  transition-property: opacity;  transition-duration: var(--transition-250);  font-size: 1.2em;  letter-spacing: 4px;  text-transform: uppercase;  animation: lightboxPulse 1.5s ease-in-out infinite;}.show {
@@ -296,19 +316,25 @@  visibility: hidden;}.lightboxImageWrapper {  position: relative;  width: 90vw;  height: 90vh;}.closeButton {.lightboxClose {  position: absolute;  top: 20px;  right: 20px;  background: transparent;  border: none;  top: 16px;  right: 16px;  width: 40px;  height: 40px;  background: rgba(0, 0, 0, 0.6);  border: 1px solid rgba(255, 255, 255, 0.2);  border-radius: var(--radius-2);  color: white;  font-size: 2rem;  cursor: pointer;  font-size: 1.2em;  display: flex;  align-items: center;  justify-content: center;  transition: border-color 200ms, background 200ms;  z-index: 1;}.lightboxClose:hover {  border-color: var(--color-blue);  background: rgba(14, 63, 244, 0.2);}
modified styles/pages/code.module.css
@@ -16,6 +16,17 @@  }}@keyframes cardEnter {  from {    opacity: 0;    transform: translateY(20px);  }  to {    opacity: 1;    transform: translateY(0);  }}.background {  position: absolute;  top: 0;
@@ -46,7 +57,7 @@.paragraph {  font-size: 1.5em;  margin-top: 0;  margin-bottom: 20px;  margin-bottom: 30px;  font-weight: 300;  color: black;}
@@ -89,12 +100,14 @@  width: 100%;  flex-wrap: wrap;  gap: 20px;  padding-bottom: 60px;}.project {  width: calc(50% - 20px);  width: calc(50% - 10px);  display: flex;  flex-direction: column;  animation: cardEnter 600ms cubic-bezier(0.16, 1, 0.3, 1) both;}@media (max-width: 767.98px) {
@@ -105,27 +118,61 @@.projectHeading {  font-weight: 700;  margin-top: 60px;  margin-bottom: 20px;  margin-top: 40px;  margin-bottom: 8px;  font-size: 2em;  color: black;}.tags {  display: flex;  flex-wrap: wrap;  gap: 6px;  margin-bottom: 12px;}.tag {  display: inline-block;  font-size: 0.75em;  padding: 2px 8px;  background-color: var(--color-blue);  border-radius: var(--radius-2);  color: white;  font-family: monospace;  text-transform: uppercase;  letter-spacing: 1px;}.projectParagraph {  font-size: 1.5em;  font-size: 1.3em;  margin-top: 0;  margin-bottom: 20px;  margin-bottom: 16px;  font-weight: 300;  color: black;  flex-grow: 1;  line-height: 1.5;}.projectCommit {  font-family: monospace;  background: var(--color-primary);  color: #00ff00;  padding: 16px;  overflow-x: hidden;  max-width: 100%;  text-overflow: ellipsis;  font-size: 0.85em;  line-height: 1.6;  border-radius: var(--radius-2);  margin-top: 0;  margin-bottom: 16px;}.projectButton {  padding: 10px 15px;  font-size: 1.2em;  padding: 8px 12px;  font-size: 0.9em;  text-decoration: none;  background-color: black;  margin-bottom: 20px;  font-weight: 700;  text-transform: uppercase;  display: inline-flex;
@@ -141,8 +188,9 @@  transform: scale(1);  transition-duration: 250ms;  transition-property: transform;  width: 125px;  width: 120px;  text-align: center;  border-radius: var(--radius-2);}.projectButton svg {
@@ -152,13 +200,3 @@.projectButton:hover {  transform: scale(1.2);}.projectCommit {  font-family: monospace;  background: black;  color: #00ff00;  padding: 20px;  overflow-x: hidden;  max-width: 100%;  text-overflow: ellipsis;}
modified styles/pages/contact.module.css
@@ -43,6 +43,7 @@  grid-template-rows: auto;  grid-template-areas: "left right";  margin-left: 60px;  width: calc(100vw - 60px);  transform: translateX(-100vw);  animation: slideUp 750ms 500ms forwards;}
@@ -50,6 +51,7 @@@media (max-width: 1023.98px) {  .grid {    margin-left: 0;    width: 100%;    grid-template-columns: 1fr;    grid-template-rows: auto auto;    grid-template-areas:
@@ -71,27 +73,31 @@  .gridLeft {    grid-column: 1;    grid-row: 1;    min-height: auto;    align-items: flex-start;  }}.gridRight {  grid-area: right;  min-height: 100vh;  height: 100vh;  width: 100%;  display: flex;  align-items: center;  align-items: flex-end;  overflow-y: auto;  background-color: white;}@media (max-width: 1023.98px) {  .gridRight {    grid-column: 1;    grid-row: 2;  }}@media (max-width: 1023.98px) {  .gridLeft,  .gridRight {    min-height: auto;    height: auto;    min-height: 50vh;    overflow-y: visible;    align-items: flex-start;    padding-top: 20px;    padding-bottom: 30px;  }}
@@ -102,8 +108,7 @@@media (max-width: 1023.98px) {  .contactWrapper {    min-height: auto;    padding-top: 30px;    padding-bottom: 30px;    padding: 10px 20px 30px;  }}
@@ -116,14 +121,19 @@.heading::before {  content: "";  display: block;  width: 75px;  height: 5px;  width: 60px;  height: 4px;  margin-bottom: 10px;  background-color: var(--color-blue);  background-image: linear-gradient(    to right,    var(--color-blue) 0,    var(--color-purple) 100%  );}@media (max-width: 767.98px) {  .heading {    margin-top: 0;    margin-bottom: 10px;  }}
@@ -155,9 +165,11 @@.contactKey {  text-transform: uppercase;  font-size: 0.8em;  font-size: 0.75em;  font-weight: 700;  opacity: 0.7;  color: rgba(255, 255, 255, 0.4);  letter-spacing: 2px;  font-family: monospace;}.contactValue {
@@ -199,68 +211,154 @@}.chat {  margin: 30px 0;  display: flex;  flex-direction: column;  justify-content: flex-end;  padding: 30px;  width: 100%;  min-height: 100%;}@media (max-width: 1023.98px) {  .chat {    justify-content: flex-start;  }}.chatLine {  display: flex;  margin-bottom: 20px;  justify-content: center;  opacity: 0;  margin-bottom: 12px;  align-items: flex-start;}.chatLine:global(.fade-appear) {  opacity: 0;  transform: translateX(-100px);}.chatLine:global(.fade-appear-active) {  opacity: 1;  transform: translateX(0);  transition-property: opacity, transform;  transition-duration: 250ms;}.chatLine:global(.fade-appear-done) {  opacity: 1;.chatLineUser {  justify-content: flex-end;}.chatBubble {  font-size: 1.2em;  padding: 10px 20px;  background-color: rgba(0, 0, 0, 0.7);  color: white;  width: 65%;  font-size: 1.1em;  padding: 12px 18px;  background: rgba(0, 0, 0, 0.06);  border-radius: var(--radius-2);  color: black;  max-width: 75%;  line-height: 1.5;}@media (max-width: 767.98px) {  .chatBubble {    font-size: 1em;    width: 70%;  }}.chatBubble span {  display: block;  font-size: 0.5em;  font-size: 0.65em;  text-transform: uppercase;  margin-top: 5px;  color: rgba(255, 255, 255, 0.7);  letter-spacing: 1px;  font-weight: 800;  margin-top: 8px;  color: var(--color-blue);  letter-spacing: 2px;  font-weight: 700;  font-family: monospace;}.chatAvatar {  margin-right: 20px;  width: 50px;  height: 50px;  margin-right: 16px;  width: 40px;  height: 40px;  display: inline-flex;  flex-shrink: 0;}@media (max-width: 767.98px) {  .chatAvatar {    margin-right: 10px;    width: 40px;    height: 40px;    width: 36px;    height: 36px;  }}.chatBubbleUser {  background-image: linear-gradient(    to right,    var(--color-blue) 0,    var(--color-purple) 100%  );  color: white;}.chatBubbleUser span {  display: none;}.chatOptions {  display: flex;  flex-wrap: wrap;  gap: 8px;  margin-top: 4px;  margin-bottom: 12px;  padding-left: 56px;}@media (max-width: 767.98px) {  .chatOptions {    padding-left: 0;  }}.chatOption {  padding: 8px 16px;  font-size: 0.9em;  font-weight: 600;  background: none;  border: 1px solid rgba(0, 0, 0, 0.2);  border-radius: var(--radius-2);  color: black;  cursor: none;  transition: border-color 200ms, background 200ms;  font-family: inherit;}.chatOption:hover {  border-color: var(--color-blue);  background: rgba(14, 63, 244, 0.05);}@keyframes dotPulse {  0%, 80%, 100% {    opacity: 0.3;  }  40% {    opacity: 1;  }}.typingDots {  display: inline-flex;  gap: 4px;  align-items: center;}.typingDots span {  display: inline-block;  width: 6px;  height: 6px;  background: rgba(0, 0, 0, 0.4);  border-radius: 50%;  animation: dotPulse 1.4s infinite;  margin-top: 0;  font-size: inherit;  letter-spacing: normal;  text-transform: none;  font-weight: normal;  font-family: inherit;  color: transparent;}.typingDots span:nth-child(2) {  animation-delay: 0.2s;}.typingDots span:nth-child(3) {  animation-delay: 0.4s;}
modified styles/pages/index.module.css
@@ -7,12 +7,14 @@  }}@keyframes slideStart {@keyframes slideUp {  from {    transform: translateX(-100vw);    opacity: 0;    transform: translateY(30px);  }  to {    transform: translateX(0);    opacity: 1;    transform: translateY(0);  }}
@@ -46,7 +48,7 @@.word {  opacity: 0.2;  font-size: 14vw;  font-size: 11vw;  text-transform: uppercase;  margin: 0;  position: absolute;
@@ -83,55 +85,94 @@  transition-property: opacity, transform;}.description {  font-size: 3.5em;  font-weight: bolder;.hero {  position: relative;  z-index: 20;  opacity: 0;  animation-name: fadeStart;  animation-duration: 1500ms;  animation-fill-mode: forwards;  animation-play-state: paused;  position: relative;  z-index: 20;}.description::before {.hero::before {  content: "";  display: block;  width: 75px;  height: 5px;  margin: 0 0 20px 0;  background-color: var(--color-blue);  width: 60px;  height: 4px;  margin-bottom: 24px;  background-image: linear-gradient(    to right,    var(--color-blue) 0,    var(--color-purple) 100%  );}@media (max-width: 767.98px) {  .description {    font-size: 2em;  }.name {  margin: 0 0 16px 0;  line-height: 0.9;  overflow: visible;}.name {  font-size: 2.5em;.firstName {  display: block;  font-size: clamp(2.8em, 6.5vw, 5em);  font-weight: 800;  text-transform: uppercase;  letter-spacing: -0.02em;}.lastName {  display: block;  font-size: clamp(2.8em, 6.5vw, 5em);  font-weight: 800;  text-transform: uppercase;  padding: 5px;  margin: 0 0 2px 0;  align-self: flex-start;  letter-spacing: -0.02em;  background-image: linear-gradient(    to right,    var(--color-blue) 0,    var(--color-purple) 100%  );  transform: translateX(-100vw);  animation-name: slideStart;  animation-duration: 750ms;  animation-fill-mode: forwards;  animation-play-state: paused;  position: relative;  z-index: 20;  -webkit-background-clip: text;  background-clip: text;  -webkit-text-fill-color: transparent;  filter: drop-shadow(0 0 20px rgba(0, 0, 0, 0.8));}.role {  display: flex;  align-items: baseline;  gap: 10px;  font-family: monospace;  font-size: 1.5em;  letter-spacing: 2px;  text-transform: uppercase;}.roleTitle {  color: white;  font-weight: 700;}.roleAt {  color: var(--color-blue);  font-weight: 400;}.roleCompany {  color: rgba(255, 255, 255, 0.6);  font-weight: 400;}@media (max-width: 767.98px) {  .name {    font-size: 1.5em;  .firstName,  .lastName {    font-size: 10vw;  }  .role {    flex-direction: column;    gap: 2px;    font-size: 0.85em;  }}
modified yarn.lock
@@ -153,11 +153,6 @@  dependencies:    tslib "^2.4.0""@gar/promisify@^1.0.1":  version "1.1.3"  resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"  integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="@img/colour@^1.0.0":  version "1.0.0"  resolved "https://registry.yarnpkg.com/@img/colour/-/colour-1.0.0.tgz#d2fabb223455a793bf3bf9c70de3d28526aa8311"
@@ -339,66 +334,50 @@    "@jridgewell/resolve-uri" "^3.1.0"    "@jridgewell/sourcemap-codec" "^1.4.14""@next/env@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/env/-/env-16.1.6.tgz#0f85979498249a94ef606ef535042a831f905e89"  integrity sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="@next/swc-darwin-arm64@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.6.tgz#fbe1e360efdcc9ebd0a10301518275bc59e12a91"  integrity sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw=="@next/swc-darwin-x64@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.6.tgz#0e3781ef3abc8251c2a21addc733d9a87f44829b"  integrity sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ=="@next/swc-linux-arm64-gnu@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.6.tgz#b24511af2c6129f2deaf5c8c04d297fe09cd40d7"  integrity sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw=="@next/swc-linux-arm64-musl@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.6.tgz#9d4ed0565689fc6a867250f994736a5b8c542ccb"  integrity sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ=="@next/swc-linux-x64-gnu@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.6.tgz#cc757f4384e7eab7d3dba704a97f737518bae0d2"  integrity sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ=="@next/swc-linux-x64-musl@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.6.tgz#ef1341740f29717deea7c6ec27ae6269386e20d1"  integrity sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg=="@next/swc-win32-arm64-msvc@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.6.tgz#fee8719242aecf9c39c3a66f1f73821f7884dd16"  integrity sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw=="@next/swc-win32-x64-msvc@16.1.6":  version "16.1.6"  resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.6.tgz#60c27323c30f35722b20fd6d62449fbb768e46d9"  integrity sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A=="@npmcli/fs@^1.0.0":  version "1.1.1"  resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257"  integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==  dependencies:    "@gar/promisify" "^1.0.1"    semver "^7.3.5""@npmcli/move-file@^1.0.1":  version "1.1.2"  resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674"  integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==  dependencies:    mkdirp "^1.0.4"    rimraf "^3.0.2""@next/env@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/env/-/env-16.2.2.tgz#209b1972833367f1009d07c40250eae9924b5489"  integrity sha512-LqSGz5+xGk9EL/iBDr2yo/CgNQV6cFsNhRR2xhSXYh7B/hb4nePCxlmDvGEKG30NMHDFf0raqSyOZiQrO7BkHQ=="@next/swc-darwin-arm64@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.2.tgz#3fef301c711e8c249367a8e5bf6de70fb74a05a4"  integrity sha512-B92G3ulrwmkDSEJEp9+XzGLex5wC1knrmCSIylyVeiAtCIfvEJYiN3v5kXPlYt5R4RFlsfO/v++aKV63Acrugg=="@next/swc-darwin-x64@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.2.tgz#729584bfae41fca5e381229a3d1fe0eaf313cc0e"  integrity sha512-7ZwSgNKJNQiwW0CKhNm9B1WS2L1Olc4B2XY0hPYCAL3epFnugMhuw5TMWzMilQ3QCZcCHoYm9NGWTHbr5REFxw=="@next/swc-linux-arm64-gnu@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.2.tgz#edd526da879fe56e4cb82d57aeb5174956c65493"  integrity sha512-c3m8kBHMziMgo2fICOP/cd/5YlrxDU5YYjAJeQLyFsCqVF8xjOTH/QYG4a2u48CvvZZSj1eHQfBCbyh7kBr30Q=="@next/swc-linux-arm64-musl@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.2.tgz#f5990229520663cd759b0eaa426dace2b0510a10"  integrity sha512-VKLuscm0P/mIfzt+SDdn2+8TNNJ7f0qfEkA+az7OqQbjzKdBxAHs0UvuiVoCtbwX+dqMEL9U54b5wQ/aN3dHeg=="@next/swc-linux-x64-gnu@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.2.tgz#49b3fcdf73e0403fde8dc9309488c5dd3d19b587"  integrity sha512-kU3OPHJq6sBUjOk7wc5zJ7/lipn8yGldMoAv4z67j6ov6Xo/JvzA7L7LCsyzzsXmgLEhk3Qkpwqaq/1+XpNR3g=="@next/swc-linux-x64-musl@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.2.tgz#c7fa2e5cb97876efcc8773ae892e426aec1b6f97"  integrity sha512-CKXRILyErMtUftp+coGcZ38ZwE/Aqq45VMCcRLr2I4OXKrgxIBDXHnBgeX/UMil0S09i2JXaDL3Q+TN8D/cKmg=="@next/swc-win32-arm64-msvc@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.2.tgz#4d144d95344d684b62710246b15f306b3ee24341"  integrity sha512-sS/jSk5VUoShUqINJFvNjVT7JfR5ORYj/+/ZpOYbbIohv/lQfduWnGAycq2wlknbOql2xOR0DoV0s6Xfcy49+g=="@next/swc-win32-x64-msvc@16.2.2":  version "16.2.2"  resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.2.tgz#1120617f423b81a4ba588b289aeafc9c03526b71"  integrity sha512-aHaKceJgdySReT7qeck5oShucxWRiiEuwCGK8HHALe6yZga8uyFpLkPgaRw3kkF04U7ROogL/suYCNt/+CuXGA=="@swc/helpers@0.5.15":  version "0.5.15"
@@ -407,118 +386,15 @@  dependencies:    tslib "^2.8.0""@tootallnate/once@1":  version "1.1.2"  resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"  integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="@types/debug@^4.1.8":  version "4.1.12"  resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917"  integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==  dependencies:    "@types/ms" "*""@types/ms@*":  version "2.1.0"  resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78"  integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="@types/node@*":  version "25.3.0"  resolved "https://registry.yarnpkg.com/@types/node/-/node-25.3.0.tgz#749b1bd4058e51b72e22bd41e9eab6ebd0180470"  integrity sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==  dependencies:    undici-types "~7.18.0""@types/validator@^13.7.17":  version "13.15.10"  resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.15.10.tgz#742b77ec34d58554b94a76a14cef30d59e3c16b9"  integrity sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==abbrev@1:  version "1.1.1"  resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"  integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==agent-base@6, agent-base@^6.0.2:  version "6.0.2"  resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"  integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==  dependencies:    debug "4"agentkeepalive@^4.1.3:  version "4.6.0"  resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a"  integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==  dependencies:    humanize-ms "^1.2.1"aggregate-error@^3.0.0:  version "3.1.0"  resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"  integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==  dependencies:    clean-stack "^2.0.0"    indent-string "^4.0.0"ansi-regex@^5.0.1:  version "5.0.1"  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"  integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="aproba@^1.0.3 || ^2.0.0":  version "2.1.0"  resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.1.0.tgz#75500a190313d95c64e871e7e4284c6ac219f0b1"  integrity sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==are-we-there-yet@^3.0.0:  version "3.0.1"  resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd"  integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==  dependencies:    delegates "^1.0.0"    readable-stream "^3.6.0"balanced-match@^1.0.0:  version "1.0.2"  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"  integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==base64-js@^1.3.1:  version "1.5.1"  resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"  integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==baseline-browser-mapping@^2.8.3, baseline-browser-mapping@^2.9.0:baseline-browser-mapping@^2.9.0:  version "2.10.0"  resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz#5b09935025bf8a80e29130251e337c6a7fc8cbb9"  integrity sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==bindings@^1.5.0:  version "1.5.0"  resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"  integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==  dependencies:    file-uri-to-path "1.0.0"bl@^4.0.3:  version "4.1.0"  resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"  integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==  dependencies:    buffer "^5.5.0"    inherits "^2.0.4"    readable-stream "^3.4.0"brace-expansion@^1.1.7:  version "1.1.12"  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843"  integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==  dependencies:    balanced-match "^1.0.0"    concat-map "0.0.1"baseline-browser-mapping@^2.9.19:  version "2.10.14"  resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.14.tgz#d25463733a8f80bb59ab9f797c902dc88832d47c"  integrity sha512-fOVLPAsFTsQfuCkvahZkzq6nf8KvGWanlYoTh0SVA0A/PIUxQGU2AOZAoD95n2gFLVDW/jP6sbGLny95nmEuHA==browserslist@^4.24.0:  version "4.28.1"
@@ -531,78 +407,16 @@ browserslist@^4.24.0:    node-releases "^2.0.27"    update-browserslist-db "^1.2.0"buffer@^5.5.0:  version "5.7.1"  resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"  integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==  dependencies:    base64-js "^1.3.1"    ieee754 "^1.1.13"cacache@^15.2.0:  version "15.3.0"  resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb"  integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==  dependencies:    "@npmcli/fs" "^1.0.0"    "@npmcli/move-file" "^1.0.1"    chownr "^2.0.0"    fs-minipass "^2.0.0"    glob "^7.1.4"    infer-owner "^1.0.4"    lru-cache "^6.0.0"    minipass "^3.1.1"    minipass-collect "^1.0.2"    minipass-flush "^1.0.5"    minipass-pipeline "^1.2.2"    mkdirp "^1.0.3"    p-map "^4.0.0"    promise-inflight "^1.0.1"    rimraf "^3.0.2"    ssri "^8.0.1"    tar "^6.0.2"    unique-filename "^1.1.1"caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001759:  version "1.0.30001770"  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz#4dc47d3b263a50fbb243448034921e0a88591a84"  integrity sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==chownr@^1.1.1:  version "1.1.4"  resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"  integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==chownr@^2.0.0:  version "2.0.0"  resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"  integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==clean-stack@^2.0.0:  version "2.2.0"  resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"  integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==client-only@0.0.1:  version "0.0.1"  resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"  integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==color-support@^1.1.3:  version "1.1.3"  resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"  integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==concat-map@0.0.1:  version "0.0.1"  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"  integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==console-control-strings@^1.1.0:  version "1.1.0"  resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"  integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==convert-source-map@^2.0.0:  version "2.0.0"  resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
@@ -613,31 +427,14 @@ csstype@^3.0.2:  resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a"  integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==debug@4, debug@^4.1.0, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4:debug@^4.1.0, debug@^4.3.1:  version "4.4.3"  resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"  integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==  dependencies:    ms "^2.1.3"decompress-response@^6.0.0:  version "6.0.0"  resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"  integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==  dependencies:    mimic-response "^3.1.0"deep-extend@^0.6.0:  version "0.6.0"  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"  integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==delegates@^1.0.0:  version "1.0.0"  resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"  integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==detect-libc@^2.0.0, detect-libc@^2.1.2:detect-libc@^2.1.2:  version "2.1.2"  resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"  integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
@@ -650,222 +447,21 @@ dom-helpers@^5.0.1:    "@babel/runtime" "^7.8.7"    csstype "^3.0.2"dottie@^2.0.6:  version "2.0.6"  resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.6.tgz#34564ebfc6ec5e5772272d466424ad5b696484d4"  integrity sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==electron-to-chromium@^1.5.263:  version "1.5.302"  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz#032a5802b31f7119269959c69fe2015d8dad5edb"  integrity sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==emoji-regex@^8.0.0:  version "8.0.0"  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"  integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==encoding@^0.1.12:  version "0.1.13"  resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"  integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==  dependencies:    iconv-lite "^0.6.2"end-of-stream@^1.1.0, end-of-stream@^1.4.1:  version "1.4.5"  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c"  integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==  dependencies:    once "^1.4.0"env-paths@^2.2.0:  version "2.2.1"  resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"  integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==err-code@^2.0.2:  version "2.0.3"  resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"  integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==escalade@^3.2.0:  version "3.2.0"  resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"  integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==expand-template@^2.0.3:  version "2.0.3"  resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"  integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==file-uri-to-path@1.0.0:  version "1.0.0"  resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"  integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==fs-constants@^1.0.0:  version "1.0.0"  resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"  integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==fs-minipass@^2.0.0:  version "2.1.0"  resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"  integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==  dependencies:    minipass "^3.0.0"fs.realpath@^1.0.0:  version "1.0.0"  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"  integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==gauge@^4.0.3:  version "4.0.4"  resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce"  integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==  dependencies:    aproba "^1.0.3 || ^2.0.0"    color-support "^1.1.3"    console-control-strings "^1.1.0"    has-unicode "^2.0.1"    signal-exit "^3.0.7"    string-width "^4.2.3"    strip-ansi "^6.0.1"    wide-align "^1.1.5"gensync@^1.0.0-beta.2:  version "1.0.0-beta.2"  resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"  integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==github-from-package@0.0.0:  version "0.0.0"  resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"  integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==glob@^7.1.3, glob@^7.1.4:  version "7.2.3"  resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"  integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==  dependencies:    fs.realpath "^1.0.0"    inflight "^1.0.4"    inherits "2"    minimatch "^3.1.1"    once "^1.3.0"    path-is-absolute "^1.0.0"graceful-fs@^4.2.6:  version "4.2.11"  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"  integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==has-unicode@^2.0.1:  version "2.0.1"  resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"  integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==http-cache-semantics@^4.1.0:  version "4.2.0"  resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5"  integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==http-proxy-agent@^4.0.1:  version "4.0.1"  resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"  integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==  dependencies:    "@tootallnate/once" "1"    agent-base "6"    debug "4"https-proxy-agent@^5.0.0:  version "5.0.1"  resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"  integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==  dependencies:    agent-base "6"    debug "4"humanize-ms@^1.2.1:  version "1.2.1"  resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"  integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==  dependencies:    ms "^2.0.0"iconv-lite@^0.6.2:  version "0.6.3"  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"  integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==  dependencies:    safer-buffer ">= 2.1.2 < 3.0.0"ieee754@^1.1.13:  version "1.2.1"  resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"  integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==imurmurhash@^0.1.4:  version "0.1.4"  resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"  integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==indent-string@^4.0.0:  version "4.0.0"  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"  integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==infer-owner@^1.0.4:  version "1.0.4"  resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"  integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==inflection@^1.13.4:  version "1.13.4"  resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.4.tgz#65aa696c4e2da6225b148d7a154c449366633a32"  integrity sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==inflight@^1.0.4:  version "1.0.6"  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"  integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==  dependencies:    once "^1.3.0"    wrappy "1"inherits@2, inherits@^2.0.3, inherits@^2.0.4:  version "2.0.4"  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==ini@~1.3.0:  version "1.3.8"  resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"  integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==ip-address@^10.0.1:  version "10.1.0"  resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4"  integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==is-fullwidth-code-point@^3.0.0:  version "3.0.0"  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"  integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==is-lambda@^1.0.1:  version "1.0.1"  resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"  integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==isexe@^2.0.0:  version "2.0.0"  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"  integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:  version "4.0.0"  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -881,11 +477,6 @@ json5@^2.2.3:  resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"  integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==lodash@^4.17.21:  version "4.17.23"  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a"  integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==loose-envify@^1.4.0:  version "1.4.0"  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -900,134 +491,7 @@ lru-cache@^5.1.1:  dependencies:    yallist "^3.0.2"lru-cache@^6.0.0:  version "6.0.0"  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"  integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==  dependencies:    yallist "^4.0.0"make-fetch-happen@^9.1.0:  version "9.1.0"  resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968"  integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==  dependencies:    agentkeepalive "^4.1.3"    cacache "^15.2.0"    http-cache-semantics "^4.1.0"    http-proxy-agent "^4.0.1"    https-proxy-agent "^5.0.0"    is-lambda "^1.0.1"    lru-cache "^6.0.0"    minipass "^3.1.3"    minipass-collect "^1.0.2"    minipass-fetch "^1.3.2"    minipass-flush "^1.0.5"    minipass-pipeline "^1.2.4"    negotiator "^0.6.2"    promise-retry "^2.0.1"    socks-proxy-agent "^6.0.0"    ssri "^8.0.0"mimic-response@^3.1.0:  version "3.1.0"  resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"  integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==minimatch@^3.1.1:  version "3.1.2"  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"  integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==  dependencies:    brace-expansion "^1.1.7"minimist@^1.2.0, minimist@^1.2.3:  version "1.2.8"  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"  integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==minipass-collect@^1.0.2:  version "1.0.2"  resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617"  integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==  dependencies:    minipass "^3.0.0"minipass-fetch@^1.3.2:  version "1.4.1"  resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6"  integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==  dependencies:    minipass "^3.1.0"    minipass-sized "^1.0.3"    minizlib "^2.0.0"  optionalDependencies:    encoding "^0.1.12"minipass-flush@^1.0.5:  version "1.0.5"  resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373"  integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==  dependencies:    minipass "^3.0.0"minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4:  version "1.2.4"  resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c"  integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==  dependencies:    minipass "^3.0.0"minipass-sized@^1.0.3:  version "1.0.3"  resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70"  integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==  dependencies:    minipass "^3.0.0"minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3:  version "3.3.6"  resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a"  integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==  dependencies:    yallist "^4.0.0"minipass@^5.0.0:  version "5.0.0"  resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"  integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==minizlib@^2.0.0, minizlib@^2.1.1:  version "2.1.2"  resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"  integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==  dependencies:    minipass "^3.0.0"    yallist "^4.0.0"mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:  version "0.5.3"  resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"  integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==mkdirp@^1.0.3, mkdirp@^1.0.4:  version "1.0.4"  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"  integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==moment-timezone@^0.5.43:  version "0.5.48"  resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.48.tgz#111727bb274734a518ae154b5ca589283f058967"  integrity sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==  dependencies:    moment "^2.29.4"moment@^2.29.4:  version "2.30.1"  resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"  integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==ms@^2.0.0, ms@^2.1.3:ms@^2.1.3:  version "2.1.3"  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"  integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -1037,117 +501,38 @@ nanoid@^3.3.6:  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"  integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==napi-build-utils@^2.0.0:  version "2.0.0"  resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e"  integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==negotiator@^0.6.2:  version "0.6.4"  resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7"  integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==next@^16.1.6:  version "16.1.6"  resolved "https://registry.yarnpkg.com/next/-/next-16.1.6.tgz#24a861371cbe211be7760d9a89ddf2415e3824de"  integrity sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==next@^16.2.2:  version "16.2.2"  resolved "https://registry.yarnpkg.com/next/-/next-16.2.2.tgz#7b02ce7ec5f2e17fc699ca2590820c779ae8282e"  integrity sha512-i6AJdyVa4oQjyvX/6GeER8dpY/xlIV+4NMv/svykcLtURJSy/WzDnnUk/TM4d0uewFHK7xSQz4TbIwPgjky+3A==  dependencies:    "@next/env" "16.1.6"    "@next/env" "16.2.2"    "@swc/helpers" "0.5.15"    baseline-browser-mapping "^2.8.3"    baseline-browser-mapping "^2.9.19"    caniuse-lite "^1.0.30001579"    postcss "8.4.31"    styled-jsx "5.1.6"  optionalDependencies:    "@next/swc-darwin-arm64" "16.1.6"    "@next/swc-darwin-x64" "16.1.6"    "@next/swc-linux-arm64-gnu" "16.1.6"    "@next/swc-linux-arm64-musl" "16.1.6"    "@next/swc-linux-x64-gnu" "16.1.6"    "@next/swc-linux-x64-musl" "16.1.6"    "@next/swc-win32-arm64-msvc" "16.1.6"    "@next/swc-win32-x64-msvc" "16.1.6"    sharp "^0.34.4"node-abi@^3.3.0:  version "3.87.0"  resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.87.0.tgz#423e28fea5c2f195fddd98acded9938c001ae6dd"  integrity sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==  dependencies:    semver "^7.3.5"node-addon-api@^7.0.0:  version "7.1.1"  resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558"  integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==node-gyp@8.x:  version "8.4.1"  resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937"  integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==  dependencies:    env-paths "^2.2.0"    glob "^7.1.4"    graceful-fs "^4.2.6"    make-fetch-happen "^9.1.0"    nopt "^5.0.0"    npmlog "^6.0.0"    rimraf "^3.0.2"    semver "^7.3.5"    tar "^6.1.2"    which "^2.0.2"    "@next/swc-darwin-arm64" "16.2.2"    "@next/swc-darwin-x64" "16.2.2"    "@next/swc-linux-arm64-gnu" "16.2.2"    "@next/swc-linux-arm64-musl" "16.2.2"    "@next/swc-linux-x64-gnu" "16.2.2"    "@next/swc-linux-x64-musl" "16.2.2"    "@next/swc-win32-arm64-msvc" "16.2.2"    "@next/swc-win32-x64-msvc" "16.2.2"    sharp "^0.34.5"node-releases@^2.0.27:  version "2.0.27"  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e"  integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==nopt@^5.0.0:  version "5.0.0"  resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88"  integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==  dependencies:    abbrev "1"npmlog@^6.0.0:  version "6.0.2"  resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830"  integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==  dependencies:    are-we-there-yet "^3.0.0"    console-control-strings "^1.1.0"    gauge "^4.0.3"    set-blocking "^2.0.0"object-assign@^4.1.1:  version "4.1.1"  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"  integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==once@^1.3.0, once@^1.3.1, once@^1.4.0:  version "1.4.0"  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"  integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==  dependencies:    wrappy "1"p-map@^4.0.0:  version "4.0.0"  resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"  integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==  dependencies:    aggregate-error "^3.0.0"path-is-absolute@^1.0.0:  version "1.0.1"  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"  integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==pg-connection-string@^2.6.1:  version "2.11.0"  resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.11.0.tgz#5dca53ff595df33ba9db812e181b19909866d10b"  integrity sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==picocolors@^1.0.0, picocolors@^1.1.1:  version "1.1.1"  resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
@@ -1162,37 +547,6 @@ postcss@8.4.31:    picocolors "^1.0.0"    source-map-js "^1.0.2"prebuild-install@^7.1.1:  version "7.1.3"  resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec"  integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==  dependencies:    detect-libc "^2.0.0"    expand-template "^2.0.3"    github-from-package "0.0.0"    minimist "^1.2.3"    mkdirp-classic "^0.5.3"    napi-build-utils "^2.0.0"    node-abi "^3.3.0"    pump "^3.0.0"    rc "^1.2.7"    simple-get "^4.0.0"    tar-fs "^2.0.0"    tunnel-agent "^0.6.0"promise-inflight@^1.0.1:  version "1.0.1"  resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"  integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==promise-retry@^2.0.1:  version "2.0.1"  resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22"  integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==  dependencies:    err-code "^2.0.2"    retry "^0.12.0"prop-types@^15.6.2:  version "15.8.1"  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
@@ -1202,24 +556,6 @@ prop-types@^15.6.2:    object-assign "^4.1.1"    react-is "^16.13.1"pump@^3.0.0:  version "3.0.3"  resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d"  integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==  dependencies:    end-of-stream "^1.1.0"    once "^1.3.1"rc@^1.2.7:  version "1.2.8"  resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"  integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==  dependencies:    deep-extend "^0.6.0"    ini "~1.3.0"    minimist "^1.2.0"    strip-json-comments "~2.0.1"react-dom@^19.2.4:  version "19.2.4"  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.4.tgz#6fac6bd96f7db477d966c7ec17c1a2b1ad8e6591"
@@ -1252,42 +588,6 @@ react@^19.2.4:  resolved "https://registry.yarnpkg.com/react/-/react-19.2.4.tgz#438e57baa19b77cb23aab516cf635cd0579ee09a"  integrity sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:  version "3.6.2"  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"  integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==  dependencies:    inherits "^2.0.3"    string_decoder "^1.1.1"    util-deprecate "^1.0.1"retry-as-promised@^7.0.4:  version "7.1.1"  resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-7.1.1.tgz#3626246f04c1941ff10cebcfa3df0577fd8ab2d7"  integrity sha512-hMD7odLOt3LkTjcif8aRZqi/hybjpLNgSk5oF5FCowfCjok6LukpN2bDX7R5wDmbgBQFn7YoBxSagmtXHaJYJw==retry@^0.12.0:  version "0.12.0"  resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"  integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==rimraf@^3.0.2:  version "3.0.2"  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"  integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==  dependencies:    glob "^7.1.3"safe-buffer@^5.0.1, safe-buffer@~5.2.0:  version "5.2.1"  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"  integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="safer-buffer@>= 2.1.2 < 3.0.0":  version "2.1.2"  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"  integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==scheduler@^0.27.0:  version "0.27.0"  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd"
@@ -1298,44 +598,12 @@ semver@^6.3.1:  resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"  integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==semver@^7.3.5, semver@^7.5.4, semver@^7.7.3:semver@^7.7.3:  version "7.7.4"  resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a"  integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==sequelize-pool@^7.1.0:  version "7.1.0"  resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz#210b391af4002762f823188fd6ecfc7413020768"  integrity sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==sequelize@^6.37.7:  version "6.37.7"  resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.37.7.tgz#55a6f8555ae76c1fbd4bce76b2ac5fcc0a1e6eb6"  integrity sha512-mCnh83zuz7kQxxJirtFD7q6Huy6liPanI67BSlbzSYgVNl5eXVdE2CN1FuAeZwG1SNpGsNRCV+bJAVVnykZAFA==  dependencies:    "@types/debug" "^4.1.8"    "@types/validator" "^13.7.17"    debug "^4.3.4"    dottie "^2.0.6"    inflection "^1.13.4"    lodash "^4.17.21"    moment "^2.29.4"    moment-timezone "^0.5.43"    pg-connection-string "^2.6.1"    retry-as-promised "^7.0.4"    semver "^7.5.4"    sequelize-pool "^7.1.0"    toposort-class "^1.0.1"    uuid "^8.3.2"    validator "^13.9.0"    wkx "^0.5.0"set-blocking@^2.0.0:  version "2.0.0"  resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"  integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==sharp@^0.34.4, sharp@^0.34.5:sharp@^0.34.5:  version "0.34.5"  resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.34.5.tgz#b6f148e4b8c61f1797bde11a9d1cfebbae2c57b0"  integrity sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==
@@ -1369,99 +637,11 @@ sharp@^0.34.4, sharp@^0.34.5:    "@img/sharp-win32-ia32" "0.34.5"    "@img/sharp-win32-x64" "0.34.5"signal-exit@^3.0.7:  version "3.0.7"  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"  integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==simple-concat@^1.0.0:  version "1.0.1"  resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"  integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==simple-get@^4.0.0:  version "4.0.1"  resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"  integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==  dependencies:    decompress-response "^6.0.0"    once "^1.3.1"    simple-concat "^1.0.0"smart-buffer@^4.2.0:  version "4.2.0"  resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"  integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==socks-proxy-agent@^6.0.0:  version "6.2.1"  resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce"  integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==  dependencies:    agent-base "^6.0.2"    debug "^4.3.3"    socks "^2.6.2"socks@^2.6.2:  version "2.8.7"  resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea"  integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==  dependencies:    ip-address "^10.0.1"    smart-buffer "^4.2.0"source-map-js@^1.0.2:  version "1.2.1"  resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"  integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==sqlite3@^5.1.7:  version "5.1.7"  resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.1.7.tgz#59ca1053c1ab38647396586edad019b1551041b7"  integrity sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==  dependencies:    bindings "^1.5.0"    node-addon-api "^7.0.0"    prebuild-install "^7.1.1"    tar "^6.1.11"  optionalDependencies:    node-gyp "8.x"ssri@^8.0.0, ssri@^8.0.1:  version "8.0.1"  resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af"  integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==  dependencies:    minipass "^3.1.1""string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3:  version "4.2.3"  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==  dependencies:    emoji-regex "^8.0.0"    is-fullwidth-code-point "^3.0.0"    strip-ansi "^6.0.1"string_decoder@^1.1.1:  version "1.3.0"  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"  integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==  dependencies:    safe-buffer "~5.2.0"strip-ansi@^6.0.1:  version "6.0.1"  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==  dependencies:    ansi-regex "^5.0.1"strip-json-comments@~2.0.1:  version "2.0.1"  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"  integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==styled-jsx@5.1.6:  version "5.1.6"  resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.6.tgz#83b90c077e6c6a80f7f5e8781d0f311b2fe41499"
@@ -1469,75 +649,11 @@ styled-jsx@5.1.6:  dependencies:    client-only "0.0.1"tar-fs@^2.0.0:  version "2.1.4"  resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.4.tgz#800824dbf4ef06ded9afea4acafe71c67c76b930"  integrity sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==  dependencies:    chownr "^1.1.1"    mkdirp-classic "^0.5.2"    pump "^3.0.0"    tar-stream "^2.1.4"tar-stream@^2.1.4:  version "2.2.0"  resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"  integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==  dependencies:    bl "^4.0.3"    end-of-stream "^1.4.1"    fs-constants "^1.0.0"    inherits "^2.0.3"    readable-stream "^3.1.1"tar@^6.0.2, tar@^6.1.11, tar@^6.1.2:  version "6.2.1"  resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a"  integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==  dependencies:    chownr "^2.0.0"    fs-minipass "^2.0.0"    minipass "^5.0.0"    minizlib "^2.1.1"    mkdirp "^1.0.3"    yallist "^4.0.0"toposort-class@^1.0.1:  version "1.0.1"  resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988"  integrity sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==tslib@^2.4.0, tslib@^2.8.0:  version "2.8.1"  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"  integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==tunnel-agent@^0.6.0:  version "0.6.0"  resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"  integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==  dependencies:    safe-buffer "^5.0.1"undici-types@~7.18.0:  version "7.18.2"  resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.18.2.tgz#29357a89e7b7ca4aef3bf0fd3fd0cd73884229e9"  integrity sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==unique-filename@^1.1.1:  version "1.1.1"  resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230"  integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==  dependencies:    unique-slug "^2.0.0"unique-slug@^2.0.0:  version "2.0.2"  resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c"  integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==  dependencies:    imurmurhash "^0.1.4"update-browserslist-db@^1.2.0:  version "1.2.3"  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d"
@@ -1546,53 +662,7 @@ update-browserslist-db@^1.2.0:    escalade "^3.2.0"    picocolors "^1.1.1"util-deprecate@^1.0.1:  version "1.0.2"  resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"  integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==uuid@^8.3.2:  version "8.3.2"  resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"  integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==validator@^13.9.0:  version "13.15.26"  resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.26.tgz#36c3deeab30e97806a658728a155c66fcaa5b944"  integrity sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==which@^2.0.2:  version "2.0.2"  resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"  integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==  dependencies:    isexe "^2.0.0"wide-align@^1.1.5:  version "1.1.5"  resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"  integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==  dependencies:    string-width "^1.0.2 || 2 || 3 || 4"wkx@^0.5.0:  version "0.5.0"  resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c"  integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==  dependencies:    "@types/node" "*"wrappy@1:  version "1.0.2"  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"  integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==yallist@^3.0.2:  version "3.1.1"  resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"  integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==yallist@^4.0.0:  version "4.0.0"  resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"  integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==