diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index ce118af..0000000
--- a/.babelrc
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "presets": [
- [
- "@babel/preset-env", {
- "modules": false,
- "loose": false,
- "useBuiltIns": "usage"
- }
- ],
- [
- "@babel/preset-stage-2", {
- "modules": false,
- "loose": false,
- "useBuiltIns": true,
- "decoratorsLegacy": true
- }
- ]
- ],
- "plugins": [
- [
- "@babel/transform-runtime", {
- "polyfill": false,
- "regenerator": false
- }
- ]
- ],
- "comments": false
-}
diff --git a/.cache/assets/static/cat.df59cee.d583223fc3147966ee8b395cf9b63705.svg b/.cache/assets/static/cat.df59cee.d583223fc3147966ee8b395cf9b63705.svg
new file mode 100644
index 0000000..29a5da0
--- /dev/null
+++ b/.cache/assets/static/cat.df59cee.d583223fc3147966ee8b395cf9b63705.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.cache/assets/static/favicon.ac8d93a.c7da33a4801d80a0911bb15c172d569d.png b/.cache/assets/static/favicon.ac8d93a.c7da33a4801d80a0911bb15c172d569d.png
new file mode 100644
index 0000000..97a75b7
Binary files /dev/null and b/.cache/assets/static/favicon.ac8d93a.c7da33a4801d80a0911bb15c172d569d.png differ
diff --git a/.cache/assets/static/me.cbab2cf.41b9eee976f000aaf07e1d55096c1cde.jpg b/.cache/assets/static/me.cbab2cf.41b9eee976f000aaf07e1d55096c1cde.jpg
new file mode 100644
index 0000000..b72538d
Binary files /dev/null and b/.cache/assets/static/me.cbab2cf.41b9eee976f000aaf07e1d55096c1cde.jpg differ
diff --git a/.cache/assets/static/mobile_app.ba3f0c2.bacc31c9fb3cebfe6760e3868f77376a.svg b/.cache/assets/static/mobile_app.ba3f0c2.bacc31c9fb3cebfe6760e3868f77376a.svg
new file mode 100644
index 0000000..f53daea
--- /dev/null
+++ b/.cache/assets/static/mobile_app.ba3f0c2.bacc31c9fb3cebfe6760e3868f77376a.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 9d08a1a..0000000
--- a/.editorconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-indent_style = space
-indent_size = 2
-end_of_line = lf
-insert_final_newline = true
-trim_trailing_whitespace = true
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index d758519..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/dist
-/src/assets/
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index 9d74edb..0000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,47 +0,0 @@
-module.exports = {
- root: true,
- parserOptions: {
- parser: 'babel-eslint',
- sourceType: 'module'
- },
- env: {
- browser: true
- },
- extends: [
- // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
- // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
- 'plugin:vue/essential',
- // https://github.com/standard/standard/blob/master/docs/RULES-en.md
- 'standard'
- ],
- // required to lint *.vue files
- plugins: [
- 'vue'
- ],
- globals: {
- 'ga': true, // Google Analytics
- 'cordova': true,
- '__statics': true
- },
- // add your custom rules here
- 'rules': {
- // allow async-await
- 'generator-star-spacing': 'off',
-
- // allow paren-less arrow functions
- 'arrow-parens': 0,
- 'one-var': 0,
-
- 'import/first': 0,
- 'import/named': 2,
- 'import/namespace': 2,
- 'import/default': 2,
- 'import/export': 2,
- 'import/extensions': 0,
- 'import/no-unresolved': 0,
- 'import/no-extraneous-dependencies': 0,
-
- // allow debugger during development
- 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
- }
-}
diff --git a/.postcssrc.js b/.postcssrc.js
deleted file mode 100644
index 1174fe5..0000000
--- a/.postcssrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// https://github.com/michael-ciniawsky/postcss-load-config
-
-module.exports = {
- plugins: [
- // to edit target browsers: use "browserslist" field in package.json
- require('autoprefixer')
- ]
-}
diff --git a/.stylintrc b/.stylintrc
deleted file mode 100644
index ce38d77..0000000
--- a/.stylintrc
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "blocks": "never",
- "brackets": "never",
- "colons": "never",
- "colors": "always",
- "commaSpace": "always",
- "commentSpace": "always",
- "cssLiteral": "never",
- "depthLimit": false,
- "duplicates": true,
- "efficient": "always",
- "extendPref": false,
- "globalDupe": true,
- "indentPref": 2,
- "leadingZero": "never",
- "maxErrors": false,
- "maxWarnings": false,
- "mixed": false,
- "namingConvention": false,
- "namingConventionStrict": false,
- "none": "never",
- "noImportant": false,
- "parenSpace": "never",
- "placeholder": false,
- "prefixVarsWithDollar": "always",
- "quotePref": "single",
- "semicolons": "never",
- "sortOrder": false,
- "stackedProperties": "never",
- "trailingWhitespace": "never",
- "universal": "never",
- "valid": true,
- "zeroUnits": "never",
- "zIndexNormalize": false
-}
diff --git a/README.md b/README.md
index d9a5721..93efa48 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,10 @@
-# portfolio
+# Joseph Harvey Angeles | Portfolio
> my portfolio website hosted on https://www.josephharveyangeles.com
## Change History
+* 7/17/2020
+ * version 6: Re-implemented using gridsome. Using [andre-madarang](https://andremadarang.com/)'s [starter kit](https://github.com/drehimself/gridsome-portfolio-starter).
* 3/5/2019
* version 5: Redesigned. Tried a minimalistic vibrant modern approach
* 8/3/2018
@@ -17,7 +19,11 @@
## Authors
* [**Joseph Harvey Angeles**](https://github.com/vycoder)
-
## License
+Copyright 2019 Andre Madarang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-[](http://creativecommons.org/licenses/by-nc-sa/4.0/)
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/src/blogs/codeNo0bsGuide/main.md b/blog/2017-03-25-codenoobs-guide-main.md
similarity index 90%
rename from src/blogs/codeNo0bsGuide/main.md
rename to blog/2017-03-25-codenoobs-guide-main.md
index 42fd288..96cd30b 100644
--- a/src/blogs/codeNo0bsGuide/main.md
+++ b/blog/2017-03-25-codenoobs-guide-main.md
@@ -1,65 +1,72 @@
-
-# CodeNo0b's Guide Out of Mediocrity — main()
-###### 25 March 2017
-Have you read ‘The Pragmatic Programmer’ by [Andy Hunt](https://twitter.com/PragmaticAndy) and [David Thomas](https://twitter.com/pragdave)? How about ‘The Passionate Programmer’ by [Chad Fowler](https://twitter.com/chadfowler)? Robert ([Uncle Bob](https://twitter.com/unclebobmartin)) Martin's books? If you haven't, I highly recommend that you do.
-
-‘[The Pragmatic Programmer](https://pragprog.com/book/tpp/the-pragmatic-programmer)’, considered as one of the classics, teaches you how to transition from a vanilla software developer into a master by adopting a more pragmatic approach. Written decades ago, but still very relevant in the present. ‘[The Passionate Programmer](https://pragprog.com/book/cfcar2/the-passionate-programmer)’ on the other hand, is about being nothing but remarkable, how to drive yourself and take action. If you add Uncle Bob’s books into the mix, then you are now in possession of something equivalent to Batman’s utility belt — an arsenal of stuff that will help you in every software developer endeavors that you’ll ever encounter.
-
-
-
-Don’t get me wrong — the books are all already really great, very useful and highly insightful. But let’s face it, you won’t really remember all the important information that you’ve read on a hundreds-of-pages technical books. If you don’t deliberately put an effort, you’ll most likely to remember only bits of pieces that resonates for you in that particular time of reading.
-
-And that’s the reason why I’m writing this article. I want a different form, a more cohesive structure that will help me place all the concepts and ideas quite snugly in my brain. This won’t be a summary or book review, but more of a reference guide, that I could look back to whenever I feel stuck or even down. Like a map, chart, or a mental model of the concepts discussed on all those books combined. Like a personal bible, a personal manifesto — that’s what I’ll attempt to create in this series of articles, my first ever blog post. (Oh and yeah, I wrote this mainly for myself. I’m an amateur, sorry in advance.)
-
-* * *
-
-After reading the books, I classified the ideas into different blocks. There might be a more suitable mental model but this will do in this moment. I broke down the concepts and ideas from the said books into the following components shown in the image. This will be my high-level general map. (Maybe I’ll also try to make an interactive web app or some sort, some other time.) I intentionally chose to use computer-related terms as component names for better reinforcement.
-
-
-
-### [General Characteristics](blog/codenoobsguide/generalcharacteristics)
-This is often where you find the “buzzwords” of your programming language, like a short summary of it’s capabilities. Object-oriented, multi-paradigm, portable, platform-independent, and what not’s. In the same manner, this section will outline the general characteristics of an ideal programmer.
-
-### Runtime Environment
-This component refers to the ideal programmer’s general mindset. The general ideal outlook to have on a daily basis. A maxim that you should always keep running on the background to guide you in your everyday decisions.
-
-### Preprocessing
-Refers to the techniques and ideas that you should accomplish before actually hitting that first keystroke on your mechanical keyboard to code.
-
-### In the Zone
-
-
-
-This section will discuss the things that you should keep in mind while you’re deep in that keyboard-frenzy, coding trance.
-
-### Coding Principles
-Yep, just like what it said. This will contain all the general coding principles that every developer should know. These are handy tools that will help us in our day-to-day implementation tasks.
-
-### Design Principles
-This article will not be an in-depth discussion of software design and architecture, there’s a lot of books to cover that. This will just introduce the existence of them and how they can help us.
-
-### Debugging
-This section is not about the debugger and how to use it, but the act of debugging itself. It’s more on how to find the problem to eventually fix it. You could be debugging code, or just any general problem. Whatever it is, don’t debug blindly, there’s a better way of doing it.
-
-### Interfacing
-You maybe a great coder, but if you can’t express yourself in words, you won’t be very effective on a distributed team. This section is all about communication — tips and tricks, things to remember when interfacing with people throughout your job.
-
-### Outer scope
-Lastly, this section will ponder on your software development career. How to build it, what to watch out for, and how you should generally view it.
-
-* * *
-
-I will go into detail in a separate post for every component and provide appropriate hyperlinks while I’m at it. For now, this main() article will serve as the overview.
-
-* * *
-
-###### Quick Links
-+ [General Characteristics](blog/codenoobsguide/generalcharacteristics)
-+ Runtime Environment
-+ Preprocessing
-+ In the Zone
-+ Coding Principles
-+ Design Principles
-+ Debugging
-+ Interfacing
-+ Outer Scope
+---
+title: CodeNo0b’s Guide out of Mediocrity — main()
+path: /codenoobs-guide-out-of-mediocrity-main
+date: 2017-03-25
+summary: CodeNo0b's Guide out of Mediocrity's overview, table of contents. Much like a map of best practices and pragmatic clean coding.
+tags: ['software design']
+---
+
+
+Have you read ‘The Pragmatic Programmer’ by [Andy Hunt](https://twitter.com/PragmaticAndy) and [David Thomas](https://twitter.com/pragdave)? How about ‘The Passionate Programmer’ by [Chad Fowler](https://twitter.com/chadfowler)? Robert ([Uncle Bob](https://twitter.com/unclebobmartin)) Martin's books? If you haven't, I highly recommend that you do.
+
+‘[The Pragmatic Programmer](https://pragprog.com/book/tpp/the-pragmatic-programmer)’, considered as one of the classics, teaches you how to transition from a vanilla software developer into a master by adopting a more pragmatic approach. Written decades ago, but still very relevant in the present. ‘[The Passionate Programmer](https://pragprog.com/book/cfcar2/the-passionate-programmer)’ on the other hand, is about being nothing but remarkable, how to drive yourself and take action. If you add Uncle Bob’s books into the mix, then you are now in possession of something equivalent to Batman’s utility belt — an arsenal of stuff that will help you in every software developer endeavors that you’ll ever encounter.
+
+
+
+Don’t get me wrong — the books are all already really great, very useful and highly insightful. But let’s face it, you won’t really remember all the important information that you’ve read on a hundreds-of-pages technical books. If you don’t deliberately put an effort, you’ll most likely to remember only bits of pieces that resonates for you in that particular time of reading.
+
+And that’s the reason why I’m writing this article. I want a different form, a more cohesive structure that will help me place all the concepts and ideas quite snugly in my brain. This won’t be a summary or book review, but more of a reference guide, that I could look back to whenever I feel stuck or even down. Like a map, chart, or a mental model of the concepts discussed on all those books combined. Like a personal bible, a personal manifesto — that’s what I’ll attempt to create in this series of articles, my first ever blog post. (Oh and yeah, I wrote this mainly for myself. I’m an amateur, sorry in advance.)
+
+* * *
+
+After reading the books, I classified the ideas into different blocks. There might be a more suitable mental model but this will do in this moment. I broke down the concepts and ideas from the said books into the following components shown in the image. This will be my high-level general map. (Maybe I’ll also try to make an interactive web app or some sort, some other time.) I intentionally chose to use computer-related terms as component names for better reinforcement.
+
+
+
+### [General Characteristics](blog/codenoobsguide/generalcharacteristics)
+This is often where you find the “buzzwords” of your programming language, like a short summary of it’s capabilities. Object-oriented, multi-paradigm, portable, platform-independent, and what not’s. In the same manner, this section will outline the general characteristics of an ideal programmer.
+
+### Runtime Environment
+This component refers to the ideal programmer’s general mindset. The general ideal outlook to have on a daily basis. A maxim that you should always keep running on the background to guide you in your everyday decisions.
+
+### Preprocessing
+Refers to the techniques and ideas that you should accomplish before actually hitting that first keystroke on your mechanical keyboard to code.
+
+### In the Zone
+
+
+
+This section will discuss the things that you should keep in mind while you’re deep in that keyboard-frenzy, coding trance.
+
+### Coding Principles
+Yep, just like what it said. This will contain all the general coding principles that every developer should know. These are handy tools that will help us in our day-to-day implementation tasks.
+
+### Design Principles
+This article will not be an in-depth discussion of software design and architecture, there’s a lot of books to cover that. This will just introduce the existence of them and how they can help us.
+
+### Debugging
+This section is not about the debugger and how to use it, but the act of debugging itself. It’s more on how to find the problem to eventually fix it. You could be debugging code, or just any general problem. Whatever it is, don’t debug blindly, there’s a better way of doing it.
+
+### Interfacing
+You maybe a great coder, but if you can’t express yourself in words, you won’t be very effective on a distributed team. This section is all about communication — tips and tricks, things to remember when interfacing with people throughout your job.
+
+### Outer scope
+Lastly, this section will ponder on your software development career. How to build it, what to watch out for, and how you should generally view it.
+
+* * *
+
+I will go into detail in a separate post for every component and provide appropriate hyperlinks while I’m at it. For now, this main() article will serve as the overview.
+
+* * *
+
+###### Quick Links
++ Overview
+ + [General Characteristics](/codenoobs-guide-out-of-mediocrity-genchar)
+ + Runtime Environment
+ + Preprocessing
+ + In the Zone
+ + Coding Principles
+ + Design Principles
+ + Debugging
+ + Interfacing
+ + Outer Scope
diff --git a/src/blogs/codeNo0bsGuide/generalcharacteristics.md b/blog/2017-07-06-codenoobs-guide-generalcharacteristics.md
similarity index 95%
rename from src/blogs/codeNo0bsGuide/generalcharacteristics.md
rename to blog/2017-07-06-codenoobs-guide-generalcharacteristics.md
index 2d71730..44604ef 100644
--- a/src/blogs/codeNo0bsGuide/generalcharacteristics.md
+++ b/blog/2017-07-06-codenoobs-guide-generalcharacteristics.md
@@ -1,107 +1,114 @@
-# CodeNo0b’s Guide out of Mediocrity — General Characteristics
-###### 6 July 2017
-
-_This is part of a series of articles entitled, “CodeNo0b’s Guide out of Mediocrity” — my attempt to create some sort of mental model from the concepts discussed on the classic books of Andy Hunt, Dave Thomas, Chad Fowler, and Robert Martin on a teach-myself manner. Table of contents here: [main()](blog/codenoobsguide/main)_
-
-You must be thinking, “_Oh, yet another list? If I don’t have them, does that mean I’m not cut out for this thing? Oh the horror_.” Or it could be the opposite, “_Oh boy, looks like I’m going to be very successful in the future, I have like 8/10 traits listed here!_”. I used to be like that as well. I read every article that talk about the n traits of `` (eg., fabulous chicken) like a self-evaluation checklist. If I have more than the average, I feel good about myself thinking I have the potential to make it. Sometimes, I low-key wear it in the background to make myself feel good for a few days. Eventually, I got sick of that cycle. I felt like it’s very cheap, lame, and lazy. If you’re like this, it’s probably time to stop. Do something. Stop procrastinating. The world, galaxy, universe, fate, destiny, or whatever, does not owe you anything for you to just wait there and expect something to happen. A potential does not guarantee a success. You actually have to move on your own if you want to transform that potential to kinetic. No one’s really going to do it for you. The best that others can do for you is to just inspire or motivate you, so you can start taking that first step.
-
-That being said, as a first step of your personal transformation, don’t think of this list as a self-evaluation checklist, but think of it more as a to-do list. If you don’t have one, then work on it, be like one. It won’t be easy — being mediocre is what’s easy. If you want to stay mediocre, it’s fine, no one should care. I can’t really say that being one or the other will make your life more fruitful. Who knows? Maybe it doesn’t really matter.
-
-Anyway, enough ranting. Let’s get to it.
-
-### Inquisitive
-
-Be curious. Never stop asking questions, it’s alright if you don’t know the answers right now, set it aside for a while, move on to something else. Eventually, you’ll get back to it and you’ll be able to understand it. It works something like this, every time you gain information by figuring out something, that piece of information contributes to your base knowledge which eventually increases your “figuring out” ability. It’s like agar.io and financial investments. The more money you have, the easier it is for you to earn even more money. Knowledge is also an investment, it compounds. It doesn’t look like it at first, but it will affix all of your current knowledge together, holding them even more intact. The more you acquire bits of information, the more likely for you to easily understand bigger chunks of information in the future.
-
-When I was first learning python years ago, I can’t fully wrap my head around list comprehensions. Sure, I know what it does, I can implement it, but it doesn’t feel very natural to me. I was like, “_what kind of sorcery is this?_” (My primary language before was C and Java, every dynamic language looks like sorcery to me back then.) Time passed, Java 8 happened, it piqued my interest. I was curious on how can you imbue Java, a statically-typed language with functional capabilities.
-
-
-
-
-I quickly got in the habit of using `map()` and `filter()` together with lambdas to manipulate my lists. Passing methods on `map()`, and supplying predicates on `filter()`, became second nature to me.
-
-Months later, I started looking back at my python codes again. Then it hit me, list comprehension is just like, `map()` that wandered at the wrong side of town. Tired, mugged and penniless... * (_insert — long and sweet love story of how he met an equally unfortunate yet very beautiful `filter()` with subtle elegance hidden under her tiredness, yet still looks so strong, but not borderline vegan feminazi ‘strong’. `map()` was captivated, he instantly fell in love. he doesn’t believe in destiny, he’s an agnostic with atheistic tendencies, but he knew it was fate the moment he laid eyes upon her. They eventually got together and lived happily ever after — here_) *
-
-What was I talking about again? Oh yea, I realized that Python’s list comprehension is just like Java’s `map()` and `filter()` method combined in one sweet statement.
-
-```
-nums = range(100)
-evens_squared = [ num**2 for num in nums if num % 2 == 0 ]
-# num**2: could also be any transformation function.
-# num % 2 == 0: is the filter's predicate.
-```
-
-### Realistic
-
-I don’t trust overly optimistic people. You’ve met them, these are the people who has this ‘can-do’ attitude about everything. I’m not saying it’s a bad thing, on the contrary, I admire it, but back your can-do attitude with realism. It’s not bad to be optimistic, but avoid being too optimistic that it hinders effective judgment.
-
-Understand the underlying nature of every problem you encounter. Have a good grasp of the difficulties you might face, and imagine how long things will take. These realistic expectations will serve as your foundation, giving you stamina to keep at it.
-
-You don’t want to take in an endeavor with full glee and a marching band, only to find out that it’s not always peaches and butterflies. It’s actually blood, sweat, tears, inequality, elves hates humans, unicorns aren’t real, jet fuel can’t melt steel beams, Spiderman doesn’t have internal web-shooters by default, Superman is overrated, Han Solo shot first, Gandalf’s a douchebag, some beer tastes like piss water, your Hogwarts letter won’t arrive, nobody’s special, macs are overrated, C is not overrated, you are overrated, overrating stuff is overrated, life is meaningless, our existence’s meaningless, we don’t belong anywhere, and eventually, everybody’s going to die. Reality hits you, leaving you paralyzed and broken, it scarred you for life and you never went for an adventure ever again. If only you weren’t so damn sure of yourself, and actually put in even a little bit of effort to really understand things objectively, you wouldn’t be able to f@#k this sh!t up for you and everyone you care about.
-
-
-
-### Specialist
-
-It’s not enough that you know Java’s syntax, you should at least be able to explain how Java class loader works, or how the high-level memory management is typically being handled by the JVM. If you’re a Python developer take time to understand the nuances between the Python Interpreter and the Python Virtual Machine. At least be aware of the existence of different Python implementations, CPython, IronPython, Jython, PyPy, etc. Is Python multi-threaded? Can you give some of the different domains where Python or Java were being used by the community? How would you react when you’re handed a Python project implemented in 2.7? Is, “_Oh yeah, when I said that I was a Python expert, I was referring to Python 3.x exclusively_”, an acceptable response?
-
-### Generalist
-No, I’m not messing with you. Yes, I just said, “_be a specialist_”, and now I’m contradicting myself, telling you to do the opposite. What I’m trying to say is, why not be both? Be a specialist, but at the same time, try to learn and explore the other areas of this whole software development endeavor.
-
-“_Jack of all trades, master of none_” is usually meant to be derogatory. But, when your monolithic production software started crashing in the middle of the day where half of the team is on vacation and the company is losing money and resources as time passes, it’s the jack-of-all-trades who not only knows how the application’s code works but he'll also check the apache server configuration, he can traverse your repo's merge history, analyze your web processes for potential bottlenecks, understand the recent high-level architectural changes that might have contributed to the problem, and has a good grasp of the business to understand it's customer impact. And, more importantly, after finding the problem, this jack-of-all-trades can implement the fix along with test cases, run integration tests, production server deployment, and then proceeds to send out emails detailing what happened with a Root-Cause-Analysis report, while suggesting high-level architectural decisions that might prevent future crashes to the whole organization, written in English, Chinese, Spanish, Elvish, Klingon, Dothraki and five other languages.
-
-
-
-Yes, that’s an exaggeration. I’m not saying you should be a know-it-all, people don’t like know-it-alls. But at least be the person, that when a crucial problem occurs, can quickly grasp the high-level scenario, and can point you at the right direction to focus your analysis, or to the right person that might have the in-depth expertise to figure things out, to ultimately solve the problem at hand.
-
-Yes, I never said it was easy. This has nothing to do with perfectionism either. Don’t limit yourself by some predefined norms. If you don’t want to be a mediocre then start picking up everything that’s useful. You’re not a genius? You’re too old too learn? They said you can’t be both? There’s no such thing as a full-stack developer? 10x developer is a myth? Cats doesn’t have 9 lives? Yeah, uhm.. Cool story bro, but I don’t care. What I care about is, if it’s looks like it would be useful, take it, learn it, move forward. I’m not saying that you should disregard rock-solid science altogether — you know what I mean? I don’t know how to say it, just be a specialist, but at the same time be a generalist as well! Cool? Alright.
-
-### Creative
-
-Creativity is a slightly sensitive topic, it’s generally seen as an abstract quality that you are born with. Being said that, let’s get this out of the way: there’s no such thing as left-brained or right-brained person, it has been debunked by science a long time ago; Creativity isn’t something that you’re either born with or you’re not; Being artistic and being logical aren’t mutually exclusive.
-
-Okay, I may have lied a little. Actually, creativity is something that you’re born with. But with that I mean, everyone is born capable of being creative. It’s just that, you haven’t had the chance to nurture it, then you grew up thinking you were never creative to begin with. Creativity is not exclusive to arts, literature nor music. Creativity is present in everything you do to express yourself, the way you dress, the way you write that letter ‘s’, the way you think, the way you live your life. Almost every man-made thing that we see today is a product of creativity along with necessity, ingenuity and some other stuff. As a human being, we seem to have this urge to create something, convey ourselves in different forms, maybe it’s an extension of communication, an inevitable consequence of evolution.
-
-Programming is a creative pursuit, a craft, but also a science, and that’s what makes it beautiful and fun. Explore different solutions to your problem, have fun, figure out the pros and cons of each solution, try to think about how would you solve the same problem on a different language, think about how other domains solved a similar kind of problem, think about different circumstances your solution might encounter, how would it perform?
-
-> Clean code is simple and direct. Clean code reads like well-written prose. — [Grady Booch](https://twitter.com/Grady_Booch)
-
-### Passionate
-
-This is probably not surprising, and it’s probably getting old already. I wont talk about it too much, you probably read like 100 articles talking about passion already.
-
-The word ‘passion’ seems daunting, even worrying, especially if you don’t feel like this programming thing is really your passion. Passion seems like this thing everybody’s talking about, but nobody actually know what it supposed to look like, and yet it has become a mantra for success that everybody’s chanting. We’re too busy spending a lot of time worrying and looking for passion that we missed a lot of opportunities to be productive.
-
-That was me, until I got tired of screening everything, asking whether it’s aligned to my ‘passion’ before assimilating it in my life, like there was only a limited number rooms from which I can put things.
-
-Let’s do it differently. From now on, apply the general idea of passion to everything you do. Let the quality of your work be the ultimate expression of your life. Put your whole heart even on little things. Sometimes, a simple shift in mindset can lead to a breakthrough.
-
-
-
-### Remarkable
-
-What does it mean to be remarkable, really? By definition it means, ‘_something that is worthy of attention_’. It’s one of those words that you already knew, but you haven’t really paid attention on what it actually entails.
-
-> Remarkable definitely doesn't mean the same thing as good. Usually, products that are remarkable are good. But, products that are good are seldom remarkable. — [Chad Fowler](https://twitter.com/chadfowler), [The Passionate Programmer](https://pragprog.com/book/cfcar2/the-passionate-programmer)
-
-According to Mr. Chad Fowler, (_Notice me senpai! kyaa! *weeaboo intensifies_) You might be the smartest or fastest, but being good isn’t enough. You have to involve yourself in doing something.
-
-Release successful open source software, write books and articles, and aim to speak at conferences, etc. — Are couple of ways to help increase your remarkability as software developer.
-
-It’s definitely not easy to be remarkable (Isn’t that why we’re doing this?), few people managed to be one. It’s a never-ending endeavor. And I think that’s a good thing, it’s something to strive for and to look forward.
-
-
-
-* * *
-
-###### Quick Links
-+ [Overview](blog/codenoobsguide/main)
- + [General Characteristics](blog/codenoobsguide/generalcharacteristics)
- + Runtime Environment
- + Preprocessing
- + In the Zone
- + Coding Principles
- + Design Principles
- + Debugging
- + Interfacing
- + Outer Scope
\ No newline at end of file
+---
+title: CodeNo0b’s Guide out of Mediocrity — General Characteristics
+path: /codenoobs-guide-out-of-mediocrity-genchar
+date: 2017-07-06
+summary: Here I explore some of the key traits for our ideal best version of our developer self. Keep in mind, this isn't a checklist of whether you have it or not. It's a goal that we should always strive to achieve.
+tags: ['software design']
+---
+
+
+_This is part of a series of articles entitled, “CodeNo0b’s Guide out of Mediocrity” — my attempt to create some sort of mental model from the concepts discussed on the classic books of Andy Hunt, Dave Thomas, Chad Fowler, and Robert Martin on a teach-myself manner. Table of contents here: [main()](/codenoobs-guide-out-of-mediocrity-main)_
+
+You must be thinking, “_Oh, yet another list? If I don’t have them, does that mean I’m not cut out for this thing? Oh the horror_.” Or it could be the opposite, “_Oh boy, looks like I’m going to be very successful in the future, I have like 8/10 traits listed here!_”. I used to be like that as well. I read every article that talk about the n traits of `` (eg., fabulous chicken) like a self-evaluation checklist. If I have more than the average, I feel good about myself thinking I have the potential to make it. Sometimes, I low-key wear it in the background to make myself feel good for a few days. Eventually, I got sick of that cycle. I felt like it’s very cheap, lame, and lazy. If you’re like this, it’s probably time to stop. Do something. Stop procrastinating. The world, galaxy, universe, fate, destiny, or whatever, does not owe you anything for you to just wait there and expect something to happen. A potential does not guarantee a success. You actually have to move on your own if you want to transform that potential to kinetic. No one’s really going to do it for you. The best that others can do for you is to just inspire or motivate you, so you can start taking that first step.
+
+That being said, as a first step of your personal transformation, don’t think of this list as a self-evaluation checklist, but think of it more as a to-do list. If you don’t have one, then work on it, be like one. It won’t be easy — being mediocre is what’s easy. If you want to stay mediocre, it’s fine, no one should care. I can’t really say that being one or the other will make your life more fruitful. Who knows? Maybe it doesn’t really matter.
+
+Anyway, enough ranting. Let’s get to it.
+
+### Inquisitive
+
+Be curious. Never stop asking questions, it’s alright if you don’t know the answers right now, set it aside for a while, move on to something else. Eventually, you’ll get back to it and you’ll be able to understand it. It works something like this, every time you gain information by figuring out something, that piece of information contributes to your base knowledge which eventually increases your “figuring out” ability. It’s like agar.io and financial investments. The more money you have, the easier it is for you to earn even more money. Knowledge is also an investment, it compounds. It doesn’t look like it at first, but it will affix all of your current knowledge together, holding them even more intact. The more you acquire bits of information, the more likely for you to easily understand bigger chunks of information in the future.
+
+When I was first learning python years ago, I can’t fully wrap my head around list comprehensions. Sure, I know what it does, I can implement it, but it doesn’t feel very natural to me. I was like, “_what kind of sorcery is this?_” (My primary language before was C and Java, every dynamic language looks like sorcery to me back then.) Time passed, Java 8 happened, it piqued my interest. I was curious on how can you imbue Java, a statically-typed language with functional capabilities.
+
+
+
+
+I quickly got in the habit of using `map()` and `filter()` together with lambdas to manipulate my lists. Passing methods on `map()`, and supplying predicates on `filter()`, became second nature to me.
+
+Months later, I started looking back at my python codes again. Then it hit me, list comprehension is just like, `map()` that wandered at the wrong side of town. Tired, mugged and penniless... * (_insert — long and sweet love story of how he met an equally unfortunate yet very beautiful `filter()` with subtle elegance hidden under her tiredness, yet still looks so strong, but not borderline vegan feminazi ‘strong’. `map()` was captivated, he instantly fell in love. he doesn’t believe in destiny, he’s an agnostic with atheistic tendencies, but he knew it was fate the moment he laid eyes upon her. They eventually got together and lived happily ever after — here_) *
+
+What was I talking about again? Oh yea, I realized that Python’s list comprehension is just like Java’s `map()` and `filter()` method combined in one sweet statement.
+
+```
+nums = range(100)
+evens_squared = [ num**2 for num in nums if num % 2 == 0 ]
+# num**2: could also be any transformation function.
+# num % 2 == 0: is the filter's predicate.
+```
+
+### Realistic
+
+I don’t trust overly optimistic people. You’ve met them, these are the people who has this ‘can-do’ attitude about everything. I’m not saying it’s a bad thing, on the contrary, I admire it, but back your can-do attitude with realism. It’s not bad to be optimistic, but avoid being too optimistic that it hinders effective judgment.
+
+Understand the underlying nature of every problem you encounter. Have a good grasp of the difficulties you might face, and imagine how long things will take. These realistic expectations will serve as your foundation, giving you stamina to keep at it.
+
+You don’t want to take in an endeavor with full glee and a marching band, only to find out that it’s not always peaches and butterflies. It’s actually blood, sweat, tears, inequality, elves hates humans, unicorns aren’t real, jet fuel can’t melt steel beams, Spiderman doesn’t have internal web-shooters by default, Superman is overrated, Han Solo shot first, Gandalf’s a douchebag, some beer tastes like piss water, your Hogwarts letter won’t arrive, nobody’s special, macs are overrated, C is not overrated, you are overrated, overrating stuff is overrated, life is meaningless, our existence’s meaningless, we don’t belong anywhere, and eventually, everybody’s going to die. Reality hits you, leaving you paralyzed and broken, it scarred you for life and you never went for an adventure ever again. If only you weren’t so damn sure of yourself, and actually put in even a little bit of effort to really understand things objectively, you wouldn’t be able to f@#k this sh!t up for you and everyone you care about.
+
+
+
+### Specialist
+
+It’s not enough that you know Java’s syntax, you should at least be able to explain how Java class loader works, or how the high-level memory management is typically being handled by the JVM. If you’re a Python developer take time to understand the nuances between the Python Interpreter and the Python Virtual Machine. At least be aware of the existence of different Python implementations, CPython, IronPython, Jython, PyPy, etc. Is Python multi-threaded? Can you give some of the different domains where Python or Java were being used by the community? How would you react when you’re handed a Python project implemented in 2.7? Is, “_Oh yeah, when I said that I was a Python expert, I was referring to Python 3.x exclusively_”, an acceptable response?
+
+### Generalist
+No, I’m not messing with you. Yes, I just said, “_be a specialist_”, and now I’m contradicting myself, telling you to do the opposite. What I’m trying to say is, why not be both? Be a specialist, but at the same time, try to learn and explore the other areas of this whole software development endeavor.
+
+“_Jack of all trades, master of none_” is usually meant to be derogatory. But, when your monolithic production software started crashing in the middle of the day where half of the team is on vacation and the company is losing money and resources as time passes, it’s the jack-of-all-trades who not only knows how the application’s code works but he'll also check the apache server configuration, he can traverse your repo's merge history, analyze your web processes for potential bottlenecks, understand the recent high-level architectural changes that might have contributed to the problem, and has a good grasp of the business to understand it's customer impact. And, more importantly, after finding the problem, this jack-of-all-trades can implement the fix along with test cases, run integration tests, production server deployment, and then proceeds to send out emails detailing what happened with a Root-Cause-Analysis report, while suggesting high-level architectural decisions that might prevent future crashes to the whole organization, written in English, Chinese, Spanish, Elvish, Klingon, Dothraki and five other languages.
+
+
+
+Yes, that’s an exaggeration. I’m not saying you should be a know-it-all, people don’t like know-it-alls. But at least be the person, that when a crucial problem occurs, can quickly grasp the high-level scenario, and can point you at the right direction to focus your analysis, or to the right person that might have the in-depth expertise to figure things out, to ultimately solve the problem at hand.
+
+Yes, I never said it was easy. This has nothing to do with perfectionism either. Don’t limit yourself by some predefined norms. If you don’t want to be a mediocre then start picking up everything that’s useful. You’re not a genius? You’re too old too learn? They said you can’t be both? There’s no such thing as a full-stack developer? 10x developer is a myth? Cats doesn’t have 9 lives? Yeah, uhm.. Cool story bro, but I don’t care. What I care about is, if it’s looks like it would be useful, take it, learn it, move forward. I’m not saying that you should disregard rock-solid science altogether — you know what I mean? I don’t know how to say it, just be a specialist, but at the same time be a generalist as well! Cool? Alright.
+
+### Creative
+
+Creativity is a slightly sensitive topic, it’s generally seen as an abstract quality that you are born with. Being said that, let’s get this out of the way: there’s no such thing as left-brained or right-brained person, it has been debunked by science a long time ago; Creativity isn’t something that you’re either born with or you’re not; Being artistic and being logical aren’t mutually exclusive.
+
+Okay, I may have lied a little. Actually, creativity is something that you’re born with. But with that I mean, everyone is born capable of being creative. It’s just that, you haven’t had the chance to nurture it, then you grew up thinking you were never creative to begin with. Creativity is not exclusive to arts, literature nor music. Creativity is present in everything you do to express yourself, the way you dress, the way you write that letter ‘s’, the way you think, the way you live your life. Almost every man-made thing that we see today is a product of creativity along with necessity, ingenuity and some other stuff. As a human being, we seem to have this urge to create something, convey ourselves in different forms, maybe it’s an extension of communication, an inevitable consequence of evolution.
+
+Programming is a creative pursuit, a craft, but also a science, and that’s what makes it beautiful and fun. Explore different solutions to your problem, have fun, figure out the pros and cons of each solution, try to think about how would you solve the same problem on a different language, think about how other domains solved a similar kind of problem, think about different circumstances your solution might encounter, how would it perform?
+
+> Clean code is simple and direct. Clean code reads like well-written prose.
+> — [Grady Booch](https://twitter.com/Grady_Booch)
+
+### Passionate
+
+This is probably not surprising, and it’s probably getting old already. I wont talk about it too much, you probably read like 100 articles talking about passion already.
+
+The word ‘passion’ seems daunting, even worrying, especially if you don’t feel like this programming thing is really your passion. Passion seems like this thing everybody’s talking about, but nobody actually know what it supposed to look like, and yet it has become a mantra for success that everybody’s chanting. We’re too busy spending a lot of time worrying and looking for passion that we missed a lot of opportunities to be productive.
+
+That was me, until I got tired of screening everything, asking whether it’s aligned to my ‘passion’ before assimilating it in my life, like there was only a limited number rooms from which I can put things.
+
+Let’s do it differently. From now on, apply the general idea of passion to everything you do. Let the quality of your work be the ultimate expression of your life. Put your whole heart even on little things. Sometimes, a simple shift in mindset can lead to a breakthrough.
+
+
+
+### Remarkable
+
+What does it mean to be remarkable, really? By definition it means, ‘_something that is worthy of attention_’. It’s one of those words that you already knew, but you haven’t really paid attention on what it actually entails.
+
+> Remarkable definitely doesn't mean the same thing as good. Usually, products that are remarkable are good. But, products that are good are seldom remarkable. — [Chad Fowler](https://twitter.com/chadfowler), [The Passionate Programmer](https://pragprog.com/book/cfcar2/the-passionate-programmer)
+
+According to Mr. Chad Fowler, (_Notice me senpai! kyaa! *weeaboo intensifies_) You might be the smartest or fastest, but being good isn’t enough. You have to involve yourself in doing something.
+
+Release successful open source software, write books and articles, and aim to speak at conferences, etc. — Are couple of ways to help increase your remarkability as software developer.
+
+It’s definitely not easy to be remarkable (Isn’t that why we’re doing this?), few people managed to be one. It’s a never-ending endeavor. And I think that’s a good thing, it’s something to strive for and to look forward.
+
+
+
+* * *
+
+###### Quick Links
++ [Overview](/codenoobs-guide-out-of-mediocrity-main)
+ + General Characteristics
+ + Runtime Environment
+ + Preprocessing
+ + In the Zone
+ + Coding Principles
+ + Design Principles
+ + Debugging
+ + Interfacing
+ + Outer Scope
diff --git a/src/blogs/2018/chronocross.md b/blog/2018-08-06-introducing-chronocross.md
similarity index 93%
rename from src/blogs/2018/chronocross.md
rename to blog/2018-08-06-introducing-chronocross.md
index dffa48f..f343f97 100644
--- a/src/blogs/2018/chronocross.md
+++ b/blog/2018-08-06-introducing-chronocross.md
@@ -1,102 +1,107 @@
-# Introducing Chronocross — A Simple Productivity App built on Quasar and Firebase
-###### 6 August 2018
-###### Also published on [Quasar Framework's Medium Publication](https://medium.com/quasar-framework/introducing-chronocross-3139448df974)
-
-From the greek word “_chronos_" which means “_time_", and the latin “_curos_", which means “_to attend_", [Chronocross](https://play.google.com/store/apps/details?id=org.yevlabs.chronocross) is a Todo app that integrates other productivity techniques: The Pomodoro Technique and Eisenhower Matrix, into one cohesive workflow.
-
-In a nutshell, Chronocross is really just a simple tool that I built to complement my workflow. I'm a huge productivity geek. I was hooked on crossing things off a list. I use [Cirillo's Pomodoro Technique](https://francescocirillo.com/pages/pomodoro-technique) to manage procrastination and maintain my focus.
-
-> The Pomodoro Technique® is a time management method that uses a timer to break down your work into intervals, traditionally 25 minutes in length separated by short breaks. — [Wikipedia](https://en.wikipedia.org/wiki/Pomodoro_Technique)
-
-Coupled with another productivity technique, [Eisenhower Matrix](http://eisenhower-matrix.com/) to help me prioritize which task should be worked on first thing in the morning and which should be last. My every working day felt like total bliss.
-
-
-
-Eventually, moving between a todo app, a separate Pomodoro app, and a spreadsheet for my Eisenhower box felt lacking. It felt like it was begging me to integrate them all together into one cohesive app. At this point, I couldn’t really call myself a software developer if I didn’t immediately answer to the calling.
-
-Originally, **Chronocross** was built using Angular. I was learning Angular back then and building an app using it seems like a good practice. But I just did not want to make another web app, because I giving myself a chance to procrastinate by switching and fooling around on other sites would drop my productivity. I decided to use Electron and develop it as a desktop application.
-
-This sounded good at the time, but learning Angular and Electron along with my day-job made it really difficult to accomplish. I was working as a Java developer back then and this was my first time coming back to front-end after the whole JavaScript revolution. I learned the basics: HTML, CSS, JQuery and JavaScript back at the university. But I was in for a surprise. Configuring Electron to work with Angular was a nightmare to my unacquainted mind. Modify tsconfig? and Webpack? Loaders? Install NPM? What? Javascript can access the I/O now? Nodejs?
-
-
-
-I did eventually manage to make it work (somehow). It took me a really long time and countless frustrations to do it; I almost dropped it to use Java and Swing and not bother learning something new that year. Halfway through my feature list I ended up shelving my little pet project.
-
-
-
-Almost a year later, I was working at a different company as a Full-Stack Engineer, whatever that means (I think it means: I know Java and a little bit of HTML), using Angular in the front-end. I started to get that itch of wanting to learn new stuff again. I found myself at the doorsteps of the Vue ecosystem. I knew about Vue even back when I was first learning Angular but since Angular was the company’s choice of framework, I just shrugged it off. IMHO, Vue. Is. Pretty. Freaking. Awesome. The experience was love-at-first-vue-instance.
-
-##### Quasar Framework
-After porting my previous Angular portfolio website to Vue, I ventured farther in the Vue ecosystem's doorsteps and found myself along the valleys of Quasar Framework. I read the docs. And. It. Was. Just. Soooo. good.
-
-
-
-Quasar is a framework that lets you build responsive Single-Page Apps, Server-side Rendered apps, Progressive Web Apps, Hybrid Mobile apps and Electron apps, **all using the same codebase**. Not only that it has a built-in UI library too that comes with Material and IOS theme. This is like a dream. All you ever need to worry about is build your idea, if you do it right, in just a single command you can build your project for other platforms. How awesome is that? I know some people will probably raise an eyebrow when they hear "hybrid Cordova and Electron apps". But in my opinion, Quasar does the job for 90% of the use cases maybe even more. And it's still improving every day.
-
-##### Chronocross 2.0
-I took the opportunity of learning Quasar by getting back at building Chronocross. I decided to build it as a mobile app this time. I wanted to at least have a similar experience of leaving your monitor and keyboard to actually wind up an actual pomodoro or a kitchen timer.
-
-I scrapped my previous designs and started out fresh. For this little app, I decided that I would implement four major features represented by separate tabs: The Pomodoro Tab, Tasks tab, Eisenhower Box tab and the Reports tab.
-
-The Pomodoro tab is a pretty regular timer that you can play, pause, stop and restart. Sprint indicators at the top, A 5 minutes break sprint comes after every 25-minute work sprint. The last break sprint, which I call the long break, is 15 minutes. Of course, these sprint duration could always be tweaked on the settings but those were the traditional duration so I made them default.
-
-
-
-The second tab contains the _Tasks list_. Here you’ll find your tasks. Listed as cards, each card contains some basic info at first glance: task name, priority, and a progress bar that represents the time spent work on the task versus its estimate. There’s a collapsible that contains other information such as the actual estimated time, current progress and a short description. There’s also a list of subtasks in case you feel like breaking the main task into chunks.
-
-
-
-Tapping a task selects it and the previous little FAB turns to an expandable FAB that contains other options. Delete, Edit, Reset (resets the progress back to 0), Mark as done and play. Hitting the play button will run the Pomodoro timer on the selected task, which means all of your work sprint will be recorded on the currently selected task. This will be very useful for tracking. The timer tab can still be used independently if there is no selected task (or you unselect a current task by tapping it again), it will just function as a regular pomodoro timer. To prevent the records from getting corrupted, I disabled the select functionality if the timer is currently active — but it is still possible to check the details of the other tasks.
-
-I used Firebase's [real-time database](https://firebase.google.com/products/realtime-database/) to store all the tasks and progress time records, which is also a pretty convenient service. There's a plugin especially made for vue to make it even more convenient which is called [Vuefire](https://github.com/vuejs/vuefire). And of course, I used it together with [FirebaseAuth](https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth) for login and signup.
-
-I created four cards that represents each Eisenhower quadrant for the third tab. A preview of the tasks was placed under each of the quadrant’s label. These are determined by the priority you chose when creating a task back in the task tab. A high priority task will automatically be categorized as _Urgent_ and _Important_ task.
-
-
-
-Expanding a quadrant will list all the current tasks categorized under it. If you felt like the priority has changed, you can move it to a different quadrant. The same thing could be achieved if you edit the priority back at the tasks tab. But doing so here frames it in an Eisenhower matrix perspective.
-
-
-
-Lastly the final tab is the reports. As a Software Engineer, part of the job entails some paperwork (I bet you didn't expect that), but not the traditional paperwork most desk jobs has. Our version of paperwork has something to do with metrics, task tracking, burndown charts, and other stuff — pretty boring stuff if you're not the manager or the scrum master and you really just don’t care about how fast you’re going, you just want to write code and go home. Let’s admit it though, logging hours on your tasks is pretty boring. It takes away from your momentum when you’re deep in that coding frenzy, implementing features one after another, fixing bugs as fast as you gulp that coffee. Much of the inspiration for this simple app is solely for treating this case. At the end of the day or week, I wanted to see what tasks I’ve worked on for the time period and how long I spent working on them.
-
-
-
-All that’s left to do now is to update those Jira cards at the end of day and my scrum master would be very happy. If ever I forgot to log my work hours on a day, I could still filter the date and choose from the really simple awesome datepicker that quasar provided.
-
-
-
-Sometimes, there are tasks that took longer than a day to finish. Maybe it was big or there were other tasks that needed your attention that you had to park the current task you're working on — I added a task view for that scenario. It's funny how trivial this report charts feature is but I ended up liking it the most.
-
-
-
-I also implemented other features like:
-- Keep awake, prevents your screen from sleeping so you can always see the timer.
-- Background persist, lets you run the app in the background.
-- Local push notifications, displays a notification when the timer’s up when the app is running on the background.
-- Perpetual full screen, I just felt like it feels more “focus-inducing” when the app is in full screen.
-
-To really cap this project off, I signed up for a google developer account in order to publish the app on Google Playstore. You had to pay a $25 one-off registration fee but you can publish as much apps as you like afterwards. It's not that bad of a deal. Publishing the app in google play is pretty straightforward, you fill out all the necessary information upload your APK and then you're done. (Click this [link](https://support.google.com/googleplay/android-developer/answer/7159011#rollout) for more information about rolling out a release) You had to wait for a couple of hours before the app becomes visible on the playstore.
-
-Before uploading the APK, I had to make sure it's signed and zip aligned first. Android requires that all APKs be digitally signed with a certificate before they can be installed. After building my Quasar app using `quasar build -m cordova` the resulting `.apk` will be available on the appropriate release folder (`project-dir/src-cordova/platforms/android/app/build/outputs/apk/release`). I generated my private key using keytool and then used `jarsigner` to sign the package. [`apksigner`](https://developer.android.com/studio/command-line/apksigner) could also be used to achieve the same results. After successfully signing my APK, it's also required to zip align the package or Google Play console will throw an error. I used [`zipalign`](https://developer.android.com/studio/command-line/zipalign) to accomplish this. (If you plan on using `apksigner`, it invalidates the package if you make further changes to the APK, therefore, you must use zipalign *before* signing the package). More information about app signing [here](https://developer.android.com/studio/publish/app-signing).
-
-In just a few hours, Chronocross became visible in the playstore. I informed some of my friends who are also interested with Pomodoro and productivity stuff and gave them the [link](https://play.google.com/store/apps/details?id=org.yevlabs.chronocross).
-
-
-
-I don't really expect it to perform well at the Playstore, I'm just satisfied that I can cross Chronocross out of my unfinished projects list. There are probably tons of improvements that could still be done. I could even generate an electron app out of it, add a report extraction and automate it directly straight to Jira or something. I might update it from time to time if I feel like it, or if some people also found it useful and wanted some more features.
-
-
-
-Overall, I'm quite happy with the experience and I'll probably continue building random apps using Quasar. After all, one of the joys of programming is not always about creating the next successful product. Sometimes, it's about building something that solves one of those small problems that you encounter daily.
-
-
-
-_This article is not affiliated with, associated with, or endorsed by the Pomodoro Technique® or Francesco Cirillo._
-
-
-
-
-
-
-_This article was also published on Quasar Framework's Official Medium [publication](https://medium.com/quasar-framework/introducing-chronocross-3139448df974)._
\ No newline at end of file
+---
+title: Introducing Chronocross - A Simple Productivity App Built on Quasar and Firebase
+path: /introducing-chronocross
+date: 2018-08-06
+summary: From the greek word “chronos“ which means “time“, and the latin “curos“, which means “to attend“, Chronocross is a Todo app that integrates other productivity techniques - The Pomodoro Technique and Eisenhower Matrix, into one cohesive workflow
+tags: ['projects', 'quasar', 'vue']
+---
+
+
+From the greek word “_chronos_" which means “_time_", and the latin “_curos_", which means “_to attend_", [Chronocross](https://play.google.com/store/apps/details?id=org.yevlabs.chronocross) is a Todo app that integrates other productivity techniques: The Pomodoro Technique and Eisenhower Matrix, into one cohesive workflow.
+
+In a nutshell, Chronocross is really just a simple tool that I built to complement my workflow. I'm a huge productivity geek. I was hooked on crossing things off a list. I use [Cirillo's Pomodoro Technique](https://francescocirillo.com/pages/pomodoro-technique) to manage procrastination and maintain my focus.
+
+> The Pomodoro Technique® is a time management method that uses a timer to break down your work into intervals, traditionally 25 minutes in length separated by short breaks. — [Wikipedia](https://en.wikipedia.org/wiki/Pomodoro_Technique)
+
+Coupled with another productivity technique, [Eisenhower Matrix](http://eisenhower-matrix.com/) to help me prioritize which task should be worked on first thing in the morning and which should be last. My every working day felt like total bliss.
+
+
+
+Eventually, moving between a todo app, a separate Pomodoro app, and a spreadsheet for my Eisenhower box felt lacking. It felt like it was begging me to integrate them all together into one cohesive app. At this point, I couldn’t really call myself a software developer if I didn’t immediately answer to the calling.
+
+Originally, **Chronocross** was built using Angular. I was learning Angular back then and building an app using it seems like a good practice. But I just did not want to make another web app, because I giving myself a chance to procrastinate by switching and fooling around on other sites would drop my productivity. I decided to use Electron and develop it as a desktop application.
+
+This sounded good at the time, but learning Angular and Electron along with my day-job made it really difficult to accomplish. I was working as a Java developer back then and this was my first time coming back to front-end after the whole JavaScript revolution. I learned the basics: HTML, CSS, JQuery and JavaScript back at the university. But I was in for a surprise. Configuring Electron to work with Angular was a nightmare to my unacquainted mind. Modify tsconfig? and Webpack? Loaders? Install NPM? What? Javascript can access the I/O now? Nodejs?
+
+
+
+I did eventually manage to make it work (somehow). It took me a really long time and countless frustrations to do it; I almost dropped it to use Java and Swing and not bother learning something new that year. Halfway through my feature list I ended up shelving my little pet project.
+
+
+
+Almost a year later, I was working at a different company as a Full-Stack Engineer, whatever that means (I think it means: I know Java and a little bit of HTML), using Angular in the front-end. I started to get that itch of wanting to learn new stuff again. I found myself at the doorsteps of the Vue ecosystem. I knew about Vue even back when I was first learning Angular but since Angular was the company’s choice of framework, I just shrugged it off. IMHO, Vue. Is. Pretty. Freaking. Awesome. The experience was love-at-first-vue-instance.
+
+##### Quasar Framework
+After porting my previous Angular portfolio website to Vue, I ventured farther in the Vue ecosystem's doorsteps and found myself along the valleys of Quasar Framework. I read the docs. And. It. Was. Just. Soooo. good.
+
+
+
+Quasar is a framework that lets you build responsive Single-Page Apps, Server-side Rendered apps, Progressive Web Apps, Hybrid Mobile apps and Electron apps, **all using the same codebase**. Not only that it has a built-in UI library too that comes with Material and IOS theme. This is like a dream. All you ever need to worry about is build your idea, if you do it right, in just a single command you can build your project for other platforms. How awesome is that? I know some people will probably raise an eyebrow when they hear "hybrid Cordova and Electron apps". But in my opinion, Quasar does the job for 90% of the use cases maybe even more. And it's still improving every day.
+
+##### Chronocross 2.0
+I took the opportunity of learning Quasar by getting back at building Chronocross. I decided to build it as a mobile app this time. I wanted to at least have a similar experience of leaving your monitor and keyboard to actually wind up an actual pomodoro or a kitchen timer.
+
+I scrapped my previous designs and started out fresh. For this little app, I decided that I would implement four major features represented by separate tabs: The Pomodoro Tab, Tasks tab, Eisenhower Box tab and the Reports tab.
+
+The Pomodoro tab is a pretty regular timer that you can play, pause, stop and restart. Sprint indicators at the top, A 5 minutes break sprint comes after every 25-minute work sprint. The last break sprint, which I call the long break, is 15 minutes. Of course, these sprint duration could always be tweaked on the settings but those were the traditional duration so I made them default.
+
+
+
+The second tab contains the _Tasks list_. Here you’ll find your tasks. Listed as cards, each card contains some basic info at first glance: task name, priority, and a progress bar that represents the time spent work on the task versus its estimate. There’s a collapsible that contains other information such as the actual estimated time, current progress and a short description. There’s also a list of subtasks in case you feel like breaking the main task into chunks.
+
+
+
+Tapping a task selects it and the previous little FAB turns to an expandable FAB that contains other options. Delete, Edit, Reset (resets the progress back to 0), Mark as done and play. Hitting the play button will run the Pomodoro timer on the selected task, which means all of your work sprint will be recorded on the currently selected task. This will be very useful for tracking. The timer tab can still be used independently if there is no selected task (or you unselect a current task by tapping it again), it will just function as a regular pomodoro timer. To prevent the records from getting corrupted, I disabled the select functionality if the timer is currently active — but it is still possible to check the details of the other tasks.
+
+I used Firebase's [real-time database](https://firebase.google.com/products/realtime-database/) to store all the tasks and progress time records, which is also a pretty convenient service. There's a plugin especially made for vue to make it even more convenient which is called [Vuefire](https://github.com/vuejs/vuefire). And of course, I used it together with [FirebaseAuth](https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth) for login and signup.
+
+I created four cards that represents each Eisenhower quadrant for the third tab. A preview of the tasks was placed under each of the quadrant’s label. These are determined by the priority you chose when creating a task back in the task tab. A high priority task will automatically be categorized as _Urgent_ and _Important_ task.
+
+
+
+Expanding a quadrant will list all the current tasks categorized under it. If you felt like the priority has changed, you can move it to a different quadrant. The same thing could be achieved if you edit the priority back at the tasks tab. But doing so here frames it in an Eisenhower matrix perspective.
+
+
+
+Lastly the final tab is the reports. As a Software Engineer, part of the job entails some paperwork (I bet you didn't expect that), but not the traditional paperwork most desk jobs has. Our version of paperwork has something to do with metrics, task tracking, burndown charts, and other stuff — pretty boring stuff if you're not the manager or the scrum master and you really just don’t care about how fast you’re going, you just want to write code and go home. Let’s admit it though, logging hours on your tasks is pretty boring. It takes away from your momentum when you’re deep in that coding frenzy, implementing features one after another, fixing bugs as fast as you gulp that coffee. Much of the inspiration for this simple app is solely for treating this case. At the end of the day or week, I wanted to see what tasks I’ve worked on for the time period and how long I spent working on them.
+
+
+
+All that’s left to do now is to update those Jira cards at the end of day and my scrum master would be very happy. If ever I forgot to log my work hours on a day, I could still filter the date and choose from the really simple awesome datepicker that quasar provided.
+
+
+
+Sometimes, there are tasks that took longer than a day to finish. Maybe it was big or there were other tasks that needed your attention that you had to park the current task you're working on — I added a task view for that scenario. It's funny how trivial this report charts feature is but I ended up liking it the most.
+
+
+
+I also implemented other features like:
+- Keep awake, prevents your screen from sleeping so you can always see the timer.
+- Background persist, lets you run the app in the background.
+- Local push notifications, displays a notification when the timer’s up when the app is running on the background.
+- Perpetual full screen, I just felt like it feels more “focus-inducing” when the app is in full screen.
+
+To really cap this project off, I signed up for a google developer account in order to publish the app on Google Playstore. You had to pay a $25 one-off registration fee but you can publish as much apps as you like afterwards. It's not that bad of a deal. Publishing the app in google play is pretty straightforward, you fill out all the necessary information upload your APK and then you're done. (Click this [link](https://support.google.com/googleplay/android-developer/answer/7159011#rollout) for more information about rolling out a release) You had to wait for a couple of hours before the app becomes visible on the playstore.
+
+Before uploading the APK, I had to make sure it's signed and zip aligned first. Android requires that all APKs be digitally signed with a certificate before they can be installed. After building my Quasar app using `quasar build -m cordova` the resulting `.apk` will be available on the appropriate release folder (`project-dir/src-cordova/platforms/android/app/build/outputs/apk/release`). I generated my private key using keytool and then used `jarsigner` to sign the package. [`apksigner`](https://developer.android.com/studio/command-line/apksigner) could also be used to achieve the same results. After successfully signing my APK, it's also required to zip align the package or Google Play console will throw an error. I used [`zipalign`](https://developer.android.com/studio/command-line/zipalign) to accomplish this. (If you plan on using `apksigner`, it invalidates the package if you make further changes to the APK, therefore, you must use zipalign *before* signing the package). More information about app signing [here](https://developer.android.com/studio/publish/app-signing).
+
+In just a few hours, Chronocross became visible in the playstore. I informed some of my friends who are also interested with Pomodoro and productivity stuff and gave them the [link](https://play.google.com/store/apps/details?id=org.yevlabs.chronocross).
+
+
+
+I don't really expect it to perform well at the Playstore, I'm just satisfied that I can cross Chronocross out of my unfinished projects list. There are probably tons of improvements that could still be done. I could even generate an electron app out of it, add a report extraction and automate it directly straight to Jira or something. I might update it from time to time if I feel like it, or if some people also found it useful and wanted some more features.
+
+
+
+Overall, I'm quite happy with the experience and I'll probably continue building random apps using Quasar. After all, one of the joys of programming is not always about creating the next successful product. Sometimes, it's about building something that solves one of those small problems that you encounter daily.
+
+
+
+_This article is not affiliated with, associated with, or endorsed by the Pomodoro Technique® or Francesco Cirillo._
+
+
+
+
+
+
+_This article was also published on Quasar Framework's Official Medium [publication](https://medium.com/quasar-framework/introducing-chronocross-3139448df974)._
diff --git a/src/blogs/2018/weird-js.md b/blog/2018-09-15-weird-js.md
similarity index 97%
rename from src/blogs/2018/weird-js.md
rename to blog/2018-09-15-weird-js.md
index bb9462a..d3cb10c 100644
--- a/src/blogs/2018/weird-js.md
+++ b/blog/2018-09-15-weird-js.md
@@ -1,1517 +1,1525 @@
-# Javascript: The Weird Parts
-###### 15 September 2018
-
-Javascript is weird, let's get that out of the way. Still, it's not like Javascript is illogical, in fact, most of it's weirdness is a side effect of its power while coping up with programmers' whims. But once you understand why it does what it does, we'll realize that it's not that complex after all. All languages has its own fair share of quirks and nuances that we just have to learn.
-
-This article/guide is my transcription of Anthony Alicea's lecture entitled: Javascript - Understanding the Weird Parts. I expounded and added additional explanation on topics where I felt like more examples and details are necessary. This is not for people new to Javascript, it's more for people who are familiar with Javascript, but still have huge knowledge gaps. After reading this and you still crave for more, I highly recommend reading [Eloquent Javascript](https://eloquentjavascript.net) by Marijn Haverbeke (_saying the word "eloquent" makes you feel 10x smarter already, but not as much as the word "quintessential"_) and Kyle Simpson's [You Dont Know JS](https://github.com/getify/You-Dont-Know-JS) is also one of the best.
-
-
-
-## Syntax Parser
-A program that reads code and determines what it does and if it's grammar valid.
-
-## Lexical Environment
-Where something sits physically in the code you write. It determines how a piece of code will interact with other elements of the code. The Syntax parser makes decisions based from where a code is placed.
-
-## Execution Context
-A wrapper to help manage the code that is running. It contains some metadata, some elements that you didn't write. Javascript attaches the `this` and `outerEnvironment` that your code has access to while it runs.
-
-## The Global Execution Context.
-Everytime a function is run, a new execution context is being created. The global execution context is the root context, the main context where there is no other else that's running.
-
-> What's executing isn't what you've written, it's being processed by the javascript engine beforehand.
-
-### Global Object
-Is the object every running javascript code has, the object associated with the global execution context. You can reference it by the special/keyword variable `this` on the root context or by the variable `window` (if you're using node, V8 engine's version is the variable `global`).
-
-```javascript
-// At the root context (not inside a function)
-window === this
-```
-
-Defining a variable and function will attach it to the current execution context.
-
-### Hoisting
-The process at which the memory space of variables and functions are setup.
-
-The execution is created in two phases:
-
-##### Creation Phase
-The phase where `this` and the `outerEnvironment` is created while also setting up the variables and functions' memory space placing on the `variable environment`, together they are what we refer to as the execution context.
-
-One little caveat for variables: Variables are attached to execution context with a placeholder value called `undefined`, the actual value is determined on the execution phase. Functions, on the other hand get attached as is and ready for invocation.
-
-##### Execution Phase
-Javascript runs your code line by line. Variables' values are resolved based on the result of the expressions.
-```javascript
-var a = 'Hello world';
-
-function b() {
- console.log('Called b!');
-}
-
-b();
-console.log(a);
-```
-will output:
-```
-Called b!
-Hello world
-```
-Consider the following code below that in most programming languages will throw an error:
-```javascript
-b();
-console.log(a);
-
-var = a 'Hello world';
-
-function b() {
- console.log('Called b!');
-}
-```
-will output
-```
-Called b!
-undefined
-```
-Noticed how `b()` was still executed properly while `a` is also available, albeit a different value.
-
-On the creation phase, the javascript engine checks the code and for every variable declaration (eg: `var`) it sets up memory and attaches it on the execution context. The value is then resolved on the execution phase.
-
-```javascript
-b();
-console.log(a);
-var a = 'Hello world';
-console.log(a);
-function b() {
- console.log('Called b!');
-}
-```
-```
-Called b!
-undefined
-Hello world
-```
-
-### Single Threaded and Synchronous
-The Javascript language is single threaded which means, command is being ran one at a time (under the hood, the browser maybe not) and synchronous which means, in order. Code is being ran one at a time and in order.
-
-### The Execution Stack
-Everytime a function is invocated, a new execution context is created and is placed on top of the execution stack, whichever is on top is the one currently running, once it finishes, it gets popped off the stack.
-
-Which means, each function call gets its own separate and independent execution context, and its own `this`. Note that, the `variable environment` is not the same with `this`.
-
-```javascript
-function b() {
- var myVar;
- console.log(myVar);
-}
-
-function a() {
- var myVar = 2;
- console.log(myVar);
- b();
-}
-
-var myVar = 1;
-console.log(myVar);
-a();
-console.log(myVar);
-```
-Will give the following result:
-```
-1
-2
-undefined
-1
-```
-
-### The Outer Environment
-In every execution context, there's a reference to the outer environment. If a certain variable is not found in the current `variable environment`, Javascript will look for it at the outer environment which refers to the `variable environment` of the one that created it, this does **NOT** refer to the previous execution context on the stack but from it's lexical environment, or the execution environment of where it was written.
-```javascript
-function b() {
- console.log(myVar);
-}
-
-function a() {
- var myVar = 2;
- b();
-}
-
-var myVar = 1;
-a();
-```
-The output is:
-```
-1
-```
-In this example the outer environment of both `a()` and `b()` is the same, which is the global or root environment.
-```javascript
-function a() {
-
- function b() {
- console.log(myVar);
- }
-
- var myVar = 2;
- b();
-}
-
-var myVar = 1;
-a();
-```
-Now, in this example `b`'s outer environment is `a`'s, while `a`'s outer environment is the global environment. Hence, the output is:
-```
-2
-```
-
-Also note that in the global scope, the `variable environment` resides in the global (`window`) object. We can't directly access or inspect the `variable environment` of a function's execution context but we can for the root global context because it's attached to the global object. Moreover, in the global execution context `this` === global (`window`) object.
-
-It's a bit confusing but just remember that in the global execution context, we could roughly consider the `variable environment`, `this` and the `outer environment` to be on the same place which is the global `window` object.
-
-##### Let
-The block-scoping variable declaration of Javascript ES6. The variable is only available on it's own block.
-```javascript
-if (a > b) {
- let c = true;
-}
-console.log(c);
-```
-```
-undefined
-```
-
-### Primitive Types
-A type of data that represents a single value. The atomic unit that make up an object.
-1. `undefined`
-2. `null`
-3. Boolean - `true` or `false`
-4. Number - a floating-point, there's always some decimals. `123`
-5. String - a sequence of characters. `string`
-6. Symbol - Introduced in es6.
-
-### Operator
-A special function that accepts an argument and returns a value that is just syntactically or written differently. `+`, `-`, `*`, `/`, (and etc) are just functions with special characters that are written in an infix notation instead of postfix are prefix like normal functions. ie: `+(a, b)`
-
-#### Operator precedence
-Which operator function gets executed first if there's more than one in the same line of executable code. The higher precedence gets executed first.
-```javascript
-var a = 3 + 4 * 5; // (4 * 5) first. Pretty basic
-```
-
-#### Associativity
-When operators have the same precedence, the order from which they get called is the associativity. Left-to-right or right-to-left associativity.
-
-```javascript
-var a = 2, b = 3, c = 4;
-a = b = c;
-console.log(a); // 4
-console.log(b); // 4
-console.log(c); // 4
-```
-The `=` operator has *right-to-left* associativity. Here's what actually happened.
-```javascript
-// eq(a, eq(b, c))
-a = b = c
-a = (b = c)
-a = (4)
-```
-
-| Precedence | Operator Type | Associativity | Individual Operator |
-| ----------- | ----------------------------- | ------------- | ------------------- |
-| 20 | Grouping | n/a | `( … )` |
-| 19 | Member Access | left-to-right | …` . `… |
-| | Computed Member Access | left-to-right | `…[…]` |
-| | `new`(with argument list) | n/a | `new … (…)` |
-| | Function call | left-to-right | `… (…)` |
-| 18 | `new`(without argument list) | right-to-left | `new …` |
-| 17 | Postfix Increment | n/a | `…++` |
-| | Postfix Decrement | | `…--` |
-| 16 | Logical NOT | right-to-left | `!…` |
-| | Bitwise NOT | | `~…` |
-| | Unary Plus | | `+…` |
-| | Unary Negation | | `-…` |
-| | Prefix Increment | | `++…` |
-| | Prefix Decrement | | `--…` |
-| | typeof | | `typeof …` |
-| | void | | `void …` |
-| | delete | | `delete …` |
-| | await | | `await …` |
-| 15 | Exponentiation | right-to-left | `… ** …` |
-| 14 | Multiplication | left-to-right | `… * …` |
-| | Division | | `… / …` |
-| | Remainder | | `… % …` |
-| 13 | Addition | left-to-right | `… + …` |
-| | Subtraction | | `… - …` |
-| 12 | Bitwise Left Shift | left-to-right | `… << …` |
-| | Bitwise Right Shift | | `… >> …` |
-| | Bitwise Unsigned Right Shift | | `… >>> …` |
-| 11 | Less Than | left-to-right | `… < …` |
-| | Less Than or Equal | | `… <= …` |
-| | Greater Than | left-to-right | `… > …` |
-| | Greater Than or Equal | | `… >= …` |
-| 10 | Equality | left-to-right | `… == …` |
-| | Inequality | | `… != …` |
-| | Strict Equality | | `… === …` |
-| | Strict Inequality | | `… !== …` |
-| 9 | Bitwise AND | left-to-right | `… & …` |
-| 8 | Bitwise XOR | left-to-right | `… ^ …` |
-| 7 | Bitwise OR | left-to-right | `… | …` |
-| 6 | Logical AND | left-to-right | `… && …` |
-| 5 | Logical OR | left-to-right | `… || …` |
-| 4 | Conditional | right-to-left | `… ? … : …` |
-| 3 | Assignment | right-to-left | `… = …` |
-| | | | `… += …` |
-| | | | `… -= …` |
-| | | | `… **= …` |
-| | | | `… *= … ` |
-| | | | `… /= … ` |
-| | | | `… %= … ` |
-| | | | `… <<= … ` |
-| | | | `… >>= … ` |
-| | | | `… >>>= … ` |
-| | | | `… &= … ` |
-| | | | `… ^= … ` |
-| | | | `… |= … ` |
-| 2 | yield | right-to-left | `yield …` |
-| | yield* | | `yield* …` |
-| 1 | Comma / Sequence | left-to-right | `… , …` |
-
-
-
-#### Type Coercion
-Because Javascript is dynamically-typed, it automatically converts or attempts to convert a value from one type to another.
-
-```javascript
-var a = 1 + '2'; // '12'
-```
-The value `1` was coerced into a `String` by the javascript engine.
-
-Here's a more compelling example:
-
-```javascript
-1 < 2 < 3 // true
-3 < 2 < 1 // true, why??
-```
-The `<` operator has the same precedence with a *left-to-right* associavity. Which means:
-```javascript
-3 < 2 < 1
-(3 < 2) < 1
-false < 1 // false gets coerced into a number = 0
-0 < 1
-true
-```
-Which means, the same applies to `1 < 2 < 3`, `false < 3`, `1 < 3`. Type coercion can cause a lot of problems when you don't know what's going on.
-
-##### Equality Comparisons and Sameness
-Notice how type coercion can affect equality operators that results to weird behaviors
-```javascript
-3 == 3 // true
-"3" == 3 // true
-false == 0 // true
-null < 1 // true because null coerces to 0 < 1
-null == 0 // false
-"" == 0 // true
-"" == false // true
-```
-Strict equality `===`, it compares two values but doesn't try to coerce any of them.
-```javascript
-3 === 3 // true
-"3" === "3" // true
-"3" === 3 // false
-```
-
-##### Sameness Comparisons
-| x | y | == | === | Object.is |
-| :----------------- | :---------------- | :---: | :---: | :-------: |
-| undefined | undefined | true | true | true |
-| null | null | true | true | true |
-| true | true | true | true | true |
-| false | false | true | true | true |
-| 'foo' | 'foo' | true | true | true |
-| 0 | 0 | true | true | true |
-| +0 | -0 | true | true | false |
-| +0 | 0 | true | true | true |
-| -0 | 0 | true | true | false |
-| 0 | false | true | false | false |
-| "" | false | true | false | false |
-| "" | 0 | true | false | false |
-| '0' | 0 | true | false | false |
-| '17' | 17 | true | false | false |
-| [1, 2] | '1,2' | true | false | false |
-| new String('foo') | 'foo' | true | false | false |
-| null | undefined | true | false | false |
-| null | false | false | false | false |
-| undefined | false | false | false | false |
-| { foo: 'bar' } | { foo: 'bar' } | false | false | false |
-| new String('foo') | new String('foo') | false | false | false |
-| 0 | null | false | false | false |
-| 0 | NaN | false | false | false |
-| 'foo' | NaN | false | false | false |
-| NaN | NaN | false | false | true |
-
-##### Existence and Booleans
-Javascript coerces `undefined`, `null`, `""` to `false`. Hence, we could write simple `if` conditions like this:
-```javascript
-var a;
-// goes to internet to check some value
-if (a) { // if it exists
- console.log('Something is there');
-}
-```
-One caveat though, `0` coerces to `false` as well, hence if in the above code `a` was `0`, the behavior is not valid anymore. That's why people often do something like this:
-```javascript
-if (a || a === 0) {
- console.log('Somethign is there');
-}
-```
-Just never check existence in this way if you expect the value could be `0`.
-
-##### Default Values
-Using type coercion and operator precedence, there's a common trick being used to create default values.
-
-```javascript
-function greet(name) {
- name = name || '';
- console.log('Hello ' + name);
-}
-greet();
-greet('Feynman');
-```
-
-This works because `||` operator doesn't just return `true` or `false` but it actually returns the value that can be coerced to `true`.
-```javascript
-undefined || 'hello' // hello
-null || 4 // 0
-```
-In es6, there's a different way of assigning default value but this trick is still common and could be used not just in function parameters.
-
-```javascript
-function greet(name='Your name here') {
- console.log('Hello ' + name);
-}
-```
-
-### Objects
-Objects in Javascript is the same as what you expect from other languages. It's a container of primitives and other objects, which can be accessed by `.` or `[]`. The dot `.` operator and the computed member access `[]` have the same precedence and associativity.
-
-```javascript
-var person = new Object();
-person['firstname'] = 'Sherlock';
-person['lastname'] = 'Holmes';
-
-var firstNameProperty = 'firstname';
-
-console.log(person);
-console.log(person[firstNameProperty]);
-
-console.log(person['lastname']);
-console.log(person.firstname);
-
-person.address = new Object();
-person.address.street = '221B Baker Street';
-person.address.city = 'London';
-person.address.country = 'United Kingdom';
-
-console.log(person.address.street);
-console.log(person['address']['city']);
-console.log(person.address['country']);
-
-// via object literal
-var sherlock = {
- firstname: 'Sherlock',
- lastname: 'Holmes',
- address: {
- street: '221B Baker Street',
- city: 'London',
- country: 'United Kingdom'
- };
-};
-
-
-function greet(person) {
- console.log('Hi ' + person.firstname);
-}
-
-greet(sherlock);
-greet({
- firstname: 'John',
- lastname: 'Watson'
-});
-
-```
-
-### Functions
-In Javascript, everything is either an object or a primitive. Functions are treated like usual objects as well, they could be assigned to variables, passed around, or created on the fly. Javascript functions are first-class functions.
-
-Think of functions as special type of object that can have properties but functions also has an invocable special property called `code` and a string property called `name`.
-
-```javascript
-function greet() {
- console.log('hi');
-}
-
-greet.language = 'english';
-greet.hey = function () {
- console.log('hey');
-}
-
-console.log(greet.language);
-console.log(greet.hey());
-```
-
-#### Function Statement
-A **Statement** is a unit of code that when executed doesn't result in a value.
-```javascript
-
-if (true == true) { // this is an if statement
-
-}
-
-// function statement, it will be executed
-// and created a spot in memory for greet
-function greet() {
- console.log('hi');
-}
-
-greet();
-```
-
-#### Function Expression
-
-An **Expression** is a unit of code that results in a value. `a = 1` is an expression, so is `x || 2`.
-
-```javascript
-// This is a function expression
-// This will return a function.
-function() {
- console.log('hi');
-}
-
-// That's why we could do this:
-var greet = function() {
- console.log('hi');
-}
-// essentially the same with:
-var greet = function greetMe() {
- console.log('hi');
-}
-// But since greetMe will just be reassigned to greet, it's optional.
-```
-Consider the following code, taking into account what we've learned about **hoisting**.
-```javascript
-greet(); // called and then defined.
-function greet() {
- console.log('greet');
-}
-
-newGreet();
-var newGreet = function() {
- console.log('hello');
-}
-```
-`newGreet()` will throw an error. `newGreet` is a value, and in creation phase, it will be assigned to `undefined` when the memory space was set up for it. The value is function but it will be resolved when that line was executed.
-
-Moreover, since functions are also treated as an object we could create one on the fly and pass it as an argument to other functions.
-```javascript
-function invoker(a) {
- a();
-}
-
-function invoker(function(){
- console.log('sup?');
-});
-```
-##### Passing by Value and by Reference
-In Javascript when a primitive value is reassigned or passed to a function as an argument, the copy of the said value is created to be used inside the function - this called *pass by value*. But when an object is reassigned or passed as an argument, what is being used is the actual reference to the object, not a copy. Which means, changing the value of object within the function will also change the original value - this called *pass by reference*.
-
-```javascript
-// by value
-var a = 2;
-var b = a;
-b = 3;
-
-console.log(a); // 2
-console.log(b); // 3
-
-// by reference
-var c = { greeting: 'hi' };
-var d = c;
-
-c.greeting = 'hello';
-
-console.log(c.greeting); // 'hello'
-console.log(d.greeting); // 'hello'
-
-```
-Note that an assignment `=` operator also creates a new memory space, a different memory address for the said value. Hence the following code behaves as follows:
-```javascript
-var c = { greeting: 'hi' };
-var d = c;
-
-c = { greeting: 'hello' };
-console.log(d.greeting); // hi
-console.log(c.greeting); // hello
-```
-
-#### The `this` keyword
-We've learned that when a function is invoked, a new execution context is created and put on top of the stack. The execution context has it's own `variable environment`, `outer environment` and `this`.
-
-`this` is an object that points to a different thing depending on where it was called. In other words, `this` is dynamically bound.
-
-```javascript
-
-function a() {
- console.log(this);
- this.greet = 'hello';
-}
-
-var b = function() {
- console.log(this);
-}
-
-// console.log(greet) // will throw an error, not yet defined
-console.log(this);
-a(); // points to the global object
-b(); // points to the global object
-console.log(greet); // 'hello'
-
-var c = {
- name: 'The c object',
- log: function() {
- this.name = 'updated c object';
- console.log(this); // no longer points to the global object
- }
-}
-
-c.log(); // { name: 'updated c object', log: function }
-```
-This will make total sense if you have something like this:
-```javascript
-var sayMyName = function() {
- console.log('Hello there, ' + this.name);
-}
-
-var holmes = {
- name: 'Sherlock',
- greet: sayMyName
-}
-
-var watson = {
- name: 'John',
- greet: sayMyName
-}
-
-holmes.greet(); // 'Hello there, Sherlock'
-watson.greet(); // 'Hello there, John'
-
-```
-The `this.a` in `sayMayName` refers to the particular object it's attached to on the time it was called. Always remember, `this` always refers to an object. But now consider the following:
-```javascript
-var d = {
- name: '',
- fun: function () {
- this.name = 'Holmes'
-
- var setName = function(newName) {
- this.name = newName;
- }
- setName('Watson');
- }
-}
-
-d.fun();
-console.log(d.name); // Holmes
-console.log(name); // Watson
-```
-
-What happened? When `setName` was called inside `d.fun`, the `this` operator is now pointing to the global object. The object that `this` was referring to was lost and defaulted back to the global object.
-
-To understand this, remember that `this` is always bound to the object that called it. `d.fun()`, `fun`'s `this` is bound to `d`, but right before `fun()` finished executing, `setName()` was invoked but isn't bound to any object (it was invoked by `fun`, but `fun` is not an object), hence it got thrown off to the global object.
-
-A common solution for solving this problem is usually done by exploiting the concept of how the execution context behaves when it can't find a certain variable, it goes out to the outer environment that points to its parent lexical context until it finds it.
-```javascript
-var e = {
- name: '',
- fun: function () {
- var self = this
- self.name = 'Holmes'
-
- var setName = function(newName) {
- self.name = newName;
- }
- setName('Watson');
- }
-}
-
-e.fun();
-console.log(e.name); // Watson
-// console.log(name); // Error
-```
-When `setName` executes, `self` is not present in it's `variable environment`, so it goes to look on the `outer environment` which happens to point to `fun`'s execution context, where it finds `self`. `setName` is written inside `fun` that's why the `outer environment` points to `fun` and not because it's right below `setName`'s execution context on the execution stack.
-
-There are other ways to get around and explicitly bind `this` to certain object by using Javascript's built-in methods, `call()`, `apply()` and `bind()`.
-
-#### `call()`, `apply()` and `bind()`
-Whenever a Javascript function is created, each function gets `call()`, `apply()` and `bind()` attached to them by the Javascript engine as properties that we have access to. The `this` keyword is bound to the object where it was invoked, if there's no such object, the binding is lost and `this` binds to the default binding, which is the `global` object (`undefined` when on _strict mode_). But using said functions we could explicitly bind `this` to whatever object we like.
-
-##### `call()`
-Invokes the target function binding the reference to `this` to the given first parameter.
-```javascript
-var person = {
- name: 'Sherlock Holmes',
- log: function() {
- console.log(this.name);
- }
-}
-
-var logFn = person.log;
-
-var person2 = {name: 'John Watson'};
-logFn.call(person2);
-```
-```
-John Watson
-```
-
-##### `apply()`
-With respect to `this` binding, `call(..)` and `apply(..)` are identical. They do behave differently when used with their additional parameters.
-```javascript
-var sherlock = {
- firstName: 'Sherlock',
- lastName: 'Holmes',
- getFullName: function() {
- return this.firstName + ' ' + this.lastName;
- }
-}
-
-var watson = {
- firstName: 'John',
- lastName: 'Watson',
- getFullName: function() {
- return this.firstName + ' ' + this.lastName;
- }
-}
-
-var wrappedLog = function (a, b) {
- console.log(this.getFullName())
- console.log(a, b);
- console.log('------');
-}
-console.log(sherlock.getFullName());
-console.log('------');
-wrappedLog.call(watson, 'arg1', 'arg2');
-// wrappedLog.apply(watson, 'arg1', 'arg2'); // will throw an error
-wrappedLog.apply(watson, ['arg1', 'arg2']);
-```
-```
-Sherlock Holmes
-------
-John Watson
-arg1 arg2
-------
-John Watson
-arg1 arg2
-------
-```
-
-`apply()` just unrolls its array arguments and provide it as the `targetFn`'s arguments. It doesn't seem useful at first glance but it's very convenient if you are doing some array manipulations and you want the result to be used as arguments for a generic target function.
-
-```javascript
-function someFrameworkTask = function(targetFn, targetOb, arrArgs) {
- // Do some work on arrArgs
- arrArgs.push(...);
- arrArgs.splice(...);
- // targetFn.call(targetOb, arr[0], arr[1], ...arr[2]); // we have to know how many arguments targetFn has beforehand
- targetFn.apply(targetOb, arr);
-}
-```
-
-###### Hard Binding
-Explicit binding is cool but what if we wanted a certain function to be permanently bound to a specific `this` without worrying that it could be modified someplace else.
-```javascript
-var sherlock = {
- firstName: 'Sherlock',
- lastName: 'Holmes',
- getFullName: function() {
- return this.firstName + ' ' + this.lastName;
- }
-}
-
-var watson = {
- firstName: 'John',
- lastName: 'Watson',
- getFullName: function() {
- return this.firstName + ' ' + this.lastName;
- }
-}
-
-var logName = function() {
- console.log(this.getFullName());
-}
-
-var hardbound = function() {
- logName.call(sherlock);
-}
-
-hardbound();
-hardbound.call(watson);
-hardbound.apply(watson);
-```
-```
-Sherlock Holmes
-Sherlock Holmes
-Sherlock Holmes
-```
-We created a `hardbound` variable whose value is just a function that wraps a `call` invocation, explicitly binding it to `sherlock`. When `hardbound()` is invoked, it's the same as calling `call(sherlock)`, but this wrapping mechanism that we have implemented has made the binding permanent. Invoking `hardbound.call(watson)` would only bind `this` to the anonymous wrapper function that will just be ignored when `logName.call(sherlock)` is invoked.
-
-This hard binding is so common that it was also provided by the Javascript engine called `bind()`. Of course its implementation is far more robust and less error prone than ours.
-
-
-##### `bind()`
-`bind()` on the other hand, takes an object as a parameter and then returns a new function where `this` is hard bound to the said object.
-```javascript
-var sherlock = {
- name: 'Sherlock Holmes',
- log: function() {
- console.log(this.name);
- }
-}
-
-var watson = { name: 'John Watson'};
-
-var logName = sherlock.log.bind(watson);
-
-logName();
-logName.bind(sherlock)();
-```
-```
-John Watson
-John Watson
-```
-
-Note that it's still possible to change this binding if we used the keyword `new` that we'll explore in a different chapter.
-
-##### Function Currying
-Passing parameters to `bind()` does something interesting, it gave us the ability to curry. Currying is creating a copy of a function with some preset parameter values or partial application of parameters.
-```javascript
-function power(base, exponent) {
- return base ** exponent;
-}
-
-var square = power.bind(this, 2);
-
-square(2); // 4
-square(5); // 32
-```
-In this example, we're not after the `this` binding so we could just bind it to the global object, we're not using it anyway. We're more interested on how we can use currying if we pass more arguments to `bind`. Passing `2` on `power.bind(this, 2)` would make `square` a `power()` function that have it's `base` parameter permanently set to the value `2`. We say that `square` is a `power()` function whose arguments are partially applied.
-
-Supplying more parameters to bind would just fill the arguments of the target function.
-
-```javascript
-var four = power.bind(this, 2, 2);
-four(5); // 4. 5 will be passed as the 3rd parameter that we're just ignoring.
-```
-
-Currying, is widely used in Functional style of programming. We could also create the same behavior by exploiting closures that will be discussed in the next sections.
-
-##### Function Overloading
-Javascript has no function overloading capabilities because functions are treated as objects, unlike in other languages. Javascript doesn't care about the number of parameters, it just care about the name of the function you're trying to invoke. If your function expect 2 parameters but you only pass 1 argument, the second parameter will be `undefined`. Likewise, if you expect 2 parameters and you pass 3 arguments, you'll just have no straightforward way to access the third parameter (unless you access the built-in `arguments` property a functions have). It's still possible to convey a somewhat cleaner overloading concept by utilizing default parameters:
-
-```javascript
-function greet(firstName, greeting = "Hi", question="How are you?") {
- return `${greeting} ${firstName}! ${question}`;
-}
-
-greet('John'); // "Hi John! How are you?
-greet('John', 'Hey'); // "Hey John! How are you?"
-greet('John', 'Hey', 'Sup?'); // "Hey John! Sup?"
-```
-
-#### Immediately-Invoked Function Expressions (IIFE)
-An anonymous function expression that was being immediately invoked upon load.
-```javascript
-function greet(name) { // Function statement
- console.log('Hello ' + name);
-};
-
-var greetFun = function(name) { // Function expression
- console.log('Hello ' + name);
-};
-
-var greeting = function(name) { // Immediately-invoked function expression
- return 'Hello ' + name;
-}('John');
-
-console.log(greeting); // 'Hello John' - Holds the result of the IIFE
-
-// function(name) { // Will throw an error
-// console.log('Hello ' + name); // Syntax parser expects
-// } // a function name
-
-(function(name){
- console.log('Hi ' + name);
-}('John'));
-```
-IIFE's are widely used among javascript frameworks and libraries for initialization while managing namespace collisions.
-```javascript
-// defined in someplace else ie: foo.js
-var greeting = 'Hola'; // Bound to global
-
-// somewhere in another file ie: greet.js
-(function() {
- var greeting = 'Hello';
- console.log(greeting);
-}());
-console.log(greeting);
-```
-```
-Hello
-Hola
-```
-
-#### Function Constructors with `new`
-Functions that are used to construct objects together with `new` operator. These functions are normal functions but when `new` is applied to them, Javascript engine does something different, it creates an empty `this` object and returns it.
-```javascript
-function Foo() {
- this.hello = 'hey';
-}
-
-var f = new Foo();
-console.log(f);
-```
-```
-f {
- hello: 'hey'
-}
-```
-But still, don't forget that these are still normal functions. When invoked without `new`, `this` would refer to the global object like what we've learned. That's why it's a convention that any function intended to use as function constructors should always start with capital letters.
-```javascript
-function Foo(){
- console.log(this);
-}
-Foo();
-new Foo();
-var f = Foo();
-console.log(f); // undefine because Foo() was invoked as a function
-```
-```
-Window {...}
-Foo {}
-undefined
-```
-That being said, when creating objects using `new` don't return anything on the function constructor or it will mess up the javascript engine's decision making.
-```javascript
-function Foo(greeting) {
- this.greet = greeting;
- return {
- b: 'azinga'
- }
-}
-
-var f = new Foo('hello');
-console.log(f);
-```
-```
-{b: 'azinga'}
-```
-
-#### Built-in Function Constructors
-Some of the most common objects has built-in function constructors shipped together with Javascript. Almost all primitive values has a wrapper object counterparts that includes some added properties and methods.
-```javascript
-var num = new Number(3.14151629);
-num.toFixed(2);
-
-var tesla = new String("Nikola Tesla");
-tesla.toLowerCase();
-```
-Just a word of caution, be careful in using these wrapper objects because it can cause bugs specially when it comes to comparisons where coercion is taking place.
-```javascript
-var meaningOfLife = 42;
-var is42 = new Number(42);
-
-console.log(meaningOfLife == is42); // true
-console.log(meaningOfLife === is42); // false
-```
-
-#### Determining `this`
-We've seen how `bind`, `call` and `apply` work but what happens when `new` is applied into the mix?
-```javascript
-var og = {
- greet: 'hello'
-}
-
-function foo() {
- console.log(this.greet);
-}
-
-var hi = {
- greet: 'hi'
-}
-
-var hardbound = foo.bind(hi);
-
-hardbound();
-hardbound.call(og);
-new foo();
-new hardbound();
-```
-```
-hi
-hi
-undefined
-undefined
-```
-In this example, we see that `new` overrides what `this` refers to explicitly bound by `bind`. It always creates a new empty object, that's why `undefined` was always the result.
-
-In summary, the order of precedence to determine the `this` binding would be the following, the first rule that applies would be the `this` binding:
-
-1. `new` binding - the newly created object.
-2. Explicit binding (`call`, `apply` or `bind`) - whatever the explicit object was
-3. Implicit binding - the owning or containing object from which the function was called.
-4. Default binding - if none of the above it falls back to the global object, (or `undefined` on `strict-mode`)
-
-
-### Closures
-The ability to treat functions as values, brings up an interesting question. What happens to the functions' local variables when the said function has finished executing and was already popped off the execution stack?
-```javascript
-function greet(greeting) {
- return function(name) {
- console.log(greeting + ' ' + name);
- }
-}
-
-var sayHi = greet('Hi');
-var sayHello = greet('Hello');
-sayHi('Holmes');
-sayHello('Watson');
-greet('Sup')('Morty');
-```
-```
-Hi Holmes
-Hello Watson
-Sup Morty
-```
-Remember that each function can access its outer environment whenever it wasn't able to look for a certain variable in its own environment? Not only that, functions in Javascript also maintains a reference to its outer environment even though said environment has already finished executing.
-
-In the example above, `sayHi` is a reference to a function where `'Hi'` was passed as an argument to the parameter, said function returns yet another function where said parameter is being used in addition to the latter functions' own parameter.
-
-When `sayHi('Holmes')` was invoked, it will execute `console.log(greeting + ' ' + name);`, it knows what the variable `name` is but `greeting` is not present in its own execution environment. It then goes out to its outer environment which is the place where it was written and looks for `greeting` variable. Javascript knows that said function was created inside `greet()`, eventhough it has already been popped off the stack, it's variable environment still persists which will be picked up by the `sayHi` invocation.
-
-This feature — being able to still reference the variable environment of an enclosing scope, albeit said execution environment has already been executed — is called **closure**. A function that reference variables from it's outer environment is called *a closure*.
-
-Closures can result to interesting behaviors such as:
-```javascript
-function buildFunctions() {
- const arr = [];
- for (var i = 0; i < 3; i++) {
- arr.push(function() {
- console.log(i);
- });
- }
- return arr;
-}
-
-const fs = buildFunctions();
-fs[0]();
-fs[1]();
-fs[2]();
-```
-The result is partly alarming at first sight. We might think that the output would be something like:
-```
-// Did you expect?
-0
-1
-2
-```
-But instead, when we run this code we would get:
-```
-// Actual result:
-3
-3
-3
-```
-Why? The value that's being pushed in `arr` is a function that accesses the variable `i`. We know that functions doesn't get evaluated until invocation. Only when `fs[0]()` is run that it looks for `i` and has to go to its outer environment to resolve the value. But `buildFunctions()` has already been executed when we assigned the resulting array to `fs`. `buildFunctions`'s variable environment still persists but `var i`'s value has already been incremented to `3` when it finished running. Hence, when we try to reference it on our `fs[n]()` calls, what we get is the current state of the enclosing variable environment of `buildFunctions`.
-
-We could around this by using es6's `let` variable declaration to let Javascript know that we're interested only on the block level scope value of `i`:
-```javascript
-function buildFunctions() {
- const arr = [];
- for (let i = 0; i < 3; i++) {
- arr.push(function() {
- console.log(i);
- });
- }
- return arr;
-}
-```
-
-Or by adding what we know from IIFEs and exploiting it, we could come up with something like:
-```javascript
-function buildFunctions() {
- const arr = [];
- for (var i = 0; i < 3; i++) {
- arr.push(
- (function(j){
- return function() {
- console.log(j);
- }
- }(i));
- );
- }
- return arr;
-}
-
-var fs = buildFunctions();
-```
-This code is confusing and would be frowned upon when used in the real world but it does perfectly demonstrates what we've learned about Javascript's Closures, IIFEs and scope chains. `arr` will contain a value that is, still a function but that function is a result of an immediately-invoked function that encapsulates `i` as `j`.
-
-Now, when we invoked `fs[0]();`, `console.log(j)` will be executed, it will look for the variable `j` but since it wasn't in its own variable environment, it will then find it as the parameter of the enclosing IIFE which was in turn a copy of the value of the parameter `i` of the enclosing function. Remember that objects are pass by reference and primitives are pass by values? The value of `j` is whatever the value of `i` at the time of its execution, subsequent changes to `i` will not affect `j`.
-
-Going back to the original example, if it isn't a function and we immediately used the value of `i` like `arr.push(i)`, it would be a different scenario. But since it's a function along with the behavior of closures we are somehow able to retain the state of `buildFunctions`. This behavior is further demonstrated by the code below:
-```javascript
-function saveState() {
- const arr = [];
- return function(n) {
- arr.push(n);
- return arr;
- };
-}
-
-const myState = saveState();
-
-console.log(myState(1));
-console.log(myState('Yo'));
-const test = myState('test');
-console.log(myState(100));
-// ... some other code here
-console.log(test);
-console.log(myState('7'));
-```
-```
-[1]
-[1, "Yo"]
-[1, "Yo", "test", 100]
-[1, "Yo", "test", 100]
-[1, "Yo", "test", 100, "7"]
-```
-
-##### Function Factories
-Using closures we could come up with interesting patterns like the commonly used function factory below:
-```javascript
-function makeGreeting(language) {
- return function(firstName, lastName) {
- if (language === 'en') {
- console.log(`Hello ${firstName} ${lastName}`);
- }
- if (language === 'es') {
- console.log(`Hola ${firstName} ${lastName}`);
- }
- }
-}
-
-var greetEnglish = makeGreeting('en');
-var greetSpanish = makeGreeting('es');
-
-greetEnglish('John', 'Doe'); // Hello John Doe
-greetSpanish('John', 'Doe'); // Hola John Doe
-```
-
-##### Currying using Closures
-As you might expect, due to the nature of closure we could also create currying functions without relying on `bind`
-```javascript
-var power = function(base) {
- return function(exponent) {
- return base ** exponent;
- }
-}
-
-var square = power(2);
-square(5); // 32
-```
-Or, using ES6's arrow functions we could create an arguable concise version albeit slightly confusing if we're not aware of what's actually happenning.
-```javascript
-let power = (base) => (exponent) => base ** exponent;
-let square = power(2);
-let cube = power(3);
-
-square(5); // 32
-cube(4); // 81
-```
-
-### Functional Programming
-Using our knowledge in Closures, Functions and how Javascript treats it as first-class functions, we could now peform a certain style of programming that involves function manipulations like the following:
-```javascript
-var mapForEach = function(arr, work) {
- const newArr = [];
- for (var i=0; i < arr.length; i++) {
- newArr.push(work(arr[i]));
- };
- return newArr;
-}
-
-var list = [1, 2, 3];
-
-var doubled = mapForEach(list, function(eachElem) {
- return eachElem * 2;
-});
-console.log(doubled); // [2, 4, 6]
-```
-We created a function `mapForEach` that accepts an array and applies some `work()` on each element and then returns the new array, this sort of thing enables us to transform an array that is very generic — something that we could use in different scenarios.
-```javascript
-var isUnderAge = function(age) {
- return age < 18;
-}
-
-var areAllUnderage = mapForEach(list, isUnderAge);
-console.log(areAllUnderAge);
-```
-Using closures and currying we could make the code above something more interesting.
-```javascript
-// Currying using bind
-var checkPastLimitViaBind = function(limit) {
- return function(limiter, element) {
- return element > limter;
- }.bind(this, limit);
-}
-
-// Or we could use just plain closures
-var checkPastLimit = function(limit) {
- return function(element) {
- return element > limit;
- }
-}
-
-var isAdult = checkPastLimit(18); // equal to checkPastLimitViaBind(18)
-console.log(list, isAdult);
-```
-Building up on the above examples, we could demonstrate the power of using small, independent and granular functions to do more interesting things:
-```javascript
-function filterArray(arr, predicate) {
- var newArr = [];
- for(var i = 0; i < arr.length; i++) {
- if(predicate(arr[i])) {
- newArr.push(arr[i]);
- }
- }
-}
-
-var population = [15, 20, 23, 25, 16, 14, 10, 18];
-var adults = filterArray(population, isAdult);
-console.log(adults);
-
-var me = {
- name: 'John Smith',
- age: 18
-}
-
-console.log(isAdult(me.age));
-```
-```
-[20, 23, 25, 18]
-true
-```
-Note that in ES6, `map`, `filter` and other functional utilities are available in arrays by default. There's also a good Javascript library called `lodash` that provides us with a lot of functional helpers.
-
-## The Prototype
-The Javascript engine always attaches a *prototype* whenever an object gets created. A prototype is used as the fallback source of properties. When an object gets a request for a property that it does not have, its prototype will be searched for the said property. When we create a `string` for example:
-```javascript
-var myString = "The quick brown fox jumps over the lazy dog";
-```
-After being processed by the Javascript engine, `myString` will have several properties and methods available for us that we didn't code, these methods are coming from the String prototype. We could take a look at the prototype by accessing the `__proto__` property. Or by invoking `Object.getPrototypeOf()`.
-```javascript
-myString.__proto__;
-Object.getPrototypeOf(myString);
-
-```
-Think of the prototype as the original blueprint that describes a certain object. Note that two object can each have a prototype that refers to the same protoype object.
-```javascript
-Object.getPrototypeOf("new String") === Object.getPrototypeOf(myString)
-```
-
-### Prototypical Inheritance
-The prototype is also an object and thus it also have a prototype. This is how the concept of inheritance is being achieved by Javascript. Instead of the conventional classes, Javascript objects are composition of various prototypes that will ultimately define the said object's behavior.
-When a property is not found on the object, it will search its prototype and if not found, it will look on the prototype's prototype and so on, further down the *prototype chain* until it eventually finds the said property.
-
-To demonstrate this, let's manually modify an object's prototype. Note that this is for demonstration purposes only and should never be done in actual development or you might mess up the background decision making of the Javascript engine as it runs your code.
-```javascript
-var human = {
- firstName: 'Default',
- lastName: 'Default'
- getFullName: function() {
- return this.firstName + ' ' + this.lastName;
- }
-}
-
-var watson = {
- firstName: 'John',
- lastName: 'Watson'
-}
-
-
-// Demo purposes only, let's reassign the prototype object
-watson.__proto__ = human
-
-console.log(watson.getFullName());
-console.log(watson.firstName);
-
-var nameless = {}
-nameless.__proto__ = human
-console.log(nameless.getFullName());
-```
-```
-John Watson
-John
-Default Default
-```
-The first `console.log` references `getFullName` which the object `watson` doesn't have, the Javascript engine then goes in the prototype object which we have set to `human` and finds it there thus printing `John Watson`.
-The second `console.log` on the other hand references `firstName` which `watson` already have that's why the Javascript engine doesn't search further down the prototype chain.
-
-If we go further down to the root of the prototype chain of any object we'll discover that everything originates from the `Object` prototype.
-```javascript
-var str = "";
-var arr = [];
-var fun = function() {};
-var ob = {};
-
-console.log(str.__proto__.__proto__ === arr.__proto__.__proto__ === fun.__proto__.__proto__ === ob.__proto__);
-console.log(ob.__proto__.__proto__);
-```
-```
-true
-null
-```
-
-### Reflection
-A javascript object can look at itself, extend its by behavior and functionality by adding and/or modifying its own property and methods.
-```javascript
-var base = {
- a: 'a',
- b: 'b',
- c: 'c'
-};
-
-var z = {
- a: 'x',
- b: 'y'
-}
-
-z.__proto__ = base;
-
-for (var prop in z) {
- if (z.hasOwnProperty(prop)) {
- console.log(z[prop]);
- }
-}
-```
-> word of caution, don't use `for`..`in` when iterating array values, because you could also iterate through the properties of the Array object itself as well, not just the elements.
-```
-x
-y
-```
-The example below is a contrived version of the inner workings of the lodash's `extend` function. `createArray()` and `lib` is actually not necessary but important to demonstrate how javascript libraries exploit functional programming to implement interesting stuff like this. `createAssigner` takes some sort of utility function, in this case a function that determines all existing props in an object, then returns another function that takes an `obj` parameter where the `getKeysFunc` will be used against. `lib` is now an object where all utility functions like `extend` exists by composing and chaining utility functions like `createAssigner`. Also notice that the resulting return function of `createAssigner` only takes one parameter but when we use `lib.extend` we passed 3 arguments. If this were any other language this wouldn't be possible but since Javascript doesn't care about parameter length, and all it cares about is the function name, it's possible to not define all parameters. After all, we can still access them via `arguments`.
-```javascript
-function createAssigner(getKeysFunc)
- return function(obj) {
- var length = arguments.length;
- if (length < 2 || obj == null) {
- return obj;
- }
-
- for (var i = 1; i < length; i++) {
- var source = arguments[i];
- var keys = getKeysFunc(source);
- for (var j = 0; j < keys.length; j++) {
- var key = keys[j];
- obj[key] = source[key];
- }
- }
- }
-}
-
-var lib = {
- extend: createAssigner(Object.keys);
-}
-
-var ob1 = {
- a: 'a',
- b: 'b'
- c: 'c'
-}
-
-var ob2 = {
- m: 'm',
- n: 'n',
- o: 'o'
-}
-
-var ob3 = {
- x: 'x',
- y: 'y',
- z: 'z'
-}
-
-lib.extend(ob1, ob2, obj3);
-for (var key in ob1) {
- console.log(obj1[key]);
-}
-```
-```
-a
-b
-c
-m
-n
-o
-x
-y
-z
-```
-`ob1` extended its behavior by adding all properties and methods coming from `ob2` and `ob3`. And we did that dynamically at run-time.
-
-#### Function Constructor's `.prototype`
-In every javascript function there's a `.prototype` property **NOT** to be confused with `.__proto__` property. The latter is the fallback source of any object, or the source template, like what we've discussed before. On the other hand, `.prototype` is being set and used when a function is used as a function constructor upon using the `new` operator.
-```javascript
-function Person(name) {
- this.name = name;
-}
-
-function foo() {}
-
-var holmes = new Person('holmes');
-var watson = new Person('watson');
-
-console.log(Person.__proto__ === foo.__proto__);
-console.log(holmes.__proto__ === Person.prototype === watson.__proto__);
-```
-```
-true
-true
-```
-Does it make sense? `Person` itself is a function that's why its and `foo`'s `__proto__` refer to the same thing. But then `holmes` and `watson`'s `__proto__` points to `Person.prototype` because they were created with `new`. Hence, `.prototype` of a function a is a special property that points to the object that will be the `__proto__` of all the objects that will be created out of it via `new`.
-
-#### Extending via `.prototype`
-Using `.prototype` we can now extend all the objects behavior by adding or modifying it.
-```javascript
-function Person(firstname, lastname) {
- this.firstname = firstname;
- this.lastname = lastname;
-}
-
-Person.prototype.getFullName = function() {
- return this.firstName + ' ' + this.lastName;
-}
-
-var sherlock = new Person('Sherlock', 'Holmes');
-var watson = new Person('John', 'Watson');
-
-
-console.log(sherlock.getFullName());
-console.log(watson.getFullName());
-```
-```
-Sherlock Holmes
-John Watson
-```
-
-### Pure Prototypal Inheritance with `Object.create`
-Another way of creating objects without relying on `new` operator. Using `Object.create` is considered as the pure prototypal inheritance because it really just assigns the target object as the prototype, nothing more and nothing less. Note that `Object.create` may not be present in older javascript versions.
-```javascript
-var person = {
- firstname: 'Default',
- lastname: 'Default',
- greet: function() {
- return 'Hi ' + this.firstname;
- }
-}
-
-var holmes = Object.create(person);
-holmes.firstname = 'Sherlock';
-holmes.lastname = 'Holmes';
-```
-
-### ES6 Classes
-ES6 added a better syntax to create objects without using function constructors.
-```javascript
-class Person {
- constructor(firstname, lastname) {
- this.firstname = firstname;
- this.lastname = lastname;
- }
-
- greet() {
- return 'Hello ' + this.firstname + ' ' + this.lastname;
- }
-}
-```
-You then use the keyword `extends` to indicate the prototype
-```javascript
-class InformalPerson extends Person {
- constructor(firstname, lastname) {
- super(firstname, lastname);
- }
-
- greet() {
- return 'Yo ' + this.firstname;
- }
-}
-```
-Tread carefully though, while it looks like Java classes and other conventional OOP classes, it's very important to remember that these are still just function constructors under the hood and they create objects. Don't try to strictly wrap your head around conventional OOP relationships when using ES6 classes.
-
-##### Figuring out what something is, `typeof` and `instanceof`
-Due to the dynamic nature of Javascript we will sometimes find ourselves trying to figure out what the type of the object truly is for some reason or another.
-
-```javascript
-var num = 4;
-var str = "Hello";
-var ob = {};
-var arr = [];
-var fun = function() {};
-console.log(typeof num); // number
-console.log(typeof str); // string
-console.log(typeof ob); // object
-console.log(typeof arr); // object
-console.log(typeof fun); // function
-console.log(typeof undefined); // undefined
-console.log(typeof null); // object
-console.log(holmes instanceof Person); // true
-```
-We can see in the code above how `typeof` and `instanceof` works, and immediately you should pay attention to `arr` and `null`. `null` apparently is also an `object`, and same as arrays. It does make sense since arrays aren't really primitives but a type of an object. In order to determine if an object is an array, we could do something like this:
-```javascript
-// a little weird, more of a workaround
-console.log(Object.prototype.toString.call(arr) === '[object Array]'); // true
-
-// Or, in newer versions of Javascript, we could use:
-console.log(arr instanceof Array); // true
-console.log(Array.isArray(arr)); // true
-```
-
-### Strict Mode
-We've learned that Javascript is a bit liberal or flexible. It's useful but sometimes we want it to be a bit stricter if we use strict mode.
-```javascript
-var person;
-persom = {}; // suppose we accidentally typed a typo
-console.log(persom); // Object {}, person is undefined.
-```
-If we then do this:
-```javascript
-"use strict"
-var person;
-persom = {}; // Will throw an error here.
-```
-Strict mode could also be applied locally on a function.
-```javascript
-function funfun() {
- "use strict"
- x = {};
-}
-var y;
-z = {};
-console.log(z);
-funfun();
-```
-```
-Object {}
-Uncaught ReferenceError: x is not defined
-```
-More details about strict mode could be read over at [MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode).
\ No newline at end of file
+---
+title: Javascript, The Weird Parts
+path: /javascript-weird-parts
+date: 2018-09-15
+summary: Javascript is weird, let's get that out of the way. Still, it's not like Javascript is illogical, in fact, most of it's weirdness is a side effect of its power while coping up with programmers' whims. But once you understand why it does what it does, we'll realize that it's not that complex after all. All languages has its own fair share of quirks and nuances that we just have to learn.
+tags: ['learnings']
+---
+
+# Javascript: The Weird Parts
+###### 15 September 2018
+
+Javascript is weird, let's get that out of the way. Still, it's not like Javascript is illogical, in fact, most of it's weirdness is a side effect of its power while coping up with programmers' whims. But once you understand why it does what it does, we'll realize that it's not that complex after all. All languages has its own fair share of quirks and nuances that we just have to learn.
+
+This article/guide is my transcription of Anthony Alicea's lecture entitled: Javascript - Understanding the Weird Parts. I expounded and added additional explanation on topics where I felt like more examples and details are necessary. This is not for people new to Javascript, it's more for people who are familiar with Javascript, but still have huge knowledge gaps. After reading this and you still crave for more, I highly recommend reading [Eloquent Javascript](https://eloquentjavascript.net) by Marijn Haverbeke (_saying the word "eloquent" makes you feel 10x smarter already, but not as much as the word "quintessential"_) and Kyle Simpson's [You Dont Know JS](https://github.com/getify/You-Dont-Know-JS) is also one of the best.
+
+
+
+## Syntax Parser
+A program that reads code and determines what it does and if it's grammar valid.
+
+## Lexical Environment
+Where something sits physically in the code you write. It determines how a piece of code will interact with other elements of the code. The Syntax parser makes decisions based from where a code is placed.
+
+## Execution Context
+A wrapper to help manage the code that is running. It contains some metadata, some elements that you didn't write. Javascript attaches the `this` and `outerEnvironment` that your code has access to while it runs.
+
+## The Global Execution Context.
+Everytime a function is run, a new execution context is being created. The global execution context is the root context, the main context where there is no other else that's running.
+
+> What's executing isn't what you've written, it's being processed by the javascript engine beforehand.
+
+### Global Object
+Is the object every running javascript code has, the object associated with the global execution context. You can reference it by the special/keyword variable `this` on the root context or by the variable `window` (if you're using node, V8 engine's version is the variable `global`).
+
+```javascript
+// At the root context (not inside a function)
+window === this
+```
+
+Defining a variable and function will attach it to the current execution context.
+
+### Hoisting
+The process at which the memory space of variables and functions are setup.
+
+The execution is created in two phases:
+
+##### Creation Phase
+The phase where `this` and the `outerEnvironment` is created while also setting up the variables and functions' memory space placing on the `variable environment`, together they are what we refer to as the execution context.
+
+One little caveat for variables: Variables are attached to execution context with a placeholder value called `undefined`, the actual value is determined on the execution phase. Functions, on the other hand get attached as is and ready for invocation.
+
+##### Execution Phase
+Javascript runs your code line by line. Variables' values are resolved based on the result of the expressions.
+```javascript
+var a = 'Hello world';
+
+function b() {
+ console.log('Called b!');
+}
+
+b();
+console.log(a);
+```
+will output:
+```
+Called b!
+Hello world
+```
+Consider the following code below that in most programming languages will throw an error:
+```javascript
+b();
+console.log(a);
+
+var = a 'Hello world';
+
+function b() {
+ console.log('Called b!');
+}
+```
+will output
+```
+Called b!
+undefined
+```
+Noticed how `b()` was still executed properly while `a` is also available, albeit a different value.
+
+On the creation phase, the javascript engine checks the code and for every variable declaration (eg: `var`) it sets up memory and attaches it on the execution context. The value is then resolved on the execution phase.
+
+```javascript
+b();
+console.log(a);
+var a = 'Hello world';
+console.log(a);
+function b() {
+ console.log('Called b!');
+}
+```
+```
+Called b!
+undefined
+Hello world
+```
+
+### Single Threaded and Synchronous
+The Javascript language is single threaded which means, command is being ran one at a time (under the hood, the browser maybe not) and synchronous which means, in order. Code is being ran one at a time and in order.
+
+### The Execution Stack
+Everytime a function is invocated, a new execution context is created and is placed on top of the execution stack, whichever is on top is the one currently running, once it finishes, it gets popped off the stack.
+
+Which means, each function call gets its own separate and independent execution context, and its own `this`. Note that, the `variable environment` is not the same with `this`.
+
+```javascript
+function b() {
+ var myVar;
+ console.log(myVar);
+}
+
+function a() {
+ var myVar = 2;
+ console.log(myVar);
+ b();
+}
+
+var myVar = 1;
+console.log(myVar);
+a();
+console.log(myVar);
+```
+Will give the following result:
+```
+1
+2
+undefined
+1
+```
+
+### The Outer Environment
+In every execution context, there's a reference to the outer environment. If a certain variable is not found in the current `variable environment`, Javascript will look for it at the outer environment which refers to the `variable environment` of the one that created it, this does **NOT** refer to the previous execution context on the stack but from it's lexical environment, or the execution environment of where it was written.
+```javascript
+function b() {
+ console.log(myVar);
+}
+
+function a() {
+ var myVar = 2;
+ b();
+}
+
+var myVar = 1;
+a();
+```
+The output is:
+```
+1
+```
+In this example the outer environment of both `a()` and `b()` is the same, which is the global or root environment.
+```javascript
+function a() {
+
+ function b() {
+ console.log(myVar);
+ }
+
+ var myVar = 2;
+ b();
+}
+
+var myVar = 1;
+a();
+```
+Now, in this example `b`'s outer environment is `a`'s, while `a`'s outer environment is the global environment. Hence, the output is:
+```
+2
+```
+
+Also note that in the global scope, the `variable environment` resides in the global (`window`) object. We can't directly access or inspect the `variable environment` of a function's execution context but we can for the root global context because it's attached to the global object. Moreover, in the global execution context `this` === global (`window`) object.
+
+It's a bit confusing but just remember that in the global execution context, we could roughly consider the `variable environment`, `this` and the `outer environment` to be on the same place which is the global `window` object.
+
+##### Let
+The block-scoping variable declaration of Javascript ES6. The variable is only available on it's own block.
+```javascript
+if (a > b) {
+ let c = true;
+}
+console.log(c);
+```
+```
+undefined
+```
+
+### Primitive Types
+A type of data that represents a single value. The atomic unit that make up an object.
+1. `undefined`
+2. `null`
+3. Boolean - `true` or `false`
+4. Number - a floating-point, there's always some decimals. `123`
+5. String - a sequence of characters. `string`
+6. Symbol - Introduced in es6.
+
+### Operator
+A special function that accepts an argument and returns a value that is just syntactically or written differently. `+`, `-`, `*`, `/`, (and etc) are just functions with special characters that are written in an infix notation instead of postfix are prefix like normal functions. ie: `+(a, b)`
+
+#### Operator precedence
+Which operator function gets executed first if there's more than one in the same line of executable code. The higher precedence gets executed first.
+```javascript
+var a = 3 + 4 * 5; // (4 * 5) first. Pretty basic
+```
+
+#### Associativity
+When operators have the same precedence, the order from which they get called is the associativity. Left-to-right or right-to-left associativity.
+
+```javascript
+var a = 2, b = 3, c = 4;
+a = b = c;
+console.log(a); // 4
+console.log(b); // 4
+console.log(c); // 4
+```
+The `=` operator has *right-to-left* associativity. Here's what actually happened.
+```javascript
+// eq(a, eq(b, c))
+a = b = c
+a = (b = c)
+a = (4)
+```
+
+| Precedence | Operator Type | Associativity | Individual Operator |
+| ----------- | ----------------------------- | ------------- | ------------------- |
+| 20 | Grouping | n/a | `( … )` |
+| 19 | Member Access | left-to-right | …` . `… |
+| | Computed Member Access | left-to-right | `…[…]` |
+| | `new`(with argument list) | n/a | `new … (…)` |
+| | Function call | left-to-right | `… (…)` |
+| 18 | `new`(without argument list) | right-to-left | `new …` |
+| 17 | Postfix Increment | n/a | `…++` |
+| | Postfix Decrement | | `…--` |
+| 16 | Logical NOT | right-to-left | `!…` |
+| | Bitwise NOT | | `~…` |
+| | Unary Plus | | `+…` |
+| | Unary Negation | | `-…` |
+| | Prefix Increment | | `++…` |
+| | Prefix Decrement | | `--…` |
+| | typeof | | `typeof …` |
+| | void | | `void …` |
+| | delete | | `delete …` |
+| | await | | `await …` |
+| 15 | Exponentiation | right-to-left | `… ** …` |
+| 14 | Multiplication | left-to-right | `… * …` |
+| | Division | | `… / …` |
+| | Remainder | | `… % …` |
+| 13 | Addition | left-to-right | `… + …` |
+| | Subtraction | | `… - …` |
+| 12 | Bitwise Left Shift | left-to-right | `… << …` |
+| | Bitwise Right Shift | | `… >> …` |
+| | Bitwise Unsigned Right Shift | | `… >>> …` |
+| 11 | Less Than | left-to-right | `… < …` |
+| | Less Than or Equal | | `… <= …` |
+| | Greater Than | left-to-right | `… > …` |
+| | Greater Than or Equal | | `… >= …` |
+| 10 | Equality | left-to-right | `… == …` |
+| | Inequality | | `… != …` |
+| | Strict Equality | | `… === …` |
+| | Strict Inequality | | `… !== …` |
+| 9 | Bitwise AND | left-to-right | `… & …` |
+| 8 | Bitwise XOR | left-to-right | `… ^ …` |
+| 7 | Bitwise OR | left-to-right | `… | …` |
+| 6 | Logical AND | left-to-right | `… && …` |
+| 5 | Logical OR | left-to-right | `… || …` |
+| 4 | Conditional | right-to-left | `… ? … : …` |
+| 3 | Assignment | right-to-left | `… = …` |
+| | | | `… += …` |
+| | | | `… -= …` |
+| | | | `… **= …` |
+| | | | `… *= … ` |
+| | | | `… /= … ` |
+| | | | `… %= … ` |
+| | | | `… <<= … ` |
+| | | | `… >>= … ` |
+| | | | `… >>>= … ` |
+| | | | `… &= … ` |
+| | | | `… ^= … ` |
+| | | | `… |= … ` |
+| 2 | yield | right-to-left | `yield …` |
+| | yield* | | `yield* …` |
+| 1 | Comma / Sequence | left-to-right | `… , …` |
+
+
+
+#### Type Coercion
+Because Javascript is dynamically-typed, it automatically converts or attempts to convert a value from one type to another.
+
+```javascript
+var a = 1 + '2'; // '12'
+```
+The value `1` was coerced into a `String` by the javascript engine.
+
+Here's a more compelling example:
+
+```javascript
+1 < 2 < 3 // true
+3 < 2 < 1 // true, why??
+```
+The `<` operator has the same precedence with a *left-to-right* associavity. Which means:
+```javascript
+3 < 2 < 1
+(3 < 2) < 1
+false < 1 // false gets coerced into a number = 0
+0 < 1
+true
+```
+Which means, the same applies to `1 < 2 < 3`, `false < 3`, `1 < 3`. Type coercion can cause a lot of problems when you don't know what's going on.
+
+##### Equality Comparisons and Sameness
+Notice how type coercion can affect equality operators that results to weird behaviors
+```javascript
+3 == 3 // true
+"3" == 3 // true
+false == 0 // true
+null < 1 // true because null coerces to 0 < 1
+null == 0 // false
+"" == 0 // true
+"" == false // true
+```
+Strict equality `===`, it compares two values but doesn't try to coerce any of them.
+```javascript
+3 === 3 // true
+"3" === "3" // true
+"3" === 3 // false
+```
+
+##### Sameness Comparisons
+| x | y | == | === | Object.is |
+| :----------------- | :---------------- | :---: | :---: | :-------: |
+| undefined | undefined | true | true | true |
+| null | null | true | true | true |
+| true | true | true | true | true |
+| false | false | true | true | true |
+| 'foo' | 'foo' | true | true | true |
+| 0 | 0 | true | true | true |
+| +0 | -0 | true | true | false |
+| +0 | 0 | true | true | true |
+| -0 | 0 | true | true | false |
+| 0 | false | true | false | false |
+| "" | false | true | false | false |
+| "" | 0 | true | false | false |
+| '0' | 0 | true | false | false |
+| '17' | 17 | true | false | false |
+| [1, 2] | '1,2' | true | false | false |
+| new String('foo') | 'foo' | true | false | false |
+| null | undefined | true | false | false |
+| null | false | false | false | false |
+| undefined | false | false | false | false |
+| { foo: 'bar' } | { foo: 'bar' } | false | false | false |
+| new String('foo') | new String('foo') | false | false | false |
+| 0 | null | false | false | false |
+| 0 | NaN | false | false | false |
+| 'foo' | NaN | false | false | false |
+| NaN | NaN | false | false | true |
+
+##### Existence and Booleans
+Javascript coerces `undefined`, `null`, `""` to `false`. Hence, we could write simple `if` conditions like this:
+```javascript
+var a;
+// goes to internet to check some value
+if (a) { // if it exists
+ console.log('Something is there');
+}
+```
+One caveat though, `0` coerces to `false` as well, hence if in the above code `a` was `0`, the behavior is not valid anymore. That's why people often do something like this:
+```javascript
+if (a || a === 0) {
+ console.log('Somethign is there');
+}
+```
+Just never check existence in this way if you expect the value could be `0`.
+
+##### Default Values
+Using type coercion and operator precedence, there's a common trick being used to create default values.
+
+```javascript
+function greet(name) {
+ name = name || '';
+ console.log('Hello ' + name);
+}
+greet();
+greet('Feynman');
+```
+
+This works because `||` operator doesn't just return `true` or `false` but it actually returns the value that can be coerced to `true`.
+```javascript
+undefined || 'hello' // hello
+null || 4 // 0
+```
+In es6, there's a different way of assigning default value but this trick is still common and could be used not just in function parameters.
+
+```javascript
+function greet(name='Your name here') {
+ console.log('Hello ' + name);
+}
+```
+
+### Objects
+Objects in Javascript is the same as what you expect from other languages. It's a container of primitives and other objects, which can be accessed by `.` or `[]`. The dot `.` operator and the computed member access `[]` have the same precedence and associativity.
+
+```javascript
+var person = new Object();
+person['firstname'] = 'Sherlock';
+person['lastname'] = 'Holmes';
+
+var firstNameProperty = 'firstname';
+
+console.log(person);
+console.log(person[firstNameProperty]);
+
+console.log(person['lastname']);
+console.log(person.firstname);
+
+person.address = new Object();
+person.address.street = '221B Baker Street';
+person.address.city = 'London';
+person.address.country = 'United Kingdom';
+
+console.log(person.address.street);
+console.log(person['address']['city']);
+console.log(person.address['country']);
+
+// via object literal
+var sherlock = {
+ firstname: 'Sherlock',
+ lastname: 'Holmes',
+ address: {
+ street: '221B Baker Street',
+ city: 'London',
+ country: 'United Kingdom'
+ };
+};
+
+
+function greet(person) {
+ console.log('Hi ' + person.firstname);
+}
+
+greet(sherlock);
+greet({
+ firstname: 'John',
+ lastname: 'Watson'
+});
+
+```
+
+### Functions
+In Javascript, everything is either an object or a primitive. Functions are treated like usual objects as well, they could be assigned to variables, passed around, or created on the fly. Javascript functions are first-class functions.
+
+Think of functions as special type of object that can have properties but functions also has an invocable special property called `code` and a string property called `name`.
+
+```javascript
+function greet() {
+ console.log('hi');
+}
+
+greet.language = 'english';
+greet.hey = function () {
+ console.log('hey');
+}
+
+console.log(greet.language);
+console.log(greet.hey());
+```
+
+#### Function Statement
+A **Statement** is a unit of code that when executed doesn't result in a value.
+```javascript
+
+if (true == true) { // this is an if statement
+
+}
+
+// function statement, it will be executed
+// and created a spot in memory for greet
+function greet() {
+ console.log('hi');
+}
+
+greet();
+```
+
+#### Function Expression
+
+An **Expression** is a unit of code that results in a value. `a = 1` is an expression, so is `x || 2`.
+
+```javascript
+// This is a function expression
+// This will return a function.
+function() {
+ console.log('hi');
+}
+
+// That's why we could do this:
+var greet = function() {
+ console.log('hi');
+}
+// essentially the same with:
+var greet = function greetMe() {
+ console.log('hi');
+}
+// But since greetMe will just be reassigned to greet, it's optional.
+```
+Consider the following code, taking into account what we've learned about **hoisting**.
+```javascript
+greet(); // called and then defined.
+function greet() {
+ console.log('greet');
+}
+
+newGreet();
+var newGreet = function() {
+ console.log('hello');
+}
+```
+`newGreet()` will throw an error. `newGreet` is a value, and in creation phase, it will be assigned to `undefined` when the memory space was set up for it. The value is function but it will be resolved when that line was executed.
+
+Moreover, since functions are also treated as an object we could create one on the fly and pass it as an argument to other functions.
+```javascript
+function invoker(a) {
+ a();
+}
+
+function invoker(function(){
+ console.log('sup?');
+});
+```
+##### Passing by Value and by Reference
+In Javascript when a primitive value is reassigned or passed to a function as an argument, the copy of the said value is created to be used inside the function - this called *pass by value*. But when an object is reassigned or passed as an argument, what is being used is the actual reference to the object, not a copy. Which means, changing the value of object within the function will also change the original value - this called *pass by reference*.
+
+```javascript
+// by value
+var a = 2;
+var b = a;
+b = 3;
+
+console.log(a); // 2
+console.log(b); // 3
+
+// by reference
+var c = { greeting: 'hi' };
+var d = c;
+
+c.greeting = 'hello';
+
+console.log(c.greeting); // 'hello'
+console.log(d.greeting); // 'hello'
+
+```
+Note that an assignment `=` operator also creates a new memory space, a different memory address for the said value. Hence the following code behaves as follows:
+```javascript
+var c = { greeting: 'hi' };
+var d = c;
+
+c = { greeting: 'hello' };
+console.log(d.greeting); // hi
+console.log(c.greeting); // hello
+```
+
+#### The `this` keyword
+We've learned that when a function is invoked, a new execution context is created and put on top of the stack. The execution context has it's own `variable environment`, `outer environment` and `this`.
+
+`this` is an object that points to a different thing depending on where it was called. In other words, `this` is dynamically bound.
+
+```javascript
+
+function a() {
+ console.log(this);
+ this.greet = 'hello';
+}
+
+var b = function() {
+ console.log(this);
+}
+
+// console.log(greet) // will throw an error, not yet defined
+console.log(this);
+a(); // points to the global object
+b(); // points to the global object
+console.log(greet); // 'hello'
+
+var c = {
+ name: 'The c object',
+ log: function() {
+ this.name = 'updated c object';
+ console.log(this); // no longer points to the global object
+ }
+}
+
+c.log(); // { name: 'updated c object', log: function }
+```
+This will make total sense if you have something like this:
+```javascript
+var sayMyName = function() {
+ console.log('Hello there, ' + this.name);
+}
+
+var holmes = {
+ name: 'Sherlock',
+ greet: sayMyName
+}
+
+var watson = {
+ name: 'John',
+ greet: sayMyName
+}
+
+holmes.greet(); // 'Hello there, Sherlock'
+watson.greet(); // 'Hello there, John'
+
+```
+The `this.a` in `sayMayName` refers to the particular object it's attached to on the time it was called. Always remember, `this` always refers to an object. But now consider the following:
+```javascript
+var d = {
+ name: '',
+ fun: function () {
+ this.name = 'Holmes'
+
+ var setName = function(newName) {
+ this.name = newName;
+ }
+ setName('Watson');
+ }
+}
+
+d.fun();
+console.log(d.name); // Holmes
+console.log(name); // Watson
+```
+
+What happened? When `setName` was called inside `d.fun`, the `this` operator is now pointing to the global object. The object that `this` was referring to was lost and defaulted back to the global object.
+
+To understand this, remember that `this` is always bound to the object that called it. `d.fun()`, `fun`'s `this` is bound to `d`, but right before `fun()` finished executing, `setName()` was invoked but isn't bound to any object (it was invoked by `fun`, but `fun` is not an object), hence it got thrown off to the global object.
+
+A common solution for solving this problem is usually done by exploiting the concept of how the execution context behaves when it can't find a certain variable, it goes out to the outer environment that points to its parent lexical context until it finds it.
+```javascript
+var e = {
+ name: '',
+ fun: function () {
+ var self = this
+ self.name = 'Holmes'
+
+ var setName = function(newName) {
+ self.name = newName;
+ }
+ setName('Watson');
+ }
+}
+
+e.fun();
+console.log(e.name); // Watson
+// console.log(name); // Error
+```
+When `setName` executes, `self` is not present in it's `variable environment`, so it goes to look on the `outer environment` which happens to point to `fun`'s execution context, where it finds `self`. `setName` is written inside `fun` that's why the `outer environment` points to `fun` and not because it's right below `setName`'s execution context on the execution stack.
+
+There are other ways to get around and explicitly bind `this` to certain object by using Javascript's built-in methods, `call()`, `apply()` and `bind()`.
+
+#### `call()`, `apply()` and `bind()`
+Whenever a Javascript function is created, each function gets `call()`, `apply()` and `bind()` attached to them by the Javascript engine as properties that we have access to. The `this` keyword is bound to the object where it was invoked, if there's no such object, the binding is lost and `this` binds to the default binding, which is the `global` object (`undefined` when on _strict mode_). But using said functions we could explicitly bind `this` to whatever object we like.
+
+##### `call()`
+Invokes the target function binding the reference to `this` to the given first parameter.
+```javascript
+var person = {
+ name: 'Sherlock Holmes',
+ log: function() {
+ console.log(this.name);
+ }
+}
+
+var logFn = person.log;
+
+var person2 = {name: 'John Watson'};
+logFn.call(person2);
+```
+```
+John Watson
+```
+
+##### `apply()`
+With respect to `this` binding, `call(..)` and `apply(..)` are identical. They do behave differently when used with their additional parameters.
+```javascript
+var sherlock = {
+ firstName: 'Sherlock',
+ lastName: 'Holmes',
+ getFullName: function() {
+ return this.firstName + ' ' + this.lastName;
+ }
+}
+
+var watson = {
+ firstName: 'John',
+ lastName: 'Watson',
+ getFullName: function() {
+ return this.firstName + ' ' + this.lastName;
+ }
+}
+
+var wrappedLog = function (a, b) {
+ console.log(this.getFullName())
+ console.log(a, b);
+ console.log('------');
+}
+console.log(sherlock.getFullName());
+console.log('------');
+wrappedLog.call(watson, 'arg1', 'arg2');
+// wrappedLog.apply(watson, 'arg1', 'arg2'); // will throw an error
+wrappedLog.apply(watson, ['arg1', 'arg2']);
+```
+```
+Sherlock Holmes
+------
+John Watson
+arg1 arg2
+------
+John Watson
+arg1 arg2
+------
+```
+
+`apply()` just unrolls its array arguments and provide it as the `targetFn`'s arguments. It doesn't seem useful at first glance but it's very convenient if you are doing some array manipulations and you want the result to be used as arguments for a generic target function.
+
+```javascript
+function someFrameworkTask = function(targetFn, targetOb, arrArgs) {
+ // Do some work on arrArgs
+ arrArgs.push(...);
+ arrArgs.splice(...);
+ // targetFn.call(targetOb, arr[0], arr[1], ...arr[2]); // we have to know how many arguments targetFn has beforehand
+ targetFn.apply(targetOb, arr);
+}
+```
+
+###### Hard Binding
+Explicit binding is cool but what if we wanted a certain function to be permanently bound to a specific `this` without worrying that it could be modified someplace else.
+```javascript
+var sherlock = {
+ firstName: 'Sherlock',
+ lastName: 'Holmes',
+ getFullName: function() {
+ return this.firstName + ' ' + this.lastName;
+ }
+}
+
+var watson = {
+ firstName: 'John',
+ lastName: 'Watson',
+ getFullName: function() {
+ return this.firstName + ' ' + this.lastName;
+ }
+}
+
+var logName = function() {
+ console.log(this.getFullName());
+}
+
+var hardbound = function() {
+ logName.call(sherlock);
+}
+
+hardbound();
+hardbound.call(watson);
+hardbound.apply(watson);
+```
+```
+Sherlock Holmes
+Sherlock Holmes
+Sherlock Holmes
+```
+We created a `hardbound` variable whose value is just a function that wraps a `call` invocation, explicitly binding it to `sherlock`. When `hardbound()` is invoked, it's the same as calling `call(sherlock)`, but this wrapping mechanism that we have implemented has made the binding permanent. Invoking `hardbound.call(watson)` would only bind `this` to the anonymous wrapper function that will just be ignored when `logName.call(sherlock)` is invoked.
+
+This hard binding is so common that it was also provided by the Javascript engine called `bind()`. Of course its implementation is far more robust and less error prone than ours.
+
+
+##### `bind()`
+`bind()` on the other hand, takes an object as a parameter and then returns a new function where `this` is hard bound to the said object.
+```javascript
+var sherlock = {
+ name: 'Sherlock Holmes',
+ log: function() {
+ console.log(this.name);
+ }
+}
+
+var watson = { name: 'John Watson'};
+
+var logName = sherlock.log.bind(watson);
+
+logName();
+logName.bind(sherlock)();
+```
+```
+John Watson
+John Watson
+```
+
+Note that it's still possible to change this binding if we used the keyword `new` that we'll explore in a different chapter.
+
+##### Function Currying
+Passing parameters to `bind()` does something interesting, it gave us the ability to curry. Currying is creating a copy of a function with some preset parameter values or partial application of parameters.
+```javascript
+function power(base, exponent) {
+ return base ** exponent;
+}
+
+var square = power.bind(this, 2);
+
+square(2); // 4
+square(5); // 32
+```
+In this example, we're not after the `this` binding so we could just bind it to the global object, we're not using it anyway. We're more interested on how we can use currying if we pass more arguments to `bind`. Passing `2` on `power.bind(this, 2)` would make `square` a `power()` function that have it's `base` parameter permanently set to the value `2`. We say that `square` is a `power()` function whose arguments are partially applied.
+
+Supplying more parameters to bind would just fill the arguments of the target function.
+
+```javascript
+var four = power.bind(this, 2, 2);
+four(5); // 4. 5 will be passed as the 3rd parameter that we're just ignoring.
+```
+
+Currying, is widely used in Functional style of programming. We could also create the same behavior by exploiting closures that will be discussed in the next sections.
+
+##### Function Overloading
+Javascript has no function overloading capabilities because functions are treated as objects, unlike in other languages. Javascript doesn't care about the number of parameters, it just care about the name of the function you're trying to invoke. If your function expect 2 parameters but you only pass 1 argument, the second parameter will be `undefined`. Likewise, if you expect 2 parameters and you pass 3 arguments, you'll just have no straightforward way to access the third parameter (unless you access the built-in `arguments` property a functions have). It's still possible to convey a somewhat cleaner overloading concept by utilizing default parameters:
+
+```javascript
+function greet(firstName, greeting = "Hi", question="How are you?") {
+ return `${greeting} ${firstName}! ${question}`;
+}
+
+greet('John'); // "Hi John! How are you?
+greet('John', 'Hey'); // "Hey John! How are you?"
+greet('John', 'Hey', 'Sup?'); // "Hey John! Sup?"
+```
+
+#### Immediately-Invoked Function Expressions (IIFE)
+An anonymous function expression that was being immediately invoked upon load.
+```javascript
+function greet(name) { // Function statement
+ console.log('Hello ' + name);
+};
+
+var greetFun = function(name) { // Function expression
+ console.log('Hello ' + name);
+};
+
+var greeting = function(name) { // Immediately-invoked function expression
+ return 'Hello ' + name;
+}('John');
+
+console.log(greeting); // 'Hello John' - Holds the result of the IIFE
+
+// function(name) { // Will throw an error
+// console.log('Hello ' + name); // Syntax parser expects
+// } // a function name
+
+(function(name){
+ console.log('Hi ' + name);
+}('John'));
+```
+IIFE's are widely used among javascript frameworks and libraries for initialization while managing namespace collisions.
+```javascript
+// defined in someplace else ie: foo.js
+var greeting = 'Hola'; // Bound to global
+
+// somewhere in another file ie: greet.js
+(function() {
+ var greeting = 'Hello';
+ console.log(greeting);
+}());
+console.log(greeting);
+```
+```
+Hello
+Hola
+```
+
+#### Function Constructors with `new`
+Functions that are used to construct objects together with `new` operator. These functions are normal functions but when `new` is applied to them, Javascript engine does something different, it creates an empty `this` object and returns it.
+```javascript
+function Foo() {
+ this.hello = 'hey';
+}
+
+var f = new Foo();
+console.log(f);
+```
+```
+f {
+ hello: 'hey'
+}
+```
+But still, don't forget that these are still normal functions. When invoked without `new`, `this` would refer to the global object like what we've learned. That's why it's a convention that any function intended to use as function constructors should always start with capital letters.
+```javascript
+function Foo(){
+ console.log(this);
+}
+Foo();
+new Foo();
+var f = Foo();
+console.log(f); // undefine because Foo() was invoked as a function
+```
+```
+Window {...}
+Foo {}
+undefined
+```
+That being said, when creating objects using `new` don't return anything on the function constructor or it will mess up the javascript engine's decision making.
+```javascript
+function Foo(greeting) {
+ this.greet = greeting;
+ return {
+ b: 'azinga'
+ }
+}
+
+var f = new Foo('hello');
+console.log(f);
+```
+```
+{b: 'azinga'}
+```
+
+#### Built-in Function Constructors
+Some of the most common objects has built-in function constructors shipped together with Javascript. Almost all primitive values has a wrapper object counterparts that includes some added properties and methods.
+```javascript
+var num = new Number(3.14151629);
+num.toFixed(2);
+
+var tesla = new String("Nikola Tesla");
+tesla.toLowerCase();
+```
+Just a word of caution, be careful in using these wrapper objects because it can cause bugs specially when it comes to comparisons where coercion is taking place.
+```javascript
+var meaningOfLife = 42;
+var is42 = new Number(42);
+
+console.log(meaningOfLife == is42); // true
+console.log(meaningOfLife === is42); // false
+```
+
+#### Determining `this`
+We've seen how `bind`, `call` and `apply` work but what happens when `new` is applied into the mix?
+```javascript
+var og = {
+ greet: 'hello'
+}
+
+function foo() {
+ console.log(this.greet);
+}
+
+var hi = {
+ greet: 'hi'
+}
+
+var hardbound = foo.bind(hi);
+
+hardbound();
+hardbound.call(og);
+new foo();
+new hardbound();
+```
+```
+hi
+hi
+undefined
+undefined
+```
+In this example, we see that `new` overrides what `this` refers to explicitly bound by `bind`. It always creates a new empty object, that's why `undefined` was always the result.
+
+In summary, the order of precedence to determine the `this` binding would be the following, the first rule that applies would be the `this` binding:
+
+1. `new` binding - the newly created object.
+2. Explicit binding (`call`, `apply` or `bind`) - whatever the explicit object was
+3. Implicit binding - the owning or containing object from which the function was called.
+4. Default binding - if none of the above it falls back to the global object, (or `undefined` on `strict-mode`)
+
+
+### Closures
+The ability to treat functions as values, brings up an interesting question. What happens to the functions' local variables when the said function has finished executing and was already popped off the execution stack?
+```javascript
+function greet(greeting) {
+ return function(name) {
+ console.log(greeting + ' ' + name);
+ }
+}
+
+var sayHi = greet('Hi');
+var sayHello = greet('Hello');
+sayHi('Holmes');
+sayHello('Watson');
+greet('Sup')('Morty');
+```
+```
+Hi Holmes
+Hello Watson
+Sup Morty
+```
+Remember that each function can access its outer environment whenever it wasn't able to look for a certain variable in its own environment? Not only that, functions in Javascript also maintains a reference to its outer environment even though said environment has already finished executing.
+
+In the example above, `sayHi` is a reference to a function where `'Hi'` was passed as an argument to the parameter, said function returns yet another function where said parameter is being used in addition to the latter functions' own parameter.
+
+When `sayHi('Holmes')` was invoked, it will execute `console.log(greeting + ' ' + name);`, it knows what the variable `name` is but `greeting` is not present in its own execution environment. It then goes out to its outer environment which is the place where it was written and looks for `greeting` variable. Javascript knows that said function was created inside `greet()`, eventhough it has already been popped off the stack, it's variable environment still persists which will be picked up by the `sayHi` invocation.
+
+This feature — being able to still reference the variable environment of an enclosing scope, albeit said execution environment has already been executed — is called **closure**. A function that reference variables from it's outer environment is called *a closure*.
+
+Closures can result to interesting behaviors such as:
+```javascript
+function buildFunctions() {
+ const arr = [];
+ for (var i = 0; i < 3; i++) {
+ arr.push(function() {
+ console.log(i);
+ });
+ }
+ return arr;
+}
+
+const fs = buildFunctions();
+fs[0]();
+fs[1]();
+fs[2]();
+```
+The result is partly alarming at first sight. We might think that the output would be something like:
+```
+// Did you expect?
+0
+1
+2
+```
+But instead, when we run this code we would get:
+```
+// Actual result:
+3
+3
+3
+```
+Why? The value that's being pushed in `arr` is a function that accesses the variable `i`. We know that functions doesn't get evaluated until invocation. Only when `fs[0]()` is run that it looks for `i` and has to go to its outer environment to resolve the value. But `buildFunctions()` has already been executed when we assigned the resulting array to `fs`. `buildFunctions`'s variable environment still persists but `var i`'s value has already been incremented to `3` when it finished running. Hence, when we try to reference it on our `fs[n]()` calls, what we get is the current state of the enclosing variable environment of `buildFunctions`.
+
+We could around this by using es6's `let` variable declaration to let Javascript know that we're interested only on the block level scope value of `i`:
+```javascript
+function buildFunctions() {
+ const arr = [];
+ for (let i = 0; i < 3; i++) {
+ arr.push(function() {
+ console.log(i);
+ });
+ }
+ return arr;
+}
+```
+
+Or by adding what we know from IIFEs and exploiting it, we could come up with something like:
+```javascript
+function buildFunctions() {
+ const arr = [];
+ for (var i = 0; i < 3; i++) {
+ arr.push(
+ (function(j){
+ return function() {
+ console.log(j);
+ }
+ }(i));
+ );
+ }
+ return arr;
+}
+
+var fs = buildFunctions();
+```
+This code is confusing and would be frowned upon when used in the real world but it does perfectly demonstrates what we've learned about Javascript's Closures, IIFEs and scope chains. `arr` will contain a value that is, still a function but that function is a result of an immediately-invoked function that encapsulates `i` as `j`.
+
+Now, when we invoked `fs[0]();`, `console.log(j)` will be executed, it will look for the variable `j` but since it wasn't in its own variable environment, it will then find it as the parameter of the enclosing IIFE which was in turn a copy of the value of the parameter `i` of the enclosing function. Remember that objects are pass by reference and primitives are pass by values? The value of `j` is whatever the value of `i` at the time of its execution, subsequent changes to `i` will not affect `j`.
+
+Going back to the original example, if it isn't a function and we immediately used the value of `i` like `arr.push(i)`, it would be a different scenario. But since it's a function along with the behavior of closures we are somehow able to retain the state of `buildFunctions`. This behavior is further demonstrated by the code below:
+```javascript
+function saveState() {
+ const arr = [];
+ return function(n) {
+ arr.push(n);
+ return arr;
+ };
+}
+
+const myState = saveState();
+
+console.log(myState(1));
+console.log(myState('Yo'));
+const test = myState('test');
+console.log(myState(100));
+// ... some other code here
+console.log(test);
+console.log(myState('7'));
+```
+```
+[1]
+[1, "Yo"]
+[1, "Yo", "test", 100]
+[1, "Yo", "test", 100]
+[1, "Yo", "test", 100, "7"]
+```
+
+##### Function Factories
+Using closures we could come up with interesting patterns like the commonly used function factory below:
+```javascript
+function makeGreeting(language) {
+ return function(firstName, lastName) {
+ if (language === 'en') {
+ console.log(`Hello ${firstName} ${lastName}`);
+ }
+ if (language === 'es') {
+ console.log(`Hola ${firstName} ${lastName}`);
+ }
+ }
+}
+
+var greetEnglish = makeGreeting('en');
+var greetSpanish = makeGreeting('es');
+
+greetEnglish('John', 'Doe'); // Hello John Doe
+greetSpanish('John', 'Doe'); // Hola John Doe
+```
+
+##### Currying using Closures
+As you might expect, due to the nature of closure we could also create currying functions without relying on `bind`
+```javascript
+var power = function(base) {
+ return function(exponent) {
+ return base ** exponent;
+ }
+}
+
+var square = power(2);
+square(5); // 32
+```
+Or, using ES6's arrow functions we could create an arguable concise version albeit slightly confusing if we're not aware of what's actually happenning.
+```javascript
+let power = (base) => (exponent) => base ** exponent;
+let square = power(2);
+let cube = power(3);
+
+square(5); // 32
+cube(4); // 81
+```
+
+### Functional Programming
+Using our knowledge in Closures, Functions and how Javascript treats it as first-class functions, we could now peform a certain style of programming that involves function manipulations like the following:
+```javascript
+var mapForEach = function(arr, work) {
+ const newArr = [];
+ for (var i=0; i < arr.length; i++) {
+ newArr.push(work(arr[i]));
+ };
+ return newArr;
+}
+
+var list = [1, 2, 3];
+
+var doubled = mapForEach(list, function(eachElem) {
+ return eachElem * 2;
+});
+console.log(doubled); // [2, 4, 6]
+```
+We created a function `mapForEach` that accepts an array and applies some `work()` on each element and then returns the new array, this sort of thing enables us to transform an array that is very generic — something that we could use in different scenarios.
+```javascript
+var isUnderAge = function(age) {
+ return age < 18;
+}
+
+var areAllUnderage = mapForEach(list, isUnderAge);
+console.log(areAllUnderAge);
+```
+Using closures and currying we could make the code above something more interesting.
+```javascript
+// Currying using bind
+var checkPastLimitViaBind = function(limit) {
+ return function(limiter, element) {
+ return element > limter;
+ }.bind(this, limit);
+}
+
+// Or we could use just plain closures
+var checkPastLimit = function(limit) {
+ return function(element) {
+ return element > limit;
+ }
+}
+
+var isAdult = checkPastLimit(18); // equal to checkPastLimitViaBind(18)
+console.log(list, isAdult);
+```
+Building up on the above examples, we could demonstrate the power of using small, independent and granular functions to do more interesting things:
+```javascript
+function filterArray(arr, predicate) {
+ var newArr = [];
+ for(var i = 0; i < arr.length; i++) {
+ if(predicate(arr[i])) {
+ newArr.push(arr[i]);
+ }
+ }
+}
+
+var population = [15, 20, 23, 25, 16, 14, 10, 18];
+var adults = filterArray(population, isAdult);
+console.log(adults);
+
+var me = {
+ name: 'John Smith',
+ age: 18
+}
+
+console.log(isAdult(me.age));
+```
+```
+[20, 23, 25, 18]
+true
+```
+Note that in ES6, `map`, `filter` and other functional utilities are available in arrays by default. There's also a good Javascript library called `lodash` that provides us with a lot of functional helpers.
+
+## The Prototype
+The Javascript engine always attaches a *prototype* whenever an object gets created. A prototype is used as the fallback source of properties. When an object gets a request for a property that it does not have, its prototype will be searched for the said property. When we create a `string` for example:
+```javascript
+var myString = "The quick brown fox jumps over the lazy dog";
+```
+After being processed by the Javascript engine, `myString` will have several properties and methods available for us that we didn't code, these methods are coming from the String prototype. We could take a look at the prototype by accessing the `__proto__` property. Or by invoking `Object.getPrototypeOf()`.
+```javascript
+myString.__proto__;
+Object.getPrototypeOf(myString);
+
+```
+Think of the prototype as the original blueprint that describes a certain object. Note that two object can each have a prototype that refers to the same protoype object.
+```javascript
+Object.getPrototypeOf("new String") === Object.getPrototypeOf(myString)
+```
+
+### Prototypical Inheritance
+The prototype is also an object and thus it also have a prototype. This is how the concept of inheritance is being achieved by Javascript. Instead of the conventional classes, Javascript objects are composition of various prototypes that will ultimately define the said object's behavior.
+When a property is not found on the object, it will search its prototype and if not found, it will look on the prototype's prototype and so on, further down the *prototype chain* until it eventually finds the said property.
+
+To demonstrate this, let's manually modify an object's prototype. Note that this is for demonstration purposes only and should never be done in actual development or you might mess up the background decision making of the Javascript engine as it runs your code.
+```javascript
+var human = {
+ firstName: 'Default',
+ lastName: 'Default'
+ getFullName: function() {
+ return this.firstName + ' ' + this.lastName;
+ }
+}
+
+var watson = {
+ firstName: 'John',
+ lastName: 'Watson'
+}
+
+
+// Demo purposes only, let's reassign the prototype object
+watson.__proto__ = human
+
+console.log(watson.getFullName());
+console.log(watson.firstName);
+
+var nameless = {}
+nameless.__proto__ = human
+console.log(nameless.getFullName());
+```
+```
+John Watson
+John
+Default Default
+```
+The first `console.log` references `getFullName` which the object `watson` doesn't have, the Javascript engine then goes in the prototype object which we have set to `human` and finds it there thus printing `John Watson`.
+The second `console.log` on the other hand references `firstName` which `watson` already have that's why the Javascript engine doesn't search further down the prototype chain.
+
+If we go further down to the root of the prototype chain of any object we'll discover that everything originates from the `Object` prototype.
+```javascript
+var str = "";
+var arr = [];
+var fun = function() {};
+var ob = {};
+
+console.log(str.__proto__.__proto__ === arr.__proto__.__proto__ === fun.__proto__.__proto__ === ob.__proto__);
+console.log(ob.__proto__.__proto__);
+```
+```
+true
+null
+```
+
+### Reflection
+A javascript object can look at itself, extend its by behavior and functionality by adding and/or modifying its own property and methods.
+```javascript
+var base = {
+ a: 'a',
+ b: 'b',
+ c: 'c'
+};
+
+var z = {
+ a: 'x',
+ b: 'y'
+}
+
+z.__proto__ = base;
+
+for (var prop in z) {
+ if (z.hasOwnProperty(prop)) {
+ console.log(z[prop]);
+ }
+}
+```
+> word of caution, don't use `for`..`in` when iterating array values, because you could also iterate through the properties of the Array object itself as well, not just the elements.
+```
+x
+y
+```
+The example below is a contrived version of the inner workings of the lodash's `extend` function. `createArray()` and `lib` is actually not necessary but important to demonstrate how javascript libraries exploit functional programming to implement interesting stuff like this. `createAssigner` takes some sort of utility function, in this case a function that determines all existing props in an object, then returns another function that takes an `obj` parameter where the `getKeysFunc` will be used against. `lib` is now an object where all utility functions like `extend` exists by composing and chaining utility functions like `createAssigner`. Also notice that the resulting return function of `createAssigner` only takes one parameter but when we use `lib.extend` we passed 3 arguments. If this were any other language this wouldn't be possible but since Javascript doesn't care about parameter length, and all it cares about is the function name, it's possible to not define all parameters. After all, we can still access them via `arguments`.
+```javascript
+function createAssigner(getKeysFunc)
+ return function(obj) {
+ var length = arguments.length;
+ if (length < 2 || obj == null) {
+ return obj;
+ }
+
+ for (var i = 1; i < length; i++) {
+ var source = arguments[i];
+ var keys = getKeysFunc(source);
+ for (var j = 0; j < keys.length; j++) {
+ var key = keys[j];
+ obj[key] = source[key];
+ }
+ }
+ }
+}
+
+var lib = {
+ extend: createAssigner(Object.keys);
+}
+
+var ob1 = {
+ a: 'a',
+ b: 'b'
+ c: 'c'
+}
+
+var ob2 = {
+ m: 'm',
+ n: 'n',
+ o: 'o'
+}
+
+var ob3 = {
+ x: 'x',
+ y: 'y',
+ z: 'z'
+}
+
+lib.extend(ob1, ob2, obj3);
+for (var key in ob1) {
+ console.log(obj1[key]);
+}
+```
+```
+a
+b
+c
+m
+n
+o
+x
+y
+z
+```
+`ob1` extended its behavior by adding all properties and methods coming from `ob2` and `ob3`. And we did that dynamically at run-time.
+
+#### Function Constructor's `.prototype`
+In every javascript function there's a `.prototype` property **NOT** to be confused with `.__proto__` property. The latter is the fallback source of any object, or the source template, like what we've discussed before. On the other hand, `.prototype` is being set and used when a function is used as a function constructor upon using the `new` operator.
+```javascript
+function Person(name) {
+ this.name = name;
+}
+
+function foo() {}
+
+var holmes = new Person('holmes');
+var watson = new Person('watson');
+
+console.log(Person.__proto__ === foo.__proto__);
+console.log(holmes.__proto__ === Person.prototype === watson.__proto__);
+```
+```
+true
+true
+```
+Does it make sense? `Person` itself is a function that's why its and `foo`'s `__proto__` refer to the same thing. But then `holmes` and `watson`'s `__proto__` points to `Person.prototype` because they were created with `new`. Hence, `.prototype` of a function a is a special property that points to the object that will be the `__proto__` of all the objects that will be created out of it via `new`.
+
+#### Extending via `.prototype`
+Using `.prototype` we can now extend all the objects behavior by adding or modifying it.
+```javascript
+function Person(firstname, lastname) {
+ this.firstname = firstname;
+ this.lastname = lastname;
+}
+
+Person.prototype.getFullName = function() {
+ return this.firstName + ' ' + this.lastName;
+}
+
+var sherlock = new Person('Sherlock', 'Holmes');
+var watson = new Person('John', 'Watson');
+
+
+console.log(sherlock.getFullName());
+console.log(watson.getFullName());
+```
+```
+Sherlock Holmes
+John Watson
+```
+
+### Pure Prototypal Inheritance with `Object.create`
+Another way of creating objects without relying on `new` operator. Using `Object.create` is considered as the pure prototypal inheritance because it really just assigns the target object as the prototype, nothing more and nothing less. Note that `Object.create` may not be present in older javascript versions.
+```javascript
+var person = {
+ firstname: 'Default',
+ lastname: 'Default',
+ greet: function() {
+ return 'Hi ' + this.firstname;
+ }
+}
+
+var holmes = Object.create(person);
+holmes.firstname = 'Sherlock';
+holmes.lastname = 'Holmes';
+```
+
+### ES6 Classes
+ES6 added a better syntax to create objects without using function constructors.
+```javascript
+class Person {
+ constructor(firstname, lastname) {
+ this.firstname = firstname;
+ this.lastname = lastname;
+ }
+
+ greet() {
+ return 'Hello ' + this.firstname + ' ' + this.lastname;
+ }
+}
+```
+You then use the keyword `extends` to indicate the prototype
+```javascript
+class InformalPerson extends Person {
+ constructor(firstname, lastname) {
+ super(firstname, lastname);
+ }
+
+ greet() {
+ return 'Yo ' + this.firstname;
+ }
+}
+```
+Tread carefully though, while it looks like Java classes and other conventional OOP classes, it's very important to remember that these are still just function constructors under the hood and they create objects. Don't try to strictly wrap your head around conventional OOP relationships when using ES6 classes.
+
+##### Figuring out what something is, `typeof` and `instanceof`
+Due to the dynamic nature of Javascript we will sometimes find ourselves trying to figure out what the type of the object truly is for some reason or another.
+
+```javascript
+var num = 4;
+var str = "Hello";
+var ob = {};
+var arr = [];
+var fun = function() {};
+console.log(typeof num); // number
+console.log(typeof str); // string
+console.log(typeof ob); // object
+console.log(typeof arr); // object
+console.log(typeof fun); // function
+console.log(typeof undefined); // undefined
+console.log(typeof null); // object
+console.log(holmes instanceof Person); // true
+```
+We can see in the code above how `typeof` and `instanceof` works, and immediately you should pay attention to `arr` and `null`. `null` apparently is also an `object`, and same as arrays. It does make sense since arrays aren't really primitives but a type of an object. In order to determine if an object is an array, we could do something like this:
+```javascript
+// a little weird, more of a workaround
+console.log(Object.prototype.toString.call(arr) === '[object Array]'); // true
+
+// Or, in newer versions of Javascript, we could use:
+console.log(arr instanceof Array); // true
+console.log(Array.isArray(arr)); // true
+```
+
+### Strict Mode
+We've learned that Javascript is a bit liberal or flexible. It's useful but sometimes we want it to be a bit stricter if we use strict mode.
+```javascript
+var person;
+persom = {}; // suppose we accidentally typed a typo
+console.log(persom); // Object {}, person is undefined.
+```
+If we then do this:
+```javascript
+"use strict"
+var person;
+persom = {}; // Will throw an error here.
+```
+Strict mode could also be applied locally on a function.
+```javascript
+function funfun() {
+ "use strict"
+ x = {};
+}
+var y;
+z = {};
+console.log(z);
+funfun();
+```
+```
+Object {}
+Uncaught ReferenceError: x is not defined
+```
+More details about strict mode could be read over at [MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode).
diff --git a/src/blogs/2019/vue-markdown-blog.md b/blog/2019-03-18-creating-a-simple-blog-using-vue-with-markdown.md
similarity index 96%
rename from src/blogs/2019/vue-markdown-blog.md
rename to blog/2019-03-18-creating-a-simple-blog-using-vue-with-markdown.md
index fe2c1ef..1de9385 100644
--- a/src/blogs/2019/vue-markdown-blog.md
+++ b/blog/2019-03-18-creating-a-simple-blog-using-vue-with-markdown.md
@@ -1,5 +1,10 @@
-# Creating a Simple Blog Using Vue with Markdown
-###### 18 March 2019
+---
+title: Creating a Simple Blog Using Vue with Markdown
+path: /creating-a-simple-blog-using-vue-with-markdown
+date: 2019-03-18
+summary: This post tells the story of my journey on trying to build a tinder-like user interface and eventually coming up with Kittynder! Tinder for cats.
+tags: ['learnings', 'projects', 'vue']
+---
I'm not a 'natural' frontend developer, learning vue and re-learning Javascript with my Java knowledge came as a challenge. Not to mention all those bundlers, builders, like webpack, gulp, grunt and other weird noises that adds to the overall complexitiy of learning modern web frameworks. But if there's one thing that helped me in learning new technologies that is, to just jump right in and build little projects. Teaching is also a widely accepted technique that will greatly help you in learning. It doesn't mean that you have to gather a huge audience that will listen to you teach something. Sometimes, the audience you need is just yourself. Write what you've learn with the intention of teaching it to your old (or future) stupid self. It's kinda weird and paradoxical I know but just roll with me on this.
@@ -63,7 +68,7 @@ Imported it as a component on `App.vue` and used it within the template.
Doing a quick `yarn serve` and visiting `localhost`, viola! It works!
-
+
At this point, we've verified that our Vue project can now understand and render markdown. We can now write our blogs in `.md` and just reference them wherever we like. And since it's a component there's nothing stopping us from using it as a route component, say in our `router.js`:
@@ -125,7 +130,7 @@ Using what we've learned, I've put things together and created a working demo on
First, let's look at the directory structure:
-
+
Notice that I've created subdirectories `2019` and `stories` which refers to different sections of the blog. This changes how we structure our routes a little but will greatly improve our overall UI.
@@ -188,7 +193,7 @@ Instead of an array of strings, I've converted it to an object. Each key refers
I've implemented all those additional changes to be able to display a UI like this:
-
+
The last thing we need to do is to adjust `router.js`. What it does is basically just map those blog sections into route objects. Entries under each section becomes the child of their respective route object. Basically, we'll be able to visit our blog entries using paths in this format: `${section}/${blog entry}`, eg: `2019/vue-markdown-blog`.
diff --git a/src/blogs/2019/kittynder.md b/blog/2019-06-11-kittynder.md
similarity index 98%
rename from src/blogs/2019/kittynder.md
rename to blog/2019-06-11-kittynder.md
index e99c298..f4269a4 100644
--- a/src/blogs/2019/kittynder.md
+++ b/blog/2019-06-11-kittynder.md
@@ -1,5 +1,10 @@
-# Creating a Tinder-like swipe UI on Vue
-###### 11 June 2019
+---
+title: Kittynder - Creating a Tinder-like swipe UI on Vue
+path: /kittynder
+date: 2019-06-11
+summary: This post tells the story of my journey on trying to build a tinder-like user interface and eventually coming up with Kittynder! Tinder for cats.
+tags: ['learnings', 'vue', 'design']
+---
Have you ever wondered how that swipe-right-swipe-left, tinder-like user experience was built? I did, several days ago. I come from more of a backend background, and to my uninitiated mind, I find this sort of thing really amazing.
diff --git a/src/statics/images/blogs/2018/chronocross/chronocross.png b/blog/images/chronocross/chronocross.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/chronocross.png
rename to blog/images/chronocross/chronocross.png
diff --git a/src/statics/images/blogs/2018/chronocross/eisenhower-do-it.png b/blog/images/chronocross/eisenhower-do-it.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/eisenhower-do-it.png
rename to blog/images/chronocross/eisenhower-do-it.png
diff --git a/src/statics/images/blogs/2018/chronocross/eisenhower.png b/blog/images/chronocross/eisenhower.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/eisenhower.png
rename to blog/images/chronocross/eisenhower.png
diff --git a/src/statics/images/blogs/2018/chronocross/pomodoro-work.png b/blog/images/chronocross/pomodoro-work.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/pomodoro-work.png
rename to blog/images/chronocross/pomodoro-work.png
diff --git a/src/statics/images/blogs/2018/chronocross/reports-daily-select.png b/blog/images/chronocross/reports-daily-select.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/reports-daily-select.png
rename to blog/images/chronocross/reports-daily-select.png
diff --git a/src/statics/images/blogs/2018/chronocross/reports-daily.png b/blog/images/chronocross/reports-daily.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/reports-daily.png
rename to blog/images/chronocross/reports-daily.png
diff --git a/src/statics/images/blogs/2018/chronocross/reports-task.png b/blog/images/chronocross/reports-task.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/reports-task.png
rename to blog/images/chronocross/reports-task.png
diff --git a/src/statics/images/blogs/2018/chronocross/tasklist-expand-task.png b/blog/images/chronocross/tasklist-expand-task.png
similarity index 100%
rename from src/statics/images/blogs/2018/chronocross/tasklist-expand-task.png
rename to blog/images/chronocross/tasklist-expand-task.png
diff --git a/blog/images/codenoobsguide/genchar.png b/blog/images/codenoobsguide/genchar.png
new file mode 100644
index 0000000..7b863d8
Binary files /dev/null and b/blog/images/codenoobsguide/genchar.png differ
diff --git a/blog/images/codenoobsguide/main.png b/blog/images/codenoobsguide/main.png
new file mode 100644
index 0000000..aa27d5b
Binary files /dev/null and b/blog/images/codenoobsguide/main.png differ
diff --git a/src/statics/images/blogs/2019/vue-markdown-blog/filestruc.png b/blog/images/vue-markdown-blog/filestruc.png
similarity index 100%
rename from src/statics/images/blogs/2019/vue-markdown-blog/filestruc.png
rename to blog/images/vue-markdown-blog/filestruc.png
diff --git a/src/statics/images/blogs/2019/vue-markdown-blog/foo.png b/blog/images/vue-markdown-blog/foo.png
similarity index 100%
rename from src/statics/images/blogs/2019/vue-markdown-blog/foo.png
rename to blog/images/vue-markdown-blog/foo.png
diff --git a/src/statics/images/blogs/2019/vue-markdown-blog/home.png b/blog/images/vue-markdown-blog/home.png
similarity index 100%
rename from src/statics/images/blogs/2019/vue-markdown-blog/home.png
rename to blog/images/vue-markdown-blog/home.png
diff --git a/src/statics/images/blogs/2018/weird-javascript.png b/blog/images/weird-js/weird-javascript.png
similarity index 100%
rename from src/statics/images/blogs/2018/weird-javascript.png
rename to blog/images/weird-js/weird-javascript.png
diff --git a/gridsome.config.js b/gridsome.config.js
new file mode 100644
index 0000000..6ec591d
--- /dev/null
+++ b/gridsome.config.js
@@ -0,0 +1,82 @@
+// This is where project configuration and plugin options are located.
+// Learn more: https://gridsome.org/docs/config
+
+// Changes here require a server restart.
+// To restart press CTRL + C in terminal and run `gridsome develop`
+
+module.exports = {
+ siteName: 'Joseph Harvey Angeles | Personal Portfolio',
+ siteDescription: 'A simple portfolio theme for Gridsome powered by Tailwind CSS v1',
+ siteUrl: 'https://www.josephharveyangeles.com',
+ plugins: [
+ {
+ use: 'gridsome-plugin-tailwindcss',
+ },
+ {
+ use: '@gridsome/vue-remark',
+ options: {
+ typeName: 'Project', // Required
+ baseDir: './projects', // Where .md files are located
+ pathPrefix: '/projects', // Add route prefix. Optional
+ template: './src/templates/Project.vue', // Optional
+ plugins: [
+ [ 'gridsome-plugin-remark-shiki', { theme: 'Material-Theme-Palenight', skipInline: true } ]
+ ],
+ }
+ },
+ {
+ use: '@gridsome/source-filesystem',
+ options: {
+ path: 'blog/**/*.md',
+ typeName: 'Post',
+ refs: {
+ tags: {
+ typeName: 'Tag',
+ create: true
+ }
+ }
+ }
+ },
+ {
+ use: 'gridsome-plugin-rss',
+ options: {
+ contentTypeName: 'Post',
+ feedOptions: {
+ title: 'Joseph Harvey Angeles | Blog',
+ feed_url: 'https://www.josephharveyangeles.com/rss.xml',
+ site_url: 'https://www.josephharveyangeles.com/'
+ },
+ feedItemOptions: node => ({
+ title: node.title,
+ description: node.summary,
+ url: 'https://www.josephharveyangeles.com' + node.path,
+ author: 'Joseph Harvey Angeles',
+ date: node.date
+ }),
+ output: {
+ dir: './static',
+ name: 'rss.xml'
+ }
+ }
+ },
+ {
+ use: '@gridsome/plugin-sitemap',
+ options: {
+ cacheTime: 600000, // default
+ }
+ },
+ ],
+ templates: {
+ Tag: '/tag/:id'
+ },
+ transformers: {
+ remark: {
+ plugins: [
+ [ 'gridsome-plugin-remark-shiki', { theme: 'Material-Theme-Palenight', skipInline: true } ]
+ ],
+ externalLinksTarget: '_blank',
+ externalLinksRel: ['nofollow', 'noopener', 'noreferrer'],
+ anchorClassName: 'icon icon-link',
+ }
+ },
+}
diff --git a/gridsome.server.js b/gridsome.server.js
new file mode 100644
index 0000000..8aeda39
--- /dev/null
+++ b/gridsome.server.js
@@ -0,0 +1,11 @@
+// Server API makes it possible to hook into various parts of Gridsome
+// on server-side and add custom data to the GraphQL data layer.
+// Learn more: https://gridsome.org/docs/server-api
+
+// Changes here require a server restart.
+// To restart press CTRL + C in terminal and run `gridsome develop`
+
+module.exports = function (api, options) {
+ api.loadSource(store => {
+ })
+}
diff --git a/license b/license
new file mode 100644
index 0000000..4dbcdf1
--- /dev/null
+++ b/license
@@ -0,0 +1,7 @@
+Copyright 2019 Andre Madarang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/netlify.toml b/netlify.toml
index 89f63df..fd68ede 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,9 +1,3 @@
[build]
- command = "quasar build"
- publish = "dist/spa-mat"
- environment = { YARN_VERSION = "1.6.0" }
-
-[[redirects]]
- from = "/*"
- to = "/index.html"
- status = 200
+ publish = "dist"
+ command = "gridsome build"
diff --git a/package.json b/package.json
index c523678..5a09c46 100644
--- a/package.json
+++ b/package.json
@@ -1,48 +1,25 @@
{
- "name": "portfolio",
- "version": "5.1.0",
- "description": "Joseph Harvey Angeles | Software Engineer",
- "productName": "Joseph Harvey Angeles | Software Engineer",
- "cordovaId": "org.cordova.quasar.app",
- "author": "yev ",
+ "name": "andremadarang",
"private": true,
"scripts": {
- "lint": "eslint --ext .js,.vue src",
- "test": "echo \"No test specified\" && exit 0"
+ "build": "gridsome build",
+ "develop": "gridsome develop",
+ "explore": "gridsome explore"
},
"dependencies": {
- "@fortawesome/fontawesome-svg-core": "^1.2.13",
- "@fortawesome/free-brands-svg-icons": "^5.7.0",
- "@fortawesome/vue-fontawesome": "^0.1.5",
- "axios": "^0.18.0",
- "vue-disqus": "^3.0.5",
- "vue-social-sharing": "^2.4.2",
- "vuelidate": "^0.7.4"
+ "@gridsome/plugin-sitemap": "^0.4.0",
+ "@gridsome/source-filesystem": "^0.6.2",
+ "@gridsome/transformer-remark": "^0.6.1",
+ "@gridsome/vue-remark": "^0.2.2",
+ "axios": "^0.19.2",
+ "gridsome": "^0.7.18",
+ "gridsome-plugin-remark-shiki": "^0.3.1",
+ "gridsome-plugin-rss": "^1.2.0",
+ "vue-fuse": "^2.2.1",
+ "vue-scrollto": "^2.18.1",
+ "vue-typed-js": "^0.1.2"
},
"devDependencies": {
- "babel-eslint": "^8.2.1",
- "eslint": "^4.18.2",
- "eslint-config-standard": "^11.0.0",
- "eslint-friendly-formatter": "^4.0.1",
- "eslint-loader": "^2.0.0",
- "eslint-plugin-import": "^2.9.0",
- "eslint-plugin-node": "^6.0.1",
- "eslint-plugin-promise": "^3.7.0",
- "eslint-plugin-standard": "^3.0.1",
- "eslint-plugin-vue": "^4.3.0",
- "prerender-spa-plugin": "^3.4.0",
- "quasar-cli": "^0.17.0",
- "strip-ansi": "=3.0.1",
- "vue-markdown-loader": "^2.4.1"
- },
- "engines": {
- "node": ">= 8.9.0",
- "npm": ">= 5.6.0",
- "yarn": ">= 1.6.0"
- },
- "browserslist": [
- "> 1%",
- "last 2 versions",
- "not ie <= 10"
- ]
+ "gridsome-plugin-tailwindcss": "^3.0.1"
+ }
}
diff --git a/projects/2017-02-06-osyshub.md b/projects/2017-02-06-osyshub.md
new file mode 100644
index 0000000..f777720
--- /dev/null
+++ b/projects/2017-02-06-osyshub.md
@@ -0,0 +1,17 @@
+---
+title: OSyshub
+subtitle: Our Lady of the Most Holy Rosary Parish System Hub
+description: Parish-related processes and management system.
+date: 2017-02-06
+---
+
+
+OLMHRP — Our Lady of the Most Holy Rosary Parish is a church near the hometown when I grew up in. I wrote OSyshub as a solution to help digitized and automate most of the parish-related processes.
+
+OSysHub is purely written in Java and Java Swing to build the UI. OSysHub is just fancy way of saying, System Hub. The idea is to create a unified application that will handle all church related-processes. I designed it with a plugin architecture so I could build every system independently and iteratively on-demand.
+
+Currently, OSysHub contains a Columbary Management System and a Voucher/Cheque Printing feature complete with tests.
+
+I've extracted an API — [Bethelscribe](https://github.com/vycoder/bethelscribe) out of OSysHub and made it public on github.
+
+> "We have a major problem regarding filing records. OSysHub was the solution that we never knew we needed until it's here." — Our Lady of the Most Holy Rosary Parish Admin
diff --git a/projects/2018-06-04-zoom-app.md b/projects/2018-06-04-zoom-app.md
new file mode 100644
index 0000000..ce14a54
--- /dev/null
+++ b/projects/2018-06-04-zoom-app.md
@@ -0,0 +1,13 @@
+---
+title: Zoom App
+subtitle: Product Inventory App using Barcode
+description: An inventory and tracking mobile application.
+date: 2018-06-04
+---
+
+
+ZoomApp is a mobile application that I created for a client that wanted a mobile solution for an inventory and tracking system.
+
+The application is specifically tailored for the client's use case. Equipped with a barcode and camera functionality, it helps the clients track the products that are being delivered across the country.
+
+> "He's very professional and knowledgeable in this line of work. He's one of the best collaborators in this industry. He will surely give you the finished product/project beyond expectation. We will surely come back and get his service again in the future." — Karen Daguio, Sendeya
diff --git a/projects/2019-01-20-dldnation.md b/projects/2019-01-20-dldnation.md
new file mode 100644
index 0000000..2a9bc17
--- /dev/null
+++ b/projects/2019-01-20-dldnation.md
@@ -0,0 +1,15 @@
+---
+title: DLDNation
+subtitle: Fitness Web App
+description: Dedicated Fitness Web App for DLDNation, where users can subscribe to latest health and fitness tips, routines and exercies for DLDNation's clients.
+date: 2019-01-20
+---
+
+
+Sean and Dala are a husband and wife coaching team that takes no BS approach to health and fitness. They offer highly effective training programs, meal plans and over-all health and fitness coaching.
+
+www.dldnation.com is an extension of their passionate work — an exclusive online platform that gives users access to what DlDNation is all about.
+
+Regular health and fitness video content, training tips, meal diets, and latest trends. It's a platform where Dala can share her expertise to a wider audience. User's can also directly chat and message Dala for a one-on-one remote consultation.
+
+Checkout the dev version [here](https://develop--dldnation.netlify.app).
diff --git a/projects/2019-06-25-wilyfish.md b/projects/2019-06-25-wilyfish.md
new file mode 100644
index 0000000..f0677b0
--- /dev/null
+++ b/projects/2019-06-25-wilyfish.md
@@ -0,0 +1,14 @@
+---
+title: Wilyfish
+subtitle: Brand Management and Protection Platform
+description: A brand management platform that contains various tools for managing and protecting your brand using actionable intelligent Data Analytics. I've built both the web app and the mobile version available in both Android and iOS devices.
+date: 2019-06-25
+---
+
+
+
+WilyFish is a brand protection platform offering innovative search tools for locating the “unfindable” in databases and on the internet. WilyFish is the best tool for your trademark clearance, trademark policing and domain name availability because WilyFish can locate graphics, design images, logo images, words, and phrases.
+
+I'm mainly responsible for the design and implementation of the mobile application as well as the frontend aspect of the Wilyfish platform.
+
+_Interested about protecting your brand? Check out Wilyfish [here](https://wilyfish.com)_.
diff --git a/projects/2020-02-21-sixgill.md b/projects/2020-02-21-sixgill.md
new file mode 100644
index 0000000..070e224
--- /dev/null
+++ b/projects/2020-02-21-sixgill.md
@@ -0,0 +1,14 @@
+---
+title: Sixgill Fishing App
+subtitle: A social media platform for Sixgill Fishing community
+description: A social media platform for Sixgill fishing community. Users can share their latest catch, ask questions, get up-to-date with latest giveaways, and more. Available in both Android and iOS devices.
+date: 2020-02-21
+---
+
+
+
+It's a social media platform for line fishing enthusiasts. Users can share their latest catch, fishing spots, tips and tricks. There's also a Question and Answer section that works much like Quora.
+
+An admin CMS was also built to manage and moderate user activity. Client also regularly publish promos and giveaways directly to the app notifying all connected users via push notifications.
+
+I designed everything from the UI/UX to the backend API architecture. This is one of those projects wherein I had a lot of fun building.
diff --git a/projects/2020-07-17-enFocus.md b/projects/2020-07-17-enFocus.md
new file mode 100644
index 0000000..9021d58
--- /dev/null
+++ b/projects/2020-07-17-enFocus.md
@@ -0,0 +1,52 @@
+---
+title: enFocus
+subtitle: Productivity App (Production version of Qodo)
+description: Combines of three of the best productivity techniques; To-do list, Pomodoro and Eisenhower Method in one cohesive workflow, presented in a simple, clean and minimalist app.
+date: 2020-07-17
+---
+
+
+[**enFocus**](https://getenfocus.com) combines of three of the best productivity techniques: To-do list, Pomodoro and Eisenhower Method in one cohesive workflow, presented in a simple, clean and minimalist app. It's available in [Desktop](https://getenfocus.com/download) (Windows, Linux) and [Mobile (Android)](https://play.google.com/store/apps/details?id=com.nightowl.enfocus.app) platforms.
+
+- 📋 Organize your tasks into projects.
+- ⏱️ Work on your tasks into chunks of focused sprints.
+- ⚖️ Manage priorities, eliminate "mere-urgency" and time-wasters tasks.
+- 📊 Keep track of your progress.
+
+**The Pomodoro Technique®** is a time management method developed by Francesco Cirilo in the late 1980's. The technique uses a timer to break down work into intervals, 25 minutes in length, separated by short breaks of 5 minutes, and a 15-minute long break after 4 successive sprints. This philosophy aims to provide the user with the maximum focus and creative freshness, thereby allowing them to complete projects faster with less mental fatigue.
+
+
+
+**The Eisenhower Method** complements the Pomodoro Technique really well. This method stems from a quote attributed to Dwight D. Eisenhower: *"I have two kinds of problems, the urgent and the important. The urgent are not important, and the important are never urgent."*
+
+
+
+The Eisenhower Method is a simple tool for considering the long-term outcomes of your daily tasks and focusing on what will make you most efficient, not just most productive. Visualize all your tasks in a matrix of urgent/important. All of your daily tasks and projects should fall into one of these four quadrants:
+
+- Urgent & Important tasks are to be done immediately
+- Not Urgent & Important tasks are to be scheduled or considered in other quadrants
+- Urgent & Unimportant tasks are to be delegated to someone else
+- Not Urgent & Unimportant tasks are to be deleted
+
+
+**Other Features**
+
+- Lightweight
+- Keeps screen on
+- Swipe tasks to complete or start
+- Sprint Duration options
+- Group tasks into projects
+- Fullscreen mode
+- No personal data collection
+- and more
+
+**Premium Features**
+
+- More Sprint Duration options
+- Custom reports
+- Export reports to CSV, PNG or SVG
+- Ad free
+- All future features are free
+- **Feature priority suggestions*
+
+**enFocus is designed to strongly adhere with the Pomodoro Technique and The Eisenhower Method to keeps things authentic and also simple.*
diff --git a/src/statics/images/projects/asskit.png b/projects/images/asskit.png
similarity index 100%
rename from src/statics/images/projects/asskit.png
rename to projects/images/asskit.png
diff --git a/src/statics/images/projects/chronocross.png b/projects/images/chronocross.png
similarity index 100%
rename from src/statics/images/projects/chronocross.png
rename to projects/images/chronocross.png
diff --git a/src/statics/images/projects/dldnation.png b/projects/images/dldnation.png
similarity index 100%
rename from src/statics/images/projects/dldnation.png
rename to projects/images/dldnation.png
diff --git a/projects/images/enfocus/logo.png b/projects/images/enfocus/logo.png
new file mode 100644
index 0000000..1d484d4
Binary files /dev/null and b/projects/images/enfocus/logo.png differ
diff --git a/projects/images/enfocus/priority.gif b/projects/images/enfocus/priority.gif
new file mode 100644
index 0000000..bb0b930
Binary files /dev/null and b/projects/images/enfocus/priority.gif differ
diff --git a/projects/images/enfocus/tasks.gif b/projects/images/enfocus/tasks.gif
new file mode 100644
index 0000000..b1e33a6
Binary files /dev/null and b/projects/images/enfocus/tasks.gif differ
diff --git a/src/statics/images/projects/ghostdrive.png b/projects/images/ghostdrive.png
similarity index 100%
rename from src/statics/images/projects/ghostdrive.png
rename to projects/images/ghostdrive.png
diff --git a/src/statics/images/projects/jquizzer.png b/projects/images/jquizzer.png
similarity index 100%
rename from src/statics/images/projects/jquizzer.png
rename to projects/images/jquizzer.png
diff --git a/src/statics/images/projects/killthebeast.png b/projects/images/killthebeast.png
similarity index 100%
rename from src/statics/images/projects/killthebeast.png
rename to projects/images/killthebeast.png
diff --git a/src/statics/images/projects/kittynder.gif b/projects/images/kittynder.gif
similarity index 100%
rename from src/statics/images/projects/kittynder.gif
rename to projects/images/kittynder.gif
diff --git a/src/statics/images/projects/ledlamp.png b/projects/images/ledlamp.png
similarity index 100%
rename from src/statics/images/projects/ledlamp.png
rename to projects/images/ledlamp.png
diff --git a/src/statics/images/projects/nreciquery.png b/projects/images/nreciquery.png
similarity index 100%
rename from src/statics/images/projects/nreciquery.png
rename to projects/images/nreciquery.png
diff --git a/src/statics/images/projects/osyshub.png b/projects/images/osyshub.png
similarity index 100%
rename from src/statics/images/projects/osyshub.png
rename to projects/images/osyshub.png
diff --git a/src/statics/images/projects/pingponger.png b/projects/images/pingponger.png
similarity index 100%
rename from src/statics/images/projects/pingponger.png
rename to projects/images/pingponger.png
diff --git a/src/statics/images/projects/prjricemill.png b/projects/images/prjricemill.png
similarity index 100%
rename from src/statics/images/projects/prjricemill.png
rename to projects/images/prjricemill.png
diff --git a/src/statics/images/projects/recigle.png b/projects/images/recigle.png
similarity index 100%
rename from src/statics/images/projects/recigle.png
rename to projects/images/recigle.png
diff --git a/src/statics/images/projects/silica.png b/projects/images/silica.png
similarity index 100%
rename from src/statics/images/projects/silica.png
rename to projects/images/silica.png
diff --git a/src/statics/images/projects/sixgill.png b/projects/images/sixgill.png
similarity index 100%
rename from src/statics/images/projects/sixgill.png
rename to projects/images/sixgill.png
diff --git a/src/statics/images/projects/smartac.png b/projects/images/smartac.png
similarity index 100%
rename from src/statics/images/projects/smartac.png
rename to projects/images/smartac.png
diff --git a/src/statics/images/projects/sudoku.png b/projects/images/sudoku.png
similarity index 100%
rename from src/statics/images/projects/sudoku.png
rename to projects/images/sudoku.png
diff --git a/src/statics/images/projects/switcheroo.png b/projects/images/switcheroo.png
similarity index 100%
rename from src/statics/images/projects/switcheroo.png
rename to projects/images/switcheroo.png
diff --git a/src/statics/images/projects/tessa.png b/projects/images/tessa.png
similarity index 100%
rename from src/statics/images/projects/tessa.png
rename to projects/images/tessa.png
diff --git a/src/statics/images/projects/vnote.png b/projects/images/vnote.png
similarity index 100%
rename from src/statics/images/projects/vnote.png
rename to projects/images/vnote.png
diff --git a/src/statics/images/projects/vue-animate-scroll.png b/projects/images/vue-animate-scroll.png
similarity index 100%
rename from src/statics/images/projects/vue-animate-scroll.png
rename to projects/images/vue-animate-scroll.png
diff --git a/src/statics/images/projects/wilyfish.png b/projects/images/wilyfish.png
similarity index 100%
rename from src/statics/images/projects/wilyfish.png
rename to projects/images/wilyfish.png
diff --git a/src/statics/images/projects/zoomapp.png b/projects/images/zoomapp.png
similarity index 100%
rename from src/statics/images/projects/zoomapp.png
rename to projects/images/zoomapp.png
diff --git a/quasar.conf.js b/quasar.conf.js
deleted file mode 100644
index 35c97a8..0000000
--- a/quasar.conf.js
+++ /dev/null
@@ -1,165 +0,0 @@
-const path = require('path')
-const PrerenderSPAPlugin = require('prerender-spa-plugin')
-
-module.exports = function (ctx) {
- return {
- plugins: [
- 'fontawesome',
- 'vuelidate',
- 'disqus',
- 'colors'
- ],
- css: [
- 'app.styl'
- ],
- extras: [
- ctx.theme.mat ? 'roboto-font' : null,
- 'material-icons' // optional, you are not bound to it
- // 'ionicons',
- // 'mdi',
- // 'fontawesome'
- ],
- supportIE: false,
- build: {
- scopeHoisting: true,
- vueRouterMode: 'history',
- // vueCompiler: true,
- // gzip: true,
- // analyze: true,
- // extractCSS: false,
- extendWebpack (cfg) {
- cfg.module.rules.push({
- enforce: 'pre',
- test: /\.(js|vue)$/,
- loader: 'eslint-loader',
- exclude: /node_modules/
- })
- if (!ctx.prod) {
- return
- }
- cfg.plugins.push(new PrerenderSPAPlugin(path.resolve(__dirname, 'dist/spa-mat'), ['/']))
- },
- chainWebpack (chain) {
- chain.module.rule('md')
- .test(/\.md/)
- .use('vue-loader')
- .loader('vue-loader')
- .end()
- .use('vue-markdown-loader')
- .loader('vue-markdown-loader/lib/markdown-compiler')
- .options({
- raw: true
- })
- chain.resolve.alias.set('blogs', path.resolve(__dirname, './src/blogs'))
- chain.resolve.alias.set('statics', path.resolve(__dirname, './src/statics'))
- }
- },
- devServer: {
- // https: true,
- // port: 8080,
- open: true // opens browser window automatically
- },
- // framework: 'all' --- includes everything; for dev only!
- framework: {
- components: [
- 'QLayout',
- 'QLayoutHeader',
- 'QLayoutFooter',
- 'QLayoutDrawer',
- 'QPageContainer',
- 'QPage',
- 'QToolbar',
- 'QToolbarTitle',
- 'QBtn',
- 'QIcon',
- 'QList',
- 'QListHeader',
- 'QItem',
- 'QItemMain',
- 'QItemSide',
- 'QItemSeparator'
- ],
- directives: [
- 'Ripple'
- ],
- // Quasar plugins
- plugins: [
- 'Notify',
- 'Meta'
- ]
- // iconSet: ctx.theme.mat ? 'material-icons' : 'ionicons'
- // i18n: 'de' // Quasar language
- },
- // animations: 'all' --- includes all animations
- animations: [],
- ssr: {
- pwa: false
- },
- pwa: {
- // workboxPluginMode: 'InjectManifest',
- // workboxOptions: {},
- manifest: {
- // name: 'Quasar App',
- // short_name: 'Quasar-PWA',
- // description: 'Best PWA App in town!',
- display: 'standalone',
- orientation: 'portrait',
- background_color: '#ffffff',
- theme_color: '#027be3',
- icons: [
- {
- 'src': 'statics/icons/icon-128x128.png',
- 'sizes': '128x128',
- 'type': 'image/png'
- },
- {
- 'src': 'statics/icons/icon-192x192.png',
- 'sizes': '192x192',
- 'type': 'image/png'
- },
- {
- 'src': 'statics/icons/icon-256x256.png',
- 'sizes': '256x256',
- 'type': 'image/png'
- },
- {
- 'src': 'statics/icons/icon-384x384.png',
- 'sizes': '384x384',
- 'type': 'image/png'
- },
- {
- 'src': 'statics/icons/icon-512x512.png',
- 'sizes': '512x512',
- 'type': 'image/png'
- }
- ]
- }
- },
- cordova: {
- // id: 'org.cordova.quasar.app'
- },
- electron: {
- // bundler: 'builder', // or 'packager'
- extendWebpack (cfg) {
- // do something with Electron process Webpack cfg
- },
- packager: {
- // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
-
- // OS X / Mac App Store
- // appBundleId: '',
- // appCategoryType: '',
- // osxSign: '',
- // protocol: 'myapp://path',
-
- // Window only
- // win32metadata: { ... }
- },
- builder: {
- // https://www.electron.build/configuration/configuration
-
- // appId: 'quasar-app'
- }
- }
- }
-}
diff --git a/src/.temp/config.js b/src/.temp/config.js
new file mode 100644
index 0000000..81e1d88
--- /dev/null
+++ b/src/.temp/config.js
@@ -0,0 +1,8 @@
+export default {
+ "trailingSlash": true,
+ "pathPrefix": "",
+ "titleTemplate": "%s - Joseph Harvey Angeles | Personal Portfolio",
+ "siteUrl": "https://www.josephharveyangeles.com",
+ "version": "0.7.19",
+ "catchLinks": true
+}
\ No newline at end of file
diff --git a/src/.temp/constants.js b/src/.temp/constants.js
new file mode 100644
index 0000000..733d389
--- /dev/null
+++ b/src/.temp/constants.js
@@ -0,0 +1,2 @@
+export const NOT_FOUND_NAME = "404"
+export const NOT_FOUND_PATH = "/404"
diff --git a/src/.temp/icons.js b/src/.temp/icons.js
new file mode 100644
index 0000000..5d34d3d
--- /dev/null
+++ b/src/.temp/icons.js
@@ -0,0 +1,41 @@
+export default {
+ "touchiconMimeType": "image/png",
+ "faviconMimeType": "image/png",
+ "precomposed": false,
+ "touchicons": [
+ {
+ "width": 76,
+ "src": "/assets/static/src/favicon.png?width=76&key=a16d6f3"
+ },
+ {
+ "width": 152,
+ "src": "/assets/static/src/favicon.png?width=152&key=a16d6f3"
+ },
+ {
+ "width": 120,
+ "src": "/assets/static/src/favicon.png?width=120&key=a16d6f3"
+ },
+ {
+ "width": 167,
+ "src": "/assets/static/src/favicon.png?width=167&key=a16d6f3"
+ },
+ {
+ "width": 180,
+ "src": "/assets/static/src/favicon.png?width=180&key=a16d6f3"
+ }
+ ],
+ "favicons": [
+ {
+ "width": 16,
+ "src": "/assets/static/src/favicon.png?width=16&key=dd45aa3"
+ },
+ {
+ "width": 32,
+ "src": "/assets/static/src/favicon.png?width=32&key=dd45aa3"
+ },
+ {
+ "width": 96,
+ "src": "/assets/static/src/favicon.png?width=96&key=dd45aa3"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/.temp/now.js b/src/.temp/now.js
new file mode 100644
index 0000000..91a7112
--- /dev/null
+++ b/src/.temp/now.js
@@ -0,0 +1 @@
+export default 1594991398688
\ No newline at end of file
diff --git a/src/.temp/plugins-client.js b/src/.temp/plugins-client.js
new file mode 100644
index 0000000..dca28a3
--- /dev/null
+++ b/src/.temp/plugins-client.js
@@ -0,0 +1,3 @@
+
+export default [
+]
diff --git a/src/.temp/plugins-server.js b/src/.temp/plugins-server.js
new file mode 100644
index 0000000..c3bdd07
--- /dev/null
+++ b/src/.temp/plugins-server.js
@@ -0,0 +1,13 @@
+import plugin_gridsome_plugin_tailwindcss_5 from "/home/yev/Projects/portfolio/node_modules/gridsome-plugin-tailwindcss/gridsome.client.js"
+import plugin_gridsome_vue_remark_6 from "/home/yev/Projects/portfolio/node_modules/@gridsome/vue-remark/gridsome.client.js"
+
+export default [
+ {
+ run: plugin_gridsome_plugin_tailwindcss_5,
+ options: {"shouldImport":true,"shouldTimeTravel":true,"importUrlConfig":{"modernBrowser":true},"presetEnvConfig":{"stage":0,"autoprefixer":false,"features":{"focus-visible-pseudo-class":false,"focus-within-pseudo-class":false}}}
+ },
+ {
+ run: plugin_gridsome_vue_remark_6,
+ options: {}
+ }
+]
diff --git a/src/.temp/routes.js b/src/.temp/routes.js
new file mode 100644
index 0000000..605b246
--- /dev/null
+++ b/src/.temp/routes.js
@@ -0,0 +1,103 @@
+const c1 = () => import(/* webpackChunkName: "page--src--templates--tag-vue" */ "/home/yev/Projects/portfolio/src/templates/Tag.vue")
+const c2 = () => import(/* webpackChunkName: "page--src--templates--project-vue" */ "/home/yev/Projects/portfolio/src/templates/Project.vue")
+const c3 = () => import(/* webpackChunkName: "page--src--pages--projects-vue" */ "/home/yev/Projects/portfolio/src/pages/Projects.vue")
+const c4 = () => import(/* webpackChunkName: "page--src--pages--blog-vue" */ "/home/yev/Projects/portfolio/src/pages/Blog.vue")
+const c5 = () => import(/* webpackChunkName: "page--src--templates--post-vue" */ "/home/yev/Projects/portfolio/src/templates/Post.vue")
+const c6 = () => import(/* webpackChunkName: "page--src--pages--404-vue" */ "/home/yev/Projects/portfolio/src/pages/404.vue")
+const c7 = () => import(/* webpackChunkName: "page--src--pages--index-vue" */ "/home/yev/Projects/portfolio/src/pages/Index.vue")
+
+export default [
+ {
+ path: "/tag/:id/:page(\\d+)?/",
+ component: c1
+ },
+ {
+ path: "/projects/2018-06-04-zoom-app/",
+ component: c2,
+ meta: {
+ $vueRemark: () => import(/* webpackChunkName: "vue-remark--projects--2018-06-04-zoom-app-md" */ "/home/yev/Projects/portfolio/projects/2018-06-04-zoom-app.md")
+ }
+ },
+ {
+ path: "/projects/2020-07-17-en-focus/",
+ component: c2,
+ meta: {
+ $vueRemark: () => import(/* webpackChunkName: "vue-remark--projects--2020-07-17-en-focus-md" */ "/home/yev/Projects/portfolio/projects/2020-07-17-enFocus.md")
+ }
+ },
+ {
+ path: "/projects/2017-02-06-osyshub/",
+ component: c2,
+ meta: {
+ $vueRemark: () => import(/* webpackChunkName: "vue-remark--projects--2017-02-06-osyshub-md" */ "/home/yev/Projects/portfolio/projects/2017-02-06-osyshub.md")
+ }
+ },
+ {
+ path: "/projects/2019-01-20-dldnation/",
+ component: c2,
+ meta: {
+ $vueRemark: () => import(/* webpackChunkName: "vue-remark--projects--2019-01-20-dldnation-md" */ "/home/yev/Projects/portfolio/projects/2019-01-20-dldnation.md")
+ }
+ },
+ {
+ path: "/projects/2019-06-25-wilyfish/",
+ component: c2,
+ meta: {
+ $vueRemark: () => import(/* webpackChunkName: "vue-remark--projects--2019-06-25-wilyfish-md" */ "/home/yev/Projects/portfolio/projects/2019-06-25-wilyfish.md")
+ }
+ },
+ {
+ path: "/projects/2020-02-21-sixgill/",
+ component: c2,
+ meta: {
+ $vueRemark: () => import(/* webpackChunkName: "vue-remark--projects--2020-02-21-sixgill-md" */ "/home/yev/Projects/portfolio/projects/2020-02-21-sixgill.md")
+ }
+ },
+ {
+ path: "/projects/:page(\\d+)?/",
+ component: c3
+ },
+ {
+ path: "/blog/:page(\\d+)?/",
+ component: c4
+ },
+ {
+ path: "/javascript-weird-parts/",
+ component: c5
+ },
+ {
+ path: "/kittynder/",
+ component: c5
+ },
+ {
+ path: "/creating-a-simple-blog-using-vue-with-markdown/",
+ component: c5
+ },
+ {
+ path: "/introducing-chronocross/",
+ component: c5
+ },
+ {
+ path: "/codenoobs-guide-out-of-mediocrity-genchar/",
+ component: c5
+ },
+ {
+ path: "/codenoobs-guide-out-of-mediocrity-main/",
+ component: c5
+ },
+ {
+ name: "404",
+ path: "/404/",
+ component: c6
+ },
+ {
+ name: "home",
+ path: "/",
+ component: c7
+ },
+ {
+ name: "*",
+ path: "*",
+ component: c6
+ }
+]
diff --git a/src/App.vue b/src/App.vue
deleted file mode 100644
index 76260c8..0000000
--- a/src/App.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- Do you have something in mind? A business idea, a software problem, or perhaps expanding your business to the digital world? Or if you just happen to need a person with my skills, feel free to contact me, let's discuss! Email me at josephharveyangeles@gmail.com.
-
+ Salute plurimam dicit. I'm Yev, a Freelance Software Engineer based in Manila, Philippines, founder of Night Owl Studios. I convert coffee into code. I'm very passionate about Software Engineering, learning, teaching and building stuff. I specialize in creating bespoke software applications using mostly Vue.js and Quasar on the frontend, Java and Eclipse Vert.x on the backend. When I'm not building stuff for a client or working on a side project, you'll find me tinkering with hobby electronics or playing with cats.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Some projects I've worked on:
+
+
+
+
+
+
+
+
Project Qodo
+
+ An open-source productivity app that also serves as a learning resource for building multi-platform apps using Quasar. Available in both desktop and mobile. Visit the live version here. Check the Github Repo.
-
-
-
-
-
-
-
+
+
+
Sixgill Fishing App
+
+ A social media platform for Sixgill fishing community. Users can share their latest catch, ask questions, get up-to-date with latest giveaways, and more. Available in both Android and iOS devices.
+
+
+
+
Wilyfish
+
+ Wilyfish is a brand management platform that contains various tools for managing and protecting your brand using actionable intelligent Data Analytics. I've built both the web app and the mobile version available in both Android and iOS devices.
+
+
+
+
Other projects...
+
+ Visit my Projects page to get a full list of all the projects that I've worked on.
+
+
+
+
+
+
+
+
+
+
Work Experience:
+
+
+
+
+
+
+
+ DigitalCandy®
+
2018-Now
+
+
+ Software Consultant
+
+
+
+
+ Accenture
+
2017-2018
+
+
+ Application Developer Team Lead
+
+
+
+
+ Vertere Solutions, Inc - Accenture
+
2017-2018
+
+
+ Programmer Analyst 3
+
+
+
+
+ Nokia Networks
+
2014-2017
+
+
+ Software Specialist / R&D Engineer 3
+
+
+
+
-
-
-
-
About Me
-
+
+
+
+
+
Recent stuff:
+
+
+
+
+
+
+
+
+ I've been fortunate enough to have the opportunity to speak at the very first Quasar Conference. If you're interested with this awesome framework check the full recording below. I'm the first speaker, I talked about some of the techniques and nuances of building a multi-platform application.
+
+ Have something in mind? A business idea, a software problem, or perhaps you're expanding your business into the digital world? Or if you just happen to need a person with my skills, feel free to contact me. Let's discuss!
+
+
+
+
+
+
+
+
+
+
Join my Newsletter
+
+
+
+ Unfortunately I'm still working on this, Sorry! Check back again some other time.
+
-
-
-
-
-
diff --git a/src/pages/README.md b/src/pages/README.md
new file mode 100644
index 0000000..9edbf1d
--- /dev/null
+++ b/src/pages/README.md
@@ -0,0 +1,5 @@
+Pages are usually used for normal pages or for listing items from a GraphQL collection.
+Add .vue files here to create pages. For example **About.vue** will be **site.com/about**.
+Learn more about pages: https://gridsome.org/docs/pages
+
+You can delete this file.
\ No newline at end of file
diff --git a/src/pages/ThoughtsOn.vue b/src/pages/ThoughtsOn.vue
deleted file mode 100644
index 7489054..0000000
--- a/src/pages/ThoughtsOn.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/plugins/.gitkeep b/src/plugins/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/src/plugins/colors.js b/src/plugins/colors.js
deleted file mode 100644
index 1cf823a..0000000
--- a/src/plugins/colors.js
+++ /dev/null
@@ -1,40 +0,0 @@
-export default ({ Vue }) => {
- Vue.prototype.$colors = {
- // ** Blog Sections ** //
- 'codeNo0bsGuide': 'teal',
- '2018': 'indigo',
- '2019': 'deep-purple',
-
- // ** Thoughts On, Blog tag colors **//
- 'software design': 'cyan',
- 'learnings': 'pink',
- 'projects': 'purple',
- 'business': 'green',
-
- // ** Project Categories **//
- 'side': 'teal',
- 'archive': 'deep-purple',
- 'university': 'pink',
-
- // ** Project tags *//
- 'web': 'pink',
- 'vue': 'green',
- 'quasar': 'indigo',
- 'java': 'blue',
- 'firebase': 'deep-orange',
- 'cordova': 'purple',
- 'javascript': 'teal',
- 'cli': 'cyan',
- 'bash': 'cyan',
- 'electronics': 'purple',
- 'raspberry-pi': 'purple',
- 'arduino': 'pink',
- 'android': 'teal',
- 'python': 'green',
- 'django': 'indigo',
- 'typescript': 'blue',
- 'microcontroller': 'blue',
- 'angular': 'red',
- 'bootstrap': 'purple'
- }
-}
diff --git a/src/plugins/disqus.js b/src/plugins/disqus.js
deleted file mode 100644
index c8e348d..0000000
--- a/src/plugins/disqus.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import VueDisqus from 'vue-disqus'
-import SocialSharing from 'vue-social-sharing'
-
-export default ({ Vue }) => {
- Vue.use(VueDisqus)
- Vue.use(SocialSharing)
-}
diff --git a/src/plugins/fontawesome.js b/src/plugins/fontawesome.js
deleted file mode 100644
index 1c7f7fb..0000000
--- a/src/plugins/fontawesome.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { library } from '@fortawesome/fontawesome-svg-core'
-import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
-
-import {
- faDev,
- faGithub,
- faMedium,
- faYoutube,
- faTwitter,
- faLinkedin,
- faFacebook,
- faRedditSquare,
- faTwitterSquare
-} from '@fortawesome/free-brands-svg-icons'
-
-export default ({ Vue }) => {
- library.add(
- faDev,
- faGithub,
- faMedium,
- faYoutube,
- faTwitter,
- faLinkedin,
- faFacebook,
- faRedditSquare,
- faTwitterSquare
- )
- Vue.component('f-icon', FontAwesomeIcon)
-}
diff --git a/src/plugins/vuelidate.js b/src/plugins/vuelidate.js
deleted file mode 100644
index 30d04fc..0000000
--- a/src/plugins/vuelidate.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Vuelidate from 'vuelidate'
-
-export default ({ Vue }) => {
- Vue.use(Vuelidate)
-}
diff --git a/src/router/index.js b/src/router/index.js
deleted file mode 100644
index 85f745b..0000000
--- a/src/router/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import Vue from 'vue'
-import VueRouter from 'vue-router'
-
-import routes from './routes'
-
-Vue.use(VueRouter)
-
-/*
- * If not building with SSR mode, you can
- * directly export the Router instantiation
- */
-
-export default function (/* { store, ssrContext } */) {
- const Router = new VueRouter({
- scrollBehavior: () => ({ y: 0 }),
- routes,
-
- // Leave these as is and change from quasar.conf.js instead!
- // quasar.conf.js -> build -> vueRouterMode
- // quasar.conf.js -> build -> publicPath
- mode: process.env.VUE_ROUTER_MODE,
- base: process.env.VUE_ROUTER_BASE
- })
-
- return Router
-}
diff --git a/src/router/routes.js b/src/router/routes.js
deleted file mode 100644
index 75ff867..0000000
--- a/src/router/routes.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import BlogEntries from 'statics/data/blogs.json'
-
-const blogRoutes = Object.keys(BlogEntries).map(section => {
- const children = BlogEntries[section].map(child => ({
- path: child.id,
- name: child.id,
- component: () => import(`blogs/${section}/${child.id}.md`)
- }))
- return {
- path: section,
- name: section,
- component: () => import('layouts/BlogLayout.vue'),
- children
- }
-})
-const routes = [
- {
- path: '/',
- component: () => import('layouts/IndexLayout.vue'),
- children: [
- { path: '', component: () => import('pages/Index.vue') }
- ]
- },
- {
- path: '/blog',
- component: () => import('layouts/MainLayout.vue'),
- children: [
- {
- path: '',
- name: 'BlogRoot',
- component: () => import('pages/Blogs.vue')
- },
- {
- path: ':id',
- name: 'BlogIndex',
- component: () => import('pages/Blogs.vue')
- },
- {
- path: 'thoughts-on/:tag',
- name: 'thoughts',
- component: () => import('pages/ThoughtsOn.vue')
- },
- ...blogRoutes
- ]
- },
- {
- path: '/projects',
- component: () => import('layouts/MainLayout.vue'),
- children: [
- {
- path: '',
- name: 'ClientProjects',
- component: () => import('pages/Projects.vue')
- },
- {
- path: ':id',
- name: 'ProjectIndex',
- component: () => import('pages/Projects.vue')
- },
- {
- path: 'projects-in/:tag',
- name: 'projects-in',
- component: () => import('pages/ProjectsIn.vue')
- }
- ]
- },
- {
- path: '/contact',
- component: () => import('layouts/MainLayout.vue'),
- children: [
- { path: '', name: 'contact', component: () => import('pages/Contact.vue') }
- ]
- }
-]
-
-// Always leave this as last one
-if (process.env.MODE !== 'ssr') {
- routes.push({
- path: '*',
- component: () => import('pages/Error404.vue')
- })
-}
-
-export default routes
diff --git a/src/statics/bg.jpg b/src/statics/bg.jpg
deleted file mode 100644
index f9d0086..0000000
Binary files a/src/statics/bg.jpg and /dev/null differ
diff --git a/src/statics/config/particles-config.json b/src/statics/config/particles-config.json
deleted file mode 100644
index 82007dd..0000000
--- a/src/statics/config/particles-config.json
+++ /dev/null
@@ -1,110 +0,0 @@
-{
- "particles": {
- "number": {
- "value": 160,
- "density": {
- "enable": true,
- "value_area": 800
- }
- },
- "color": {
- "value": "#FFFFFF"
- },
- "shape": {
- "type": "circle",
- "stroke": {
- "width": 0,
- "color": "#000000"
- },
- "polygon": {
- "nb_sides": 5
- },
- "image": {
- "src": "img/github.svg",
- "width": 100,
- "height": 100
- }
- },
- "opacity": {
- "value": 1,
- "random": true,
- "anim": {
- "enable": true,
- "speed": 1,
- "opacity_min": 0,
- "sync": false
- }
- },
- "size": {
- "value": 3,
- "random": true,
- "anim": {
- "enable": false,
- "speed": 4,
- "size_min": 0.3,
- "sync": false
- }
- },
- "line_linked": {
- "enable": false,
- "distance": 150,
- "color": "#ffffff",
- "opacity": 0.4,
- "width": 1
- },
- "move": {
- "enable": true,
- "speed": 1,
- "direction": "none",
- "random": true,
- "straight": false,
- "out_mode": "out",
- "bounce": false,
- "attract": {
- "enable": false,
- "rotateX": 600,
- "rotateY": 600
- }
- }
- },
- "interactivity": {
- "detect_on": "canvas",
- "events": {
- "onhover": {
- "enable": true,
- "mode": "bubble"
- },
- "onclick": {
- "enable": true,
- "mode": "repulse"
- },
- "resize": true
- },
- "modes": {
- "grab": {
- "distance": 400,
- "line_linked": {
- "opacity": 1
- }
- },
- "bubble": {
- "distance": 250,
- "size": 0,
- "duration": 2,
- "opacity": 0,
- "speed": 3
- },
- "repulse": {
- "distance": 400,
- "duration": 0.4
- },
- "push": {
- "particles_nb": 4
- },
- "remove": {
- "particles_nb": 2
- }
- }
- },
- "retina_detect": true
-}
\ No newline at end of file
diff --git a/src/statics/data/blog-categories.json b/src/statics/data/blog-categories.json
deleted file mode 100644
index 753d2d8..0000000
--- a/src/statics/data/blog-categories.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "root": {
- "title": "Blogs",
- "description": "I use writing as another form of learning. Here are my latest musings, epiphany, discoveries, rants, and what nots."
- },
- "codeNo0bsGuide": {
- "title": "CodeNo0b's Guide out of Mediocrity",
- "description": "A series of articles that maps out and summarizes wisdoms about Software Development, Design and Engineering. Taken from the mosts influential books in the industry: 'The Pragmatic Programmer' by Andy Hunt and David Thomas, 'The Passionate Programmer' by Chad Fowler, 'Clean Code' by Robert Martin and 'Refactoring' by Martin Fowler, wrapping it up in a certain mental model."
- },
- "2018": {
- "title": "20XVIII CE",
- "description": "Articles, musings, thoughts I have over the past year."
- },
- "2019": {
- "title": "20XIX CE",
- "description": "Thoughts so far.."
- },
- "projects": {
- "title": "Projects",
- "description": "Articles about weekend projects that I've built and currently working on."
- },
- "learnings": {
- "title": "Learnings",
- "description": "My musings, findings, experiments and introspection about a certain technology, framework, language or any new thing that I had picked up to learn. Writing about what I'm currently learning helps me fill those knowledge gaps."
- },
- "software design": {
- "title": "Software Design",
- "description": "Software design and architecture are among my favorite topics and as a Software Craftman's Oath keeper it's no wonder I often write about it."
- },
- "business": {
- "title": "Business",
- "description": "Articles running my own business as a freelance software engineer and building my own software consultancy company."
- }
-}
diff --git a/src/statics/data/blogs.json b/src/statics/data/blogs.json
deleted file mode 100644
index 1c10777..0000000
--- a/src/statics/data/blogs.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "codeNo0bsGuide": [
- {
- "id": "main",
- "date": "March 25, 2017",
- "tags": ["software design"],
- "title": "CodeNo0b's Guide out of Mediocrity - Main",
- "description": "CodeNo0b's Guide out of Mediocrity's overview, table of contents. Much like a map of best practices and pragmatic clean coding."
- },
- {
- "id": "generalcharacteristics",
- "date": "July 6, 2017",
- "tags": ["software design"],
- "title": "CodeNo0b's Guide out of Mediocrity - General Characteristics",
- "description": "Here I explore some of the key traits for our ideal best version of our developer self. Keep in mind, this isn't a checklist of whether you have it or not. It's a goal that we should always strive to achieve."
- }
- ],
- "2018": [
- {
- "id": "chronocross",
- "date": "August 6, 2018",
- "tags": ["projects", "learnings"],
- "title": "Introducing Chronocross",
- "description": "From the greek word “chronos“ which means “time“, and the latin “curos“, which means “to attend“, Chronocross is a Todo app that integrates other productivity techniques: The Pomodoro Technique and Eisenhower Matrix, into one cohesive workflow"
- },
- {
- "id": "weird-js",
- "date": "September 15, 2018",
- "tags": ["learnings"],
- "title": "Javascript's Weird Parts",
- "description": "Javascript is weird, let's get that out of the way. Still, it's not like Javascript is illogical, in fact, most of it's weirdness is a side effect of its power while coping up with programmers' whims. But once you understand why it does what it does, we'll realize that it's not that complex after all. All languages has its own fair share of quirks and nuances that we just have to learn."
- }
- ],
- "2019": [
- {
- "id": "vue-markdown-blog",
- "date": "March 18, 2019",
- "tags": ["learnings", "projects"],
- "title": "Creating a Simple Blog using Vue with Markdown",
- "description": "In this post, I tell the story of how I added a simple blogging feature on my website without the use of any third-party service."
- },
- {
- "id": "kittynder",
- "date": "June 11, 2019",
- "tags": ["learnings", "projects"],
- "title": "Creating a Tinder-like Swipe UI on Vue",
- "description": "This post tells the story of my journey on trying to build a tinder-like user interface and eventually coming up with Kittynder! Tinder for cats."
- }
- ]
-}
diff --git a/src/statics/data/index.json b/src/statics/data/index.json
deleted file mode 100644
index b9f8df3..0000000
--- a/src/statics/data/index.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "greeting": "Hi, I'm Harvey",
- "introduction": [
- "I consider myself as a Digital Solutions Expert. I help and guide clients on making optimum decisions to solve their digital problems. My Software Engineering knowledge coupled with my experience in building bespoke software makes me well-equipped in providing a complete service from development to deployment."
- ],
- "socials": [
- { "iconType": "fa", "icon": ["fab", "linkedin"], "class": "icon", "link": "https://www.linkedin.com/in/josephharveyangeles/" },
- { "iconType": "fa", "icon": ["fab", "twitter"], "class": "icon", "link": "https://twitter.com/yev" },
- { "iconType": "fa", "icon": ["fab", "github"], "class": "icon", "link": "https://github.com/vycoder/" },
- { "iconType": "fa", "icon": ["fab", "medium"], "class": "icon", "link": "https://medium.com/@yhev" },
- { "iconType": "fa", "icon": ["fab", "youtube"], "class": "icon-disabled", "link": "https://github.com/vycoder/" },
- { "iconType": "fa", "icon": ["fab", "dev"], "class": "icon", "link": "https://dev.to/josephharveyangeles" },
- { "iconType": "mat", "icon": "access_time", "class": "icon", "link": "https://wakatime.com/@yev" },
- { "iconType": "mat", "icon": "mail", "class": "icon", "link": "mailto:josephharveyangeles@gmail.com" }
- ],
- "meta": {
- "description": {
- "name": "description",
- "content": "Joseph Harvey Angeles' website. Software Engineer, Software Developer, Web Developer, Full-stack engineer. Clean Code advocate. DevOps. He likes cats."
- },
- "keywords": {
- "name": "keywords",
- "content": "Web Development, Software Engineer, Software Developer, Full-stack Developer, Full-stack Engineer"
- }
- },
- "about": [
- "I'm a Full-Stack Software Engineer based in Manila, Philippines. I'm very passionate about learning, teaching and just building things in general. And cats, I like cats very much. And also memes. Elon memes, so hot right now.",
- "I used to work as a technical lead at a corporate company but decided to go freelance in the middle of 2018 due to various reasons. I just really feel like this is where I could provide more value for my work; working close and direct with clients. Guiding and providing insights on how to go about developing a software product.",
- "When I'm not working on a client project, I'm developing side projects or fiddling with hobby electronics. I haven't written much these days, but it's also something that I've been planning to work on for years — creating regular content to my blog and possibly a youtube channel."
- ],
- "experience": [
- {
- "logo": "digitalcandy.png",
- "title": "Software Consultant",
- "company": "DigitalCandy",
- "date": "2019 - Now"
- },
- {
- "logo": "accenture.jpeg",
- "title": "Application Developer Team Lead",
- "company": "Accenture",
- "date": "2017 - 2018"
- },
- {
- "logo": "vertere.png",
- "title": "Programmer Analyst III",
- "company": "Vertetre Solutions, Inc - Accenture",
- "date": "2017 - 2018"
- },
- {
- "logo": "nokia.png",
- "title": "Software Specialist / R&D Engineer II",
- "company": "Nokia Networks",
- "date": "2014 - 2017"
- }
- ]
-}
diff --git a/src/statics/data/project-category.json b/src/statics/data/project-category.json
deleted file mode 100644
index fdfeba8..0000000
--- a/src/statics/data/project-category.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "client": {
- "title": "Client Projects",
- "description": "I quit corporate and started freelancing a few months ago. Here's a collection of all projects that I have worked on since I started working as an independent software developer."
- },
- "side": {
- "title": "Side Projects",
- "description": "Building stuff is my hobby. Apps, tools, OSS, electronics, etc."
- },
- "archive": {
- "title": "Archive",
- "description": "Amateur side projects that I've done when I was younger. I still like to keep tabs on it just for old time's sake for a quick reminder of what projects I was working on during those yesteryears."
- },
- "university": {
- "title": "School Projects",
- "description": "University project archives. Dead stuff. Graveyard."
- }
-}
diff --git a/src/statics/data/projects.json b/src/statics/data/projects.json
deleted file mode 100644
index 002c694..0000000
--- a/src/statics/data/projects.json
+++ /dev/null
@@ -1,382 +0,0 @@
-{
- "client": [
- {
- "title": "Sixgill Fishing App + (Admin CMS)",
- "subtitle": "A social media platform for a line fishing community",
- "description": [
- "It's a social media platform for line fishing enthusiasts. Users can share their latest catch, fishing spots, tips and tricks. There's also a Question and Answer section that works much like Quora.",
- "An admin CMS was also built to manage and moderate user activity. Client also regularly publish promos and giveaways directly to the app notifying all connected users via push notifications.",
- "I designed everything from the UI/UX to the backend API architecture. This is one of those projects wherein I had a lot of fun building."
- ],
- "image": "sixgill.png",
- "tags": ["vue", "quasar", "capacitor", "java", "vertx"]
- },
- {
- "title": "Wilyfish",
- "subtitle": "Brand Protection Platform",
- "description": [
- "WilyFish is a brand protection platform offering innovative search tools for locating the “unfindable” in databases and on the internet. WilyFish is the best tool for your trademark clearance, trademark policing and domain name availability because WilyFish can locate graphics, design images, logo images, words, and phrases.",
- "I'm mainly responsible for the design and implementation of the mobile application as well as the frontend aspect of the Wilyfish platform.",
- "Interested about protecting your brand? Check out Wilyfish here"
- ],
- "image": "wilyfish.png",
- "links": [],
- "tags": ["web", "vue", "quasar"]
- },
- {
- "title": "DLDNation",
- "subtitle": "Fitness Web App",
- "description": [
- "Sean and Dala are a husband and wife coaching team that takes no BS approach to health and fitness. They offer highly effective training programs, meal plans and over-all health and fitness coaching.",
- "www.dldnation.com is an extension of their passionate work — an exclusive online platform that gives users access to what DlDNation is all about.",
- "Regular health and fitness video content, training tips, meal diets, and latest trends. It's a platform where Dala can share her expertise to a wider audience."
- ],
- "image": "dldnation.png",
- "links": [],
- "tags": ["web", "vue", "quasar", "firebase"],
- "kuote": {
- "avatar": "https://lh3.googleusercontent.com/a-/AAuE7mBZuZ0q0aKT2bzDCXQZzq99J05WbjpEgNIZNuG0WA=s70-p-k-rw-no",
- "name": "Dala McDevitt",
- "role": "DLDNation LLC",
- "message": ""
- }
- },
- {
- "title": "Zoom App",
- "subtitle": "Product Inventory App with Barcode",
- "description": [
- "ZoomApp is a mobile application that I created for a client that wanted a mobile solution for an inventory and tracking system.",
- "The application is specifically tailored for the client's use case. Equipped with a barcode and camera functionality, it helps the clients track the products that are being delivered across the country."
- ],
- "image": "zoomapp.png",
- "tags": ["vue", "quasar", "cordova"],
- "quote": {
- "name": "Karen Daguio",
- "role": "Sendeya",
- "message": "He's very professional and knowledgeable in this line of work. He's one of the best collaborators in this industry. He will surely give you the finished product/project beyond expectation. We will surely come back and get his service again in the future."
- }
- },
- {
- "title": "OSysHub",
- "subtitle": "OLMHRP System Hub",
- "description": [
- "OLMHRP — Our Lady of the Most Holy Rosary Parish is a church near the hometown when I grew up in. I wrote OSyshub as a solution to help digitized and automate most of the parish-related processes.",
- "OSysHub is purely written in Java and Java Swing to build the UI. OSysHub is just fancy way of saying, System Hub. The idea is to create a unified application that will handle all church related-processes. I designed it with a plugin architecture so I could build every system independently and iteratively on-demand.",
- "Currently, OSysHub contains a Columbary Management System and a Voucher/Cheque Printing feature complete with tests.",
- "I've extracted an API — Bethelscribe out of OSysHub and made it public on github."
- ],
- "image": "osyshub.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/bethelscribe" }
- ],
- "tags": ["java"],
- "quote": {
- "name": "Admin",
- "role": "Our Lady of the Most Holy Rosary Parish",
- "message": "We have a major problem regarding filing records. OSysHub was the solution that we never knew we needed until it's here."
- }
- }
- ],
- "side": [
- {
- "title": "Kittynder",
- "subtitle": "Tinder for Cats",
- "description": [
- "It's a fun little side project that I'm currently working on that matches your feline babies to other feline babies.",
- "I've also published a blog post detailing my journey on how I implemented the core UI swiping functionality."
- ],
- "image": "kittynder.gif",
- "tags": ["vue", "quasar", "cordova"]
- },
- {
- "title": "Chronocross",
- "subtitle": "Time-management and TODO app",
- "description": [
- "From the greek word \"chronos\" which means \"time\", and the latin word \"curo\" which means \"to attend\", Chronocross is combination of a TODO app together with productivity techniques Pomodoro Technique ® and Eisenhower Matrix.",
- "At work, we use Jira to track and manage our tasks, but like most devs, I tend to neglect logging my hours, even totally forgetting what and how much time I spent working on a task. Like who has time for that? There's a task and I'll work on it and move on to others. But yeah, metrics are still important and necessary. That's where the impetus for Chronocross came from.",
- "I've been practicing the Pomodoro technique and Eisenhower matrix even before this — I figured, why not just combine them and just extract a report at the end of day. I could probably take it even further, update the Jira card automatically based on the extracted report and never bother about manually logging anymore."
- ],
- "image": "chronocross.png",
- "links": [
- { "iconType": "mat", "icon": "android", "url": "https://play.google.com/store/apps/details?id=org.yevlabs.chronocross" }
- ],
- "tags": ["quasar", "vue", "web", "cordova"]
- },
- {
- "title": "jQuizzer",
- "subtitle": "Java Quizzer Mobile App",
- "description": [
- "JQuizzer is Java 8 exam reviewer presented in a simple quiz application. The app covers six topics: Building blocks, Operators and Statements, Core Java, Methods and Encapsulation, Class Design and Exception.",
- "The app was written in Vue built for mobile using Quasar Framework, it uses the browser's local storage to persist the scores of the user."
- ],
- "image": "jquizzer.png",
- "links": [
- { "iconType": "mat", "icon": "android", "url": "https://play.google.com/store/apps/details?id=org.yevlabs.jquizzer" }
- ],
- "tags": ["quasar", "vue", "web", "cordova"]
- },
- {
- "title": "vue-animate-scroll",
- "subtitle": "An open-source vue library",
- "description": [
- "A simple Vue directive that animates elements as they scroll into view.",
- "Check out demo here. Installation and setup details over at github's README."
- ],
- "image": "vue-animate-scroll.png",
- "links": [
- { "iconType": "mat", "icon": "public", "url": "https://vue-animate-onscroll.netlify.com/" },
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/vue-animate-onscroll" }
- ],
- "tags": ["vue", "javascript"]
- },
- {
- "title": "Tessa",
- "subtitle": "Test-case Creation Tool",
- "description": [
- "Tessa is a command-line utility tool written in Java that generates all possible test cases from a given tautology-based statements.",
- "I made it to automate a specific task back when I was working at Nokia Networks. We implement configuration combinations and test with each possible scenarios to verify it validity. The problem can be viewed as a tautology statement, — that's what I started with. Tessa parses an input into an equation then builds the tautology logic tree than can be easily manipulated and calculated. It automatically simplifies and applies De Morgan's Law as it sees fit. It will then output all possible scenarios including their validity into the console, text file or an html file.",
- "I also presented a talk and demo of Tessa as a finalist for Nokia Manila TC Innovaton 2016.",
- "PS: The name 'Tessa' is a word play on the words 'Test Case', in case that wasn't as obvious as I think. "
- ],
- "image": "tessa.png",
- "tags": ["java", "cli"]
- }
- ],
- "archive": [
- {
- "title": "Recigle",
- "subtitle": "Recipe Lookup Web App",
- "description": [
- "Recigle is really just google but for recipes. The idea is that, if you ever want to cook something but you don't want to buy groceries, you could just look for recipes that you could cook with only the ingredients you currently have.",
- "The app is written in Angular and deployed on github pages. It's backend is written on python and was deployed on a cloud server.",
- "Recigle is a fully functional prototype, it lacks actual data recipes that's why it doesn't do much right now.",
- "I'm not sure If I'm ever going to continue working on this project, I just wrote it mainly for fun and just to try out python in the backend."
- ],
- "image": "recigle.png",
- "links": [
- { "iconType": "mat", "icon": "public", "url": "http://josephharveyangeles.com/recigle/#/" },
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/recigle" }
- ],
- "tags": ["angular", "typescript", "web", "bootstrap"]
- },
- {
- "title": "nReciquery",
- "subtitle": "REST Recipe Lookup",
- "description": [
- "nReciquery is the REST backend that Recigle consumes. It is built on Python using Django and django-rest-framework deployed on PythonAnywhere.com. See ReadMe for more details. ",
- "I wrote the app mainly just to try out and explore backend technologies, I was fond of python that time so I figured to try experience what's like to use it on the backend.",
- "The server is running when I worked on this project but since I'm just using a free-tier, it may be decommisioned by the time you read this. But codes are just hosted on github."
- ],
- "image": "nreciquery.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/nreciquery" }
- ],
- "tags": ["python", "django", "django-rest-framework"]
- },
- {
- "title": "PrjRiceMill",
- "subtitle": "Rice Mill Machine Automation Device",
- "description": [
- "Project Rice Mill, for a lack of a better name, — is a set devices/sensors and an accompanying android application that monitors and automate the operation of a rice-milling machine.",
- "The idea was to retrofit an existing rice-milling machine with my custom devices that monitors various information such as: weight of the load, status, and so on, and relay those information on the android application that I designed and implemented.",
- "You can start or stop the operation of the machine using the app and the machine could also automatically stop upon determining the absence of rice grains."
- ],
- "image": "prjricemill.png",
- "tags": ["android", "arduino", "microcontroller", "electronics"]
- },
- {
- "title": "swRtcheIoo",
- "subtitle": "IR Remote-controlled Power Extension",
- "description": [
- "This is a fun little weekend project that I built that was born out of laziness. swRtcheIoo is just a power extension that is controlled by an Infrared remote. A gizDuino Mini USB Atmega168 (An Arduino clone) served as the brain of the whole device it controls four solid-state relays, uses an IR sensor to detect IR signals coming from the remote of course, complete with LED indicators.",
- "I didn't want to buy nor design my own IR remote, I just went dumpster diving and found an old remote that still works. I decoded what each buttons do and implemented the Arduino to interpret said signals and toggle the relays accordingly.",
- "PS: swRtcheIoo is a bad pun, I just switched the letters I and R from the word \"switcheroo\" because this device switches stuff, get it?"
- ],
- "image": "switcheroo.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/swRtcherIoo" }
- ],
- "tags": ["arduino", "electronics"]
- },
- {
- "title": "PingPonger",
- "subtitle": "A version of Pong written in Java Swing",
- "description": [
- "PingPonger is just another implementation of the classic Pong game that I wrote in Java for practice.",
- "It taught me the basics of Java's shapes, graphics and colors. I was curious about collision detection mechanisms at that time, Pong seemed like a very good start to explore the concept."
- ],
- "image": "pingponger.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/PingPonger" }
- ],
- "tags": ["java"]
- },
- {
- "title": "Sudoku Solver",
- "subtitle": "9x9 Sudoku Solver",
- "description": [
- "This is a command-line applcation written in Java. It accepts a space-separated values of 9x9 Sudoku as input, and it will solve all possible solutions for the given Sudoku board.",
- "I implemented a matrix-based state stack algorithm with slight optimizations to solve the puzzle. It first parses the input to build the board matrix in memory, it then reads the board row by row if it encounters a missing cell, it will come up with all possible numbers to fill the cell. My algorithm will save each possible number onto a stack along with the state of the board and will proceed solving using that number, if it encounters a dead-end it will pop the stack and just repeat the process over again.",
- "I've missed working on problems such as this that's why I really had fun doing it."
- ],
- "image": "sudoku.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/SudokuSolver" }
- ],
- "tags": ["java"]
- },
- {
- "title": "vNote",
- "subtitle": "A version of Notepad written Java Swing",
- "description": [
- "vNote is just my version of Notepad that has an auto-back-up and auto-recover functionality.",
- "This served as one my practice exercises on Java's Swing UI API. It has all the basic features the notepad has, File and Edit menus, complete with keyboard shortcuts and mnemonics."
- ],
- "image": "vnote.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/vnote" }
- ],
- "tags": ["java"]
- },
- {
- "title": "Kill The Beast",
- "subtitle": "A cli, text-based game of chance",
- "description": [
- "'Kill the beast' is a simple text-based chance game where you will try and defeat the beast based on a narrative. Test your luck against the beast on a card guessing game from a standard deck of cards. Check out the game mechanics in the ReadMe file for more information.",
- "The game is written in bash complete with a swell narrative and ascii arts, truly reminiscent of the old days.",
- "I was learning the fundamentals of bash scripting that time, and this seems like a good exercise idea to work on. Plus it has that nostalgic feeling of the old text-based game that proliferated the early computer days, the time when I wasn't probably born yet."
- ],
- "image": "killthebeast.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/killthebeast" }
- ],
- "tags": ["bash"]
- },
- {
- "title": "Smartac",
- "subtitle": "Tic-tac-toe on C",
- "description": [
- "Smartac is a version of tic-tac-toe written in C that is played on the command-line interface.",
- "The user will play against my code which ensures that any match will end in either the player's loss or a tie.",
- "This is the first complete program that I wrote when I was first learning the C language. I learn the basics of computing and how to think about programming.",
- "A tic-tac-toe game has a fairly complex mechanics. Having a 9x9 board with two players, I had to think about all the possible plays for each cell whether you are the player or the opponent, extracted some patterns and built an algorithm that will never lose.",
- "It's an incomplete algorithm. My code always gets the first pick and it always pick the center cell which improves its chances of winning."
- ],
- "image": "smartac.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/smartac" }
- ],
- "tags": ["c"]
- },
- {
- "title": "Silica",
- "subtitle": "Trainer for basic arithmetic",
- "description": [
- "Silica is written in C, it's a CLI-based quiz game. It covers the basic arithmetic operations: Add, Subtract, Multiply and Divide. The user is being flashed an equation one at time, calculates the score based on how fast the user has answered. Like the old-school games, it gets more difficult round after round. Complete with 8-bit sounds.",
- "Writing those 8bit sounds was also one of the fun things about this project. I extracted the pitch and duration values of every note on the music sheet I like and used them as arguments to windows.h's Beep() method producing nostalgic 8bit sounds.",
- "I also implemented a power of two (2n) category. I was enrolled on a Computer Networks class at that time and I figured it would make me subnet easier if I memorized them. I played it during those down time at college days to keep me sharp."
- ],
- "image": "silica.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/Silica" }
- ],
- "tags": ["c"]
- },
- {
- "title": "Σ Prompt",
- "subtitle": "Assembly CLI utility",
- "description": [
- "Σ prompt (I also refer to it as assembly toolkit, assKit for short) is written in C when I was studying Assembly language back at the university.",
- "It has all the common operations that I often need when working on an assembly program such as: Hextables, Hexcalculators, ASCII conversion, etc.",
- "I was so obsessed with 8bit applications at that time that I felt like creating CLI-based applications are cool. (they still are).",
- "Asskit is not full-pledged CLI library but an executable that has it's own shell and argument parser that I personally implemented — I really wanted to give it custom colors and all so I could really feel I was in Tron or something."
- ],
- "image": "asskit.png",
- "links": [
- { "iconType": "fa", "icon": ["fab", "github"], "url": "https://github.com/vycoder/sigmaprompt" }
- ],
- "tags": ["c"]
- },
- {
- "title": "LED Music Lamp",
- "subtitle": "LED VU Meter Lamp",
- "description": [
- "This is probably the first electronic hardware project that I created when I was first learning about electronics while I was undergoing my BS in Engineering.",
- "It is built out of LED arrays connected to a TIP31 NPN power transistor hooked on my computer speakers's signal output that ultimately acts as a VU meter (Volume Unit Meter).",
- "I soldered everything on a silver-painted PCB put in a makeshift enclosure made out of a glass jar with baby powder coating to diffuse light a bit. I added shards of broken glasses for added cool light effect. I also spray-painted the bottom of the jar (now, the top of the LED lamp) with silver paint to focus the light on the the glass itself."
- ],
- "image": "ledlamp.png",
- "tags": ["electronics"]
- }
- ],
- "university": [
- {
- "title": "Romeocito",
- "subtitle": "Low-cost Braille Printer",
- "description": [
- "Romeocito is my undergraduate thesis project that I built along with @mdgman, @sethjuriste and @rbtabor in partnership with the Non-profit organization: Resources of the Blind, Incorporation. At the time when we're building Romeocito there were only Two Braille Printers in the Philippines that were being shared by the entire blind community to print large publications in Braille. The cost of said industrial printers ranges from Php 250,000.00 to a million pesos — that's what inspired us to build Romeocito.",
- "Our goal was to create a cheap, non-industrial, household alternative to enable more households with blind individuals have access to reading resources.",
- "The result is a low-cost Braille printer that consists of two soleniod printing heads controlled by PIC16F877A microcontroller that communicates with the computer via the Serial port. We have also created an accompanying custom document editor to use in conjuction with the printer. It also has a bluetooth interface that can directly communicate to an accompanying android application that can be used to print documents as well. Ultimately, all the components used only cost around Php 10,000.00.",
- "The biggest challenge in this project was using limited resources to achieve considerable results. Solenoids we're the most costly components that Romeocito has. It's the one component we would not compromise, we had the folks at RBI got us the same model of solenoids their industrial printers have.",
- "Braille characters are composed of 6 dots to encode a letter, industrial printers have mechanical contraptions to emboss a Braille character in one motion using six solenoids. I have designed an algorithm to get around that problem that had greatly helped in making Romeocito possible.",
- "The algorithm makes use of our custom encoding scheme that encodes characters into an array of dots. In Romeocito, we didn't use of any costly mechanical contraptions and just arranged the solenoid in an array, each solenoid is responsible for embossing a dot on it's column range width and just leverage the use of software the control each solenoids until they were able to print the whole document. The tradeoff for the huge reduction of cost was the speed. Romeocito prints far slower as opposed to it's industrial counterparts, still we've considered it a good a sacrifice for a household alternative. I've also designed the software to be scalable into four or six more solenoids making it print more faster.",
- "PS: The name Romeocito was inspired by the cheapest industrial Braille printer that time, which was called: Romeo."
- ],
- "awards": "Ideaspace 2014 Qualifier, 2nd Best Design Project 2014, 1st Runner-up ICpEP Engbensyon Design Exhibit 2014, 2nd Runner-up TIP Science Fair Project 2014",
- "tags": ["java", "android", "electronics", "microcontroller"]
- },
- {
- "title": "Kirkos",
- "subtitle": "Sumobot",
- "description": [
- "Kirkos is created for the Annual Sumobot Robotics Competition where I competed as a school representative.",
- "At this point I was fairly accustomed on working with a lot constraints — with so little time for preparation and utter lack of high-powered motors, I decided to seek for creative solutions.",
- "I know I wouldn't win with power, having a scoop would be useless on it that's why I decided to turn the problem on its head and just opt for a circular chassis instead (hence the name Kirkos from its greek word), retrofitted it with makeshift bump sensors and let it rolled. I also programmed some random maneuvers on startup.",
- "My general strategy: Just evade and hoped that the opponents high powered motors can't deal with an opponent they couldn't crash into at first contact. It did perform pretty well in the elimations round but got totally crushed on the next semi-final rounds."
- ],
- "awards": "Sumobot Robotics Competition 2014 School Represenative",
- "tags": ["arduino", "electronics"]
- },
- {
- "title": "Anjuli",
- "subtitle": "Catering Website + CMS",
- "description": [
- "Anjuli is a catering website I built for an actual client as requirement for the partial fulfillment of my Bachelors. It has an accompanying CMS written in vanilla Javascript, JQuery, HTML and CSS."
- ],
- "tags": ["web"]
- },
- {
- "title": "Droiduino",
- "subtitle": "Android-controlled Racing Bot",
- "description": [
- "Droiduino is racebot controlled by an Arduino with a steering user interface android application that communicates via bluetooth.",
- "What sets Droiduino apart from it's opponents on the competition is how I designed the steering interface. Most bots uses a button-centric or joypad-like user interface to control the bot which means, the bot can only move in one direction at a time resulting to a stop-reorient-start laggy movement. Unless you implement a multi-touch functionality it can never maneuver pretty well on sharp turns.",
- "Luckily for me, nobody has seemed to have thought about it that time. I implemented a custom encoding scheme that can relay all four direction component on a single byte based on the location of the draggable trackball interface on my android app. The code on the arduino doesn't read a character for 'up', 'down', 'left' or 'right', it reads an actual byte and extracts the direction of both X and Y axis on their respective bit position based on my encoding scheme. I took it further and encoded a 'speed' component depending on how far from the center you dragged the ball on your screen. I would only need 2 bits for direction after all.",
- "The result was, Droiduino can react on the racetrack far more efficiently than it's opponents, it can move diagonally, do sharp turns, slow-down to gain traction, or speed up on straight course."
- ],
- "awards": "CpE Robotics Competition 2013 Champion",
- "tags": ["android", "arduino"]
- },
- {
- "title": "Sinivo",
- "subtitle": "Client-Server Course Management System",
- "description": [
- "Inviso is a client-server application that is intended to be used in a faculty environment. The server is used to assign classes or course loads to faculties, time, names of students and all.",
- "The client application will be installed on the instructor's laptop attached to an RFID reader, students will register their attendance by tapping their RFID cards. A valid attendance will only be recorded if the student has tapped his RFID card both on the start and at the end of the class.",
- "Sinivo is an anagram of the latin word: Inviso, which means, to look at or to watch. "
- ],
- "tags": ["java", "electronics", "RFID"]
- },
- {
- "title": "Somlif!q",
- "subtitle": "Gamified Collaboration Platform for University Students",
- "description": [
- "Somlifiq's, which stands for, \"Something like Facebook, but not quite!\" main goal is to influence the students of the whole campus on different courses and programs to collaborate and build inter-disciplinary projects.",
- "When I was back in college I've always wanted to really build large side-projects, but most importantly I wanted to collaborate and learn with other students. I always found myself wanting to build something that seems hard or expensive because of a certain issue but a mechanical engineer would just recommend a gear system to solve it. That's when I pitched my project idea for that semester on my instructor.",
- "Each student can post or pitch a project that they are currently or planning to work on, then other students can comment and participate on the said project. Upon completion of a project, a user can unlock profile badges such as: R0b0warrior, SolderBender, Gearhead, etc..",
- "The platform would contain more features and is obviously very big. I only implemented the most important features to demonstrate what I learned in class in order to complete the course hoping that the idea would spark some interest on the faculty and eventually make it a reality."
- ],
- "tags": ["web"]
- }
- ]
-}
diff --git a/src/statics/icons/apple-icon-152x152.png b/src/statics/icons/apple-icon-152x152.png
deleted file mode 100644
index 90bfbba..0000000
Binary files a/src/statics/icons/apple-icon-152x152.png and /dev/null differ
diff --git a/src/statics/icons/favicon-16x16.png b/src/statics/icons/favicon-16x16.png
deleted file mode 100644
index 6fc82a0..0000000
Binary files a/src/statics/icons/favicon-16x16.png and /dev/null differ
diff --git a/src/statics/icons/favicon-32x32.png b/src/statics/icons/favicon-32x32.png
deleted file mode 100644
index 5ac416c..0000000
Binary files a/src/statics/icons/favicon-32x32.png and /dev/null differ
diff --git a/src/statics/icons/icon-128x128.png b/src/statics/icons/icon-128x128.png
deleted file mode 100644
index 7206ac7..0000000
Binary files a/src/statics/icons/icon-128x128.png and /dev/null differ
diff --git a/src/statics/icons/icon-192x192.png b/src/statics/icons/icon-192x192.png
deleted file mode 100644
index 31558f8..0000000
Binary files a/src/statics/icons/icon-192x192.png and /dev/null differ
diff --git a/src/statics/icons/icon-384x384.png b/src/statics/icons/icon-384x384.png
deleted file mode 100644
index 8df1f4d..0000000
Binary files a/src/statics/icons/icon-384x384.png and /dev/null differ
diff --git a/src/statics/icons/icon-512x512.png b/src/statics/icons/icon-512x512.png
deleted file mode 100644
index 1204d98..0000000
Binary files a/src/statics/icons/icon-512x512.png and /dev/null differ
diff --git a/src/statics/icons/ms-icon-144x144.png b/src/statics/icons/ms-icon-144x144.png
deleted file mode 100644
index 2649b44..0000000
Binary files a/src/statics/icons/ms-icon-144x144.png and /dev/null differ
diff --git a/src/statics/images/blogs/codenoobsguide/genchar.png b/src/statics/images/blogs/codenoobsguide/genchar.png
deleted file mode 100644
index 2dfc72d..0000000
Binary files a/src/statics/images/blogs/codenoobsguide/genchar.png and /dev/null differ
diff --git a/src/statics/images/blogs/codenoobsguide/main.png b/src/statics/images/blogs/codenoobsguide/main.png
deleted file mode 100644
index bc64885..0000000
Binary files a/src/statics/images/blogs/codenoobsguide/main.png and /dev/null differ
diff --git a/src/statics/scripts/particles.min.js b/src/statics/scripts/particles.min.js
deleted file mode 100644
index bab7b16..0000000
--- a/src/statics/scripts/particles.min.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/* -----------------------------------------------
-/* Author : Vincent Garreau - vincentgarreau.com
-/* MIT license: http://opensource.org/licenses/MIT
-/* Demo / Generator : vincentgarreau.com/particles.js
-/* GitHub : github.com/VincentGarreau/particles.js
-/* How to use? : Check the GitHub README
-/* v2.0.0
-/* ----------------------------------------------- */
-function hexToRgb (e) { var a = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; e = e.replace(a, function (e, a, t, i) { return a + a + t + t + i + i }); var t = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e); return t ? {r: parseInt(t[1], 16), g: parseInt(t[2], 16), b: parseInt(t[3], 16)} : null } function clamp (e, a, t) { return Math.min(Math.max(e, a), t) } function isInArray (e, a) { return a.indexOf(e) > -1 } var pJS = function (e, a) { var t = document.querySelector('#' + e + ' > .particles-js-canvas-el'); this.pJS = {canvas: {el: t, w: t.offsetWidth, h: t.offsetHeight}, particles: {number: {value: 400, density: {enable: !0, value_area: 800}}, color: {value: '#fff'}, shape: {type: 'circle', stroke: {width: 0, color: '#ff0000'}, polygon: {nb_sides: 5}, image: {src: '', width: 100, height: 100}}, opacity: {value: 1, random: !1, anim: {enable: !1, speed: 2, opacity_min: 0, sync: !1}}, size: {value: 20, random: !1, anim: {enable: !1, speed: 20, size_min: 0, sync: !1}}, line_linked: {enable: !0, distance: 100, color: '#fff', opacity: 1, width: 1}, move: {enable: !0, speed: 2, direction: 'none', random: !1, straight: !1, out_mode: 'out', bounce: !1, attract: {enable: !1, rotateX: 3e3, rotateY: 3e3}}, array: []}, interactivity: {detect_on: 'canvas', events: {onhover: {enable: !0, mode: 'grab'}, onclick: {enable: !0, mode: 'push'}, resize: !0}, modes: {grab: {distance: 100, line_linked: {opacity: 1}}, bubble: {distance: 200, size: 80, duration: 0.4}, repulse: {distance: 200, duration: 0.4}, push: {particles_nb: 4}, remove: {particles_nb: 2}}, mouse: {}}, retina_detect: !1, fn: {interact: {}, modes: {}, vendors: {}}, tmp: {}}; var i = this.pJS; a && Object.deepExtend(i, a), i.tmp.obj = {size_value: i.particles.size.value, size_anim_speed: i.particles.size.anim.speed, move_speed: i.particles.move.speed, line_linked_distance: i.particles.line_linked.distance, line_linked_width: i.particles.line_linked.width, mode_grab_distance: i.interactivity.modes.grab.distance, mode_bubble_distance: i.interactivity.modes.bubble.distance, mode_bubble_size: i.interactivity.modes.bubble.size, mode_repulse_distance: i.interactivity.modes.repulse.distance}, i.fn.retinaInit = function () { i.retina_detect && window.devicePixelRatio > 1 ? (i.canvas.pxratio = window.devicePixelRatio, i.tmp.retina = !0) : (i.canvas.pxratio = 1, i.tmp.retina = !1), i.canvas.w = i.canvas.el.offsetWidth * i.canvas.pxratio, i.canvas.h = i.canvas.el.offsetHeight * i.canvas.pxratio, i.particles.size.value = i.tmp.obj.size_value * i.canvas.pxratio, i.particles.size.anim.speed = i.tmp.obj.size_anim_speed * i.canvas.pxratio, i.particles.move.speed = i.tmp.obj.move_speed * i.canvas.pxratio, i.particles.line_linked.distance = i.tmp.obj.line_linked_distance * i.canvas.pxratio, i.interactivity.modes.grab.distance = i.tmp.obj.mode_grab_distance * i.canvas.pxratio, i.interactivity.modes.bubble.distance = i.tmp.obj.mode_bubble_distance * i.canvas.pxratio, i.particles.line_linked.width = i.tmp.obj.line_linked_width * i.canvas.pxratio, i.interactivity.modes.bubble.size = i.tmp.obj.mode_bubble_size * i.canvas.pxratio, i.interactivity.modes.repulse.distance = i.tmp.obj.mode_repulse_distance * i.canvas.pxratio }, i.fn.canvasInit = function () { i.canvas.ctx = i.canvas.el.getContext('2d') }, i.fn.canvasSize = function () { i.canvas.el.width = i.canvas.w, i.canvas.el.height = i.canvas.h, i && i.interactivity.events.resize && window.addEventListener('resize', function () { i.canvas.w = i.canvas.el.offsetWidth, i.canvas.h = i.canvas.el.offsetHeight, i.tmp.retina && (i.canvas.w *= i.canvas.pxratio, i.canvas.h *= i.canvas.pxratio), i.canvas.el.width = i.canvas.w, i.canvas.el.height = i.canvas.h, i.particles.move.enable || (i.fn.particlesEmpty(), i.fn.particlesCreate(), i.fn.particlesDraw(), i.fn.vendors.densityAutoParticles()), i.fn.vendors.densityAutoParticles() }) }, i.fn.canvasPaint = function () { i.canvas.ctx.fillRect(0, 0, i.canvas.w, i.canvas.h) }, i.fn.canvasClear = function () { i.canvas.ctx.clearRect(0, 0, i.canvas.w, i.canvas.h) }, i.fn.particle = function (e, a, t) { if (this.radius = (i.particles.size.random ? Math.random() : 1) * i.particles.size.value, i.particles.size.anim.enable && (this.size_status = !1, this.vs = i.particles.size.anim.speed / 100, i.particles.size.anim.sync || (this.vs = this.vs * Math.random())), this.x = t ? t.x : Math.random() * i.canvas.w, this.y = t ? t.y : Math.random() * i.canvas.h, this.x > i.canvas.w - 2 * this.radius ? this.x = this.x - this.radius : this.x < 2 * this.radius && (this.x = this.x + this.radius), this.y > i.canvas.h - 2 * this.radius ? this.y = this.y - this.radius : this.y < 2 * this.radius && (this.y = this.y + this.radius), i.particles.move.bounce && i.fn.vendors.checkOverlap(this, t), this.color = {}, typeof e.value === 'object') if (e.value instanceof Array) { var s = e.value[Math.floor(Math.random() * i.particles.color.value.length)]; this.color.rgb = hexToRgb(s) } else void 0 != e.value.r && void 0 != e.value.g && void 0 != e.value.b && (this.color.rgb = {r: e.value.r, g: e.value.g, b: e.value.b}), void 0 != e.value.h && void 0 != e.value.s && void 0 != e.value.l && (this.color.hsl = {h: e.value.h, s: e.value.s, l: e.value.l}); else e.value == 'random' ? this.color.rgb = {r: Math.floor(256 * Math.random()) + 0, g: Math.floor(256 * Math.random()) + 0, b: Math.floor(256 * Math.random()) + 0} : typeof e.value === 'string' && (this.color = e, this.color.rgb = hexToRgb(this.color.value)); this.opacity = (i.particles.opacity.random ? Math.random() : 1) * i.particles.opacity.value, i.particles.opacity.anim.enable && (this.opacity_status = !1, this.vo = i.particles.opacity.anim.speed / 100, i.particles.opacity.anim.sync || (this.vo = this.vo * Math.random())); var n = {}; switch (i.particles.move.direction) { case 'top':n = {x: 0, y: -1}; break; case 'top-right':n = {x: 0.5, y: -0.5}; break; case 'right':n = {x: 1, y: -0}; break; case 'bottom-right':n = {x: 0.5, y: 0.5}; break; case 'bottom':n = {x: 0, y: 1}; break; case 'bottom-left':n = {x: -0.5, y: 1}; break; case 'left':n = {x: -1, y: 0}; break; case 'top-left':n = {x: -0.5, y: -0.5}; break; default:n = {x: 0, y: 0} }i.particles.move.straight ? (this.vx = n.x, this.vy = n.y, i.particles.move.random && (this.vx = this.vx * Math.random(), this.vy = this.vy * Math.random())) : (this.vx = n.x + Math.random() - 0.5, this.vy = n.y + Math.random() - 0.5), this.vx_i = this.vx, this.vy_i = this.vy; var r = i.particles.shape.type; if (typeof r === 'object') { if (r instanceof Array) { var c = r[Math.floor(Math.random() * r.length)]; this.shape = c } } else this.shape = r; if (this.shape == 'image') { var o = i.particles.shape; this.img = {src: o.image.src, ratio: o.image.width / o.image.height}, this.img.ratio || (this.img.ratio = 1), i.tmp.img_type == 'svg' && void 0 != i.tmp.source_svg && (i.fn.vendors.createSvgImg(this), i.tmp.pushing && (this.img.loaded = !1)) } }, i.fn.particle.prototype.draw = function () { function e () { i.canvas.ctx.drawImage(r, a.x - t, a.y - t, 2 * t, 2 * t / a.img.ratio) } var a = this; if (void 0 != a.radius_bubble) var t = a.radius_bubble; else var t = a.radius; if (void 0 != a.opacity_bubble) var s = a.opacity_bubble; else var s = a.opacity; if (a.color.rgb) var n = 'rgba(' + a.color.rgb.r + ',' + a.color.rgb.g + ',' + a.color.rgb.b + ',' + s + ')'; else var n = 'hsla(' + a.color.hsl.h + ',' + a.color.hsl.s + '%,' + a.color.hsl.l + '%,' + s + ')'; switch (i.canvas.ctx.fillStyle = n, i.canvas.ctx.beginPath(), a.shape) { case 'circle':i.canvas.ctx.arc(a.x, a.y, t, 0, 2 * Math.PI, !1); break; case 'edge':i.canvas.ctx.rect(a.x - t, a.y - t, 2 * t, 2 * t); break; case 'triangle':i.fn.vendors.drawShape(i.canvas.ctx, a.x - t, a.y + t / 1.66, 2 * t, 3, 2); break; case 'polygon':i.fn.vendors.drawShape(i.canvas.ctx, a.x - t / (i.particles.shape.polygon.nb_sides / 3.5), a.y - t / 0.76, 2.66 * t / (i.particles.shape.polygon.nb_sides / 3), i.particles.shape.polygon.nb_sides, 1); break; case 'star':i.fn.vendors.drawShape(i.canvas.ctx, a.x - 2 * t / (i.particles.shape.polygon.nb_sides / 4), a.y - t / 1.52, 2 * t * 2.66 / (i.particles.shape.polygon.nb_sides / 3), i.particles.shape.polygon.nb_sides, 2); break; case 'image':if (i.tmp.img_type == 'svg') var r = a.img.obj; else var r = i.tmp.img_obj; r && e() }i.canvas.ctx.closePath(), i.particles.shape.stroke.width > 0 && (i.canvas.ctx.strokeStyle = i.particles.shape.stroke.color, i.canvas.ctx.lineWidth = i.particles.shape.stroke.width, i.canvas.ctx.stroke()), i.canvas.ctx.fill() }, i.fn.particlesCreate = function () { for (var e = 0; e < i.particles.number.value; e++)i.particles.array.push(new i.fn.particle(i.particles.color, i.particles.opacity.value)) }, i.fn.particlesUpdate = function () { for (var e = 0; e < i.particles.array.length; e++) { var a = i.particles.array[e]; if (i.particles.move.enable) { var t = i.particles.move.speed / 2; a.x += a.vx * t, a.y += a.vy * t } if (i.particles.opacity.anim.enable && (a.opacity_status == 1 ? (a.opacity >= i.particles.opacity.value && (a.opacity_status = !1), a.opacity += a.vo) : (a.opacity <= i.particles.opacity.anim.opacity_min && (a.opacity_status = !0), a.opacity -= a.vo), a.opacity < 0 && (a.opacity = 0)), i.particles.size.anim.enable && (a.size_status == 1 ? (a.radius >= i.particles.size.value && (a.size_status = !1), a.radius += a.vs) : (a.radius <= i.particles.size.anim.size_min && (a.size_status = !0), a.radius -= a.vs), a.radius < 0 && (a.radius = 0)), i.particles.move.out_mode == 'bounce') var s = {x_left: a.radius, x_right: i.canvas.w, y_top: a.radius, y_bottom: i.canvas.h}; else var s = {x_left: -a.radius, x_right: i.canvas.w + a.radius, y_top: -a.radius, y_bottom: i.canvas.h + a.radius}; switch (a.x - a.radius > i.canvas.w ? (a.x = s.x_left, a.y = Math.random() * i.canvas.h) : a.x + a.radius < 0 && (a.x = s.x_right, a.y = Math.random() * i.canvas.h), a.y - a.radius > i.canvas.h ? (a.y = s.y_top, a.x = Math.random() * i.canvas.w) : a.y + a.radius < 0 && (a.y = s.y_bottom, a.x = Math.random() * i.canvas.w), i.particles.move.out_mode) { case 'bounce':a.x + a.radius > i.canvas.w ? a.vx = -a.vx : a.x - a.radius < 0 && (a.vx = -a.vx), a.y + a.radius > i.canvas.h ? a.vy = -a.vy : a.y - a.radius < 0 && (a.vy = -a.vy) } if (isInArray('grab', i.interactivity.events.onhover.mode) && i.fn.modes.grabParticle(a), (isInArray('bubble', i.interactivity.events.onhover.mode) || isInArray('bubble', i.interactivity.events.onclick.mode)) && i.fn.modes.bubbleParticle(a), (isInArray('repulse', i.interactivity.events.onhover.mode) || isInArray('repulse', i.interactivity.events.onclick.mode)) && i.fn.modes.repulseParticle(a), i.particles.line_linked.enable || i.particles.move.attract.enable) for (var n = e + 1; n < i.particles.array.length; n++) { var r = i.particles.array[n]; i.particles.line_linked.enable && i.fn.interact.linkParticles(a, r), i.particles.move.attract.enable && i.fn.interact.attractParticles(a, r), i.particles.move.bounce && i.fn.interact.bounceParticles(a, r) } } }, i.fn.particlesDraw = function () { i.canvas.ctx.clearRect(0, 0, i.canvas.w, i.canvas.h), i.fn.particlesUpdate(); for (var e = 0; e < i.particles.array.length; e++) { var a = i.particles.array[e]; a.draw() } }, i.fn.particlesEmpty = function () { i.particles.array = [] }, i.fn.particlesRefresh = function () { cancelRequestAnimFrame(i.fn.checkAnimFrame), cancelRequestAnimFrame(i.fn.drawAnimFrame), i.tmp.source_svg = void 0, i.tmp.img_obj = void 0, i.tmp.count_svg = 0, i.fn.particlesEmpty(), i.fn.canvasClear(), i.fn.vendors.start() }, i.fn.interact.linkParticles = function (e, a) { var t = e.x - a.x, s = e.y - a.y, n = Math.sqrt(t * t + s * s); if (n <= i.particles.line_linked.distance) { var r = i.particles.line_linked.opacity - n / (1 / i.particles.line_linked.opacity) / i.particles.line_linked.distance; if (r > 0) { var c = i.particles.line_linked.color_rgb_line; i.canvas.ctx.strokeStyle = 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + r + ')', i.canvas.ctx.lineWidth = i.particles.line_linked.width, i.canvas.ctx.beginPath(), i.canvas.ctx.moveTo(e.x, e.y), i.canvas.ctx.lineTo(a.x, a.y), i.canvas.ctx.stroke(), i.canvas.ctx.closePath() } } }, i.fn.interact.attractParticles = function (e, a) { var t = e.x - a.x, s = e.y - a.y, n = Math.sqrt(t * t + s * s); if (n <= i.particles.line_linked.distance) { var r = t / (1e3 * i.particles.move.attract.rotateX), c = s / (1e3 * i.particles.move.attract.rotateY); e.vx -= r, e.vy -= c, a.vx += r, a.vy += c } }, i.fn.interact.bounceParticles = function (e, a) { var t = e.x - a.x, i = e.y - a.y, s = Math.sqrt(t * t + i * i), n = e.radius + a.radius; n >= s && (e.vx = -e.vx, e.vy = -e.vy, a.vx = -a.vx, a.vy = -a.vy) }, i.fn.modes.pushParticles = function (e, a) { i.tmp.pushing = !0; for (var t = 0; e > t; t++)i.particles.array.push(new i.fn.particle(i.particles.color, i.particles.opacity.value, {x: a ? a.pos_x : Math.random() * i.canvas.w, y: a ? a.pos_y : Math.random() * i.canvas.h})), t == e - 1 && (i.particles.move.enable || i.fn.particlesDraw(), i.tmp.pushing = !1) }, i.fn.modes.removeParticles = function (e) { i.particles.array.splice(0, e), i.particles.move.enable || i.fn.particlesDraw() }, i.fn.modes.bubbleParticle = function (e) { function a () { e.opacity_bubble = e.opacity, e.radius_bubble = e.radius } function t (a, t, s, n, c) { if (a != t) if (i.tmp.bubble_duration_end) { if (void 0 != s) { var o = n - p * (n - a) / i.interactivity.modes.bubble.duration, l = a - o; d = a + l, c == 'size' && (e.radius_bubble = d), c == 'opacity' && (e.opacity_bubble = d) } } else if (r <= i.interactivity.modes.bubble.distance) { if (void 0 != s) var v = s; else var v = n; if (v != a) { var d = n - p * (n - a) / i.interactivity.modes.bubble.duration; c == 'size' && (e.radius_bubble = d), c == 'opacity' && (e.opacity_bubble = d) } } else c == 'size' && (e.radius_bubble = void 0), c == 'opacity' && (e.opacity_bubble = void 0) } if (i.interactivity.events.onhover.enable && isInArray('bubble', i.interactivity.events.onhover.mode)) { var s = e.x - i.interactivity.mouse.pos_x, n = e.y - i.interactivity.mouse.pos_y, r = Math.sqrt(s * s + n * n), c = 1 - r / i.interactivity.modes.bubble.distance; if (r <= i.interactivity.modes.bubble.distance) { if (c >= 0 && i.interactivity.status == 'mousemove') { if (i.interactivity.modes.bubble.size != i.particles.size.value) if (i.interactivity.modes.bubble.size > i.particles.size.value) { var o = e.radius + i.interactivity.modes.bubble.size * c; o >= 0 && (e.radius_bubble = o) } else { var l = e.radius - i.interactivity.modes.bubble.size, o = e.radius - l * c; o > 0 ? e.radius_bubble = o : e.radius_bubble = 0 } if (i.interactivity.modes.bubble.opacity != i.particles.opacity.value) if (i.interactivity.modes.bubble.opacity > i.particles.opacity.value) { var v = i.interactivity.modes.bubble.opacity * c; v > e.opacity && v <= i.interactivity.modes.bubble.opacity && (e.opacity_bubble = v) } else { var v = e.opacity - (i.particles.opacity.value - i.interactivity.modes.bubble.opacity) * c; v < e.opacity && v >= i.interactivity.modes.bubble.opacity && (e.opacity_bubble = v) } } } else a(); i.interactivity.status == 'mouseleave' && a() } else if (i.interactivity.events.onclick.enable && isInArray('bubble', i.interactivity.events.onclick.mode)) { if (i.tmp.bubble_clicking) { var s = e.x - i.interactivity.mouse.click_pos_x, n = e.y - i.interactivity.mouse.click_pos_y, r = Math.sqrt(s * s + n * n), p = ((new Date()).getTime() - i.interactivity.mouse.click_time) / 1e3; p > i.interactivity.modes.bubble.duration && (i.tmp.bubble_duration_end = !0), p > 2 * i.interactivity.modes.bubble.duration && (i.tmp.bubble_clicking = !1, i.tmp.bubble_duration_end = !1) }i.tmp.bubble_clicking && (t(i.interactivity.modes.bubble.size, i.particles.size.value, e.radius_bubble, e.radius, 'size'), t(i.interactivity.modes.bubble.opacity, i.particles.opacity.value, e.opacity_bubble, e.opacity, 'opacity')) } }, i.fn.modes.repulseParticle = function (e) { function a () { var a = Math.atan2(d, p); if (e.vx = u * Math.cos(a), e.vy = u * Math.sin(a), i.particles.move.out_mode == 'bounce') { var t = {x: e.x + e.vx, y: e.y + e.vy}; t.x + e.radius > i.canvas.w ? e.vx = -e.vx : t.x - e.radius < 0 && (e.vx = -e.vx), t.y + e.radius > i.canvas.h ? e.vy = -e.vy : t.y - e.radius < 0 && (e.vy = -e.vy) } } if (i.interactivity.events.onhover.enable && isInArray('repulse', i.interactivity.events.onhover.mode) && i.interactivity.status == 'mousemove') { var t = e.x - i.interactivity.mouse.pos_x, s = e.y - i.interactivity.mouse.pos_y, n = Math.sqrt(t * t + s * s), r = {x: t / n, y: s / n}, c = i.interactivity.modes.repulse.distance, o = 100, l = clamp(1 / c * (-1 * Math.pow(n / c, 2) + 1) * c * o, 0, 50), v = {x: e.x + r.x * l, y: e.y + r.y * l}; i.particles.move.out_mode == 'bounce' ? (v.x - e.radius > 0 && v.x + e.radius < i.canvas.w && (e.x = v.x), v.y - e.radius > 0 && v.y + e.radius < i.canvas.h && (e.y = v.y)) : (e.x = v.x, e.y = v.y) } else if (i.interactivity.events.onclick.enable && isInArray('repulse', i.interactivity.events.onclick.mode)) if (i.tmp.repulse_finish || (i.tmp.repulse_count++, i.tmp.repulse_count == i.particles.array.length && (i.tmp.repulse_finish = !0)), i.tmp.repulse_clicking) { var c = Math.pow(i.interactivity.modes.repulse.distance / 6, 3), p = i.interactivity.mouse.click_pos_x - e.x, d = i.interactivity.mouse.click_pos_y - e.y, m = p * p + d * d, u = -c / m * 1; c >= m && a() } else i.tmp.repulse_clicking == 0 && (e.vx = e.vx_i, e.vy = e.vy_i) }, i.fn.modes.grabParticle = function (e) { if (i.interactivity.events.onhover.enable && i.interactivity.status == 'mousemove') { var a = e.x - i.interactivity.mouse.pos_x, t = e.y - i.interactivity.mouse.pos_y, s = Math.sqrt(a * a + t * t); if (s <= i.interactivity.modes.grab.distance) { var n = i.interactivity.modes.grab.line_linked.opacity - s / (1 / i.interactivity.modes.grab.line_linked.opacity) / i.interactivity.modes.grab.distance; if (n > 0) { var r = i.particles.line_linked.color_rgb_line; i.canvas.ctx.strokeStyle = 'rgba(' + r.r + ',' + r.g + ',' + r.b + ',' + n + ')', i.canvas.ctx.lineWidth = i.particles.line_linked.width, i.canvas.ctx.beginPath(), i.canvas.ctx.moveTo(e.x, e.y), i.canvas.ctx.lineTo(i.interactivity.mouse.pos_x, i.interactivity.mouse.pos_y), i.canvas.ctx.stroke(), i.canvas.ctx.closePath() } } } }, i.fn.vendors.eventsListeners = function () { i.interactivity.detect_on == 'window' ? i.interactivity.el = window : i.interactivity.el = i.canvas.el, (i.interactivity.events.onhover.enable || i.interactivity.events.onclick.enable) && (i.interactivity.el.addEventListener('mousemove', function (e) { if (i.interactivity.el == window) var a = e.clientX, t = e.clientY; else var a = e.offsetX || e.clientX, t = e.offsetY || e.clientY; i.interactivity.mouse.pos_x = a, i.interactivity.mouse.pos_y = t, i.tmp.retina && (i.interactivity.mouse.pos_x *= i.canvas.pxratio, i.interactivity.mouse.pos_y *= i.canvas.pxratio), i.interactivity.status = 'mousemove' }), i.interactivity.el.addEventListener('mouseleave', function (e) { i.interactivity.mouse.pos_x = null, i.interactivity.mouse.pos_y = null, i.interactivity.status = 'mouseleave' })), i.interactivity.events.onclick.enable && i.interactivity.el.addEventListener('click', function () { if (i.interactivity.mouse.click_pos_x = i.interactivity.mouse.pos_x, i.interactivity.mouse.click_pos_y = i.interactivity.mouse.pos_y, i.interactivity.mouse.click_time = (new Date()).getTime(), i.interactivity.events.onclick.enable) switch (i.interactivity.events.onclick.mode) { case 'push':i.particles.move.enable ? i.fn.modes.pushParticles(i.interactivity.modes.push.particles_nb, i.interactivity.mouse) : i.interactivity.modes.push.particles_nb == 1 ? i.fn.modes.pushParticles(i.interactivity.modes.push.particles_nb, i.interactivity.mouse) : i.interactivity.modes.push.particles_nb > 1 && i.fn.modes.pushParticles(i.interactivity.modes.push.particles_nb); break; case 'remove':i.fn.modes.removeParticles(i.interactivity.modes.remove.particles_nb); break; case 'bubble':i.tmp.bubble_clicking = !0; break; case 'repulse':i.tmp.repulse_clicking = !0, i.tmp.repulse_count = 0, i.tmp.repulse_finish = !1, setTimeout(function () { i.tmp.repulse_clicking = !1 }, 1e3 * i.interactivity.modes.repulse.duration) } }) }, i.fn.vendors.densityAutoParticles = function () { if (i.particles.number.density.enable) { var e = i.canvas.el.width * i.canvas.el.height / 1e3; i.tmp.retina && (e /= 2 * i.canvas.pxratio); var a = e * i.particles.number.value / i.particles.number.density.value_area, t = i.particles.array.length - a; t < 0 ? i.fn.modes.pushParticles(Math.abs(t)) : i.fn.modes.removeParticles(t) } }, i.fn.vendors.checkOverlap = function (e, a) { for (var t = 0; t < i.particles.array.length; t++) { var s = i.particles.array[t], n = e.x - s.x, r = e.y - s.y, c = Math.sqrt(n * n + r * r); c <= e.radius + s.radius && (e.x = a ? a.x : Math.random() * i.canvas.w, e.y = a ? a.y : Math.random() * i.canvas.h, i.fn.vendors.checkOverlap(e)) } }, i.fn.vendors.createSvgImg = function (e) { var a = i.tmp.source_svg, t = /#([0-9A-F]{3,6})/gi, s = a.replace(t, function (a, t, i, s) { if (e.color.rgb) var n = 'rgba(' + e.color.rgb.r + ',' + e.color.rgb.g + ',' + e.color.rgb.b + ',' + e.opacity + ')'; else var n = 'hsla(' + e.color.hsl.h + ',' + e.color.hsl.s + '%,' + e.color.hsl.l + '%,' + e.opacity + ')'; return n }), n = new Blob([s], {type: 'image/svg+xml;charset=utf-8'}), r = window.URL || window.webkitURL || window, c = r.createObjectURL(n), o = new Image(); o.addEventListener('load', function () { e.img.obj = o, e.img.loaded = !0, r.revokeObjectURL(c), i.tmp.count_svg++ }), o.src = c }, i.fn.vendors.destroypJS = function () { cancelAnimationFrame(i.fn.drawAnimFrame), t.remove(), pJSDom = null }, i.fn.vendors.drawShape = function (e, a, t, i, s, n) { var r = s * n, c = s / n, o = 180 * (c - 2) / c, l = Math.PI - Math.PI * o / 180; e.save(), e.beginPath(), e.translate(a, t), e.moveTo(0, 0); for (var v = 0; r > v; v++)e.lineTo(i, 0), e.translate(i, 0), e.rotate(l); e.fill(), e.restore() }, i.fn.vendors.exportImg = function () { window.open(i.canvas.el.toDataURL('image/png'), '_blank') }, i.fn.vendors.loadImg = function (e) { if (i.tmp.img_error = void 0, i.particles.shape.image.src != '') if (e == 'svg') { var a = new XMLHttpRequest(); a.open('GET', i.particles.shape.image.src), a.onreadystatechange = function (e) { a.readyState == 4 && (a.status == 200 ? (i.tmp.source_svg = e.currentTarget.response, i.fn.vendors.checkBeforeDraw()) : (console.log('Error pJS - Image not found'), i.tmp.img_error = !0)) }, a.send() } else { var t = new Image(); t.addEventListener('load', function () { i.tmp.img_obj = t, i.fn.vendors.checkBeforeDraw() }), t.src = i.particles.shape.image.src } else console.log('Error pJS - No image.src'), i.tmp.img_error = !0 }, i.fn.vendors.draw = function () { i.particles.shape.type == 'image' ? i.tmp.img_type == 'svg' ? i.tmp.count_svg >= i.particles.number.value ? (i.fn.particlesDraw(), i.particles.move.enable ? i.fn.drawAnimFrame = requestAnimFrame(i.fn.vendors.draw) : cancelRequestAnimFrame(i.fn.drawAnimFrame)) : i.tmp.img_error || (i.fn.drawAnimFrame = requestAnimFrame(i.fn.vendors.draw)) : void 0 != i.tmp.img_obj ? (i.fn.particlesDraw(), i.particles.move.enable ? i.fn.drawAnimFrame = requestAnimFrame(i.fn.vendors.draw) : cancelRequestAnimFrame(i.fn.drawAnimFrame)) : i.tmp.img_error || (i.fn.drawAnimFrame = requestAnimFrame(i.fn.vendors.draw)) : (i.fn.particlesDraw(), i.particles.move.enable ? i.fn.drawAnimFrame = requestAnimFrame(i.fn.vendors.draw) : cancelRequestAnimFrame(i.fn.drawAnimFrame)) }, i.fn.vendors.checkBeforeDraw = function () { i.particles.shape.type == 'image' ? i.tmp.img_type == 'svg' && void 0 == i.tmp.source_svg ? i.tmp.checkAnimFrame = requestAnimFrame(check) : (cancelRequestAnimFrame(i.tmp.checkAnimFrame), i.tmp.img_error || (i.fn.vendors.init(), i.fn.vendors.draw())) : (i.fn.vendors.init(), i.fn.vendors.draw()) }, i.fn.vendors.init = function () { i.fn.retinaInit(), i.fn.canvasInit(), i.fn.canvasSize(), i.fn.canvasPaint(), i.fn.particlesCreate(), i.fn.vendors.densityAutoParticles(), i.particles.line_linked.color_rgb_line = hexToRgb(i.particles.line_linked.color) }, i.fn.vendors.start = function () { isInArray('image', i.particles.shape.type) ? (i.tmp.img_type = i.particles.shape.image.src.substr(i.particles.shape.image.src.length - 3), i.fn.vendors.loadImg(i.tmp.img_type)) : i.fn.vendors.checkBeforeDraw() }, i.fn.vendors.eventsListeners(), i.fn.vendors.start() }; Object.deepExtend = function (e, a) { for (var t in a)a[t] && a[t].constructor && a[t].constructor === Object ? (e[t] = e[t] || {}, arguments.callee(e[t], a[t])) : e[t] = a[t]; return e }, window.requestAnimFrame = (function () { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (e) { window.setTimeout(e, 1e3 / 60) } }()), window.cancelRequestAnimFrame = (function () { return window.cancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || clearTimeout }()), window.pJSDom = [], window.particlesJS = function (e, a) { typeof e !== 'string' && (a = e, e = 'particles-js'), e || (e = 'particles-js'); var t = document.getElementById(e), i = 'particles-js-canvas-el', s = t.getElementsByClassName(i); if (s.length) for (;s.length > 0;)t.removeChild(s[0]); var n = document.createElement('canvas'); n.className = i, n.style.width = '100%', n.style.height = '100%'; var r = document.getElementById(e).appendChild(n); r != null && pJSDom.push(new pJS(e, a)) }, window.particlesJS.load = function (e, a, t) { var i = new XMLHttpRequest(); i.open('GET', a), i.onreadystatechange = function (a) { if (i.readyState == 4) if (i.status == 200) { var s = JSON.parse(a.currentTarget.response); window.particlesJS(e, s), t && t() } else console.log('Error pJS - XMLHttpRequest status: ' + i.status), console.log('Error pJS - File config not found') }, i.send() }
diff --git a/src/templates/Post.vue b/src/templates/Post.vue
new file mode 100644
index 0000000..6d94ee6
--- /dev/null
+++ b/src/templates/Post.vue
@@ -0,0 +1,47 @@
+
+
+
+
{{ $page.post.title }}
+
{{ $page.post.date }}
+
+
+ {{ tag.title }}
+
+
+
+
+ Back to Blog
+
+
+
+
+
+
+query Post ($path: String!) {
+ post: post (path: $path) {
+ title
+ date (format: "MMMM D, Y")
+ content
+ tags {
+ title
+ path
+ }
+ }
+}
+
+
+
+
+
diff --git a/src/templates/Project.vue b/src/templates/Project.vue
new file mode 100644
index 0000000..74c3f45
--- /dev/null
+++ b/src/templates/Project.vue
@@ -0,0 +1,37 @@
+
+
+