<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yatrik Patel</title>
    <description>The latest articles on DEV Community by Yatrik Patel (@ytrkptl).</description>
    <link>https://dev.to/ytrkptl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F524612%2Ff0879899-8017-44ed-868f-4e99d616e790.jpg</url>
      <title>DEV Community: Yatrik Patel</title>
      <link>https://dev.to/ytrkptl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ytrkptl"/>
    <language>en</language>
    <item>
      <title>Looking for some feedback on this Avatar-letter project I thought of sharing months ago</title>
      <dc:creator>Yatrik Patel</dc:creator>
      <pubDate>Fri, 02 Apr 2021 23:38:05 +0000</pubDate>
      <link>https://dev.to/ytrkptl/looking-for-some-feedback-on-this-avatar-letter-project-i-thought-of-sharing-months-ago-2h5k</link>
      <guid>https://dev.to/ytrkptl/looking-for-some-feedback-on-this-avatar-letter-project-i-thought-of-sharing-months-ago-2h5k</guid>
      <description>&lt;p&gt;I hesitated in sharing this and kept it a secret for a few months now for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this really going to help someone?&lt;/li&gt;
&lt;li&gt;Is this worth the time and money?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I first created this, I was super excited and thought I would make it open source and allow anyone to add their own avatar-letter sets to it. I had even put together the article below and was ready to share it, but after answering the questions above, I chose not to. But I cannot contain my thoughts and need to open up. Also, I want to know everyone else's thoughts about this. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;So please just provide some feedback about this project and I would greatly appreciate it. And before you have to mention, let me share that I am already aware of many other avatar providers or libraries that exist. &lt;/li&gt;
&lt;li&gt;Finally, please also share how to go about such ideas in the future. Should I keep thinking over and over again about what I am sharing or should I just share and get feedback for the pure joy of it?&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;What follows below is my article as it was originally written months ago (verbatim)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Wanting To Open Source But Need Guidance
&lt;/h2&gt;

&lt;p&gt;Over the last 2-3 years, in my free time, I've been learning web and mobile development online. During that time, I've created several projects that live either on my computer, online, or both. These include projects made to solve a problem I encountered while working (for both past and current employers), tutorials I've followed while learning something new, and projects I'm passionate about. However, I've never really created a service or an API that is open to the public for use, and/or haven't created any open source projects myself. So, I wanted to give this a shot.&lt;/p&gt;

&lt;h3&gt;
  
  
  How This Idea Originated?
&lt;/h3&gt;

&lt;p&gt;I originally came across this idea when working on a math project that I'm building. It involved getting a user picture or avatar to be displayed on the screen. To do this, I had several options to choose from like Avatars from Material UI, Chakra, and so on. However, I did not want to download any extra packages to my project. I also had the option to use placeholder images provided by sites like Robohash, but I've had problems with such services in the past and did not want to rely on them for the entirety of my project. This time, I wanted something I had more control over. So I decided to create my own Robohash-like site that returns images or avatars upon simply entering the proper URL in the image tag's "src" attribute or in the browser. I did not want the API to return images of avatars but instead images of "avatar-letters" or alphabets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Here's an example image of what will be returned by set1 of avatar-letter:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcds7o44iimp2y8rsa18h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcds7o44iimp2y8rsa18h.png" alt="example full size avatar-letter for the letter " width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why I Felt This Was Needed?
&lt;/h3&gt;

&lt;p&gt;I felt like this sort of a project was needed (maybe) because all the component libraries or avatars I've encountered typically return an image that is made using some sort of flat and simple typeface, font, or the like and NOT a stylish, 3D-ish font instead. What I wanted to return was an image containing alphabets that looked out of this world.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Oh wow, while typing this article, I have already come across so many new ideas and possibilities to extend this project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Anyways, here are images of what most such avatar-letter libraries, sites, etc. return:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lnfsxh2wsjclh4y42df.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lnfsxh2wsjclh4y42df.png" alt="example image of avatar-letters found elsewhere" width="355" height="690"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Have So Far?
&lt;/h3&gt;

