From 4804626db7d754c7fdef29fb035c5abd1cd3715d Mon Sep 17 00:00:00 2001 From: khoaxuantu <68913255+khoaxuantu@users.noreply.github.com> Date: Mon, 4 Dec 2023 01:12:18 +0700 Subject: [PATCH] Updates --- 200.html | 2 +- 404.html | 2 +- about/index.html | 2 +- asset-manifest.json | 10 +++++----- blogs/great_ytb_channels_1/index.html | 4 ++-- blogs/great_ytb_channels_2/index.html | 6 +++--- blogs/index.html | 2 +- blogs/learn_from_react_bun_boilerplate/index.html | 6 +++--- blogs/uncommon_javascript_notes/index.html | 6 +++--- blogs/uncommon_javascript_notes_1/index.html | 14 +++++++------- contact/index.html | 2 +- guestbook/index.html | 2 +- index.html | 2 +- projects/index.html | 4 ++-- static/js/951.59825386.chunk.js | 1 + static/js/951.f82459b9.chunk.js | 1 - static/js/main.6cba0be9.js | 3 --- static/js/main.6cba0be9.js.map | 1 - static/js/main.e935baba.js | 3 +++ ...js.LICENSE.txt => main.e935baba.js.LICENSE.txt} | 0 static/js/main.e935baba.js.map | 1 + ...mon_javascript_notes_1.e9d0fcaa90720cd4a514.md} | 12 ++++++------ 22 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 static/js/951.59825386.chunk.js delete mode 100644 static/js/951.f82459b9.chunk.js delete mode 100644 static/js/main.6cba0be9.js delete mode 100644 static/js/main.6cba0be9.js.map create mode 100644 static/js/main.e935baba.js rename static/js/{main.6cba0be9.js.LICENSE.txt => main.e935baba.js.LICENSE.txt} (100%) create mode 100644 static/js/main.e935baba.js.map rename static/media/{uncommon_javascript_notes_1.64bd23357e14f40bc006.md => uncommon_javascript_notes_1.e9d0fcaa90720cd4a514.md} (98%) diff --git a/200.html b/200.html index 15c29ff..c47848d 100644 --- a/200.html +++ b/200.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/404.html b/404.html index 79040a7..9d2a818 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -Tuslipid - 404
\ No newline at end of file +Tuslipid - 404
\ No newline at end of file diff --git a/about/index.html b/about/index.html index bd26c6d..978e5f3 100644 --- a/about/index.html +++ b/about/index.html @@ -1 +1 @@ -Tuslipid - About me
Hi there! I'm Tu
Xuan Khoa Tu Nguyen | 阮春科秀 | Tu | Nguyễn Xuân Khoa Tú
~ You can call me by any name ~

Get to know me

I am a web developer from Vietnam. You have learned how to call me above, but I also use Tuslipid as my nickname across social medias and games.

I initially chose Mechanical Engineering as my major. Still, with enthusiasm for programming and intelligent systems, since my Sophomore year in late 2020, I have started self-studying Computer Science simultaneously with advice from my seniors and professors and attempted to develop further in this major.

I'm passionate about full-stack web development and cloud services, and currently continuing my career development journey at Pixta Vietnam.

typing cat

I love learning and trying new things...Let's me show you the things I'm confident

Where I studied

National Taiwan University of Science and Technology

Bachelor of Science - BSc,Computer Science / Mechanical Engineering
Sep 2018 - July 2022
Specialization:
  • Software Engineering
  • Algorithms & Data Structure
  • Machine Learning
  • Automation Control

Hanoi - Amsterdam High School for the Gifted

History
Aug 2015 - May 2018

Where I have worked

Fullstack Web Developer @ Pixta

06/2023 - now | Hanoi, Vietnam

Develop and maintain the backend system of PixtaStock. Analyze data, evaluate the effectiveness of features to improve and develop new features.

Work closely with the Japan product design team to maintain the web application for internal tools.

Provide technical support to resolve and monitor PixtaStock's issues reported by the customers.

Frequently used stacks: Ruby on Rails, React, NodeJS, MySQL, MongoDB, Docker, AWS

Updating...

Data Engineer Intern @ Pegatron

02/2022 - 06/2022 | Taipei, Taiwan

Participated in the Shop Floor Information System (SFIS) development team, which processes the data to integrate it with Pegatron's manufacturing process among 7 global and 2 local factories.

Learned how to track and update the data flow, manage and develop databases via Oracle Database.

Contributed to the transformation and loading process in the ETL and customer's report by retrieving the data into >30 forms.

Robotic Automation Engineering Trainee @ Techman

06/2020 - 08/2020 | Taoyuan, Taiwan

Got training in practical robotic processing and functioning. (Robotic arm, AI, IoT, Computer vision)

Developed the TM robotic automation project and presented the project at the 2020 Taipei Industrial Automation Exhibition.

Won the First Prize in the Projects competition held by the company.

What I have built

Above are only my featured projects. Let's navigate to my full list here ---> All Projects

Get in touch

I am primarily active in Linkedin, Discord, Github, Gmail, and Facebook, but I also have other connections in Reddit, DEV Community, or CodePen.

~ Feel free to connect with me ~

\ No newline at end of file +Tuslipid - About me
Hi there! I'm Tu
Xuan Khoa Tu Nguyen | 阮春科秀 | Tu | Nguyễn Xuân Khoa Tú
~ You can call me by any name ~

Get to know me

I am a web developer from Vietnam. You have learned how to call me above, but I also use Tuslipid as my nickname across social medias and games.

I initially chose Mechanical Engineering as my major. Still, with enthusiasm for programming and intelligent systems, since my Sophomore year in late 2020, I have started self-studying Computer Science simultaneously with advice from my seniors and professors and attempted to develop further in this major.

I'm passionate about full-stack web development and cloud services, and currently continuing my career development journey at Pixta Vietnam.

typing cat

I love learning and trying new things...Let's me show you the things I'm confident

Where I studied

National Taiwan University of Science and Technology

Bachelor of Science - BSc,Computer Science / Mechanical Engineering
Sep 2018 - July 2022
Specialization:
  • Software Engineering
  • Algorithms & Data Structure
  • Machine Learning
  • Automation Control

Hanoi - Amsterdam High School for the Gifted

History
Aug 2015 - May 2018

Where I have worked

Fullstack Web Developer @ Pixta

06/2023 - now | Hanoi, Vietnam

Develop and maintain the backend system of PixtaStock. Analyze data, evaluate the effectiveness of features to improve and develop new features.

Work closely with the Japan product design team to maintain the web application for internal tools.

Provide technical support to resolve and monitor PixtaStock's issues reported by the customers.

Frequently used stacks: Ruby on Rails, React, NodeJS, MySQL, MongoDB, Docker, AWS

Updating...

Data Engineer Intern @ Pegatron

02/2022 - 06/2022 | Taipei, Taiwan

Participated in the Shop Floor Information System (SFIS) development team, which processes the data to integrate it with Pegatron's manufacturing process among 7 global and 2 local factories.

Learned how to track and update the data flow, manage and develop databases via Oracle Database.

Contributed to the transformation and loading process in the ETL and customer's report by retrieving the data into >30 forms.

Robotic Automation Engineering Trainee @ Techman

06/2020 - 08/2020 | Taoyuan, Taiwan

Got training in practical robotic processing and functioning. (Robotic arm, AI, IoT, Computer vision)

Developed the TM robotic automation project and presented the project at the 2020 Taipei Industrial Automation Exhibition.

Won the First Prize in the Projects competition held by the company.

What I have built

Above are only my featured projects. Let's navigate to my full list here ---> All Projects

Get in touch

I am primarily active in Linkedin, Discord, Github, Gmail, and Facebook, but I also have other connections in Reddit, DEV Community, or CodePen.

~ Feel free to connect with me ~

\ No newline at end of file diff --git a/asset-manifest.json b/asset-manifest.json index e53c113..9e62cde 100644 --- a/asset-manifest.json +++ b/asset-manifest.json @@ -1,7 +1,7 @@ { "files": { "main.css": "/static/css/main.ce584f9e.css", - "main.js": "/static/js/main.6cba0be9.js", + "main.js": "/static/js/main.e935baba.js", "static/js/436.5ef6ea98.chunk.js": "/static/js/436.5ef6ea98.chunk.js", "static/css/631.5cc9aec9.chunk.css": "/static/css/631.5cc9aec9.chunk.css", "static/js/631.97393ba1.chunk.js": "/static/js/631.97393ba1.chunk.js", @@ -14,7 +14,7 @@ "static/js/771.aca2d55b.chunk.js": "/static/js/771.aca2d55b.chunk.js", "static/js/659.24fbd8b6.chunk.js": "/static/js/659.24fbd8b6.chunk.js", "static/js/769.39682b76.chunk.js": "/static/js/769.39682b76.chunk.js", - "static/js/951.f82459b9.chunk.js": "/static/js/951.f82459b9.chunk.js", + "static/js/951.59825386.chunk.js": "/static/js/951.59825386.chunk.js", "static/js/197.c54db791.chunk.js": "/static/js/197.c54db791.chunk.js", "static/media/background.webp": "/static/media/background.0fe630389f9da00b4da2.webp", "static/media/TaiwanTech.webp": "/static/media/TaiwanTech.3239f7b9cd053ceaa9ae.webp", @@ -26,7 +26,7 @@ "static/media/HanoiAms.webp": "/static/media/HanoiAms.ddc950d4a3afc5346ba9.webp", "static/media/uncommon_javascript_notes.md": "/static/media/uncommon_javascript_notes.48b5ad3a25f8a4068dd6.md", "static/media/MailSPA.webp": "/static/media/MailSPA.324994b1a4d69b103723.webp", - "static/media/uncommon_javascript_notes_1.md": "/static/media/uncommon_javascript_notes_1.64bd23357e14f40bc006.md", + "static/media/uncommon_javascript_notes_1.md": "/static/media/uncommon_javascript_notes_1.e9d0fcaa90720cd4a514.md", "static/media/Wiki.webp": "/static/media/Wiki.8bcf16832e49d293cb0f.webp", "static/media/Firebase-Light.svg": "/static/media/Firebase-Light.be39887274fc1d39cbc0.svg", "static/media/Flask-Dark.svg": "/static/media/Flask-Dark.3b200b23ebd34ac92edc.svg", @@ -69,7 +69,7 @@ "static/media/CSS.svg": "/static/media/CSS.5fcd7f5683afc0fc6d01.svg", "static/media/HTML.svg": "/static/media/HTML.ca0db580ffd74f086f2d.svg", "main.ce584f9e.css.map": "/static/css/main.ce584f9e.css.map", - "main.6cba0be9.js.map": "/static/js/main.6cba0be9.js.map", + "main.e935baba.js.map": "/static/js/main.e935baba.js.map", "436.5ef6ea98.chunk.js.map": "/static/js/436.5ef6ea98.chunk.js.map", "631.5cc9aec9.chunk.css.map": "/static/css/631.5cc9aec9.chunk.css.map", "631.97393ba1.chunk.js.map": "/static/js/631.97393ba1.chunk.js.map", @@ -81,6 +81,6 @@ }, "entrypoints": [ "static/css/main.ce584f9e.css", - "static/js/main.6cba0be9.js" + "static/js/main.e935baba.js" ] } \ No newline at end of file diff --git a/blogs/great_ytb_channels_1/index.html b/blogs/great_ytb_channels_1/index.html index a430b70..9fb971a 100644 --- a/blogs/great_ytb_channels_1/index.html +++ b/blogs/great_ytb_channels_1/index.html @@ -1,4 +1,4 @@ -Tuslipid - Great Youtube Channels (Part 1)Tuslipid - Great Youtube Channels (Part 1)
Great Youtube Channels (Part 1)