&lt;p&gt;The following is what I have, and let me just say that I have not used any fonts so far in creating the avatar-letter images that are being returned by this API. Instead, I chose some cool-looking alphabet images that I found for free on Freepik. I had to edit the images from Freepik further using PowerPoint and also using the Sharp library. The images weren't as editable as I wanted, so I just went with the best I could get.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Here's an example image of what will be returned by set2 of avatar-letter:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg033ozfrnmzsyioddihd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg033ozfrnmzsyioddihd.png" alt="example full size avatar-letter for the letter " width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The following is a breakdown of what the avatar-letter API expects:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F996hjgj5b4b1cqw1eymk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F996hjgj5b4b1cqw1eymk.png" alt="breakdown of what the API expects as far as the url is concerned" width="800" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Need Help On?
&lt;/h3&gt;

&lt;p&gt;I am wondering how to go about this project so I can make it available for anyone to contribute to while ensuring that I get the final say regarding what image sets are added to this project. Does anyone have experience in creating such services or projects?&lt;/p&gt;

&lt;h3&gt;
  
  
  Problems I Encountered
&lt;/h3&gt;

&lt;p&gt;The biggest problem I encountered was being unable to have full control over editing the images and all their layers since I relied on the free images found on the internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Suggestions/Feedback
&lt;/h3&gt;

&lt;p&gt;I am open to any suggestions, comments, feedback that you can provide on this project and how it can be improved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helpful Links
&lt;/h3&gt;

&lt;p&gt;You can find the avatar-letter site at the following link:&lt;br&gt;
&lt;a href="https://avatar-letter.netlify.app/" rel="noopener noreferrer"&gt;Avatar-letter&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;p&gt;I owe it to the following sites, people, authors, etc. for providing their resources for free:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Blue arrow was downloaded from Pixabay and created by Clker-Free-Vector-Images.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The alphabet images were downloaded from my site but were originally found on Freepik at the following links:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.freepik.com/free-vector/colorful-alphabet_958008.htm" rel="noopener noreferrer"&gt;pikisuperstar&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.freepik.com/free-vector/hand-drawn-colorful-alphabet_2920859.htm" rel="noopener noreferrer"&gt;Sapann-Design&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>help</category>
    </item>
    <item>
      <title>Having fun creating Ugly Christmas Sweaters with SVGs this Winter</title>
      <dc:creator>Yatrik Patel</dc:creator>
      <pubDate>Mon, 28 Dec 2020 20:25:07 +0000</pubDate>
      <link>https://dev.to/ytrkptl/having-fun-creating-ugly-christmas-sweaters-with-svgs-this-winter-15hj</link>
      <guid>https://dev.to/ytrkptl/having-fun-creating-ugly-christmas-sweaters-with-svgs-this-winter-15hj</guid>
      <description>&lt;p&gt;I have been wanting to share this for a while now. I must do it now. Waiting longer or waiting till it is nearly perfect might be a mistake, especially in this tech industry anyways. So let me just go ahead and share what I currently have via this &lt;a href="https://codepen.io/ytrkptl/pen/OJRxWmZ" rel="noopener noreferrer"&gt;CodePen&lt;/a&gt;. There is probably a lot that can be improved but hey, I am just doing this for fun!&lt;/p&gt;

&lt;p&gt;Below is a short summary of my journey with these sweaters so far.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I started
&lt;/h2&gt;

&lt;p&gt;I started creating these using polygons, and no curves at all. So I had something crappy at first, like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd6caj6m54fhjw44el08b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd6caj6m54fhjw44el08b.png" alt="Ugly Christmas Sweater made with polygons" width="425" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I had after fooling with Quadratic Curves
&lt;/h2&gt;

&lt;p&gt;I needed some curved lines and came across Quadratic Curves and started to modify the code accordingly. Here is what I had then:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwypo5901qtqocythjdxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwypo5901qtqocythjdxn.png" alt="Sweater 1 with curves" width="453" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I have after incorporating SVG patterns
&lt;/h2&gt;

&lt;p&gt;Later, I realized that I could use SVG patterns to draw the zigzag lines as a background to fill the entire sweater instead. So here is what I have now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3c5nl4qhuj9zbgu69clx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3c5nl4qhuj9zbgu69clx.png" alt="Sweater 2 with curves and SVG patterns" width="452" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Using Quadratic Curves improved the quality of my canvas drawing a ton. I also realized that it is possible to use SVG patterns to create the zigzag background I was hoping to create. It was much harder or maybe inefficient with the "for-loops" I was originally using. Either ways, I have left both of them in there to fool with later on.&lt;/p&gt;

&lt;p&gt;I hope you enjoy recreating some sweaters and keep doing so until you find the one you like. Feel free to share a picture of the one it made for you if you'd like 😉. At last, Stay Warm, Happy Holidays, and Happy New Year 🎉!&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Patterns" rel="noopener noreferrer"&gt;Patterns on MDN&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://css-tricks.com/snippets/svg/svg-patterns/" rel="noopener noreferrer"&gt;Geoff Graham's article on CSS Tricks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Automating Zoom Participation: From Manual Excel Grunt Work to Web App</title>
      <dc:creator>Yatrik Patel</dc:creator>
      <pubDate>Thu, 03 Dec 2020 21:22:02 +0000</pubDate>
      <link>https://dev.to/ytrkptl/count-participation-in-your-zoom-meetings-the-easier-way-using-javascript-53o0</link>
      <guid>https://dev.to/ytrkptl/count-participation-in-your-zoom-meetings-the-easier-way-using-javascript-53o0</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This article was updated with the help of Gemini 3 Pro, an AI writing assistant from Google.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As an educator, tracking student participation is vital for engagement and grading, but the process can be incredibly tedious. This project was born out of the need to automate the manual grunt work of counting Zoom chat messages, allowing teachers to focus on teaching rather than administrative tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Context: Participation as a Grade
&lt;/h2&gt;

&lt;p&gt;This application was built for a specific use case: a remote classroom where participation was graded based on chat activity.&lt;/p&gt;

&lt;p&gt;As a remote teacher teaching children over Zoom, I set a requirement that participation via chat messages counted towards their participation grade. While answering math questions was the primary way to participate, a couple of greeting messages (like "Good morning") were acceptable as well. This meant every single message needed to be tracked to ensure students received the credit they earned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Manual Tracking Overload
&lt;/h2&gt;

&lt;p&gt;To count participation manually, I had to rely on Zoom's text logs. At the time I started, Zoom saved chat messages in a specific format:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1nixxy8crovztvl7n2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1nixxy8crovztvl7n2f.png" alt="old chat" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Excel Nightmare
&lt;/h3&gt;

&lt;p&gt;My previous workflow involved copying the text into an Excel file, sorting it, and using formulas to count messages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy text from the Zoom log.&lt;/li&gt;
&lt;li&gt;Paste into Excel.&lt;/li&gt;
&lt;li&gt;Sort column to group messages by sender ("From Person A...").&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;countA&lt;/code&gt; function to tally participation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev1h588il6i71lxjdyq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev1h588il6i71lxjdyq8.png" alt="old chat in Excel" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a single meeting, this took about 5 minutes. It was manageable, but inefficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accounting for Weekly Participation
&lt;/h3&gt;

&lt;p&gt;The real problem arose when trying to track participation over a full week or for multiple classes. If you have 5 classes a week, that 5-minute task turns into 25-35 minutes of mindless copy-pasting and sorting. As the number of students or meetings increases, the manual overhead becomes unsustainable.&lt;/p&gt;

&lt;p&gt;Teachers simply don't have that kind of time to waste.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Automating with JavaScript
&lt;/h2&gt;

&lt;p&gt;I built this web app to reduce that weekly workload from 30+ minutes to just a few seconds. The app parses the Zoom chat logs, aggregates the data, and presents a clear count of participation for each student.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Instant results regardless of class size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability:&lt;/strong&gt; Eliminates human error in counting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; All processing happens locally in your browser. No data is sent to any external server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflow:&lt;/strong&gt; Frees up educators to focus on student engagement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://zoom-chat-counter.yatrik.dev" rel="noopener noreferrer"&gt;&lt;strong&gt;Live Demo&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://github.com/ytrkptl/zoom-chat-participation-counter" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Repository&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Deep Dive: Parsing Zoom Logs
&lt;/h2&gt;