I watch youtube a lot!

There was a time I spent 2 - 3 hours per day watching youtube, video to video. Recently, I am not like this anymore, but throwing back what I have watched so far, I realize that my time hadn’t been wasted like an initial thought.

In this topic, I will show you a list of the Youtube channels which I find interesting. They are just like a drop in the ocean, but hope you guys find them helpful and inspiring (cuz they help me a lot as well xD).

This topic will be divided into 2 parts

  • Part 1 is our current standing and contains only channels about information technology. Because I’m focusing on IT, these channels are the majority of my list.
  • Part 2 is in the next blog, which contains channels about other genres such as general science, entertainment, etc...

Some guys are coding...

Study Platforms

Memes

To be continued...

\ No newline at end of file + I have watched that you may find interesting. Here is part 1 of my list..." data-react-helmet="true" name="twitter:description">
Great Youtube Channels (Part 1)

I watch youtube a lot!

There was a time I spent 2 - 3 hours per day watching youtube, video to video. Recently, I am not like this anymore, but throwing back what I have watched so far, I realize that my time hadn’t been wasted like an initial thought.

In this topic, I will show you a list of the Youtube channels which I find interesting. They are just like a drop in the ocean, but hope you guys find them helpful and inspiring (cuz they help me a lot as well xD).

This topic will be divided into 2 parts

  • Part 1 is our current standing and contains only channels about information technology. Because I’m focusing on IT, these channels are the majority of my list.
  • Part 2 is in the next blog, which contains channels about other genres such as general science, entertainment, etc...

Some guys are coding...

Study Platforms

Memes

To be continued...

\ No newline at end of file diff --git a/blogs/great_ytb_channels_2/index.html b/blogs/great_ytb_channels_2/index.html index d02c551..172deca 100644 --- a/blogs/great_ytb_channels_2/index.html +++ b/blogs/great_ytb_channels_2/index.html @@ -1,4 +1,4 @@ -Tuslipid - Great Youtube Channels (Part 2)Tuslipid - Great Youtube Channels (Part 2)
Great Youtube Channels (Part 2)

I watch youtube a lot!

Follow up on what I left in part 1. In this part, I will show you the list of Youtube channels with other exciting content.

General Sciences and Knowledge

Music

Food

Memes and Comedies

Only for Vietnamese... :)

Pheww... That's more than I expected, hope you enjoy it -.-

\ No newline at end of file + I have watched that you may find interesting. Here is part 2 of my list..." data-react-helmet="true" property="og:description">
Great Youtube Channels (Part 2)

I watch youtube a lot!

Follow up on what I left in part 1. In this part, I will show you the list of Youtube channels with other exciting content.

General Sciences and Knowledge

Music

Food

Memes and Comedies

Only for Vietnamese... :)

Pheww... That's more than I expected, hope you enjoy it -.-

\ No newline at end of file diff --git a/blogs/index.html b/blogs/index.html index 837aa9b..85e967a 100644 --- a/blogs/index.html +++ b/blogs/index.html @@ -1 +1 @@ -Tuslipid - Blogs
Tus's Blogs
Some notes, some ideas, some opinions

Trying to re-create React boilerplate in Bun and what I learned from it

Many people are hyped with Bun for its performance and new features compared with NodeJS. One of them is .jsx and .tsx file support with its internal transpiler, which help creating a React app by Bun becomes more convenient. But the problem here is to have a boilerplate to optimize the feature for creating React app.

Uncommon JavaScript Notes - Browser: Document, Events, Interfaces

One thing that make JavaScript weird to learn is how it interacts with the browser DOM, how to control the events, the forms, and how the resource is loaded.

Uncommon JavaScript Notes - The language

JavaScript is super complicated, like a pain in your ass. Even when you are quite familiar with programming languages logics and concepts, you still find it difficult to cover major aspects in JS.

Great Youtube Channels (Part 2)

I watch youtube a lot, and I make a list of youtube channels I have watched that you may find interesting. Here is part 2 of my list...
\ No newline at end of file +Tuslipid - Blogs
Tus's Blogs
Some notes, some ideas, some opinions

Trying to re-create React boilerplate in Bun and what I learned from it

Many people are hyped with Bun for its performance and new features compared with NodeJS. One of them is .jsx and .tsx file support with its internal transpiler, which help creating a React app by Bun becomes more convenient. But the problem here is to have a boilerplate to optimize the feature for creating React app.

Uncommon JavaScript Notes - Browser: Document, Events, Interfaces

One thing that make JavaScript weird to learn is how it interacts with the browser DOM, how to control the events, the forms, and how the resource is loaded.

Uncommon JavaScript Notes - The language

JavaScript is super complicated, like a pain in your ass. Even when you are quite familiar with programming languages logics and concepts, you still find it difficult to cover major aspects in JS.

Great Youtube Channels (Part 2)

I watch youtube a lot, and I make a list of youtube channels I have watched that you may find interesting. Here is part 2 of my list...
\ No newline at end of file diff --git a/blogs/learn_from_react_bun_boilerplate/index.html b/blogs/learn_from_react_bun_boilerplate/index.html index 8b36e7c..1e6decc 100644 --- a/blogs/learn_from_react_bun_boilerplate/index.html +++ b/blogs/learn_from_react_bun_boilerplate/index.html @@ -1,13 +1,13 @@ -Tuslipid - Trying to re-create React boilerplate in Bun and what I learned from itTuslipid - Trying to re-create React boilerplate in Bun and what I learned from it
Trying to re-create React boilerplate in Bun and what I learned from it

Introduction

Many people are hyped with Bun for its performance and new features compared with Node. One of them is .jsx and .tsx file support with its internal transpiler, which help creating a React app by Bun becomes more convenient. But the problem here is to have a boilerplate to optimize the feature for creating React app.

I came up with that idea when reading the JSX runtime of Bun. If we can exclude the works of Babel and Webpack, then we can reduce our build time and bundle's size dramatically.

I also know that there has already been some templates to create a React app in Bun, such as:

bun create react-app appname
+            for creating React app." data-react-helmet="true" name="twitter:description">
Trying to re-create React boilerplate in Bun and what I learned from it

Introduction

Many people are hyped with Bun for its performance and new features compared with Node. One of them is .jsx and .tsx file support with its internal transpiler, which help creating a React app by Bun becomes more convenient. But the problem here is to have a boilerplate to optimize the feature for creating React app.

I came up with that idea when reading the JSX runtime of Bun. If we can exclude the works of Babel and Webpack, then we can reduce our build time and bundle's size dramatically.

I also know that there has already been some templates to create a React app in Bun, such as:

bun create react-app appname
 

But the template like above simply uses Bun to run npx create-react-app and install all the preset dependencies. It means the project will keep using Babel and Webpack; that's not what I want 🙁

Then one day, I find out the appropriate templates in the create-templates repository of the Bun community (you can check them out via this link), which are react-ssr and react. Looking at the templates' code, it turned out that I barely understood what each line actually does. I was desperate to discover the true techniques behind them so that came up with an idea is to create a new custom React app boilerplate with Bun. To simulate each technique then I would be able to understand them.

Thus, why not to try?

Below, I will share what I have learned and recalled from my custom boilerplate.



Table of Contents

  • How are static contents served in a web
  • How the server-side rendering delivers React components
  • Inside the FileSystemRoute, refers to NextJS's routing
  • About client-side rendering
  • Cusom the console.log, manually custom a welcome console log



How are the static contents served in a web

The basics comes first, or, as it should be said, everything is built on top of the basics. Sometimes, we are just too focused on fancy stuff that we forget why there are the things called fundamentals. This time, it hit me hard.

I found the following code in the react-ssr template:

function serveFromDir(config: {
   directory: string;
   path: string;
diff --git a/blogs/uncommon_javascript_notes/index.html b/blogs/uncommon_javascript_notes/index.html
index 2a25553..c3375c6 100644
--- a/blogs/uncommon_javascript_notes/index.html
+++ b/blogs/uncommon_javascript_notes/index.html
@@ -1,10 +1,10 @@
-Tuslipid - Uncommon JavaScript Notes - The languageTuslipid - Uncommon JavaScript Notes - The language
Uncommon JavaScript Notes - The language

Introduction

JavaScript is super complicated, like a pain in your ass. Even when you are pretty familiar with other programming languages' logic and concepts, you still find it challenging to cover significant aspects of JS.

Let me tell you one story... I once started learning JavaScript with a mindset that "just like other programming languages". Honestly, it does have enough general programming concepts that help me gain some first tastes quickly. It has variables, operators, functions, objects and classes, which can make a newbie think: "Uhm ~~ I can understand it easily!". But the thing doesn't go as you expected, not like variables in C++, variables in JavaScript have var, const and let; not like a single def in Python, JavaScript can initiate a function in two ways: function declaration and function expression. Thus, I didn't understand its fundamentals the first time studying, and regularly lost track of my thinking flow when looking up its advanced topic. Although I have done some projects using extended JavaScript and libraries/frameworks such as React, ExpressJS, etc..., I still had a vague picture about prototypes, asynchronous, error handling, and so forth.

Things even got worse, I got an invitation to a whiteboard technical interview for a full-stack developer role, in which they asked me about JavaScript. Initially, I believe naively my fundamental ideas can handle their questions - "Well! Just some JS questions like tutorials". However, they gave me a question about asynchronous which is one of my most vulnerable parts. They asked me about a promise chain meanwhile I just had been familiar with a single promise. As a result, I solved it incompletely and failed the interview. 🥲

// Refactor the function below to async/await structure
+            you still find it difficult to cover major aspects in JS." data-react-helmet="true" name="twitter:description">
Uncommon JavaScript Notes - The language

Introduction

JavaScript is super complicated, like a pain in your ass. Even when you are pretty familiar with other programming languages' logic and concepts, you still find it challenging to cover significant aspects of JS.

Let me tell you one story... I once started learning JavaScript with a mindset that "just like other programming languages". Honestly, it does have enough general programming concepts that help me gain some first tastes quickly. It has variables, operators, functions, objects and classes, which can make a newbie think: "Uhm ~~ I can understand it easily!". But the thing doesn't go as you expected, not like variables in C++, variables in JavaScript have var, const and let; not like a single def in Python, JavaScript can initiate a function in two ways: function declaration and function expression. Thus, I didn't understand its fundamentals the first time studying, and regularly lost track of my thinking flow when looking up its advanced topic. Although I have done some projects using extended JavaScript and libraries/frameworks such as React, ExpressJS, etc..., I still had a vague picture about prototypes, asynchronous, error handling, and so forth.

Things even got worse, I got an invitation to a whiteboard technical interview for a full-stack developer role, in which they asked me about JavaScript. Initially, I believe naively my fundamental ideas can handle their questions - "Well! Just some JS questions like tutorials". However, they gave me a question about asynchronous which is one of my most vulnerable parts. They asked me about a promise chain meanwhile I just had been familiar with a single promise. As a result, I solved it incompletely and failed the interview. 🥲

// Refactor the function below to async/await structure
 function A() {
     return new Promise((resolve, reject) => {
         resolve(B);
diff --git a/blogs/uncommon_javascript_notes_1/index.html b/blogs/uncommon_javascript_notes_1/index.html
index 000a5bd..f59950e 100644
--- a/blogs/uncommon_javascript_notes_1/index.html
+++ b/blogs/uncommon_javascript_notes_1/index.html
@@ -1,10 +1,10 @@
-Tuslipid - Uncommon JavaScript Notes - Browser: Document, Events, InterfacesTuslipid - Uncommon JavaScript Notes - Browser: Document, Events, Interfaces
Uncommon JavaScript Notes - Browser: Document, Events, Interfaces

Introduction

One thing that make JavaScript weird to learn is how it interacts with the browser DOM: how to control the events, the forms, how the resource is loaded, etc...

Usually, many JavaScript tutorials tend to integrate DOM manipulation with JS, which may confuse learners as a programming language. We are all introduced by the tutorials to many APIs such as getElementById, getQuerySelector, addEventListener, etc...; but barely understand how those APIs work in the browser, why we have them, and so forth. Talking in more abstract terms, we find it difficult to be able to get a detailed insight into the mechanics of the DOM with JavaScript.

Therefore, below are the notes that help you to cover the essential parts related to browser interaction using JavaScript. It is based on javascript.info's part 2 and requires to have a fundamental knowledge of JavaScript. If you are a newbie in JS, let's check out the javascript.info's part 1 first before jumping into this section.




Table of Contents

Details




Document

Manipulate a web-page using JavaScript


Browser environment, specs

Details

The JavaScript language was intially created for web browsers. Since then, it has evolved into a language with many uses and platforms.

A platform may be a browser, or a web-server or another host. The JavaScript specification calls that a host environment.

A host environment provides its own objects and functions in addition to the language core. Web browsers give a means to control web pages, Node.js provides server-side features, and so on.

Here's a tree view of what we have when JavaScript runs in web browser:

window
+            and how the resource is loaded." data-react-helmet="true" name="twitter:description">
Uncommon JavaScript Notes - Browser: Document, Events, Interfaces

Introduction

One thing that make JavaScript weird to learn is how it interacts with the browser DOM: how to control the events, the forms, how the resource is loaded, etc...

Usually, many JavaScript tutorials tend to integrate DOM manipulation with JS, which may confuse learners as a programming language. We are all introduced by the tutorials to many APIs such as getElementById, getQuerySelector, addEventListener, etc...; but barely understand how those APIs work in the browser, why we have them, and so forth. Talking in more abstract terms, we find it difficult to be able to get a detailed insight into the mechanics of the DOM with JavaScript.

Therefore, below are the notes that help you to cover the essential parts related to browser interaction using JavaScript. It is based on javascript.info's part 2 and requires to have a fundamental knowledge of JavaScript. If you are a newbie in JS, let's check out the javascript.info's part 1 first before jumping into this section.




Table of Contents

Details




Document

Manipulate a web-page using JavaScript


Browser environment, specs

Details

The JavaScript language was intially created for web browsers. Since then, it has evolved into a language with many uses and platforms.

A platform may be a browser, or a web-server or another host. The JavaScript specification calls that a host environment.

A host environment provides its own objects and functions in addition to the language core. Web browsers give a means to control web pages, Node.js provides server-side features, and so on.

Here's a tree view of what we have when JavaScript runs in web browser:

window
     |--- DOM
     |      |--- document
     |
@@ -63,7 +63,7 @@
     |         |--- <tr>
     |         |      |--- <td>
     |         |      |       |--- text "1"
-

Other node types

There are 12 node types. In practice we usually work 4 of them:

  • document - the "entry point" into DOM
  • element nodes - HTML tags, the tree building blocks
  • text nodes - contain text
  • comments - sometimes we can put information here, it won't be shown, but JS can read it from the DOM

Walking the DOM

Details

The DOM allows us to do anything with elements and their contents, but first we need to reach the corresponding DOM object. All operations on the DOM start with the document object - the main "entry point".


DOM nodes


On top: documentElement and body

<html> = document.documentElement
+

Other node types

There are 12 node types. In practice we usually work 4 of them:

  • document - the "entry point" into DOM
  • element nodes - HTML tags, the tree building blocks
  • text nodes - contain text
  • comments - sometimes we can put information here, it won't be shown, but JS can read it from the DOM

Walking the DOM

Details

The DOM allows us to do anything with elements and their contents, but first we need to reach the corresponding DOM object. All operations on the DOM start with the document object - the main "entry point".


DOM nodes


On top: documentElement and body

<html> = document.documentElement
 <body> = document.body
 <head> = document.head
 

document.body can be null

Children: childNodes, firstChild, lastChild

There are 2 terms that we'll use from now on:

  • Child nodes (or children) - elements that are direct children. For instance, <head> and <body> are children of <html> element.
  • Descendants - all elements that are nested in the given one, including children, their children, and so on.
childNodes - lists all child nodes, including text nodes
@@ -77,7 +77,7 @@
 
  • DOM collections are read-only.
  • DOM collections are live (current state of DOM).
  • Don't use for..in to loop over collections.

Siblings and the parent

Siblings are nodes that are children of the same parent. For instance, <head> and <body> are siblings:

  • <body> is said to be the "next" or "right" sibling of <head>
  • <head> is said to be the "previous" or "left" sibling of <body> The next sibling is in nextSibling property, and the previous one - in previousSibling. The parent is available as parentNode.
alert(document.body.parentNode === document.documentElement); // true
 alert(document.head.nextSibling); // HTMLBodyElement
 alert(document.body.previousSibling); // HTMLHeadElement
-

Element-only navigation

Navigation properties listed above refer to all nodes. But for many tasks we don't want text or comment nodes. We want to manipulate element nodes that represents tags and form the structure of the page.

So let's see more navigation links that only take element nodes into account:


element nodes


The links are similar to those given above, just with Element word inside:

  • children - only those children that are element nodes.
  • firstElementChild, lastElementChild - first and last element children.
  • previousElementSibling, nextElementSibling - neighbor elements.
  • parentElement - parent element.

The <table> element supports (in addition to the given above) these properties:

  • table.rows - the collection of <tr> elements of the table.
  • table.caption/tHead/tFoot - references to elements <caption>, <thead>, <tfoot>
  • table.tBodies - the collection of <tbody> elements (can be many according to the standard, but there will alwas be at lest one - even if it is not in the source HTML, the browser will put it in the DOM).

<thead>, <tfoot>, <tbody> elements provide the rows property:

  • tbody.rows - the collection of <tr> inside.

<tr>:

  • tr.cells - the collection of <td> and <th> cells inside the given <tr>
  • tr.sectionRowIndex - the position (index) of the given <tr> inside the enclosing <thead>/<tbody>/<tfoot>.
  • tr.rowIndex - the number of the <tr> in the table as a whole (including all table rows).

<td> and <th>:

  • <td.cellIndex - the number of the cell inside the enclosing <tr>.

Searching: getElement*, querySelector*

Details
  • document.getElementById - If an element has the id attribute, we can get the element no matter where it is.
  • elem.querySelectorAll(css) - Returns all elements inside elem matching the given CSS selector.
  • elem.querySelector(css) - Returns the first element for the given CSS selector.
  • elem.matches(css) - Checks if an elem matches the given CSS-selector. It returns boolean.
  • elem.closest(css) - Looks for the nearest ancestor that matches the CSS-selector. The elem itself is also included in the search.
  • elem.getElementsByTagName(tag) - Looks for elements with the given tag an returns the collection of them. The tag parameter can also be a star "*" for "any tags".
  • elem.getElementsByClassName(className) - Returns elements that have the given CSS class.
  • document.getElementsByName(name) returns elements with the given name attribute, document-wide. Very rarely used.

Node properties: type, tag and contents

Details

DOM node classes

Different DOM nodes may have different properties. For instance, an element node corresponding to tag <a> has a link-related properties, and the one corresponding to <input> has input-related properties and so on.

Each DOM node belongs to the corresponding built-in class. The root of the hierarchy is EventTarget, that is inherited by Node, and other DOM nodes inherit from it.


DOM node classes


To see the DOM node class name, we can recall that an object ususally has the constructor property. It references the class constructor, and constructor.name is its name:

alert(document.body.constructor.name) // HTMLBodyElement
+

Element-only navigation

Navigation properties listed above refer to all nodes. But for many tasks we don't want text or comment nodes. We want to manipulate element nodes that represents tags and form the structure of the page.

So let's see more navigation links that only take element nodes into account:


element nodes


The links are similar to those given above, just with Element word inside:

  • children - only those children that are element nodes.
  • firstElementChild, lastElementChild - first and last element children.
  • previousElementSibling, nextElementSibling - neighbor elements.
  • parentElement - parent element.

The <table> element supports (in addition to the given above) these properties:

  • table.rows - the collection of <tr> elements of the table.
  • table.caption/tHead/tFoot - references to elements <caption>, <thead>, <tfoot>
  • table.tBodies - the collection of <tbody> elements (can be many according to the standard, but there will alwas be at lest one - even if it is not in the source HTML, the browser will put it in the DOM).

<thead>, <tfoot>, <tbody> elements provide the rows property:

  • tbody.rows - the collection of <tr> inside.

<tr>:

  • tr.cells - the collection of <td> and <th> cells inside the given <tr>
  • tr.sectionRowIndex - the position (index) of the given <tr> inside the enclosing <thead>/<tbody>/<tfoot>.
  • tr.rowIndex - the number of the <tr> in the table as a whole (including all table rows).

<td> and <th>:

  • <td.cellIndex - the number of the cell inside the enclosing <tr>.

Searching: getElement*, querySelector*

Details
  • document.getElementById - If an element has the id attribute, we can get the element no matter where it is.
  • elem.querySelectorAll(css) - Returns all elements inside elem matching the given CSS selector.
  • elem.querySelector(css) - Returns the first element for the given CSS selector.
  • elem.matches(css) - Checks if an elem matches the given CSS-selector. It returns boolean.
  • elem.closest(css) - Looks for the nearest ancestor that matches the CSS-selector. The elem itself is also included in the search.
  • elem.getElementsByTagName(tag) - Looks for elements with the given tag an returns the collection of them. The tag parameter can also be a star "*" for "any tags".
  • elem.getElementsByClassName(className) - Returns elements that have the given CSS class.
  • document.getElementsByName(name) returns elements with the given name attribute, document-wide. Very rarely used.

Node properties: type, tag and contents

Details

DOM node classes

Different DOM nodes may have different properties. For instance, an element node corresponding to tag <a> has a link-related properties, and the one corresponding to <input> has input-related properties and so on.

Each DOM node belongs to the corresponding built-in class. The root of the hierarchy is EventTarget, that is inherited by Node, and other DOM nodes inherit from it.


DOM node classes


To see the DOM node class name, we can recall that an object ususally has the constructor property. It references the class constructor, and constructor.name is its name:

alert(document.body.constructor.name) // HTMLBodyElement
 

The "nodeType" property

The nodeType property provides one more, "old-fashioned" way to get the "type" of a DOM node.

It has a numeric value:

  • elem.nodeType == 1 for element nodes,
  • elem.nodeType == 3 for text nodes,
  • elem.nodeType == 9 for the document object,
  • There are few other values in the specification

In modern scripts, we can use instanceof and other class-based tests to see the node type, but sometimes nodeType may be simpler.

Tag: nodeName and tagName

Given a DOM node, we can read its tag name from nodeName or tagName properties:

alert(document.body.nodeName); // BODY
 alert(document.body.tagName); // BODY
 

Differences between tagName and nodeName:

  • the tagName property exists only for Element nodes.
  • the nodeName is defined for any Node:
    • For elements it means the same as tagName.
    • For other node types (text, comment, etc...) it has a string with the node type.

innerHTML: the contents

The innerHTML property allows to get the HTML inside the element as a string.

Beware: "innerHTML +=" does a full overwrite

We can append HTML like this

elem.innerHTML += "<div>Hello<img src='smile.gif'/> !</div>";
@@ -292,7 +292,7 @@
     overflow: auto;
   }
 </style>
-

sample element

Mind the scrollbar. If the scrollbar is 16px wide then the content width remains only 300 - 16 = 284px.

Geometry

Here's the overall picture with geometry properties:

Geometry picture

  • offsetWidth: The outer width = inner CSS-width + paddings + borders
  • offsetHeight: The outer height = inner CSS-height + paddings + borders
  • clientLeft: Left border width
  • clientTop: Top border width
  • clientWidth: The inner width = inner CSS-width + paddings (exclude scrollbar)
  • clientHeight: The inner height = inner CSS-height + paddings (exclude scrollbar)
  • scrollWidth: The full inner width including the scrolled out parts
  • scrollHeight: The full inner height including the scrolled out parts
  • scrollTop: How much is scrolled up
  • scrollLeft: How much is scrolled left

Don't take width/height from CSS

We should use geometry properties instead of getComputedStyle:

  1. CSS width/height depend on another property: box-sizing that defines "what is" CSS width and height. A change in box-sizing for CSS purpose may break such JavaScript.
  2. CSS width/height maybe auto
    <span id="elem">Hello!</span>
    +

    sample element

    Mind the scrollbar. If the scrollbar is 16px wide then the content width remains only 300 - 16 = 284px.

    Geometry

    Here's the overall picture with geometry properties:

    Geometry picture

    • offsetWidth: The outer width = inner CSS-width + paddings + borders
    • offsetHeight: The outer height = inner CSS-height + paddings + borders
    • clientLeft: Left border width
    • clientTop: Top border width
    • clientWidth: The inner width = inner CSS-width + paddings (exclude scrollbar)
    • clientHeight: The inner height = inner CSS-height + paddings (exclude scrollbar)
    • scrollWidth: The full inner width including the scrolled out parts
    • scrollHeight: The full inner height including the scrolled out parts
    • scrollTop: How much is scrolled up
    • scrollLeft: How much is scrolled left

    Don't take width/height from CSS

    We should use geometry properties instead of getComputedStyle:

    1. CSS width/height depend on another property: box-sizing that defines "what is" CSS width and height. A change in box-sizing for CSS purpose may break such JavaScript.
    2. CSS width/height maybe auto
      <span id="elem">Hello!</span>
       
       <script>
         alert(getComputedStyle(elem).width); // auto
      @@ -373,7 +373,7 @@
       

      event.target

      A handler on a parent element can always get the details about where it actually happened.

      The most deeply nested element that caused the event is called a target element, accessible as event.target.

      The differences from this (= event.currentTarget):

      • event.target: is the "target" element that initiated the event, it doesn't change through the bubbling process.
      • this: is the "current" element, the one that has a currently running handler on it.

      Stopping bubbling

      A bubbling event goes from the target element straight up. Normally it goes upwards till <html>, and then to document object, and some events even reach window, calling all handlers on the path.

      But any handler may decide that the event has been fully processed and stop the bubbling.

      The method for it is event.stopPropagation().

      <body onclick="alert(`the bubbling doesn't reach here`)">
         <button onclick="event.stopPropagation()">Click me</button>
       </body>
      -

      Capturing

      There's another phase of event processing called "capturing". It is rarely used in real code, but sometimes can be useful.

      The standard DOM Events describes 3 phases of event propagation:

      1. Capturing phase - the event goes down to the element.
      2. Target phase - the event reached the target element.
      3. Bubbling phase - the event bubbles up from the element.

      Event propagation

      To catch an event on the capturing phase, we need to set the handler capture option to true:

      elem.addEventListener(..., {capture: true});
      +

      Capturing

      There's another phase of event processing called "capturing". It is rarely used in real code, but sometimes can be useful.

      The standard DOM Events describes 3 phases of event propagation:

      1. Capturing phase - the event goes down to the element.
      2. Target phase - the event reached the target element.
      3. Bubbling phase - the event bubbles up from the element.

      Event propagation

      To catch an event on the capturing phase, we need to set the handler capture option to true:

      elem.addEventListener(..., {capture: true});
       
       // or, just "true" is an alias to {capture: true}
       elem.addEventListener(..., true);
      diff --git a/contact/index.html b/contact/index.html
      index c1db587..ff98ab3 100644
      --- a/contact/index.html
      +++ b/contact/index.html
      @@ -1 +1 @@
      -Tuslipid
      ~ Oi ~
      Say hello to me by one of the following :)
      Home
      \ No newline at end of file +Tuslipid
      ~ Oi ~
      Say hello to me by one of the following :)
      Home
      \ No newline at end of file diff --git a/guestbook/index.html b/guestbook/index.html index 9e23390..14c8b4a 100644 --- a/guestbook/index.html +++ b/guestbook/index.html @@ -1,4 +1,4 @@ -Tuslipid - Guestbook
      Guestbook
      This idea is inspired by Lee Robinson's portfolio :)

      Guestbook
      This idea is inspired by Lee Robinson's portfolio :)

      Xuan Khoa Tu Nguyen
      SWE @ Pixta
      \ No newline at end of file +Tuslipid
      \ No newline at end of file diff --git a/projects/index.html b/projects/index.html index 64fff53..3dfe5dd 100644 --- a/projects/index.html +++ b/projects/index.html @@ -1,4 +1,4 @@ -Tuslipid - ProjectsTuslipid - Projects
      Projects
      I just have studied Information Technology for three years, but luckily have some fun works done.
      Algorithm Visualizer image

      Algorithm Visualizer

      • TypeScript
      • Next
      • Bootstrap

      A web application that visualizes algorithms from code (initially provides sorting algorithms demonstration).

      CS50 Finance Replication image

      CS50 Finance Replication

      • Flask
      • Bootstrap
      • SQLite
      • Firestore
      • GCP

      A web-app replication of CS50 finance's mock stock-trading website (finance.cs50.net), which initially comes from a problem set in CS50X. It has been extended with some additional features and different database.

      Font Scale Sass image

      Font Scale Sass

      • SASS

      A SASS font-scale generator module which provides a preset font size for your footnote, endnote, caption, body, blockquote, and headings (from h6 to h1).

      Random Meme Picker image

      Random Meme Picker

      • React
      • Bun
      • SASS
      • Cloud storage

      A random meme web chosen from my more than 800-meme collection. Pick a meme a day for a better life.

      E-commerce Auction image

      E-commerce Auction

      • Django
      • Bootstrap
      • PostgreSQL

      An eBay-like e-commerce auction site that will allow users to post auction listings, place bids on listings, comment on those listings, and add listings to a ”watchlist”.

      Knapsack Solvers Analysis image

      Knapsack Solvers Analysis

      • Python
      • Or-tools

      An analysis of the performance in solving typical knapsack problems by the Simplex Algorithm and the Harmony Search Algorithm, as the Advanced Algorithms coursework project.

      Email Single Page Application image

      Email Single Page Application

      • Plain JavaScript
      • Django
      • Bootstrap

      A front-end for an email client in SPA style that makes API calls to send and receive email

      Wiki Encyclopedia image

      Wiki Encyclopedia

      • Django
      • Bootstrap

      A Wikipedia-like online encyclopedia that will allow users search for an encyclopedia entry, create new entries and edit an existing entry.

      Calendar on Terminal image

      Calendar on Terminal

      • C

      A small project of calendar queried on terminal, as a midterm project when I first took the C programming course in 2020.

      Lottery Draw Robotic Application image

      Lottery Draw Robotic Application

      • Robotic automation algorithm design

      Participated in a group project to develop the robotic arm application project in the lottery drawing.

      My responsibility is to set up Eye-in-hand Vision and 3D Vision via a camera attached to the robotic arm to detect the prize's patterns and the area for the gift box container.

        Gripper Base System Sketch image

        Gripper Base System Sketch

        • AutoCAD

        A graphical sketch of robotic arm gripper base system, as a manual graphic coursework in Mechanical Graphic course.

          \ No newline at end of file +but luckily have some fun works done." data-react-helmet="true" name="twitter:description">
          Projects
          I just have studied Information Technology for three years, but luckily have some fun works done.
          Algorithm Visualizer image

          Algorithm Visualizer

          • TypeScript
          • Next
          • Bootstrap

          A web application that visualizes algorithms from code (initially provides sorting algorithms demonstration).

          CS50 Finance Replication image

          CS50 Finance Replication

          • Flask
          • Bootstrap
          • SQLite
          • Firestore
          • GCP

          A web-app replication of CS50 finance's mock stock-trading website (finance.cs50.net), which initially comes from a problem set in CS50X. It has been extended with some additional features and different database.

          Font Scale Sass image

          Font Scale Sass

          • SASS

          A SASS font-scale generator module which provides a preset font size for your footnote, endnote, caption, body, blockquote, and headings (from h6 to h1).

          Random Meme Picker image

          Random Meme Picker

          • React
          • Bun
          • SASS
          • Cloud storage

          A random meme web chosen from my more than 800-meme collection. Pick a meme a day for a better life.

          E-commerce Auction image

          E-commerce Auction

          • Django
          • Bootstrap
          • PostgreSQL

          An eBay-like e-commerce auction site that will allow users to post auction listings, place bids on listings, comment on those listings, and add listings to a ”watchlist”.

          Knapsack Solvers Analysis image

          Knapsack Solvers Analysis

          • Python
          • Or-tools

          An analysis of the performance in solving typical knapsack problems by the Simplex Algorithm and the Harmony Search Algorithm, as the Advanced Algorithms coursework project.

          Email Single Page Application image

          Email Single Page Application

          • Plain JavaScript
          • Django
          • Bootstrap

          A front-end for an email client in SPA style that makes API calls to send and receive email

          Wiki Encyclopedia image

          Wiki Encyclopedia

          • Django
          • Bootstrap

          A Wikipedia-like online encyclopedia that will allow users search for an encyclopedia entry, create new entries and edit an existing entry.

          Calendar on Terminal image

          Calendar on Terminal

          • C

          A small project of calendar queried on terminal, as a midterm project when I first took the C programming course in 2020.

          Lottery Draw Robotic Application image

          Lottery Draw Robotic Application

          • Robotic automation algorithm design

          Participated in a group project to develop the robotic arm application project in the lottery drawing.

          My responsibility is to set up Eye-in-hand Vision and 3D Vision via a camera attached to the robotic arm to detect the prize's patterns and the area for the gift box container.

            Gripper Base System Sketch image

            Gripper Base System Sketch

            • AutoCAD

            A graphical sketch of robotic arm gripper base system, as a manual graphic coursework in Mechanical Graphic course.

              \ No newline at end of file diff --git a/static/js/951.59825386.chunk.js b/static/js/951.59825386.chunk.js new file mode 100644 index 0000000..5c60d02 --- /dev/null +++ b/static/js/951.59825386.chunk.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktuslipid=self.webpackChunktuslipid||[]).push([[951],{7951:function(s,t,a){s.exports=a.p+"static/media/uncommon_javascript_notes_1.e9d0fcaa90720cd4a514.md"}}]); \ No newline at end of file diff --git a/static/js/951.f82459b9.chunk.js b/static/js/951.f82459b9.chunk.js deleted file mode 100644 index edefbf3..0000000 --- a/static/js/951.f82459b9.chunk.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktuslipid=self.webpackChunktuslipid||[]).push([[951],{7951:function(s,t,e){s.exports=e.p+"static/media/uncommon_javascript_notes_1.64bd23357e14f40bc006.md"}}]); \ No newline at end of file diff --git a/static/js/main.6cba0be9.js b/static/js/main.6cba0be9.js deleted file mode 100644 index 07116d8..0000000 --- a/static/js/main.6cba0be9.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! For license information please see main.6cba0be9.js.LICENSE.txt */ -!function(){var e={9734:function(e,t,n){"use strict";var r=n(9439),a=n(2791),i=n(9126),o=n(184);t.Z=function(e){var t=(0,a.useState)(),n=(0,r.Z)(t,2),l=n[0],u=n[1];return(0,a.useEffect)((function(){u((new Date).getFullYear())}),[]),(0,o.jsxs)("div",{className:"".concat(e.copyright_class),children:[(0,o.jsx)("div",{children:(0,o.jsx)("a",{href:"https://github.com/khoaxuantu/tuslipid",target:"_blank",rel:"noreferrer","aria-label":"web source code",children:(0,o.jsx)(i.rFR,{opacity:.8,color:"black"})})}),"Built and designed by Xuan Khoa Tu Nguyen with "," ",(0,o.jsx)("a",{href:"https://react.dev/",target:"_blank",rel:"noreferrer",children:"React"}),", "," ",(0,o.jsx)("a",{href:"https://www.typescriptlang.org/",target:"_blank",rel:"noreferrer",children:"TypeScript"})," and "," ",(0,o.jsx)("a",{href:"https://sass-lang.com/",target:"_blank",rel:"noreferrer",children:"Sass"}),".",(0,o.jsx)("br",{}),"Copyright \xa9 ",l," All Rights Reserved."]})}},5952:function(e,t,n){"use strict";n.d(t,{Z:function(){return fe}});var r=n(1413),a=n(2007),i=n.n(a),o=n(9475),l=n.n(o),u=n(77),s=n.n(u),c=n(2791),f=n(1725),d=n.n(f),p="bodyAttributes",h="htmlAttributes",m="titleAttributes",v={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title"},g=(Object.keys(v).map((function(e){return v[e]})),"charset"),b="cssText",y="href",w="http-equiv",x="innerHTML",k="itemprop",S="name",j="property",C="rel",E="src",_="target",P={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},T="defaultTitle",N="defer",O="encodeSpecialCharacters",L="onChangeClientState",R="titleTemplate",A=Object.keys(P).reduce((function(e,t){return e[P[t]]=t,e}),{}),z=[v.NOSCRIPT,v.SCRIPT,v.STYLE],M="data-react-helmet",I="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U=function(){function e(e,t){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n},B=function(e){return!1===(!(arguments.length>1&&void 0!==arguments[1])||arguments[1])?String(e):String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},W=function(e){var t=q(e,v.TITLE),n=q(e,R);if(n&&t)return n.replace(/%s/g,(function(){return Array.isArray(t)?t.join(""):t}));var r=q(e,T);return t||r||void 0},H=function(e){return q(e,L)||function(){}},V=function(e,t){return t.filter((function(t){return"undefined"!==typeof t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return D({},e,t)}),{})},Z=function(e,t){return t.filter((function(e){return"undefined"!==typeof e[v.BASE]})).map((function(e){return e[v.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a=0;n--){var r=e[n];if(r.hasOwnProperty(t))return r[t]}return null},Q=function(){var e=Date.now();return function(t){var n=Date.now();n-e>16?(e=n,t(n)):setTimeout((function(){Q(t)}),0)}}(),K=function(e){return clearTimeout(e)},J="undefined"!==typeof window?window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||Q:n.g.requestAnimationFrame||Q,G="undefined"!==typeof window?window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||K:n.g.cancelAnimationFrame||K,Y=function(e){return console&&"function"===typeof console.warn&&console.warn(e)},X=null,ee=function(e,t){var n=e.baseTag,r=e.bodyAttributes,a=e.htmlAttributes,i=e.linkTags,o=e.metaTags,l=e.noscriptTags,u=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,f=e.title,d=e.titleAttributes;re(v.BODY,r),re(v.HTML,a),ne(f,d);var p={baseTag:ae(v.BASE,n),linkTags:ae(v.LINK,i),metaTags:ae(v.META,o),noscriptTags:ae(v.NOSCRIPT,l),scriptTags:ae(v.SCRIPT,s),styleTags:ae(v.STYLE,c)},h={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(h[e]=n),r.length&&(m[e]=p[e].oldTags)})),t&&t(),u(e,h,m)},te=function(e){return Array.isArray(e)?e.join(""):e},ne=function(e,t){"undefined"!==typeof e&&document.title!==e&&(document.title=te(e)),re(v.TITLE,t)},re=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute(M),a=r?r.split(","):[],i=[].concat(a),o=Object.keys(t),l=0;l=0;f--)n.removeAttribute(i[f]);a.length===i.length?n.removeAttribute(M):n.getAttribute(M)!==o.join(",")&&n.setAttribute(M,o.join(","))}},ae=function(e,t){var n=document.head||document.querySelector(v.HEAD),r=n.querySelectorAll(e+"["+M+"]"),a=Array.prototype.slice.call(r),i=[],o=void 0;return t&&t.length&&t.forEach((function(t){var n=document.createElement(e);for(var r in t)if(t.hasOwnProperty(r))if(r===x)n.innerHTML=t.innerHTML;else if(r===b)n.styleSheet?n.styleSheet.cssText=t.cssText:n.appendChild(document.createTextNode(t.cssText));else{var l="undefined"===typeof t[r]?"":t[r];n.setAttribute(r,l)}n.setAttribute(M,"true"),a.some((function(e,t){return o=t,n.isEqualNode(e)}))?a.splice(o,1):i.push(n)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return n.appendChild(e)})),{oldTags:a,newTags:i}},ie=function(e){return Object.keys(e).reduce((function(t,n){var r="undefined"!==typeof e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},oe=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[P[n]||n]=e[n],t}),t)},le=function(e,t,n){switch(e){case v.TITLE:return{toComponent:function(){return function(e,t,n){var r,a=((r={key:t})[M]=!0,r),i=oe(n,a);return[c.createElement(v.TITLE,i,t)]}(0,t.title,t.titleAttributes)},toString:function(){return function(e,t,n,r){var a=ie(n),i=te(t);return a?"<"+e+" "+M+'="true" '+a+">"+B(i,r)+"":"<"+e+" "+M+'="true">'+B(i,r)+""}(e,t.title,t.titleAttributes,n)}};case p:case h:return{toComponent:function(){return oe(t)},toString:function(){return ie(t)}};default:return{toComponent:function(){return function(e,t){return t.map((function(t,n){var r,a=((r={key:n})[M]=!0,r);return Object.keys(t).forEach((function(e){var n=P[e]||e;if(n===x||n===b){var r=t.innerHTML||t.cssText;a.dangerouslySetInnerHTML={__html:r}}else a[n]=t[e]})),c.createElement(e,a)}))}(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!(e===x||e===b)})).reduce((function(e,t){var a="undefined"===typeof r[t]?t:t+'="'+B(r[t],n)+'"';return e?e+" "+a:a}),""),i=r.innerHTML||r.cssText||"",o=-1===z.indexOf(e);return t+"<"+e+" "+M+'="true" '+a+(o?"/>":">"+i+"")}),"")}(e,t,n)}}}},ue=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,i=e.linkTags,o=e.metaTags,l=e.noscriptTags,u=e.scriptTags,s=e.styleTags,c=e.title,f=void 0===c?"":c,d=e.titleAttributes;return{base:le(v.BASE,t,r),bodyAttributes:le(p,n,r),htmlAttributes:le(h,a,r),link:le(v.LINK,i,r),meta:le(v.META,o,r),noscript:le(v.NOSCRIPT,l,r),script:le(v.SCRIPT,u,r),style:le(v.STYLE,s,r),title:le(v.TITLE,{title:f,titleAttributes:d},r)}},se=function(e){var t,n;return n=t=function(t){function n(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!==typeof t&&"function"!==typeof t?e:t}(this,t.apply(this,arguments))}return function(e,t){if("function"!==typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(n,t),n.prototype.shouldComponentUpdate=function(e){return!s()(this.props,e)},n.prototype.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case v.SCRIPT:case v.NOSCRIPT:return{innerHTML:t};case v.STYLE:return{cssText:t}}throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")},n.prototype.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren,a=e.newChildProps,i=e.nestedChildren;return D({},r,((t={})[n.type]=[].concat(r[n.type]||[],[D({},a,this.mapNestedChildrenToProps(n,i))]),t))},n.prototype.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,i=e.newChildProps,o=e.nestedChildren;switch(r.type){case v.TITLE:return D({},a,((t={})[r.type]=o,t.titleAttributes=D({},i),t));case v.BODY:return D({},a,{bodyAttributes:D({},i)});case v.HTML:return D({},a,{htmlAttributes:D({},i)})}return D({},a,((n={})[r.type]=D({},i),n))},n.prototype.mapArrayTypeChildrenToProps=function(e,t){var n=D({},t);return Object.keys(e).forEach((function(t){var r;n=D({},n,((r={})[t]=e[t],r))})),n},n.prototype.warnOnInvalidChildren=function(e,t){return!0},n.prototype.mapChildrenToProps=function(e,t){var n=this,r={};return c.Children.forEach(e,(function(e){if(e&&e.props){var a=e.props,i=a.children,o=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[A[n]||n]=e[n],t}),t)}(F(a,["children"]));switch(n.warnOnInvalidChildren(e,i),e.type){case v.LINK:case v.META:case v.NOSCRIPT:case v.SCRIPT:case v.STYLE:r=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:r,newChildProps:o,nestedChildren:i});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:o,nestedChildren:i})}}})),t=this.mapArrayTypeChildrenToProps(r,t)},n.prototype.render=function(){var t=this.props,n=t.children,r=F(t,["children"]),a=D({},r);return n&&(a=this.mapChildrenToProps(n,a)),c.createElement(e,a)},U(n,null,[{key:"canUseDOM",set:function(t){e.canUseDOM=t}}]),n}(c.Component),t.propTypes={base:i().object,bodyAttributes:i().object,children:i().oneOfType([i().arrayOf(i().node),i().node]),defaultTitle:i().string,defer:i().bool,encodeSpecialCharacters:i().bool,htmlAttributes:i().object,link:i().arrayOf(i().object),meta:i().arrayOf(i().object),noscript:i().arrayOf(i().object),onChangeClientState:i().func,script:i().arrayOf(i().object),style:i().arrayOf(i().object),title:i().string,titleAttributes:i().object,titleTemplate:i().string},t.defaultProps={defer:!0,encodeSpecialCharacters:!0},t.peek=e.peek,t.rewind=function(){var t=e.rewind();return t||(t=ue({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}})),t},n}(l()((function(e){return{baseTag:Z([y,_],e),bodyAttributes:V(p,e),defer:q(e,N),encode:q(e,O),htmlAttributes:V(h,e),linkTags:$(v.LINK,[C,y],e),metaTags:$(v.META,[S,g,w,j,k],e),noscriptTags:$(v.NOSCRIPT,[x],e),onChangeClientState:H(e),scriptTags:$(v.SCRIPT,[E,x],e),styleTags:$(v.STYLE,[b],e),title:W(e),titleAttributes:V(m,e)}}),(function(e){X&&G(X),e.defer?X=J((function(){ee(e,(function(){X=null}))})):(ee(e),X=null)}),ue)((function(){return null})));se.renderStatic=se.rewind;var ce=n(184);function fe(e){var t=e.metadata,n=e.children;return(0,ce.jsxs)(ce.Fragment,{children:[(0,ce.jsx)(de,(0,r.Z)({},t)),(0,ce.jsx)(pe,(0,r.Z)({},t.og)),(0,ce.jsx)(he,(0,r.Z)({},t.twitter)),n]})}function de(e){var t=e.title,n=e.description,r=e.author,a=e.image,i=e.canonicalURL;return(0,ce.jsxs)(se,{titleTemplate:"Tuslipid - %s",defaultTitle:"Tuslipid",children:[(0,ce.jsx)("title",{children:t}),(0,ce.jsx)("meta",{name:"title",content:t}),(0,ce.jsx)("meta",{itemProp:"name",content:t}),n&&(0,ce.jsx)("meta",{itemProp:"description",content:n})&&(0,ce.jsx)("meta",{name:"description",content:n}),r&&(0,ce.jsx)("meta",{name:"author",content:r}),a&&(0,ce.jsx)("meta",{itemProp:"image",content:a}),i&&(0,ce.jsx)("link",{rel:"canonical",href:i})]})}function pe(e){return(0,ce.jsxs)(se,{children:[e.type&&(0,ce.jsx)("meta",{property:"og:type",content:e.type}),e.title&&(0,ce.jsx)("meta",{property:"og:title",content:e.title}),e.image&&(0,ce.jsx)("meta",{property:"og:image",content:e.image}),e.description&&(0,ce.jsx)("meta",{property:"og:description",content:e.description}),e.url&&(0,ce.jsx)("meta",{property:"og:url",content:e.url}),e.site_name&&(0,ce.jsx)("meta",{property:"og:site_name",content:e.site_name})]})}function he(e){return(0,ce.jsxs)(se,{children:[e.card&&(0,ce.jsx)("meta",{name:"twitter:card",content:e.card}),e.creator&&(0,ce.jsx)("meta",{name:"twitter:creator",content:e.creator}),e.description&&(0,ce.jsx)("meta",{name:"twitter:description",content:e.description}),e.image&&(0,ce.jsx)("meta",{name:"twitter:image",content:e.image}),e.title&&(0,ce.jsx)("meta",{name:"twitter:title",content:e.title}),e.url&&(0,ce.jsx)("meta",{name:"twitter:url",content:e.url})]})}},4695:function(e,t,n){"use strict";n.d(t,{TX:function(){return l},am:function(){return i},hU:function(){return o}});var r=n(1087),a=n(184);function i(e){return(0,a.jsx)(r.rU,{to:e.url,className:e.classname,children:e.content})}function o(e){var t;return t="string"===typeof e.icon?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"icon",children:(0,a.jsx)("img",{className:"m-1",src:e.icon,alt:"icon-"+e.id,width:32})}),(0,a.jsx)("div",{id:"name",children:e.id})]}):(0,a.jsx)(e.icon,{className:"icon",size:"1.5rem",color:"#000","aria-label":e.id}),(0,a.jsx)(r.rU,{id:e.id,className:e.classname,to:e.url,target:"_blank",children:t},e.id)}function l(e){return(0,a.jsxs)("button",{className:"btn btn-oauth ".concat(e.classname," ps-3 pe-3 pt-1 pb-1"),onClick:e.onClick,children:[(0,a.jsx)(e.icon,{size:20,color:"white",className:"me-3"}),(0,a.jsx)("span",{className:"oauth-txt",children:"Sign in with "+e.name})]})}},4749:function(e,t,n){"use strict";n.d(t,{Z:function(){return g},i:function(){return f}});var r=n(1413),a=n(5593),i=n(9126),o=n(9983);function l(e){return(0,o.w_)({tag:"svg",attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}},{tag:"polyline",attr:{points:"15 3 21 3 21 9"}},{tag:"line",attr:{x1:"10",y1:"14",x2:"21",y2:"3"}}]})(e)}var u=n(1087),s=n(184),c=n(3828),f=new a.Z(c).get();function d(e){return(0,s.jsx)(s.Fragment,{children:e.isFeatured?(0,s.jsx)(h,(0,r.Z)({},e)):(0,s.jsx)(p,(0,r.Z)({},e))})}function p(e){var t=function(e){if(void 0!==e.imageURL)return(0,s.jsx)("img",{src:e.imageURL,alt:e.title+" image"})}(e),n=m(e);return(0,s.jsxs)("div",{className:"card card-proj mb-5",children:[(0,s.jsx)("div",{className:"col-5 proj-image",children:t}),(0,s.jsxs)("div",{className:"col-7 p-3 proj-description",children:[(0,s.jsx)("h3",{className:"header-txt-proj",children:e.title}),(0,s.jsx)("ul",{className:"pb-4 ps-2 proj-tool-list",children:e.tools.map((function(e){return(0,s.jsx)("li",{className:"pe-2",children:e},e)}))}),(0,s.jsx)("div",{className:"ps-2",children:e.description.map((function(e,t){return(0,s.jsx)("p",{className:"pb-2 body-txt",children:e},t)}))}),(0,s.jsxs)("ul",{className:"proj-href",children:[n.github,n.demo]})]})]})}function h(e){var t=m(e);return(0,s.jsx)("div",{className:"card card-featured-proj",children:(0,s.jsxs)("div",{className:"p-3 proj-description",children:[(0,s.jsx)("h3",{className:"header-txt-proj",children:e.title}),(0,s.jsx)("ul",{className:"pb-4 ps-2 proj-tool-list",children:e.tools.map((function(e){return(0,s.jsx)("li",{className:"pe-2",children:e},e)}))}),(0,s.jsx)("div",{className:"ps-2",children:e.description.map((function(e,t){return(0,s.jsx)("p",{className:"pb-2 body-txt",children:e},t)}))}),(0,s.jsxs)("ul",{className:"proj-href",children:[t.github,t.demo]})]})})}function m(e){var t,n;return void 0!==e.githubURL&&(n=(0,s.jsx)("li",{children:(0,s.jsx)("a",{href:e.githubURL,target:"_blank",rel:"noreferrer","aria-label":"project github href - ".concat(e.title),children:(0,s.jsx)(i.rFR,{size:24,color:"#000"})})})),void 0!==e.demoURL&&(t=(0,s.jsx)("li",{className:"ps-3",children:(0,s.jsx)("a",{href:e.demoURL,target:"_blank",rel:"noreferrer","aria-label":"project demo href - ".concat(e.title),children:(0,s.jsx)(l,{size:24,color:"#000"})})})),{demo:t,github:n}}function v(e){return(0,s.jsxs)("div",{className:"card card-blog mb-5 fade-in-left",children:[(0,s.jsx)("h3",{className:"header-txt-blog p-3",children:e.title}),(0,s.jsx)("div",{className:"body-txt-blog p-3",children:e.brief_description}),(0,s.jsx)("div",{className:"read-more-btn mb-4",children:(0,s.jsxs)(u.rU,{className:"body-txt-blog",to:"/blogs"+e.url,children:["Read more ",">>"]})})]})}var g=function(e){var t;return"Projects"===e.content_section?t=(0,s.jsx)(d,(0,r.Z)({},e)):"Blogs"===e.content_section&&(t=(0,s.jsx)(v,(0,r.Z)({},e))),(0,s.jsx)(s.Fragment,{children:t})}},5593:function(e,t,n){"use strict";var r=n(5671),a=n(3144),i=function(){function e(t){(0,r.Z)(this,e),this.reqMedia=void 0,this.reqMedia=t}return(0,a.Z)(e,[{key:"get",value:function(){var e=this;return this.reqMedia.keys().reduce((function(t,n){return t[n.substring(n.lastIndexOf("/")+1,n.lastIndexOf("."))]=e.reqMedia(n),t}),{})}}]),e}();t.Z=i},6531:function(e,t,n){"use strict";n.d(t,{iQ:function(){return h},PX:function(){return m},H$:function(){return c},mh:function(){return v},vS:function(){return p},qd:function(){return f},z0:function(){return s},hM:function(){return d}});var r=n(9983);var a=n(9126);var i=n(5593),o=n(8678),l=new i.Z(o).get(),u=n(4749);var s=[{id:"mail",url:"mailto:tungxk2908@gmail.com",icon:function(e){return(0,r.w_)({tag:"svg",attr:{viewBox:"0 0 24 24",fill:"none"},child:[{tag:"path",attr:{fillRule:"evenodd",clipRule:"evenodd",d:"M3.00977 5.83789C3.00977 5.28561 3.45748 4.83789 4.00977 4.83789H20C20.5523 4.83789 21 5.28561 21 5.83789V17.1621C21 18.2667 20.1046 19.1621 19 19.1621H5C3.89543 19.1621 3 18.2667 3 17.1621V6.16211C3 6.11449 3.00333 6.06765 3.00977 6.0218V5.83789ZM5 8.06165V17.1621H19V8.06199L14.1215 12.9405C12.9499 14.1121 11.0504 14.1121 9.87885 12.9405L5 8.06165ZM6.57232 6.80554H17.428L12.7073 11.5263C12.3168 11.9168 11.6836 11.9168 11.2931 11.5263L6.57232 6.80554Z",fill:"currentColor"}}]})(e)}},{id:"linkedin",url:"https://www.linkedin.com/in/xuan-khoa-tu-nguyen-1a8927204/",icon:a.NQh},{id:"github",url:"https://github.com/khoaxuantu",icon:a.rFR},{id:"facebook",url:"https://www.facebook.com/xuankhoatu.nguyen/",icon:function(e){return(0,r.w_)({tag:"svg",attr:{version:"1.1",viewBox:"0 0 16 16"},child:[{tag:"path",attr:{d:"M14.5 0h-13c-0.825 0-1.5 0.675-1.5 1.5v13c0 0.825 0.675 1.5 1.5 1.5h6.5v-7h-2v-2h2v-1c0-1.653 1.347-3 3-3h2v2h-2c-0.55 0-1 0.45-1 1v1h3l-0.5 2h-2.5v7h4.5c0.825 0 1.5-0.675 1.5-1.5v-13c0-0.825-0.675-1.5-1.5-1.5z"}}]})(e)}},{id:"discord",url:"https://discordapp.com/users/623530338869837825",icon:a.KpZ},{id:"reddit",url:"https://www.reddit.com/user/khoaxuantu",icon:a.sky},{id:"dev-to",url:"https://dev.to/khoaxuantu",icon:function(e){return(0,r.w_)({tag:"svg",attr:{viewBox:"0 0 448 512"},child:[{tag:"path",attr:{d:"M120.12 208.29c-3.88-2.9-7.77-4.35-11.65-4.35H91.03v104.47h17.45c3.88 0 7.77-1.45 11.65-4.35 3.88-2.9 5.82-7.25 5.82-13.06v-69.65c-.01-5.8-1.96-10.16-5.83-13.06zM404.1 32H43.9C19.7 32 .06 51.59 0 75.8v360.4C.06 460.41 19.7 480 43.9 480h360.2c24.21 0 43.84-19.59 43.9-43.8V75.8c-.06-24.21-19.7-43.8-43.9-43.8zM154.2 291.19c0 18.81-11.61 47.31-48.36 47.25h-46.4V172.98h47.38c35.44 0 47.36 28.46 47.37 47.28l.01 70.93zm100.68-88.66H201.6v38.42h32.57v29.57H201.6v38.41h53.29v29.57h-62.18c-11.16.29-20.44-8.53-20.72-19.69V193.7c-.27-11.15 8.56-20.41 19.71-20.69h63.19l-.01 29.52zm103.64 115.29c-13.2 30.75-36.85 24.63-47.44 0l-38.53-144.8h32.57l29.71 113.72 29.57-113.72h32.58l-38.46 144.8z"}}]})(e)}},{id:"codepen",url:"https://codepen.io/khoaxuantu",icon:function(e){return(0,r.w_)({tag:"svg",attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{d:"M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"}}]})(e)}}],c=[{url:"/about",content:"About"},{url:"/blogs",content:"Blogs"},{url:"/guestbook",content:"Guestbook"},{url:"/contact",content:"Contact"}],f=[{name:"AWS",url:"https://aws.amazon.com/",icon:l["AWS-Dark"]},{name:"Bootstrap",url:"https://getbootstrap.com/",icon:l.Bootstrap},{name:"C",url:"https://cppreference.com/",icon:l.C},{name:"C++",url:"https://cplusplus.com/",icon:l.CPP},{name:"CSS",url:"https://www.w3.org/Style/CSS/Overview.en.html",icon:l.CSS},{name:"Django",url:"https://www.djangoproject.com/",icon:l.Django},{name:"Docker",url:"https://www.docker.com/",icon:l.Docker},{name:"Firebase",url:"https://firebase.google.com/",icon:l["Firebase-Light"]},{name:"Flask",url:"https://flask.palletsprojects.com/",icon:l["Flask-Light"]},{name:"GCP",url:"https://cloud.google.com/",icon:l["GCP-Light"]},{name:"HTML",url:"https://developer.mozilla.org/en-US/docs/Web/HTML",icon:l.HTML},{name:"JavaScript",url:"https://www.javascript.com/",icon:l.JavaScript},{name:"Oracle DB",url:"https://www.oracle.com/database/",icon:l.Oracle},{name:"PostgreSQL",url:"https://www.postgresql.org/",icon:l["PostgreSQL-Light"]},{name:"Python",url:"https://www.python.org/",icon:l["Python-Light"]},{name:"Rails",url:"https://rubyonrails.org/",icon:l.Rails},{name:"React",url:"https://react.dev/",icon:l["React-Dark"]},{name:"Ruby",url:"https://www.ruby-lang.org/en/",icon:l.Ruby},{name:"SASS",url:"https://sass-lang.com/",icon:l.Sass},{name:"SQLite",url:"https://sqlite.org/",icon:l.SQLite},{name:"TypeScript",url:"https://www.typescriptlang.org/",icon:l.TypeScript},{name:"NextJS",url:"https://nextjs.org/",icon:l["NextJS-Light"]},{name:"Git",url:"https://git-scm.com/",icon:l.Git},{name:"NodeJS",url:"https://nodejs.org/",icon:l["NodeJS-Dark"]},{name:"Redis",url:"https://redis.io/",icon:l["Redis-Light"]},{name:"MySQL",url:"https://www.mysql.com/",icon:l["MySQL-Light"]},{name:"MongoDB",url:"https://www.mongodb.com/",icon:l.MongoDB}],d=[{name:"Pixta Inc.",content:{title:"Fullstack Web Developer",company:"Pixta",time:"06/2023 - now",location:"Hanoi, Vietnam",description:["Develop and maintain the backend system of PixtaStock.\n Analyze data, evaluate the effectiveness of features to improve\n and develop new features.","Work closely with the Japan product design team to maintain the web application for\n internal tools.","Provide technical support to resolve and monitor PixtaStock's issues reported\n by the customers.","Frequently used stacks: Ruby on Rails, React, NodeJS, MySQL, MongoDB, Docker, AWS","Updating..."]}},{name:"Pegatron",content:{title:"Data Engineer Intern",company:"Pegatron",time:"02/2022 - 06/2022",location:"Taipei, Taiwan",description:["Participated in the Shop Floor Information System (SFIS) development team,\n which processes the data to integrate it with Pegatron's manufacturing process\n among 7 global and 2 local factories.","Learned how to track and update the data flow, manage and develop\n databases via Oracle Database.","Contributed to the transformation and loading process in the ETL\n and customer's report by retrieving the data into >30 forms."]}},{name:"Techman Robot Inc.",content:{title:"Robotic Automation Engineering Trainee",company:"Techman",time:"06/2020 - 08/2020",location:"Taoyuan, Taiwan",description:["Got training in practical robotic processing and functioning.\n (Robotic arm, AI, IoT, Computer vision)","Developed the TM robotic automation project and presented the project\n at the 2020 Taipei Industrial Automation Exhibition.","Won the First Prize in the Projects competition held by the company."]}}],p={"algo-visual":{id:"0",content_section:"Projects",title:"Algorithm Visualizer",description:["A web application that visualizes algorithms from code\n (initially provides sorting algorithms demonstration)."],tools:["TypeScript","Next","Bootstrap"],demoURL:"https://algovisual.xuankhoatu.com/",githubURL:"https://github.com/khoaxuantu/Algorithms-Visualizer",imageURL:u.i.Algovisual},"finance-rep":{id:1,content_section:"Projects",title:"CS50 Finance Replication",description:["A web-app replication of CS50 finance's mock stock-trading website\n (finance.cs50.net), which initially comes from a problem set in CS50X.\n It has been extended with some additional features and\n different database."],tools:["Flask","Bootstrap","SQLite","Firestore","GCP"],demoURL:"https://\ufb01nancerep.xuankhoatu.com/",githubURL:"https://github.com/khoaxuantu/finance-rep",imageURL:u.i.Financerep},"e-commerce-auction":{id:4,content_section:"Projects",title:"E-commerce Auction",description:["An eBay-like e-commerce auction site that will allow users to post\n auction listings, place bids on listings,\n comment on those listings, and add listings to a \u201dwatchlist\u201d."],tools:["Django","Bootstrap","PostgreSQL"],demoURL:"https://youtu.be/dC6IBfkbZs8",githubURL:"https://github.com/khoaxuantu/E-commerce_auction_site",imageURL:u.i.Auction},"knapsack-solvers-analysis":{id:4,content_section:"Projects",title:"Knapsack Solvers Analysis",description:["An analysis of the performance in solving typical knapsack problems\n by the Simplex Algorithm and the Harmony Search Algorithm,\n as the Advanced Algorithms coursework project."],tools:["Python","Or-tools"],githubURL:"https://github.com/khoaxuantu/Solving-Knapsacks-in-LinearProg-vs-HarmonySearch",imageURL:u.i.Knapsack},"email-spa":{id:4,content_section:"Projects",title:"Email Single Page Application",description:["A front-end for an email client in SPA style that makes API calls to send\n and receive email"],tools:["Plain JavaScript","Django","Bootstrap"],githubURL:"https://github.com/khoaxuantu/one-page-email",imageURL:u.i.MailSPA},"wiki-encyclopedia":{id:4,content_section:"Projects",title:"Wiki Encyclopedia",description:["A Wikipedia-like online encyclopedia that will allow users search\n for an encyclopedia entry, create new entries and edit an existing entry."],tools:["Django","Bootstrap"],githubURL:"https://github.com/khoaxuantu/wiki_encyclopedia",imageURL:u.i.Wiki},"calendar-on-terminal":{id:5,content_section:"Projects",title:"Calendar on Terminal",description:["A small project of calendar queried on terminal, as a midterm project\n when I first took the C programming course in 2020."],tools:["C"],githubURL:"https://github.com/khoaxuantu/Calendar_demo",imageURL:u.i.Calendar},"techman-proj":{id:6,content_section:"Projects",title:"Lottery Draw Robotic Application",description:["Participated in a group project to develop the robotic arm\n application project in the lottery drawing.","My responsibility is to set up Eye-in-hand Vision and\n 3D Vision via a camera attached to the robotic arm to detect\n the prize's patterns and the area for the gift box container."],tools:["Robotic automation algorithm design"],imageURL:u.i.Tm},"gripper-sketch":{id:7,content_section:"Projects",title:"Gripper Base System Sketch",description:["A graphical sketch of robotic arm gripper base system,\n as a manual graphic coursework in Mechanical Graphic course."],tools:["AutoCAD"],imageURL:u.i.AutoCAD},"fontscale-sass":{id:2,content_section:"Projects",title:"Font Scale Sass",description:["A SASS font-scale generator module which provides\n a preset font size for your footnote, endnote, caption, body, blockquote, and headings (from h6 to h1)."],tools:["SASS"],imageURL:u.i.Fontscale,githubURL:"https://github.com/khoaxuantu/Font-scale-sass",demoURL:"https://www.npmjs.com/package/fontscale-sass"},"random-meme-picker":{id:3,content_section:"Projects",title:"Random Meme Picker",description:["A random meme web chosen from my more than 800-meme collection. Pick a meme a day for a better life."],tools:["React","Bun","SASS","Cloud storage"],demoURL:"https://meme.xuankhoatu.com",githubURL:"https://github.com/khoaxuantu/random-meme-gen",imageURL:u.i.RandomMeme}},h={great_ytb_channels_1:{content_section:"Blogs",id:"great_ytb_channels_1",title:"Great Youtube Channels (Part 1)",brief_description:"I watch youtube a lot, and I make a list of youtube channels\n I have watched that you may find interesting. Here is part 1 of my list...",url:"/great_ytb_channels_1",file:"great_ytb_channels_1.md"},great_ytb_channels_2:{content_section:"Blogs",id:"great_ytb_channels_2",title:"Great Youtube Channels (Part 2)",brief_description:"I watch youtube a lot, and I make a list of youtube channels\n I have watched that you may find interesting. Here is part 2 of my list...",url:"/great_ytb_channels_2",file:"great_ytb_channels_2.md"},markdown_starter:{content_section:"Blogs",id:"markdown_starter",title:"Get started with Markdown",brief_description:"My markdown theme which is generated by React Markdown.",url:"/markdown_starter",file:"markdown_starter.md"},uncommon_javascript_notes:{content_section:"Blogs",id:"uncommon_javascript_notes",title:"Uncommon JavaScript Notes - The language",brief_description:"JavaScript is super complicated, like a pain in your ass.\n Even when you are quite familiar with programming languages logics and concepts,\n you still find it difficult to cover major aspects in JS.",url:"/uncommon_javascript_notes",file:"uncommon_javascript_notes.md"},uncommon_javascript_notes_1:{content_section:"Blogs",id:"uncommon_javascript_notes_1",title:"Uncommon JavaScript Notes - Browser: Document, Events, Interfaces",brief_description:"One thing that make JavaScript weird to learn is\n how it interacts with the browser DOM, how to control the events, the forms,\n and how the resource is loaded.",url:"/uncommon_javascript_notes_1",file:"uncommon_javascript_notes_1.md"},learn_from_react_bun_boilerplate:{content_section:"Blogs",id:"learn_from_react_bun_boilerplate",title:"Trying to re-create React boilerplate in Bun and what I learned from it",brief_description:"Many people are hyped with Bun for its performance and new features compared with\n NodeJS. One of them is .jsx and .tsx file support with its internal transpiler, which help creating a React\n app by Bun becomes more convenient. But the problem here is to have a boilerplate to optimize the feature\n for creating React app.",url:"/learn_from_react_bun_boilerplate",file:"react_bun_boilerplate.md"}},m=[{dictKey:"great_ytb_channels_1",date:"Apr 26 2023 22:35:23 GMT+0800"},{dictKey:"great_ytb_channels_2",date:"Apr 27 2023 13:30:59 GMT+0800"},{dictKey:"markdown_starter",date:"Thu Mar 23 2023 23:10:33 GMT+0700"},{dictKey:"uncommon_javascript_notes",date:"Fri Jun 16 2023 23:02:26 GMT+0700"},{dictKey:"uncommon_javascript_notes_1",date:"Sun Sep 03 2023 11:13:44 GMT+0700"},{dictKey:"learn_from_react_bun_boilerplate",date:"Sun Oct 22 2023 19:43:00 GMT+0700"}],v=[{icon:a.rFR,url:"",classname:"btn-oauth-github",name:"Github"},{icon:function(e){return(0,r.w_)({tag:"svg",attr:{version:"1.1",x:"0px",y:"0px",viewBox:"0 0 48 48",enableBackground:"new 0 0 48 48"},child:[{tag:"path",attr:{fill:"#FFC107",d:"M43.611,20.083H42V20H24v8h11.303c-1.649,4.657-6.08,8-11.303,8c-6.627,0-12-5.373-12-12\r\n\tc0-6.627,5.373-12,12-12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657C34.046,6.053,29.268,4,24,4C12.955,4,4,12.955,4,24\r\n\tc0,11.045,8.955,20,20,20c11.045,0,20-8.955,20-20C44,22.659,43.862,21.35,43.611,20.083z"}},{tag:"path",attr:{fill:"#FF3D00",d:"M6.306,14.691l6.571,4.819C14.655,15.108,18.961,12,24,12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657\r\n\tC34.046,6.053,29.268,4,24,4C16.318,4,9.656,8.337,6.306,14.691z"}},{tag:"path",attr:{fill:"#4CAF50",d:"M24,44c5.166,0,9.86-1.977,13.409-5.192l-6.19-5.238C29.211,35.091,26.715,36,24,36\r\n\tc-5.202,0-9.619-3.317-11.283-7.946l-6.522,5.025C9.505,39.556,16.227,44,24,44z"}},{tag:"path",attr:{fill:"#1976D2",d:"M43.611,20.083H42V20H24v8h11.303c-0.792,2.237-2.231,4.166-4.087,5.571\r\n\tc0.001-0.001,0.002-0.001,0.003-0.002l6.19,5.238C36.971,39.205,44,34,44,24C44,22.659,43.862,21.35,43.611,20.083z"}}]})(e)},url:"",classname:"btn-oauth-google",name:"Google"}]},3267:function(e,t,n){"use strict";n.d(t,{y:function(){return a}});var r=JSON.parse('{"Xh":"https://xuankhoatu.com/"}');function a(e){return r.Xh.slice(0,-1)+e.pathname+"/"}},8278:function(e,t,n){"use strict";n.d(t,{Ep:function(){return x},J0:function(){return g},RQ:function(){return W},WK:function(){return q},X3:function(){return $},Zn:function(){return U},Zq:function(){return F},aU:function(){return r},cP:function(){return k},fp:function(){return j},lX:function(){return v},pC:function(){return B}});var r,a=n(3144),i=n(5671),o=n(136),l=n(7277),u=n(8737),s=n(9439),c=n(4506),f=n(7762),d=n(3433);function p(){return p=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0&&(t.hash=e.substr(n),e=e.substr(0,n));var r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function S(e,t,n,a){void 0===a&&(a={});var i=a,o=i.window,l=void 0===o?document.defaultView:o,u=i.v5Compat,s=void 0!==u&&u,c=l.history,f=r.Pop,d=null,h=v();function v(){return(c.state||{idx:null}).idx}function b(){f=r.Pop;var e=v(),t=null==e?null:e-h;h=e,d&&d({action:f,location:S.location,delta:t})}function k(e){var t="null"!==l.location.origin?l.location.origin:l.location.href,n="string"===typeof e?e:x(e);return g(t,"No window.location.(origin|href) available to create URL for href: "+n),new URL(n,t)}null==h&&(h=0,c.replaceState(p({},c.state,{idx:h}),""));var S={get action(){return f},get location(){return e(l,c)},listen:function(e){if(d)throw new Error("A history only accepts one active listener");return l.addEventListener(m,b),d=e,function(){l.removeEventListener(m,b),d=null}},createHref:function(e){return t(l,e)},createURL:k,encodeLocation:function(e){var t=k(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:function(e,t){f=r.Push;var a=w(S.location,e,t);n&&n(a,e);var i=y(a,h=v()+1),o=S.createHref(a);try{c.pushState(i,"",o)}catch(u){l.location.assign(o)}s&&d&&d({action:f,location:S.location,delta:1})},replace:function(e,t){f=r.Replace;var a=w(S.location,e,t);n&&n(a,e);var i=y(a,h=v()),o=S.createHref(a);c.replaceState(i,"",o),s&&d&&d({action:f,location:S.location,delta:0})},go:function(e){return c.go(e)}};return S}!function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"}(h||(h={}));new Set(["lazy","caseSensitive","path","id","index","children"]);function j(e,t,n){void 0===n&&(n="/");var r=U(("string"===typeof t?k(t):t).pathname||"/",n);if(null==r)return null;var a=C(e);!function(e){e.sort((function(e,t){return e.score!==t.score?t.score-e.score:function(e,t){var n=e.length===t.length&&e.slice(0,-1).every((function(e,n){return e===t[n]}));return n?e[e.length-1]-t[t.length-1]:0}(e.routesMeta.map((function(e){return e.childrenIndex})),t.routesMeta.map((function(e){return e.childrenIndex})))}))}(a);for(var i=null,o=0;null==i&&o0&&(g(!0!==e.index,'Index routes must not have child routes. Please remove all child routes from route path "'+l+'".'),C(e.children,t,u,l)),(null!=e.path||e.index)&&t.push({path:l,score:A(l,e.index),routesMeta:u})};return e.forEach((function(e,t){var n;if(""!==e.path&&null!=(n=e.path)&&n.includes("?")){var r,i=(0,f.Z)(E(e.path));try{for(i.s();!(r=i.n()).done;){var o=r.value;a(e,t,o)}}catch(l){i.e(l)}finally{i.f()}}else a(e,t)})),t}function E(e){var t=e.split("/");if(0===t.length)return[];var n=(0,c.Z)(t),r=n[0],a=n.slice(1),i=r.endsWith("?"),o=r.replace(/\?$/,"");if(0===a.length)return i?[o,""]:[o];var l=E(a.join("/")),u=[];return u.push.apply(u,(0,d.Z)(l.map((function(e){return""===e?o:[o,e].join("/")})))),i&&u.push.apply(u,(0,d.Z)(l)),u.map((function(t){return e.startsWith("/")&&""===t?"/":t}))}var _=/^:\w+$/,P=3,T=2,N=1,O=10,L=-2,R=function(e){return"*"===e};function A(e,t){var n=e.split("/"),r=n.length;return n.some(R)&&(r+=L),t&&(r+=T),n.filter((function(e){return!R(e)})).reduce((function(e,t){return e+(_.test(t)?P:""===t?N:O)}),r)}function z(e,t){for(var n=e.routesMeta,r={},a="/",i=[],o=0;o and the router will parse it for you.'}function F(e){return e.filter((function(e,t){return 0===t||e.route.path&&e.route.path.length>0}))}function B(e,t,n,r){var a;void 0===r&&(r=!1),"string"===typeof e?a=k(e):(g(!(a=p({},e)).pathname||!a.pathname.includes("?"),D("?","pathname","search",a)),g(!a.pathname||!a.pathname.includes("#"),D("#","pathname","hash",a)),g(!a.search||!a.search.includes("#"),D("#","search","hash",a)));var i,o=""===e||""===a.pathname,l=o?"/":a.pathname;if(r||null==l)i=n;else{var u=t.length-1;if(l.startsWith("..")){for(var s=l.split("/");".."===s[0];)s.shift(),u-=1;a.pathname=s.join("/")}i=u>=0?t[u]:"/"}var c=function(e,t){void 0===t&&(t="/");var n="string"===typeof e?k(e):e,r=n.pathname,a=n.search,i=void 0===a?"":a,o=n.hash,l=void 0===o?"":o,u=r?r.startsWith("/")?r:function(e,t){var n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach((function(e){".."===e?n.length>1&&n.pop():"."!==e&&n.push(e)})),n.length>1?n.join("/"):"/"}(r,t):t;return{pathname:u,search:V(i),hash:Z(l)}}(a,i),f=l&&"/"!==l&&l.endsWith("/"),d=(o||"."===l)&&n.endsWith("/");return c.pathname.endsWith("/")||!f&&!d||(c.pathname+="/"),c}var W=function(e){return e.join("/").replace(/\/\/+/g,"/")},H=function(e){return e.replace(/\/+$/,"").replace(/^\/*/,"/")},V=function(e){return e&&"?"!==e?e.startsWith("?")?e:"?"+e:""},Z=function(e){return e&&"#"!==e?e.startsWith("#")?e:"#"+e:""},$=function(e){(0,o.Z)(n,e);var t=(0,l.Z)(n);function n(){return(0,i.Z)(this,n),t.apply(this,arguments)}return(0,a.Z)(n)}((0,u.Z)(Error));function q(e){return null!=e&&"number"===typeof e.status&&"string"===typeof e.statusText&&"boolean"===typeof e.internal&&"data"in e}var Q=["post","put","patch","delete"],K=(new Set(Q),["get"].concat(Q));new Set(K),new Set([301,302,303,307,308]),new Set([307,308]),"undefined"!==typeof window&&"undefined"!==typeof window.document&&window.document.createElement;Symbol("deferred")},1725:function(e){"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var i,o,l=function(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),u=1;u=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}function C(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function E(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!==typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var r,a,i=[],o=!0,l=!1;try{for(n=n.call(e);!(o=(r=n.next()).done)&&(i.push(r.value),!t||i.length!==t);o=!0);}catch(u){l=!0,a=u}finally{try{o||null==n.return||n.return()}finally{if(l)throw a}}return i}(e,t)||function(e,t){if(!e)return;if("string"===typeof e)return _(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:"none")},D=function(){return!("undefined"===typeof window||!window.navigator&&!navigator)&&(window.navigator||navigator)},F=function(e){var t=D();return t&&t.platform&&(-1!==t.platform.indexOf(e)||"MacIntel"===t.platform&&t.maxTouchPoints>1&&!window.MSStream)},B=function(e,t,n,r){return function(e){for(var t=1;t1)&&!window.MSStream},Ce=function(){return F("iPad")},Ee=function(){return F("iPhone")},_e=function(){return F("iPod")},Pe=function(e){return U(e)};function Te(e){var t=e||v,n=t.device,r=t.browser,a=t.os,i=t.engine,o=t.ua;return{isSmartTV:Z(n),isConsole:Q(n),isWearable:q(n),isEmbedded:K(n),isMobileSafari:de(r)||Ce(),isChromium:ue(r),isMobile:V(n)||Ce(),isMobileOnly:W(n),isTablet:H(n)||Ce(),isBrowser:$(n),isDesktop:$(n),isAndroid:X(a),isWinPhone:ne(a),isIOS:re(a)||Ce(),isChrome:oe(r),isFirefox:le(r),isSafari:fe(r),isOpera:pe(r),isIE:he(r),osVersion:ae(a),osName:ie(a),fullBrowserVersion:ge(r),browserVersion:be(r),browserName:ye(r),mobileVendor:J(n),mobileModel:G(n),engineName:we(i),engineVersion:xe(i),getUA:Pe(o),isEdge:se(r)||Se(o),isYandex:ce(r),deviceType:Y(n),isIOS13:je(),isIPad13:Ce(),isIPhone13:Ee(),isIPod13:_e(),isElectron:ke(),isEdgeChromium:Se(o),isLegacyEdge:se(r)&&!Se(o),isWindows:ee(a),isMacOs:te(a),isMIUI:me(r),isSamsungBrowser:ve(r)}}var Ne=Z(c),Oe=Q(c),Le=q(c),Re=K(c),Ae=de(u)||Ce(),ze=ue(u),Me=V(c)||Ce(),Ie=W(c),Ue=H(c)||Ce(),De=$(c),Fe=$(c),Be=X(d),We=ne(d),He=re(d)||Ce(),Ve=oe(u),Ze=le(u),$e=fe(u),qe=pe(u),Qe=he(u),Ke=ae(d),Je=ie(d),Ge=ge(u),Ye=be(u),Xe=ye(u),et=J(c),tt=G(c),nt=we(f),rt=xe(f),at=Pe(p),it=se(u)||Se(p),ot=ce(u),lt=Y(c),ut=je(),st=Ce(),ct=Ee(),ft=_e(),dt=ke(),pt=Se(p),ht=se(u)&&!Se(p),mt=ee(d),vt=te(d),gt=me(u),bt=ve(u);function yt(e){var t=e||window.navigator.userAgent;return m(t)}t.UA=Ie},4463:function(e,t,n){"use strict";var r=n(2791),a=n(5296);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n