&lt;p&gt;The core of the application is a string parser that normalizes the chat log formats.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling Zoom Format Changes
&lt;/h3&gt;

&lt;p&gt;Zoom updated their chat log format during the development of this tool, which broke the initial version. The new format looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyxxk3j2m0uf0isf7au6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyxxk3j2m0uf0isf7au6.png" alt="new chat" width="800" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whether the message is public or private, the relevant metadata is contained in the string segment starting with "From" and ending with a colon &lt;code&gt;:&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public:&lt;/strong&gt; &lt;code&gt;hh:mm:ss From Sender : message&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private:&lt;/strong&gt; &lt;code&gt;hh:mm:ss From Sender to Receiver(Direct Message) : message&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Parsing Logic
&lt;/h3&gt;

&lt;p&gt;The application splits the log file by newlines and iterates through each line to extract the sender's information. Here is a snippet of the core logic from &lt;code&gt;chatParser.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasCertainPattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;splitByLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;someArray&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fromIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;From&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Extract the substring starting from "From"&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fromIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Cut off at the colon to get just the meta info (e.g. "From John Doe to Host")&lt;/span&gt;
    &lt;span class="nx"&gt;sub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sub&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;someArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;someArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This extracted array is then used to create a frequency map (&lt;code&gt;{ 'From Student A': 5, ... }&lt;/code&gt;) which powers the final results table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sorting and Filtering
&lt;/h2&gt;

&lt;p&gt;Beyond simple counting, the application offers sorting and filtering to make the data more usable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sorting by Participation
&lt;/h3&gt;

&lt;p&gt;The primary goal is to see who participated the most. We can sort the frequency map by count in descending order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Converts word map to sorted array of results
 * Sorts by count in descending order
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sortByCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;wordsMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;finalWordsArray&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wordsMap&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;wordsMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;finalWordsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;finalWordsArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sorting Alphabetically
&lt;/h3&gt;

&lt;p&gt;To find specific students easily, results can be sorted alphabetically. This uses a dynamic sort function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Dynamically sorts array by property
 * Use "-property" prefix to sort in reverse order
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamicSort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sortOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sortProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sortOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;sortProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sortOrder&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sortProperty&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sortProperty&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sortProperty&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sortProperty&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;ParticipantResult&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Filtering Host Messages
&lt;/h3&gt;

&lt;p&gt;Sometimes, students message the host privately. We can filter for these messages specifically to see who is engaging directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// this function will filter the messages and return only the ones sent to the host only&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterMessagesToHostOnly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;readData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`to  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;(Direct Message)`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
          &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`to  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;(Privately)`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alphabetized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filteredArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dynamicSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="nf"&gt;updateSortedArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alphabetized&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adapting to Change
&lt;/h2&gt;

&lt;p&gt;Software that relies on third-party output formats (like Zoom logs) is inherently fragile. When Zoom changed their output format, my app initially failed. Debugging this required analyzing the new text structure and updating the parsing logic to handle both "Direct Message" and standard formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updates
&lt;/h2&gt;

&lt;p&gt;The application was last verified to be in working condition in November 2025.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Yatrik Patel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Created:&lt;/strong&gt; November 4, 2020&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Last Updated:&lt;/strong&gt; December 30, 2025&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editorial Assistance:&lt;/strong&gt; Gemini 3 Pro (for helping me update this article)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Diagrams made with Excalidraw&lt;/li&gt;
&lt;li&gt;&lt;a href="https://unsplash.com/photos/smgTvepind4" rel="noopener noreferrer"&gt;Chris Montgomery on Unsplash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pixabay.com/users/no-longer-here-19203/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1768845" rel="noopener noreferrer"&gt;No-longer-here on Pixabay&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>zoommeetings</category>
      <category>react</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
